@sharpee/ext-testing 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 (121) hide show
  1. package/LICENSE +21 -0
  2. package/dist/annotations/context.d.ts +16 -0
  3. package/dist/annotations/context.d.ts.map +1 -0
  4. package/dist/annotations/context.js +42 -0
  5. package/dist/annotations/context.js.map +1 -0
  6. package/dist/annotations/index.d.ts +6 -0
  7. package/dist/annotations/index.d.ts.map +1 -0
  8. package/dist/annotations/index.js +12 -0
  9. package/dist/annotations/index.js.map +1 -0
  10. package/dist/annotations/store.d.ts +11 -0
  11. package/dist/annotations/store.d.ts.map +1 -0
  12. package/dist/annotations/store.js +191 -0
  13. package/dist/annotations/store.js.map +1 -0
  14. package/dist/checkpoints/index.d.ts +3 -0
  15. package/dist/checkpoints/index.d.ts.map +1 -0
  16. package/dist/checkpoints/index.js +12 -0
  17. package/dist/checkpoints/index.js.map +1 -0
  18. package/dist/checkpoints/serializer.d.ts +21 -0
  19. package/dist/checkpoints/serializer.d.ts.map +1 -0
  20. package/dist/checkpoints/serializer.js +95 -0
  21. package/dist/checkpoints/serializer.js.map +1 -0
  22. package/dist/checkpoints/store.d.ts +20 -0
  23. package/dist/checkpoints/store.d.ts.map +1 -0
  24. package/dist/checkpoints/store.js +193 -0
  25. package/dist/checkpoints/store.js.map +1 -0
  26. package/dist/commands/index.d.ts +2 -0
  27. package/dist/commands/index.d.ts.map +1 -0
  28. package/dist/commands/index.js +8 -0
  29. package/dist/commands/index.js.map +1 -0
  30. package/dist/commands/registry.d.ts +28 -0
  31. package/dist/commands/registry.d.ts.map +1 -0
  32. package/dist/commands/registry.js +70 -0
  33. package/dist/commands/registry.js.map +1 -0
  34. package/dist/context/debug-context.d.ts +21 -0
  35. package/dist/context/debug-context.d.ts.map +1 -0
  36. package/dist/context/debug-context.js +172 -0
  37. package/dist/context/debug-context.js.map +1 -0
  38. package/dist/context/index.d.ts +2 -0
  39. package/dist/context/index.d.ts.map +1 -0
  40. package/dist/context/index.js +8 -0
  41. package/dist/context/index.js.map +1 -0
  42. package/dist/extension.d.ts +78 -0
  43. package/dist/extension.d.ts.map +1 -0
  44. package/dist/extension.js +938 -0
  45. package/dist/extension.js.map +1 -0
  46. package/dist/index.d.ts +40 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +63 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/types.d.ts +375 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +8 -0
  53. package/dist/types.js.map +1 -0
  54. package/dist-npm/annotations/context.d.ts +16 -0
  55. package/dist-npm/annotations/context.d.ts.map +1 -0
  56. package/dist-npm/annotations/context.js +42 -0
  57. package/dist-npm/annotations/context.js.map +1 -0
  58. package/dist-npm/annotations/index.d.ts +6 -0
  59. package/dist-npm/annotations/index.d.ts.map +1 -0
  60. package/dist-npm/annotations/index.js +12 -0
  61. package/dist-npm/annotations/index.js.map +1 -0
  62. package/dist-npm/annotations/store.d.ts +11 -0
  63. package/dist-npm/annotations/store.d.ts.map +1 -0
  64. package/dist-npm/annotations/store.js +191 -0
  65. package/dist-npm/annotations/store.js.map +1 -0
  66. package/dist-npm/checkpoints/index.d.ts +3 -0
  67. package/dist-npm/checkpoints/index.d.ts.map +1 -0
  68. package/dist-npm/checkpoints/index.js +12 -0
  69. package/dist-npm/checkpoints/index.js.map +1 -0
  70. package/dist-npm/checkpoints/serializer.d.ts +21 -0
  71. package/dist-npm/checkpoints/serializer.d.ts.map +1 -0
  72. package/dist-npm/checkpoints/serializer.js +95 -0
  73. package/dist-npm/checkpoints/serializer.js.map +1 -0
  74. package/dist-npm/checkpoints/store.d.ts +20 -0
  75. package/dist-npm/checkpoints/store.d.ts.map +1 -0
  76. package/dist-npm/checkpoints/store.js +193 -0
  77. package/dist-npm/checkpoints/store.js.map +1 -0
  78. package/dist-npm/commands/index.d.ts +2 -0
  79. package/dist-npm/commands/index.d.ts.map +1 -0
  80. package/dist-npm/commands/index.js +8 -0
  81. package/dist-npm/commands/index.js.map +1 -0
  82. package/dist-npm/commands/registry.d.ts +28 -0
  83. package/dist-npm/commands/registry.d.ts.map +1 -0
  84. package/dist-npm/commands/registry.js +70 -0
  85. package/dist-npm/commands/registry.js.map +1 -0
  86. package/dist-npm/context/debug-context.d.ts +21 -0
  87. package/dist-npm/context/debug-context.d.ts.map +1 -0
  88. package/dist-npm/context/debug-context.js +172 -0
  89. package/dist-npm/context/debug-context.js.map +1 -0
  90. package/dist-npm/context/index.d.ts +2 -0
  91. package/dist-npm/context/index.d.ts.map +1 -0
  92. package/dist-npm/context/index.js +8 -0
  93. package/dist-npm/context/index.js.map +1 -0
  94. package/dist-npm/extension.d.ts +78 -0
  95. package/dist-npm/extension.d.ts.map +1 -0
  96. package/dist-npm/extension.js +938 -0
  97. package/dist-npm/extension.js.map +1 -0
  98. package/dist-npm/index.d.ts +40 -0
  99. package/dist-npm/index.d.ts.map +1 -0
  100. package/dist-npm/index.js +63 -0
  101. package/dist-npm/index.js.map +1 -0
  102. package/dist-npm/types.d.ts +375 -0
  103. package/dist-npm/types.d.ts.map +1 -0
  104. package/dist-npm/types.js +8 -0
  105. package/dist-npm/types.js.map +1 -0
  106. package/package.json +42 -0
  107. package/src/annotations/context.ts +47 -0
  108. package/src/annotations/index.ts +6 -0
  109. package/src/annotations/store.ts +219 -0
  110. package/src/checkpoints/index.ts +2 -0
  111. package/src/checkpoints/serializer.ts +121 -0
  112. package/src/checkpoints/store.ts +188 -0
  113. package/src/commands/index.ts +1 -0
  114. package/src/commands/registry.ts +81 -0
  115. package/src/context/debug-context.ts +209 -0
  116. package/src/context/index.ts +1 -0
  117. package/src/extension.ts +1089 -0
  118. package/src/index.ts +69 -0
  119. package/src/types.ts +469 -0
  120. package/tsconfig.json +16 -0
  121. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Debug Context Implementation
