@sharpee/engine 0.9.66-beta → 0.9.69-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 (77) hide show
  1. package/action-context-factory.d.ts +11 -0
  2. package/action-context-factory.d.ts.map +1 -0
  3. package/action-context-factory.js +258 -0
  4. package/action-context-factory.js.map +1 -0
  5. package/capability-dispatch-helper.d.ts +106 -0
  6. package/capability-dispatch-helper.d.ts.map +1 -0
  7. package/capability-dispatch-helper.js +269 -0
  8. package/capability-dispatch-helper.js.map +1 -0
  9. package/command-executor.d.ts +53 -0
  10. package/command-executor.d.ts.map +1 -0
  11. package/command-executor.js +329 -0
  12. package/command-executor.js.map +1 -0
  13. package/event-adapter.d.ts +44 -0
  14. package/event-adapter.d.ts.map +1 -0
  15. package/event-adapter.js +127 -0
  16. package/event-adapter.js.map +1 -0
  17. package/event-sequencer.d.ts +73 -0
  18. package/event-sequencer.d.ts.map +1 -0
  19. package/event-sequencer.js +134 -0
  20. package/event-sequencer.js.map +1 -0
  21. package/events/event-emitter.d.ts +34 -0
  22. package/events/event-emitter.d.ts.map +1 -0
  23. package/events/event-emitter.js +67 -0
  24. package/events/event-emitter.js.map +1 -0
  25. package/game-engine.d.ts +292 -0
  26. package/game-engine.d.ts.map +1 -0
  27. package/game-engine.js +1597 -0
  28. package/game-engine.js.map +1 -0
  29. package/index.d.ts +27 -0
  30. package/index.d.ts.map +1 -0
  31. package/index.js +63 -0
  32. package/index.js.map +1 -0
  33. package/narrative/index.d.ts +5 -0
  34. package/narrative/index.d.ts.map +1 -0
  35. package/narrative/index.js +10 -0
  36. package/narrative/index.js.map +1 -0
  37. package/narrative/narrative-settings.d.ts +73 -0
  38. package/narrative/narrative-settings.d.ts.map +1 -0
  39. package/narrative/narrative-settings.js +28 -0
  40. package/narrative/narrative-settings.js.map +1 -0
  41. package/package.json +1 -15
  42. package/parser-interface.d.ts +77 -0
  43. package/parser-interface.d.ts.map +1 -0
  44. package/parser-interface.js +48 -0
  45. package/parser-interface.js.map +1 -0
  46. package/platform-operations.d.ts +83 -0
  47. package/platform-operations.d.ts.map +1 -0
  48. package/platform-operations.js +218 -0
  49. package/platform-operations.js.map +1 -0
  50. package/save-restore-service.d.ts +125 -0
  51. package/save-restore-service.d.ts.map +1 -0
  52. package/save-restore-service.js +405 -0
  53. package/save-restore-service.js.map +1 -0
  54. package/shared-data-keys.d.ts +53 -0
  55. package/shared-data-keys.d.ts.map +1 -0
  56. package/shared-data-keys.js +29 -0
  57. package/shared-data-keys.js.map +1 -0
  58. package/story.d.ts +216 -0
  59. package/story.d.ts.map +1 -0
  60. package/story.js +60 -0
  61. package/story.js.map +1 -0
  62. package/test-helpers/mock-text-service.d.ts +11 -0
  63. package/test-helpers/mock-text-service.d.ts.map +1 -0
  64. package/test-helpers/mock-text-service.js +47 -0
  65. package/test-helpers/mock-text-service.js.map +1 -0
  66. package/turn-event-processor.d.ts +89 -0
  67. package/turn-event-processor.d.ts.map +1 -0
  68. package/turn-event-processor.js +144 -0
  69. package/turn-event-processor.js.map +1 -0
  70. package/types.d.ts +214 -0
  71. package/types.d.ts.map +1 -0
  72. package/types.js +8 -0
  73. package/types.js.map +1 -0
  74. package/vocabulary-manager.d.ts +35 -0
  75. package/vocabulary-manager.d.ts.map +1 -0
  76. package/vocabulary-manager.js +74 -0
  77. package/vocabulary-manager.js.map +1 -0
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Action Context Factory - Creates ActionContext for action execution
3
+ */
4
+ import { ActionContext, Action, ScopeResolver, ValidatedCommand } from "./src/index";
5
+ import { WorldModel } from "./src/index";
6
+ import { GameContext } from './types';
7
+ /**
8
+ * Create an ActionContext for action execution
9
+ */
10
+ export declare function createActionContext(world: WorldModel, gameContext: GameContext, command: ValidatedCommand, action: Action, scopeResolver: ScopeResolver): ActionContext;
11
+ //# sourceMappingURL=action-context-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-context-factory.d.ts","sourceRoot":"","sources":["../../../../../mnt/c/repotemp/sharpee/packages/engine/src/action-context-factory.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,gBAAgB,EAA+E,MAAM,iBAAiB,CAAC;AACtK,OAAO,EAAE,UAAU,EAAuB,MAAM,sBAAsB,CAAC;AAEvE,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AA+CtC;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,UAAU,EACjB,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,aAAa,GAC3B,aAAa,CAuPf"}
@@ -0,0 +1,258 @@
1
+ "use strict";
2
+ /**
3
+ * Action Context Factory - Creates ActionContext for action execution
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createActionContext = createActionContext;
7
+ const stdlib_1 = require("./src/index.js");
8
+ const world_model_1 = require("./src/index.js");
9
+ const core_1 = require("./src/index.js");
10
+ const shared_data_keys_1 = require("./shared-data-keys");
11
+ /**
12
+ * Helper to get entity from command slot
13
+ */
14
+ function getEntityFromSlot(command, slot) {
15
+ switch (slot) {
16
+ case 'target':
17
+ case 'directObject':
18
+ case 'item':
19
+ return command.directObject?.entity ?? null;
20
+ case 'container':
21
+ case 'recipient':
22
+ case 'instrument':
23
+ case 'indirectObject':
24
+ return command.indirectObject?.entity ?? null;
25
+ default:
26
+ return command.directObject?.entity ?? null;
27
+ }
28
+ }
29
+ /**
30
+ * Generate appropriate scope error based on requirement and actual scope
31
+ */
32
+ function getScopeError(required, actual, entity) {
33
+ const params = { item: entity.name };
34
+ if (actual === stdlib_1.ScopeLevel.UNAWARE) {
35
+ return { valid: false, error: stdlib_1.ScopeErrors.NOT_KNOWN, params };
36
+ }
37
+ if (required >= stdlib_1.ScopeLevel.VISIBLE && actual < stdlib_1.ScopeLevel.VISIBLE) {
38
+ return { valid: false, error: stdlib_1.ScopeErrors.NOT_VISIBLE, params };
39
+ }
40
+ if (required >= stdlib_1.ScopeLevel.REACHABLE && actual < stdlib_1.ScopeLevel.REACHABLE) {
41
+ return { valid: false, error: stdlib_1.ScopeErrors.NOT_REACHABLE, params };
42
+ }
43
+ if (required >= stdlib_1.ScopeLevel.CARRIED && actual < stdlib_1.ScopeLevel.CARRIED) {
44
+ return { valid: false, error: stdlib_1.ScopeErrors.NOT_CARRIED, params };
45
+ }
46
+ return { valid: false, error: stdlib_1.ScopeErrors.OUT_OF_SCOPE, params };
47
+ }
48
+ /**
49
+ * Create an ActionContext for action execution
50
+ */
51
+ function createActionContext(world, gameContext, command, action, scopeResolver) {
52
+ const player = gameContext.player;
53
+ const currentLocation = world.getLocation(player.id)
54
+ ? world.getEntity(world.getLocation(player.id))
55
+ : player;
56
+ // Create sharedData object separately so it can be referenced in closures
57
+ const sharedData = {};
58
+ // Create the event method
59
+ const event = (type, data) => {
60
+ // Add standard entities
61
+ const entities = {
62
+ actor: player.id,
63
+ location: currentLocation?.id || player.id
64
+ };
65
+ // Add entities from command
66
+ if (command.directObject?.entity) {
67
+ entities.target = command.directObject.entity.id;
68
+ }
69
+ if (command.indirectObject?.entity) {
70
+ entities.indirect = command.indirectObject.entity.id;
71
+ }
72
+ // Create the event
73
+ return {
74
+ id: `evt_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
75
+ type,
76
+ timestamp: Date.now(),
77
+ data: {
78
+ ...data,
79
+ // Include action context in data instead of metadata
80
+ actionId: action.id,
81
+ turn: gameContext.currentTurn
82
+ },
83
+ entities
84
+ };
85
+ };
86
+ return {
87
+ // World querying
88
+ world,
89
+ player,
90
+ currentLocation: currentLocation,
91
+ command,
92
+ scopeResolver,
93
+ action,
94
+ // Shared data for passing information between phases
95
+ sharedData,
96
+ // Validation result - set by CommandExecutor after validate() phase
97
+ validationResult: undefined,
98
+ // Scope checking methods (delegate to scopeResolver)
99
+ canSee: (entity) => {
100
+ return scopeResolver.canSee(player, entity);
101
+ },
102
+ canReach: (entity) => {
103
+ return scopeResolver.canReach(player, entity);
104
+ },
105
+ canTake: (entity) => {
106
+ // Basic implementation - can be enhanced
107
+ return !entity.has('if.trait.scenery') &&
108
+ !entity.has('if.trait.fixed') &&
109
+ entity.type !== 'room' &&
110
+ entity.type !== 'location';
111
+ },
112
+ isInScope: (entity) => {
113
+ const level = scopeResolver.getScope(player, entity);
114
+ return level >= stdlib_1.ScopeLevel.AWARE;
115
+ },
116
+ getVisible: () => {
117
+ return scopeResolver.getVisible(player);
118
+ },
119
+ getInScope: () => {
120
+ // Get all entities and filter by scope
121
+ const allEntities = world.getAllEntities();
122
+ return allEntities.filter(entity => {
123
+ const level = scopeResolver.getScope(player, entity);
124
+ return level >= stdlib_1.ScopeLevel.AWARE;
125
+ });
126
+ },
127
+ // Scope validation methods (Phase 4 parser refactor)
128
+ getEntityScope: (entity) => {
129
+ return scopeResolver.getScope(player, entity);
130
+ },
131
+ getSlotScope: (slot) => {
132
+ const entity = getEntityFromSlot(command, slot);
133
+ if (!entity) {
134
+ return stdlib_1.ScopeLevel.UNAWARE;
135
+ }
136
+ return scopeResolver.getScope(player, entity);
137
+ },
138
+ requireScope: (entity, required) => {
139
+ const actualScope = scopeResolver.getScope(player, entity);
140
+ if (actualScope >= required) {
141
+ return { ok: true, actualScope };
142
+ }
143
+ const error = getScopeError(required, actualScope, entity);
144
+ return { ok: false, error, actualScope };
145
+ },
146
+ requireSlotScope: (slot, required) => {
147
+ const entity = getEntityFromSlot(command, slot);
148
+ if (!entity) {
149
+ return {
150
+ ok: false,
151
+ error: { valid: false, error: 'no_target', params: { slot } }
152
+ };
153
+ }
154
+ const actualScope = scopeResolver.getScope(player, entity);
155
+ if (actualScope >= required) {
156
+ return { ok: true, actualScope };
157
+ }
158
+ const error = getScopeError(required, actualScope, entity);
159
+ return { ok: false, error, actualScope };
160
+ },
161
+ requireCarriedOrImplicitTake: (entity) => {
162
+ const actualScope = scopeResolver.getScope(player, entity);
163
+ // Case 1: Already carried - success, no implicit take needed
164
+ if (actualScope >= stdlib_1.ScopeLevel.CARRIED) {
165
+ return { ok: true };
166
+ }
167
+ // Case 2: Not reachable - can't take it, return scope error
168
+ if (actualScope < stdlib_1.ScopeLevel.REACHABLE) {
169
+ const error = getScopeError(stdlib_1.ScopeLevel.REACHABLE, actualScope, entity);
170
+ return { ok: false, error };
171
+ }
172
+ // Case 3: Reachable but not carried - attempt implicit take
173
+ // Check if implicit take is disabled at story level (ADR-104)
174
+ if (gameContext.implicitActions?.implicitTake === false) {
175
+ return {
176
+ ok: false,
177
+ error: { valid: false, error: stdlib_1.ScopeErrors.NOT_CARRIED, params: { item: entity.name } }
178
+ };
179
+ }
180
+ // Check if implicit take is disabled at action level (ADR-104)
181
+ if (action.allowImplicitTake === false) {
182
+ return {
183
+ ok: false,
184
+ error: { valid: false, error: stdlib_1.ScopeErrors.NOT_CARRIED, params: { item: entity.name } }
185
+ };
186
+ }
187
+ // Check if entity can be taken (not scenery, room, door)
188
+ if (entity.has(world_model_1.TraitType.SCENERY) || entity.has(world_model_1.TraitType.ROOM) || entity.has(world_model_1.TraitType.DOOR)) {
189
+ return {
190
+ ok: false,
191
+ error: { valid: false, error: 'fixed_in_place', params: { item: entity.name } }
192
+ };
193
+ }
194
+ // Create a synthetic command for the taking action
195
+ const takeCommand = {
196
+ parsed: {
197
+ rawInput: `take ${entity.name}`,
198
+ action: stdlib_1.takingAction.id,
199
+ tokens: [],
200
+ structure: { verb: { tokens: [0], text: 'take', head: 'take' } },
201
+ pattern: 'VERB_NOUN',
202
+ confidence: 1.0
203
+ },
204
+ actionId: stdlib_1.takingAction.id,
205
+ directObject: {
206
+ entity,
207
+ parsed: {
208
+ text: entity.name,
209
+ candidates: [entity.name]
210
+ }
211
+ }
212
+ };
213
+ // Create a sub-context for the taking action
214
+ const takeContext = createActionContext(world, gameContext, takeCommand, stdlib_1.takingAction, scopeResolver);
215
+ // Run the taking action's validate phase
216
+ const validation = stdlib_1.takingAction.validate(takeContext);
217
+ if (!validation.valid) {
218
+ // Take validation failed - return the error
219
+ return {
220
+ ok: false,
221
+ error: {
222
+ valid: false,
223
+ error: validation.error || 'cannot_take',
224
+ params: validation.params
225
+ }
226
+ };
227
+ }
228
+ // Execute the taking action
229
+ stdlib_1.takingAction.execute(takeContext);
230
+ // Get the report events from the taking action
231
+ const takeEvents = stdlib_1.takingAction.report ? stdlib_1.takingAction.report(takeContext) : [];
232
+ // Filter out action.success events - the implicit_take message replaces them
233
+ // Keep if.event.taken for state tracking
234
+ const filteredTakeEvents = takeEvents.filter(e => e.type !== 'action.success');
235
+ // Create the implicit take event (for "(first taking the X)" message)
236
+ const implicitTakeEvent = (0, core_1.createEvent)('if.event.implicit_take', {
237
+ item: entity.id,
238
+ itemName: entity.name
239
+ }, {
240
+ actor: player.id,
241
+ target: entity.id,
242
+ location: currentLocation?.id || player.id
243
+ });
244
+ // Combine: implicit take notification + state change events (no success message)
245
+ const implicitTakeEvents = [implicitTakeEvent, ...filteredTakeEvents];
246
+ // Store in sharedData for the report phase to access
247
+ const existingEvents = sharedData[shared_data_keys_1.SharedDataKeys.IMPLICIT_TAKE_EVENTS] ?? [];
248
+ sharedData[shared_data_keys_1.SharedDataKeys.IMPLICIT_TAKE_EVENTS] = [...existingEvents, ...implicitTakeEvents];
249
+ return {
250
+ ok: true,
251
+ implicitTakeEvents
252
+ };
253
+ },
254
+ // Event creation
255
+ event
256
+ };
257
+ }
258
+ //# sourceMappingURL=action-context-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-context-factory.js","sourceRoot":"","sources":["../../../../../../../../mnt/c/repotemp/sharpee/packages/engine/src/action-context-factory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Capability Dispatch Helper for Universal Dispatch
3
+ *
4
+ * Enables capability dispatch for ALL stdlib actions, not just specialized verbs.
5
+ * When an entity's trait declares a capability for an action, the trait's behavior
6
+ * handles the action instead of the stdlib default.
7
+ *
8
+ * This enables patterns like:
9
+ * - Troll blocking: TrollTrait handles 'if.action.going' to block passage
10
+ * - Custom containers: ChestTrait handles 'if.action.opening' for locked chest
11
+ * - Guardian items: AxeTrait handles 'if.action.taking' while troll guards it
12
+ *
13
+ * Resolution modes (ADR-090 extension):
14
+ * - first-wins: First entity with capability determines result
15
+ * - any-blocks: Any entity returning valid: false blocks
16
+ * - all-must-pass: All entities must return valid: true
17
+ * - highest-priority: Only highest priority entity is checked
18
+ */
19
+ import { ISemanticEvent } from "./src/index";
20
+ import { IFEntity, CapabilityBehavior, CapabilitySharedData, ITrait, CapabilityResolution } from "./src/index";
21
+ import { ActionContext, ValidationResult } from "./src/index";
22
+ /**
23
+ * A single capability claim from an entity.
24
+ */
25
+ export interface CapabilityClaim {
26
+ /** The entity making the claim */
27
+ entity: IFEntity;
28
+ /** The trait claiming the capability */
29
+ trait: ITrait;
30
+ /** The behavior to use */
31
+ behavior: CapabilityBehavior;
32
+ /** Priority for resolution ordering */
33
+ priority: number;
34
+ /** Resolution override from binding (if any) */
35
+ resolutionOverride?: CapabilityResolution;
36
+ }
37
+ /**
38
+ * Result of checking for capability dispatch.
39
+ */
40
+ export interface CapabilityDispatchCheck {
41
+ /** Whether capability dispatch should be used */
42
+ shouldDispatch: boolean;
43
+ /** The trait claiming the capability (if found) - for single dispatch */
44
+ trait?: ITrait;
45
+ /** The behavior to use (if found) - for single dispatch */
46
+ behavior?: CapabilityBehavior;
47
+ /** The entity with the capability - for single dispatch */
48
+ entity?: IFEntity;
49
+ /** All claims found (for multi-entity resolution) */
50
+ claims?: CapabilityClaim[];
51
+ /** Resolution mode to use */
52
+ resolution?: CapabilityResolution;
53
+ }
54
+ /**
55
+ * Data stored for capability dispatch between phases.
56
+ */
57
+ export interface CapabilityDispatchData {
58
+ trait: ITrait;
59
+ behavior: CapabilityBehavior;
60
+ entityId: string;
61
+ entityName: string;
62
+ sharedData: CapabilitySharedData;
63
+ }
64
+ /**
65
+ * Check if capability dispatch should be used for this action and target.
66
+ *
67
+ * @param actionId - The action being executed
68
+ * @param target - The target entity (directObject) - for backward compatibility
69
+ * @returns Check result with trait and behavior if dispatch should be used
70
+ */
71
+ export declare function checkCapabilityDispatch(actionId: string, target: IFEntity | undefined): CapabilityDispatchCheck;
72
+ /**
73
+ * Check if capability dispatch should be used for this action across multiple entities.
74
+ *
75
+ * Collects all capability claims from the provided entities, sorts by priority,
76
+ * and returns the appropriate dispatch information based on resolution config.
77
+ *
78
+ * @param actionId - The action being executed
79
+ * @param entities - All entities involved in the action (directObject, indirectObject, etc.)
80
+ * @returns Check result with claims and resolution mode
81
+ */
82
+ export declare function checkCapabilityDispatchMulti(actionId: string, entities: (IFEntity | undefined)[]): CapabilityDispatchCheck;
83
+ /**
84
+ * Execute capability dispatch validation phase.
85
+ *
86
+ * Handles resolution modes:
87
+ * - first-wins/highest-priority: Single behavior validates
88
+ * - any-blocks: All behaviors validate, any false blocks
89
+ * - all-must-pass: All behaviors must return true
90
+ *
91
+ * @returns ValidationResult with dispatch data if valid
92
+ */
93
+ export declare function executeCapabilityValidate(check: CapabilityDispatchCheck, context: ActionContext): ValidationResult;
94
+ /**
95
+ * Execute capability dispatch execute phase.
96
+ */
97
+ export declare function executeCapabilityExecute(context: ActionContext): void;
98
+ /**
99
+ * Execute capability dispatch report phase.
100
+ */
101
+ export declare function executeCapabilityReport(context: ActionContext): ISemanticEvent[];
102
+ /**
103
+ * Execute capability dispatch blocked phase.
104
+ */
105
+ export declare function executeCapabilityBlocked(context: ActionContext, result: ValidationResult, actionId: string): ISemanticEvent[];
106
+ //# sourceMappingURL=capability-dispatch-helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability-dispatch-helper.d.ts","sourceRoot":"","sources":["../../../../../mnt/c/repotemp/sharpee/packages/engine/src/capability-dispatch-helper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,QAAQ,EAKR,kBAAkB,EAClB,oBAAoB,EAEpB,MAAM,EAEN,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAU,aAAa,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kCAAkC;IAClC,MAAM,EAAE,QAAQ,CAAC;IACjB,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,iDAAiD;IACjD,cAAc,EAAE,OAAO,CAAC;IACxB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,2DAA2D;IAC3D,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,qDAAqD;IACrD,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B,6BAA6B;IAC7B,UAAU,CAAC,EAAE,oBAAoB,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,oBAAoB,CAAC;CAClC;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,QAAQ,GAAG,SAAS,GAC3B,uBAAuB,CAOzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,CAAC,QAAQ,GAAG,SAAS,CAAC,EAAE,GACjC,uBAAuB,CAmEzB;AAYD;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,uBAAuB,EAC9B,OAAO,EAAE,aAAa,GACrB,gBAAgB,CAiGlB;AAuCD;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,aAAa,GACrB,IAAI,CAUN;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,aAAa,GACrB,cAAc,EAAE,CAgBlB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,gBAAgB,EACxB,QAAQ,EAAE,MAAM,GACf,cAAc,EAAE,CAyBlB"}
@@ -0,0 +1,269 @@
1
+ "use strict";
2
+ /**
3
+ * Capability Dispatch Helper for Universal Dispatch
4
+ *
5
+ * Enables capability dispatch for ALL stdlib actions, not just specialized verbs.
6
+ * When an entity's trait declares a capability for an action, the trait's behavior
7
+ * handles the action instead of the stdlib default.
8
+ *
9
+ * This enables patterns like:
10
+ * - Troll blocking: TrollTrait handles 'if.action.going' to block passage
11
+ * - Custom containers: ChestTrait handles 'if.action.opening' for locked chest
12
+ * - Guardian items: AxeTrait handles 'if.action.taking' while troll guards it
13
+ *
14
+ * Resolution modes (ADR-090 extension):
15
+ * - first-wins: First entity with capability determines result
16
+ * - any-blocks: Any entity returning valid: false blocks
17
+ * - all-must-pass: All entities must return valid: true
18
+ * - highest-priority: Only highest priority entity is checked
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.checkCapabilityDispatch = checkCapabilityDispatch;
22
+ exports.checkCapabilityDispatchMulti = checkCapabilityDispatchMulti;
23
+ exports.executeCapabilityValidate = executeCapabilityValidate;
24
+ exports.executeCapabilityExecute = executeCapabilityExecute;
25
+ exports.executeCapabilityReport = executeCapabilityReport;
26
+ exports.executeCapabilityBlocked = executeCapabilityBlocked;
27
+ const world_model_1 = require("./src/index.js");
28
+ /**
29
+ * Check if capability dispatch should be used for this action and target.
30
+ *
31
+ * @param actionId - The action being executed
32
+ * @param target - The target entity (directObject) - for backward compatibility
33
+ * @returns Check result with trait and behavior if dispatch should be used
34
+ */
35
+ function checkCapabilityDispatch(actionId, target) {
36
+ if (!target) {
37
+ return { shouldDispatch: false };
38
+ }
39
+ // Use the multi-entity version with single entity
40
+ return checkCapabilityDispatchMulti(actionId, [target]);
41
+ }
42
+ /**
43
+ * Check if capability dispatch should be used for this action across multiple entities.
44
+ *
45
+ * Collects all capability claims from the provided entities, sorts by priority,
46
+ * and returns the appropriate dispatch information based on resolution config.
47
+ *
48
+ * @param actionId - The action being executed
49
+ * @param entities - All entities involved in the action (directObject, indirectObject, etc.)
50
+ * @returns Check result with claims and resolution mode
51
+ */
52
+ function checkCapabilityDispatchMulti(actionId, entities) {
53
+ const validEntities = entities.filter((e) => e !== undefined);
54
+ if (validEntities.length === 0) {
55
+ return { shouldDispatch: false };
56
+ }
57
+ // Collect all claims
58
+ const claims = [];
59
+ for (const entity of validEntities) {
60
+ const trait = (0, world_model_1.findTraitWithCapability)(entity, actionId);
61
+ if (!trait)
62
+ continue;
63
+ const binding = (0, world_model_1.getBehaviorBinding)(trait, actionId);
64
+ if (!binding) {
65
+ // Trait claims capability but no behavior registered
66
+ console.warn(`Universal dispatch: trait "${trait.type}" claims "${actionId}" ` +
67
+ `but no behavior registered. Falling back to stdlib action.`);
68
+ continue;
69
+ }
70
+ claims.push({
71
+ entity,
72
+ trait,
73
+ behavior: binding.behavior,
74
+ priority: binding.priority,
75
+ resolutionOverride: binding.resolution
76
+ });
77
+ }
78
+ if (claims.length === 0) {
79
+ return { shouldDispatch: false };
80
+ }
81
+ // Sort by priority (highest first)
82
+ claims.sort((a, b) => b.priority - a.priority);
83
+ // Get resolution mode (use first binding override if present, else global config)
84
+ const firstOverride = claims.find(c => c.resolutionOverride)?.resolutionOverride;
85
+ const config = (0, world_model_1.getCapabilityConfig)(actionId);
86
+ const resolution = firstOverride ?? config.resolution;
87
+ // For single claim or first-wins/highest-priority, return simple result
88
+ if (claims.length === 1 || resolution === 'first-wins' || resolution === 'highest-priority') {
89
+ const primary = claims[0];
90
+ return {
91
+ shouldDispatch: true,
92
+ trait: primary.trait,
93
+ behavior: primary.behavior,
94
+ entity: primary.entity,
95
+ claims,
96
+ resolution
97
+ };
98
+ }
99
+ // For any-blocks or all-must-pass, return all claims for aggregate validation
100
+ return {
101
+ shouldDispatch: true,
102
+ trait: claims[0].trait,
103
+ behavior: claims[0].behavior,
104
+ entity: claims[0].entity,
105
+ claims,
106
+ resolution
107
+ };
108
+ }
109
+ /**
110
+ * Convert capability effects to semantic events.
111
+ */
112
+ function effectsToEvents(effects, context) {
113
+ return effects.map(effect => context.event(effect.type, effect.payload));
114
+ }
115
+ /**
116
+ * Execute capability dispatch validation phase.
117
+ *
118
+ * Handles resolution modes:
119
+ * - first-wins/highest-priority: Single behavior validates
120
+ * - any-blocks: All behaviors validate, any false blocks
121
+ * - all-must-pass: All behaviors must return true
122
+ *
123
+ * @returns ValidationResult with dispatch data if valid
124
+ */
125
+ function executeCapabilityValidate(check, context) {
126
+ const { trait, behavior, entity, claims, resolution } = check;
127
+ if (!trait || !behavior || !entity) {
128
+ return { valid: false, error: 'capability_dispatch_error' };
129
+ }
130
+ // Create sharedData for passing data between behavior phases
131
+ const sharedData = {};
132
+ // For first-wins or highest-priority (or single claim), just validate the primary
133
+ if (!claims || claims.length <= 1 || resolution === 'first-wins' || resolution === 'highest-priority') {
134
+ return validateSingleBehavior(entity, trait, behavior, context, sharedData);
135
+ }
136
+ // For any-blocks: validate all, return first failure
137
+ if (resolution === 'any-blocks') {
138
+ for (const claim of claims) {
139
+ const claimSharedData = {};
140
+ const result = claim.behavior.validate(claim.entity, context.world, context.player.id, claimSharedData);
141
+ if (!result.valid) {
142
+ // This claim blocks - use its error
143
+ const data = {
144
+ trait: claim.trait,
145
+ behavior: claim.behavior,
146
+ entityId: claim.entity.id,
147
+ entityName: claim.entity.name,
148
+ sharedData: claimSharedData
149
+ };
150
+ return {
151
+ valid: false,
152
+ error: result.error,
153
+ params: result.params,
154
+ data
155
+ };
156
+ }
157
+ }
158
+ // All passed - use primary for execute/report
159
+ const data = {
160
+ trait,
161
+ behavior,
162
+ entityId: entity.id,
163
+ entityName: entity.name,
164
+ sharedData
165
+ };
166
+ return { valid: true, data };
167
+ }
168
+ // For all-must-pass: same logic as any-blocks (any failure = overall failure)
169
+ if (resolution === 'all-must-pass') {
170
+ for (const claim of claims) {
171
+ const claimSharedData = {};
172
+ const result = claim.behavior.validate(claim.entity, context.world, context.player.id, claimSharedData);
173
+ if (!result.valid) {
174
+ const data = {
175
+ trait: claim.trait,
176
+ behavior: claim.behavior,
177
+ entityId: claim.entity.id,
178
+ entityName: claim.entity.name,
179
+ sharedData: claimSharedData
180
+ };
181
+ return {
182
+ valid: false,
183
+ error: result.error,
184
+ params: result.params,
185
+ data
186
+ };
187
+ }
188
+ }
189
+ const data = {
190
+ trait,
191
+ behavior,
192
+ entityId: entity.id,
193
+ entityName: entity.name,
194
+ sharedData
195
+ };
196
+ return { valid: true, data };
197
+ }
198
+ // Default: first-wins fallback
199
+ return validateSingleBehavior(entity, trait, behavior, context, sharedData);
200
+ }
201
+ /**
202
+ * Validate a single behavior (helper for executeCapabilityValidate).
203
+ */
204
+ function validateSingleBehavior(entity, trait, behavior, context, sharedData) {
205
+ const behaviorResult = behavior.validate(entity, context.world, context.player.id, sharedData);
206
+ const data = {
207
+ trait,
208
+ behavior,
209
+ entityId: entity.id,
210
+ entityName: entity.name,
211
+ sharedData
212
+ };
213
+ if (!behaviorResult.valid) {
214
+ return {
215
+ valid: false,
216
+ error: behaviorResult.error,
217
+ params: behaviorResult.params,
218
+ data
219
+ };
220
+ }
221
+ return { valid: true, data };
222
+ }
223
+ /**
224
+ * Execute capability dispatch execute phase.
225
+ */
226
+ function executeCapabilityExecute(context) {
227
+ const data = context.validationResult?.data;
228
+ const entity = context.command.directObject?.entity;
229
+ if (!entity || !data?.behavior) {
230
+ return;
231
+ }
232
+ // Delegate execution to behavior
233
+ data.behavior.execute(entity, context.world, context.player.id, data.sharedData);
234
+ }
235
+ /**
236
+ * Execute capability dispatch report phase.
237
+ */
238
+ function executeCapabilityReport(context) {
239
+ const data = context.validationResult?.data;
240
+ const entity = context.command.directObject?.entity;
241
+ if (!entity || !data?.behavior) {
242
+ return [];
243
+ }
244
+ // Delegate reporting to behavior
245
+ const effects = data.behavior.report(entity, context.world, context.player.id, data.sharedData);
246
+ return effectsToEvents(effects, context);
247
+ }
248
+ /**
249
+ * Execute capability dispatch blocked phase.
250
+ */
251
+ function executeCapabilityBlocked(context, result, actionId) {
252
+ // Check both validationResult.data and result.data
253
+ const data = (context.validationResult?.data ?? result.data);
254
+ const entity = context.command.directObject?.entity;
255
+ // If we have a behavior, let it handle the blocked message
256
+ if (entity && data?.behavior) {
257
+ const effects = data.behavior.blocked(entity, context.world, context.player.id, result.error || 'action_blocked', data.sharedData);
258
+ return effectsToEvents(effects, context);
259
+ }
260
+ // Default blocked event (shouldn't normally reach here)
261
+ return [
262
+ context.event('action.blocked', {
263
+ actionId,
264
+ messageId: result.error || 'action_blocked',
265
+ params: result.params || {}
266
+ })
267
+ ];
268
+ }
269
+ //# sourceMappingURL=capability-dispatch-helper.js.map