3
+ *
4
+ * Provides a unified context for debug and test commands to interact with the game world.
5
+ * Generalizes the pattern from Dungeo's GDTContext.
6
+ */
7
+
8
+ import type { WorldModel, IFEntity } from '@sharpee/world-model';
9
+ import { AuthorModel } from '@sharpee/world-model';
10
+ import type { DebugContext } from '../types.js';
11
+
12
+ /**
13
+ * Create a debug context for the given world
14
+ */
15
+ export function createDebugContext(world: WorldModel): DebugContext {
16
+ // Create AuthorModel for bypassing game rules
17
+ const author = new AuthorModel(world.getDataStore(), world);
18
+
19
+ // Debug flags storage
20
+ const flags = new Map<string, boolean>();
21
+
22
+ // Find player entity
23
+ const player = world.getPlayer();
24
+ if (!player) {
25
+ throw new Error('Cannot create debug context: no player entity found');
26
+ }
27
+
28
+ const context: DebugContext = {
29
+ world,
30
+ author,
31
+ player,
32
+ flags,
33
+
34
+ // ========================================================================
35
+ // Entity Lookup
36
+ // ========================================================================
37
+
38
+ findEntity(idOrName: string): IFEntity | undefined {
39
+ // Try exact ID match first
40
+ const byId = world.getEntity(idOrName);
41
+ if (byId) return byId;
42
+
43
+ // Normalize search term: lowercase, convert hyphens to spaces
44
+ const searchLower = idOrName.toLowerCase();
45
+ const searchNormalized = searchLower.replace(/-/g, ' ');
46
+ const allEntities = world.getAllEntities();
47
+
48
+ // Exact name match (with normalized search)
49
+ const exactMatch = allEntities.find(
50
+ (e) => e.name?.toLowerCase() === searchNormalized ||
51
+ e.name?.toLowerCase() === searchLower
52
+ );
53
+ if (exactMatch) return exactMatch;
54
+
55
+ // Partial name match (with normalized search)
56
+ const partialMatch = allEntities.find(
57
+ (e) => e.name?.toLowerCase().includes(searchNormalized) ||
58
+ e.name?.toLowerCase().includes(searchLower)
59
+ );
60
+ if (partialMatch) return partialMatch;
61
+
62
+ // ID contains search term
63
+ const idMatch = allEntities.find(
64
+ (e) => e.id.toLowerCase().includes(searchLower)
65
+ );
66
+ return idMatch;
67
+ },
68
+
69
+ findRoom(idOrName: string): IFEntity | undefined {
70
+ const entity = context.findEntity(idOrName);
71
+ if (entity && entity.type === 'room') {
72
+ return entity;
73
+ }
74
+
75
+ // Search only rooms
76
+ const searchLower = idOrName.toLowerCase();
77
+ const rooms = world.getAllEntities().filter((e) => e.type === 'room');
78
+
79
+ const exactMatch = rooms.find(
80
+ (r) => r.name?.toLowerCase() === searchLower
81
+ );
82
+ if (exactMatch) return exactMatch;
83
+
84
+ const partialMatch = rooms.find(
85
+ (r) => r.name?.toLowerCase().includes(searchLower) ||
86
+ r.id.toLowerCase().includes(searchLower)
87
+ );
88
+ return partialMatch;
89
+ },
90
+
91
+ findEntities(predicate: (entity: IFEntity) => boolean): IFEntity[] {
92
+ return world.getAllEntities().filter(predicate);
93
+ },
94
+
95
+ // ========================================================================
96
+ // Location Queries
97
+ // ========================================================================
98
+
99
+ getPlayerLocation(): IFEntity | undefined {
100
+ const locationId = world.getLocation(player.id);
101
+ if (!locationId) return undefined;
102
+ return world.getEntity(locationId);
103
+ },
104
+
105
+ getInventory(): IFEntity[] {
106
+ return world.getContents(player.id);
107
+ },
108
+
109
+ getContents(locationId: string): IFEntity[] {
110
+ return world.getContents(locationId);
111
+ },
112
+
113
+ // ========================================================================
114
+ // Mutations (bypass game rules via AuthorModel)
115
+ // ========================================================================
116
+
117
+ teleportPlayer(roomId: string): boolean {
118
+ const room = context.findRoom(roomId);
119
+ if (!room) return false;
120
+
121
+ author.moveEntity(player.id, room.id);
122
+ return true;
123
+ },
124
+
125
+ moveObject(objectId: string, locationId: string): boolean {
126
+ const object = context.findEntity(objectId);
127
+ const location = context.findEntity(locationId);
128
+
129
+ if (!object || !location) return false;
130
+
131
+ author.moveEntity(object.id, location.id);
132
+ return true;
133
+ },
134
+
135
+ takeObject(objectId: string): boolean {
136
+ const object = context.findEntity(objectId);
137
+ if (!object) return false;
138
+
139
+ author.moveEntity(object.id, player.id);
140
+ return true;
141
+ },
142
+
143
+ removeObject(objectId: string): boolean {
144
+ const object = context.findEntity(objectId);
145
+ if (!object) return false;
146
+
147
+ // Move to limbo (null location)
148
+ author.moveEntity(object.id, 'limbo');
149
+ return true;
150
+ },
151
+
152
+ spawnObject(objectId: string, locationId: string): boolean {
153
+ const object = context.findEntity(objectId);
154
+ const location = context.findEntity(locationId);
155
+
156
+ if (!object || !location) return false;
157
+
158
+ author.moveEntity(object.id, location.id);
159
+ return true;
160
+ },
161
+
162
+ // ========================================================================
163
+ // Flag Operations
164
+ // ========================================================================
165
+
166
+ setFlag(name: string, value: boolean): void {
167
+ flags.set(name, value);
168
+ },
169
+
170
+ getFlag(name: string): boolean {
171
+ return flags.get(name) ?? false;
172
+ },
173
+ };
174
+
175
+ return context;
176
+ }
177
+
178
+ /**
179
+ * Format entity for debug display
180
+ */
181
+ export function formatEntity(entity: IFEntity): string {
182
+ const traitTypes = entity.traits
183
+ ? Array.from(entity.traits.values()).map((t) => t.type.split('.').pop()).join(', ')
184
+ : 'none';
185
+ return `${entity.id} (${entity.name || 'unnamed'}) [${traitTypes}]`;
186
+ }
187
+
188
+ /**
189
+ * Format location chain for an entity
190
+ */
191
+ export function formatLocationChain(entity: IFEntity, world: WorldModel): string {
192
+ const chain: string[] = [entity.id];
193
+ let current = entity;
194
+ let depth = 0;
195
+
196
+ while (depth < 10) {
197
+ const locationId = world.getLocation(current.id);
198
+ if (!locationId) break;
199
+
200
+ chain.push(locationId);
201
+ const location = world.getEntity(locationId);
202
+ if (!location) break;
203
+
204
+ current = location;
205
+ depth++;
206
+ }
207
+
208
+ return chain.join(' -> ');
209
+ }
@@ -0,0 +1 @@
1
+ export { createDebugContext, formatEntity, formatLocationChain } from './debug-context.js';