@thijshakkenberg/valkyrie-mom-mcp 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/.claude-plugin/marketplace.json +20 -0
  2. package/.claude-plugin/plugin.json +2 -3
  3. package/.mcp.json +1 -2
  4. package/README.md +81 -22
  5. package/dist/catalogs/catalog-store.d.ts +10 -0
  6. package/dist/catalogs/catalog-store.d.ts.map +1 -1
  7. package/dist/catalogs/catalog-store.js +31 -0
  8. package/dist/catalogs/catalog-store.js.map +1 -1
  9. package/dist/diagnostics/bug-report-builder.d.ts +5 -0
  10. package/dist/diagnostics/bug-report-builder.d.ts.map +1 -0
  11. package/dist/diagnostics/bug-report-builder.js +112 -0
  12. package/dist/diagnostics/bug-report-builder.js.map +1 -0
  13. package/dist/diagnostics/ring-buffer.d.ts +16 -0
  14. package/dist/diagnostics/ring-buffer.d.ts.map +1 -0
  15. package/dist/diagnostics/ring-buffer.js +41 -0
  16. package/dist/diagnostics/ring-buffer.js.map +1 -0
  17. package/dist/diagnostics/session-trace.d.ts +19 -0
  18. package/dist/diagnostics/session-trace.d.ts.map +1 -0
  19. package/dist/diagnostics/session-trace.js +40 -0
  20. package/dist/diagnostics/session-trace.js.map +1 -0
  21. package/dist/diagnostics/tool-interceptor.d.ts +11 -0
  22. package/dist/diagnostics/tool-interceptor.d.ts.map +1 -0
  23. package/dist/diagnostics/tool-interceptor.js +73 -0
  24. package/dist/diagnostics/tool-interceptor.js.map +1 -0
  25. package/dist/diagnostics/types.d.ts +51 -0
  26. package/dist/diagnostics/types.d.ts.map +1 -0
  27. package/dist/diagnostics/types.js +2 -0
  28. package/dist/diagnostics/types.js.map +1 -0
  29. package/dist/diagnostics/valkyrie-log-finder.d.ts +12 -0
  30. package/dist/diagnostics/valkyrie-log-finder.d.ts.map +1 -0
  31. package/dist/diagnostics/valkyrie-log-finder.js +46 -0
  32. package/dist/diagnostics/valkyrie-log-finder.js.map +1 -0
  33. package/dist/io/localization-io.d.ts.map +1 -1
  34. package/dist/io/localization-io.js +3 -1
  35. package/dist/io/localization-io.js.map +1 -1
  36. package/dist/model/component-types.d.ts +1 -0
  37. package/dist/model/component-types.d.ts.map +1 -1
  38. package/dist/model/component-types.js +3 -0
  39. package/dist/model/component-types.js.map +1 -1
  40. package/dist/model/scenario-model.d.ts.map +1 -1
  41. package/dist/model/scenario-model.js +1 -0
  42. package/dist/model/scenario-model.js.map +1 -1
  43. package/dist/resources/format-docs.d.ts +3 -3
  44. package/dist/resources/format-docs.d.ts.map +1 -1
  45. package/dist/resources/format-docs.js +22 -3
  46. package/dist/resources/format-docs.js.map +1 -1
  47. package/dist/server.d.ts.map +1 -1
  48. package/dist/server.js +23 -0
  49. package/dist/server.js.map +1 -1
  50. package/dist/tools/lifecycle.d.ts.map +1 -1
  51. package/dist/tools/lifecycle.js +49 -11
  52. package/dist/tools/lifecycle.js.map +1 -1
  53. package/dist/tools/upsert.d.ts.map +1 -1
  54. package/dist/tools/upsert.js +143 -3
  55. package/dist/tools/upsert.js.map +1 -1
  56. package/dist/validation/rules/catalog-references.d.ts.map +1 -1
  57. package/dist/validation/rules/catalog-references.js +34 -9
  58. package/dist/validation/rules/catalog-references.js.map +1 -1
  59. package/dist/validation/rules/format-rules.d.ts.map +1 -1
  60. package/dist/validation/rules/format-rules.js +19 -0
  61. package/dist/validation/rules/format-rules.js.map +1 -1
  62. package/dist/validation/rules/localization-completeness.d.ts.map +1 -1
  63. package/dist/validation/rules/localization-completeness.js +15 -0
  64. package/dist/validation/rules/localization-completeness.js.map +1 -1
  65. package/dist/validation/rules/token-event-wiring.d.ts +8 -0
  66. package/dist/validation/rules/token-event-wiring.d.ts.map +1 -0
  67. package/dist/validation/rules/token-event-wiring.js +25 -0
  68. package/dist/validation/rules/token-event-wiring.js.map +1 -0
  69. package/dist/validation/validator.d.ts.map +1 -1
  70. package/dist/validation/validator.js +2 -0
  71. package/dist/validation/validator.js.map +1 -1
  72. package/package.json +4 -1
  73. package/src/catalogs/catalog-store.ts +34 -0
  74. package/src/diagnostics/bug-report-builder.ts +142 -0
  75. package/src/diagnostics/ring-buffer.ts +44 -0
  76. package/src/diagnostics/session-trace.ts +51 -0
  77. package/src/diagnostics/tool-interceptor.ts +74 -0
  78. package/src/diagnostics/types.ts +53 -0
  79. package/src/diagnostics/valkyrie-log-finder.ts +47 -0
  80. package/src/io/localization-io.ts +3 -1
  81. package/src/model/component-types.ts +3 -0
  82. package/src/model/scenario-model.ts +1 -0
  83. package/src/resources/format-docs.ts +22 -3
  84. package/src/server.ts +32 -0
  85. package/src/tools/lifecycle.ts +47 -12
  86. package/src/tools/upsert.ts +168 -3
  87. package/src/validation/rules/catalog-references.ts +35 -8
  88. package/src/validation/rules/format-rules.ts +20 -0
  89. package/src/validation/rules/localization-completeness.ts +16 -0
  90. package/src/validation/rules/token-event-wiring.ts +30 -0
  91. package/src/validation/validator.ts +2 -0
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
3
+ "name": "valkyrie-mom",
4
+ "description": "Valkyrie Mansions of Madness scenario editor plugin and MCP server",
5
+ "owner": {
6
+ "name": "Thijs Hakkenberg"
7
+ },
8
+ "plugins": [
9
+ {
10
+ "name": "valkyrie-mom",
11
+ "description": "AI-assisted Mansions of Madness scenario editor for Valkyrie — MCP server, 7 skills, and scenario designer agent",
12
+ "version": "1.0.1",
13
+ "author": {
14
+ "name": "Thijs Hakkenberg"
15
+ },
16
+ "source": "./",
17
+ "category": "development"
18
+ }
19
+ ]
20
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "valkyrie-mom",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "AI-assisted Mansions of Madness scenario editor for Valkyrie",
5
5
  "author": {
6
6
  "name": "Thijs Hakkenberg"
@@ -10,8 +10,7 @@
10
10
  "mcpServers": {
11
11
  "valkyrie-mom": {
12
12
  "command": "npx",
13
- "args": ["tsx", "${CLAUDE_PLUGIN_ROOT}/src/index.ts"],
14
- "cwd": "${CLAUDE_PLUGIN_ROOT}"
13
+ "args": ["-y", "@thijshakkenberg/valkyrie-mom-mcp"]
15
14
  }
16
15
  }
17
16
  }
package/.mcp.json CHANGED
@@ -2,8 +2,7 @@
2
2
  "mcpServers": {
3
3
  "valkyrie-mom": {
4
4
  "command": "npx",
5
- "args": ["tsx", "${CLAUDE_PLUGIN_ROOT}/src/index.ts"],
6
- "cwd": "${CLAUDE_PLUGIN_ROOT}"
5
+ "args": ["-y", "@thijshakkenberg/valkyrie-mom-mcp"]
7
6
  }
8
7
  }
9
8
  }
package/README.md CHANGED
@@ -1,47 +1,79 @@
1
1
  # valkyrie-mom-mcp
2
2
 
3
- MCP (Model Context Protocol) server for AI-assisted Mansions of Madness 2nd Edition scenario creation with [Valkyrie](https://github.com/NPBruce/valkyrie).
3
+ [![npm](https://img.shields.io/npm/v/@thijshakkenberg/valkyrie-mom-mcp)](https://www.npmjs.com/package/@thijshakkenberg/valkyrie-mom-mcp)
4
+
5
+ MCP (Model Context Protocol) server and Claude Code plugin for AI-assisted Mansions of Madness 2nd Edition scenario creation with [Valkyrie](https://github.com/NPBruce/valkyrie).
4
6
 
5
7
  ## What it does
6
8
 
7
9
  This server exposes Valkyrie scenario editing as MCP tools, enabling AI assistants (Claude, etc.) to create, modify, validate, and build complete MoM scenarios. It auto-detects the Valkyrie editor directory so scenarios appear directly in the app.
8
10
 
9
- ## Prerequisites
11
+ The plugin bundles 7 skills covering advanced patterns (event loops, mythos scaling, tile placement chains, custom puzzles, etc.) and an autonomous scenario designer agent.
10
12
 
11
- - [Node.js](https://nodejs.org/) >= 18
12
- - [Valkyrie](https://github.com/NPBruce/valkyrie) (optional, for playing built scenarios)
13
+ ## Install
13
14
 
14
- ## Setup
15
+ ### As a Claude Code plugin (recommended)
15
16
 
16
17
  ```bash
17
- npm install
18
+ claude plugin marketplace add thijs-hakkenberg/ValkyrieMCP
19
+ claude plugin install valkyrie-mom
18
20
  ```
19
21
 
20
- ### As an MCP server (Claude Code, Claude Desktop, etc.)
22
+ This gives you:
23
+ - **MCP server** with 20 tools for scenario editing (auto-started)
24
+ - **7 skills**: `/scenario`, `/event-patterns`, `/tile-placement`, `/variables-and-mythos`, `/custom-monsters`, `/ui-and-puzzles`, `/items-and-distribution`
25
+ - **Scenario designer agent** for autonomous scenario creation
26
+ - **5 MCP resources** for format documentation
21
27
 
22
- Add to your `.mcp.json` or MCP client config:
28
+ To update to the latest version:
29
+ ```bash
30
+ claude plugin marketplace update valkyrie-mom
31
+ claude plugin update valkyrie-mom
32
+ ```
33
+
34
+ To uninstall:
35
+ ```bash
36
+ claude plugin uninstall valkyrie-mom
37
+ ```
38
+
39
+ ### As a standalone MCP server (Claude Desktop, other MCP clients)
40
+
41
+ Add to your MCP client config (e.g., `~/.claude/mcp.json` or Claude Desktop settings):
23
42
 
24
43
  ```json
25
44
  {
26
45
  "mcpServers": {
27
46
  "valkyrie-mom": {
28
47
  "command": "npx",
29
- "args": ["tsx", "src/index.ts"],
30
- "cwd": "/path/to/valkyrie_mom_mcp"
48
+ "args": ["-y", "@thijshakkenberg/valkyrie-mom-mcp"]
31
49
  }
32
50
  }
33
51
  }
34
52
  ```
35
53
 
36
- ### Development
54
+ This gives you the MCP tools and resources, but not the skills or agent (those require Claude Code).
55
+
56
+ ### From source
37
57
 
38
58
  ```bash
39
- npm test # Run all tests
40
- npm run test:watch # Watch mode
41
- npm run lint # Type check
42
- npm run build # Compile to dist/
59
+ git clone https://github.com/thijs-hakkenberg/ValkyrieMCP.git
60
+ cd ValkyrieMCP
61
+ npm install
62
+ npx tsx src/index.ts # Run MCP server via stdio
43
63
  ```
44
64
 
65
+ ## Skills
66
+
67
+ | Skill | Description |
68
+ |-------|-------------|
69
+ | `/scenario` | Guided end-to-end scenario creation workflow |
70
+ | `/event-patterns` | Event loops, multi-question dialogues, silent events, token swaps, random events, variable branching |
71
+ | `/tile-placement` | Standard placement chains, multi-entry tiles, naming conventions |
72
+ | `/variables-and-mythos` | Variable system, mythos scaling formula, random generation, hero detection, content pack gating |
73
+ | `/custom-monsters` | Custom activations, evade/horror events, round-based spawn triggering |
74
+ | `/ui-and-puzzles` | Prologues, interactive journals, combination locks, built-in puzzle types |
75
+ | `/items-and-distribution` | Random items, unique items, starting items, inspection events |
76
+
45
77
  ## MCP Tools
46
78
 
47
79
  ### Lifecycle
@@ -77,7 +109,12 @@ npm run build # Compile to dist/
77
109
  ### Reference
78
110
  | Tool | Description |
79
111
  |------|-------------|
80
- | `search_game_content` | Search game content catalogs |
112
+ | `search_game_content` | Search game content catalogs (846 entries across tiles, monsters, items, audio) |
113
+
114
+ ### Diagnostics
115
+ | Tool | Description |
116
+ |------|-------------|
117
+ | `export_bug_report` | Generate a ZIP bug report with session trace, scenario files, validation results, and Valkyrie logs |
81
118
 
82
119
  ## MCP Resources
83
120
 
@@ -86,6 +123,7 @@ npm run build # Compile to dist/
86
123
  | Event format docs | `valkyrie://format/events` |
87
124
  | Localization format docs | `valkyrie://format/localization` |
88
125
  | Component format docs | `valkyrie://format/components` |
126
+ | Pattern reference | `valkyrie://format/patterns` |
89
127
  | Current scenario state | `valkyrie://scenario/current` |
90
128
 
91
129
  ## MCP Prompts
@@ -122,25 +160,45 @@ Built scenarios are ZIP archives with a `.valkyrie` extension.
122
160
 
123
161
  ## Validation Rules
124
162
 
125
- The server validates scenarios against 6 rule sets:
163
+ The server validates scenarios against 12 rule categories:
126
164
 
127
165
  1. **Unique names** - No duplicate component names
128
166
  2. **Required fields** - Tiles have `side`, displayed events have `buttons`
129
- 3. **Cross-references** - All referenced components exist (built-in game content like `Monster*` is exempt)
167
+ 3. **Cross-references** - All referenced components exist
130
168
  4. **Event graph** - `EventStart` trigger exists, no unreachable/dead-end events
131
- 5. **Localization completeness** - `quest.name`, `quest.description`, event text, button labels
132
- 6. **Format rules** - Valid format version, type=MoM, tile rotations in {0, 90, 180, 270}
169
+ 5. **Event flow** - Buttons vs event-ref consistency, silent event rules
170
+ 6. **Localization completeness** - Event text, button labels, quest metadata
171
+ 7. **Format rules** - Valid format version, type=MoM, tile rotations
172
+ 8. **Catalog references** - Tile sides, monster names, items match game content
173
+ 9. **Tile connectivity** - Tiles are spatially connected
174
+ 10. **Mythos structure** - Proper mythos trigger configuration
175
+ 11. **Investigator token** - TokenInvestigators setup and removal
176
+ 12. **Explore token** - Explore tokens linked to tile reveal events
177
+
178
+ ## Development
179
+
180
+ ```bash
181
+ npm test # Run all tests (1096 tests across 36 files)
182
+ npm run test:watch # Watch mode
183
+ npm run lint # Type check
184
+ npm run build # Compile to dist/
185
+ ```
133
186
 
134
187
  ## Project Structure
135
188
 
136
189
  ```
190
+ .claude-plugin/ Plugin manifest
191
+ skills/ 7 skill SKILL.md files
192
+ agents/ Scenario designer agent
137
193
  src/
138
194
  io/ INI parser/writer, localization CSV, ZIP packager
139
195
  model/ ScenarioModel, LocalizationStore, component types
140
- validation/ 6 rules + orchestrator
196
+ validation/ 12 rules + orchestrator
141
197
  rules/ Individual validation rule implementations
142
198
  tools/ MCP tool implementations
143
199
  resources/ Format documentation resources
200
+ catalogs/ 846-entry game content catalog
201
+ diagnostics/ Bug report builder, session trace, ring buffer
144
202
  server.ts MCP server registration
145
203
  index.ts Entry point (stdio transport)
146
204
  tests/
@@ -149,6 +207,7 @@ tests/
149
207
  model/ Model layer tests
150
208
  tools/ Tool tests
151
209
  validation/ Validation rule tests
210
+ diagnostics/ Diagnostics tests
152
211
  golden.test.ts Round-trip integrity tests
153
212
  integration.test.ts Full pipeline tests
154
213
  ```
@@ -161,4 +220,4 @@ tests/
161
220
 
162
221
  ## License
163
222
 
164
- ISC
223
+ MIT
@@ -1,4 +1,8 @@
1
1
  import type { CatalogEntry, CatalogType } from './catalog-types.js';
2
+ /** Maps lowercase catalog pack IDs to Valkyrie's case-sensitive pack IDs */
3
+ export declare const PACK_ID_MAP: Record<string, string>;
4
+ /** Convert a catalog pack ID (lowercase) to Valkyrie's case-sensitive pack ID */
5
+ export declare function getValkyriePackId(catalogPack: string): string;
2
6
  export declare class CatalogStore {
3
7
  private entries;
4
8
  private byId;
@@ -15,6 +19,12 @@ export declare class CatalogStore {
15
19
  getByType(type: CatalogType): CatalogEntry[];
16
20
  /** Get a Set of all entry IDs, optionally filtered by type. */
17
21
  getAllIds(type?: CatalogType): Set<string>;
22
+ /** Get the Valkyrie pack ID for a catalog pack string */
23
+ getPackId(catalogPack: string): string;
24
+ /** Look up a tile side's pack from catalog, return Valkyrie pack ID */
25
+ getPackForTileSide(tileId: string): string | undefined;
26
+ /** Look up a monster's pack from catalog, return Valkyrie pack ID */
27
+ getPackForMonster(monsterId: string): string | undefined;
18
28
  }
19
29
  export declare function getSharedCatalog(): CatalogStore;
20
30
  //# sourceMappingURL=catalog-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"catalog-store.d.ts","sourceRoot":"","sources":["../../src/catalogs/catalog-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAYpE,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,IAAI,CAA4B;IACxC,OAAO,CAAC,MAAM,CAAmC;;IAoCjD;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,YAAY,EAAE;IAazD,uCAAuC;IACvC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAI7C,uCAAuC;IACvC,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,EAAE;IAI5C,+DAA+D;IAC/D,SAAS,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC;CAI3C;AAKD,wBAAgB,gBAAgB,IAAI,YAAY,CAK/C"}
1
+ {"version":3,"file":"catalog-store.d.ts","sourceRoot":"","sources":["../../src/catalogs/catalog-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAYpE,4EAA4E;AAC5E,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAO9C,CAAC;AAEF,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,IAAI,CAA4B;IACxC,OAAO,CAAC,MAAM,CAAmC;;IAoCjD;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,YAAY,EAAE;IAazD,uCAAuC;IACvC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAI7C,uCAAuC;IACvC,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,EAAE;IAI5C,+DAA+D;IAC/D,SAAS,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC;IAK1C,yDAAyD;IACzD,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAItC,uEAAuE;IACvE,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAMtD,qEAAqE;IACrE,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;CAKzD;AAKD,wBAAgB,gBAAgB,IAAI,YAAY,CAK/C"}
@@ -1,5 +1,18 @@
1
1
  import { MONSTERS, TILES, AUDIO, ITEMS, INVESTIGATORS, PUZZLES, TOKENS, } from './data/all-catalogs.js';
2
2
  import { TILE_GEOMETRY } from './data/tile-geometry.js';
3
+ /** Maps lowercase catalog pack IDs to Valkyrie's case-sensitive pack IDs */
4
+ export const PACK_ID_MAP = {
5
+ base: 'MoMBase',
6
+ btt: 'BtT',
7
+ hj: 'HJ',
8
+ pots: 'PotS',
9
+ soa: 'SoA',
10
+ sot: 'SoT',
11
+ };
12
+ /** Convert a catalog pack ID (lowercase) to Valkyrie's case-sensitive pack ID */
13
+ export function getValkyriePackId(catalogPack) {
14
+ return PACK_ID_MAP[catalogPack] ?? catalogPack;
15
+ }
3
16
  export class CatalogStore {
4
17
  entries;
5
18
  byId;
@@ -66,6 +79,24 @@ export class CatalogStore {
66
79
  const source = type ? (this.byType.get(type) ?? []) : this.entries;
67
80
  return new Set(source.map(e => e.id));
68
81
  }
82
+ /** Get the Valkyrie pack ID for a catalog pack string */
83
+ getPackId(catalogPack) {
84
+ return getValkyriePackId(catalogPack);
85
+ }
86
+ /** Look up a tile side's pack from catalog, return Valkyrie pack ID */
87
+ getPackForTileSide(tileId) {
88
+ const entry = this.byId.get(tileId);
89
+ if (!entry || entry.type !== 'tile')
90
+ return undefined;
91
+ return getValkyriePackId(entry.pack);
92
+ }
93
+ /** Look up a monster's pack from catalog, return Valkyrie pack ID */
94
+ getPackForMonster(monsterId) {
95
+ const entry = this.byId.get(monsterId);
96
+ if (!entry || entry.type !== 'monster')
97
+ return undefined;
98
+ return getValkyriePackId(entry.pack);
99
+ }
69
100
  }
70
101
  /** Shared singleton instance — avoids re-indexing 846 entries multiple times */
71
102
  let sharedInstance = null;
@@ -1 +1 @@
1
- {"version":3,"file":"catalog-store.js","sourceRoot":"","sources":["../../src/catalogs/catalog-store.ts"],"names":[],"mappings":"AACA,OAAO,EACL,QAAQ,EACR,KAAK,EACL,KAAK,EACL,KAAK,EACL,aAAa,EACb,OAAO,EACP,MAAM,GACP,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,MAAM,OAAO,YAAY;IACf,OAAO,CAAiB;IACxB,IAAI,CAA4B;IAChC,MAAM,CAAmC;IAEjD;QACE,IAAI,CAAC,OAAO,GAAG;YACb,GAAG,QAAQ;YACX,GAAG,KAAK;YACR,GAAG,KAAK;YACR,GAAG,KAAK;YACR,GAAG,aAAa;YAChB,GAAG,OAAO;YACV,GAAG,MAAM;SACV,CAAC;QAEF,6CAA6C;QAC7C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1B,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACpC,IAAI,GAAG,EAAE,CAAC;oBACR,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;oBACtB,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;oBACxB,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;gBACxB,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;QAExB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACnD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAAa,EAAE,IAAkB;QACtC,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;QAEnE,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YAC3B,IAAI,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YACpD,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YACtD,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YACrE,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YACxF,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;IACL,CAAC;IAED,uCAAuC;IACvC,OAAO,CAAC,EAAU;QAChB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED,uCAAuC;IACvC,SAAS,CAAC,IAAiB;QACzB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACrC,CAAC;IAED,+DAA+D;IAC/D,SAAS,CAAC,IAAkB;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;QACnE,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACxC,CAAC;CACF;AAED,gFAAgF;AAChF,IAAI,cAAc,GAAwB,IAAI,CAAC;AAE/C,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,cAAc,GAAG,IAAI,YAAY,EAAE,CAAC;IACtC,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC"}
1
+ {"version":3,"file":"catalog-store.js","sourceRoot":"","sources":["../../src/catalogs/catalog-store.ts"],"names":[],"mappings":"AACA,OAAO,EACL,QAAQ,EACR,KAAK,EACL,KAAK,EACL,KAAK,EACL,aAAa,EACb,OAAO,EACP,MAAM,GACP,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,4EAA4E;AAC5E,MAAM,CAAC,MAAM,WAAW,GAA2B;IACjD,IAAI,EAAE,SAAS;IACf,GAAG,EAAE,KAAK;IACV,EAAE,EAAE,IAAI;IACR,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;CACX,CAAC;AAEF,iFAAiF;AACjF,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,OAAO,WAAW,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC;AACjD,CAAC;AAED,MAAM,OAAO,YAAY;IACf,OAAO,CAAiB;IACxB,IAAI,CAA4B;IAChC,MAAM,CAAmC;IAEjD;QACE,IAAI,CAAC,OAAO,GAAG;YACb,GAAG,QAAQ;YACX,GAAG,KAAK;YACR,GAAG,KAAK;YACR,GAAG,KAAK;YACR,GAAG,aAAa;YAChB,GAAG,OAAO;YACV,GAAG,MAAM;SACV,CAAC;QAEF,6CAA6C;QAC7C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1B,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACpC,IAAI,GAAG,EAAE,CAAC;oBACR,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;oBACtB,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;oBACxB,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;gBACxB,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;QAExB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACnD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAAa,EAAE,IAAkB;QACtC,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;QAEnE,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YAC3B,IAAI,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YACpD,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YACtD,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YACrE,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YACxF,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;IACL,CAAC;IAED,uCAAuC;IACvC,OAAO,CAAC,EAAU;QAChB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED,uCAAuC;IACvC,SAAS,CAAC,IAAiB;QACzB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACrC,CAAC;IAED,+DAA+D;IAC/D,SAAS,CAAC,IAAkB;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;QACnE,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,yDAAyD;IACzD,SAAS,CAAC,WAAmB;QAC3B,OAAO,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACxC,CAAC;IAED,uEAAuE;IACvE,kBAAkB,CAAC,MAAc;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,SAAS,CAAC;QACtD,OAAO,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,qEAAqE;IACrE,iBAAiB,CAAC,SAAiB;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACzD,OAAO,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;CACF;AAED,gFAAgF;AAChF,IAAI,cAAc,GAAwB,IAAI,CAAC;AAE/C,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,cAAc,GAAG,IAAI,YAAY,EAAE,CAAC;IACtC,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { SessionTrace } from './session-trace.js';
2
+ import type { ScenarioModel } from '../model/scenario-model.js';
3
+ import type { BugReportOptions, BugReportResult } from './types.js';
4
+ export declare function buildBugReport(trace: SessionTrace, model: ScenarioModel | null, options?: BugReportOptions): Promise<BugReportResult>;
5
+ //# sourceMappingURL=bug-report-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bug-report-builder.d.ts","sourceRoot":"","sources":["../../src/diagnostics/bug-report-builder.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAqBpE,wBAAsB,cAAc,CAClC,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,aAAa,GAAG,IAAI,EAC3B,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC,CA8G1B"}
@@ -0,0 +1,112 @@
1
+ import archiver from 'archiver';
2
+ import * as fs from 'node:fs';
3
+ import * as os from 'node:os';
4
+ import * as path from 'node:path';
5
+ import { validateScenario } from '../validation/validator.js';
6
+ import { getValkyrieLogPath, readLogTail } from './valkyrie-log-finder.js';
7
+ const README_TEXT = `Valkyrie MoM MCP - Bug Report
8
+ ==============================
9
+
10
+ This ZIP was generated by the export_bug_report tool.
11
+
12
+ Contents:
13
+ report.json - Session metadata and trace of MCP tool calls
14
+ validation.json - Validation results at time of export
15
+ scenario/ - Scenario INI files (if a scenario was loaded)
16
+ valkyrie-logs/ - Valkyrie Player.log tail (if found)
17
+
18
+ How to file an issue:
19
+ 1. Go to https://github.com/thijs-hakkenberg/ValkyrieMCP/issues/new
20
+ 2. Paste the issue template from the tool output
21
+ 3. Drag and drop this ZIP file into the issue
22
+ `;
23
+ export async function buildBugReport(trace, model, options = {}) {
24
+ const { outputDir = os.tmpdir(), includeScenario = true, includeValkyrieLog = true, } = options;
25
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
26
+ const zipName = `valkyrie-bug-report-${timestamp}.zip`;
27
+ const zipPath = path.join(outputDir, zipName);
28
+ // Build ZIP
29
+ const output = fs.createWriteStream(zipPath);
30
+ const archive = archiver('zip');
31
+ const done = new Promise((resolve, reject) => {
32
+ output.on('close', resolve);
33
+ archive.on('error', reject);
34
+ });
35
+ archive.pipe(output);
36
+ // report.json
37
+ const metadata = trace.getMetadata();
38
+ const entries = trace.getEntries();
39
+ const report = {
40
+ metadata,
41
+ traceEntries: entries,
42
+ exportedAt: new Date().toISOString(),
43
+ };
44
+ archive.append(JSON.stringify(report, null, 2), { name: 'report.json' });
45
+ // validation.json
46
+ let validationData = { errors: [], warnings: [], note: 'No scenario loaded' };
47
+ if (model) {
48
+ const results = validateScenario(model);
49
+ const errors = results.filter(r => r.severity === 'error');
50
+ const warnings = results.filter(r => r.severity === 'warning');
51
+ validationData = { errors, warnings };
52
+ }
53
+ archive.append(JSON.stringify(validationData, null, 2), { name: 'validation.json' });
54
+ // README.txt
55
+ archive.append(README_TEXT, { name: 'README.txt' });
56
+ // scenario/ directory
57
+ if (includeScenario && model?.scenarioDir && fs.existsSync(model.scenarioDir)) {
58
+ const scenarioFiles = fs.readdirSync(model.scenarioDir);
59
+ for (const file of scenarioFiles) {
60
+ const filePath = path.join(model.scenarioDir, file);
61
+ if (fs.statSync(filePath).isFile()) {
62
+ archive.file(filePath, { name: `scenario/${file}` });
63
+ }
64
+ }
65
+ }
66
+ // valkyrie-logs/
67
+ if (includeValkyrieLog) {
68
+ const logPath = getValkyrieLogPath();
69
+ if (logPath) {
70
+ const logContent = await readLogTail(logPath);
71
+ if (logContent) {
72
+ archive.append(logContent, { name: 'valkyrie-logs/Player.log' });
73
+ }
74
+ }
75
+ }
76
+ await archive.finalize();
77
+ await done;
78
+ // Build issue template
79
+ const errorEntries = trace.getErrorEntries();
80
+ const allEntries = trace.getEntries();
81
+ const errorCount = errorEntries.length;
82
+ const validationErrors = model ? validateScenario(model).filter(r => r.severity === 'error').length : 0;
83
+ const validationWarnings = model ? validateScenario(model).filter(r => r.severity === 'warning').length : 0;
84
+ const recentErrors = errorEntries.slice(-5).map(e => `- \`${e.tool}\` (${e.timestamp}): ${e.resultSummary.replace(/^Error:\s*/, '').slice(0, 100)}`).join('\n');
85
+ const issueTitle = `[Bug Report] MCP session with ${allEntries.length} tool calls, ${errorCount} errors`;
86
+ const issueBody = `## Bug Report
87
+
88
+ **Environment:**
89
+ - MCP Server: v${metadata.serverVersion}
90
+ - Node: ${metadata.nodeVersion}
91
+ - Platform: ${metadata.platform} ${metadata.arch}
92
+
93
+ **Session Summary:**
94
+ - Tool calls: ${allEntries.length}
95
+ - Errors: ${errorCount}
96
+ - Validation: ${validationErrors} errors, ${validationWarnings} warnings
97
+
98
+ ## What happened?
99
+ <!-- Describe what you expected vs. what actually happened -->
100
+
101
+ ## Steps to reproduce
102
+ <!-- The session trace is in the attached ZIP -->
103
+
104
+ ${recentErrors ? `## Recent errors from session trace\n${recentErrors}\n` : ''}
105
+ ## Attachments
106
+ <!-- Drag and drop the .zip bug report file here -->
107
+ `;
108
+ const escapedTitle = issueTitle.replace(/"/g, '\\"');
109
+ const ghCommand = `gh issue create --repo thijs-hakkenberg/ValkyrieMCP --title "${escapedTitle}" --body-file -`;
110
+ return { zipPath, issueTitle, issueBody, ghCommand };
111
+ }
112
+ //# sourceMappingURL=bug-report-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bug-report-builder.js","sourceRoot":"","sources":["../../src/diagnostics/bug-report-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Fixed-capacity circular buffer. When full, new items overwrite the oldest.
3
+ */
4
+ export declare class RingBuffer<T> {
5
+ private buffer;
6
+ private head;
7
+ private count;
8
+ private readonly capacity;
9
+ constructor(capacity: number);
10
+ push(item: T): void;
11
+ get size(): number;
12
+ /** Returns entries oldest-first */
13
+ toArray(): T[];
14
+ clear(): void;
15
+ }
16
+ //# sourceMappingURL=ring-buffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ring-buffer.d.ts","sourceRoot":"","sources":["../../src/diagnostics/ring-buffer.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,UAAU,CAAC,CAAC;IACvB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,QAAQ,EAAE,MAAM;IAK5B,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI;IAQnB,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,mCAAmC;IACnC,OAAO,IAAI,CAAC,EAAE;IAWd,KAAK,IAAI,IAAI;CAKd"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Fixed-capacity circular buffer. When full, new items overwrite the oldest.
3
+ */
4
+ export class RingBuffer {
5
+ buffer;
6
+ head = 0; // next write position
7
+ count = 0;
8
+ capacity;
9
+ constructor(capacity) {
10
+ this.capacity = capacity;
11
+ this.buffer = new Array(capacity);
12
+ }
13
+ push(item) {
14
+ this.buffer[this.head] = item;
15
+ this.head = (this.head + 1) % this.capacity;
16
+ if (this.count < this.capacity) {
17
+ this.count++;
18
+ }
19
+ }
20
+ get size() {
21
+ return this.count;
22
+ }
23
+ /** Returns entries oldest-first */
24
+ toArray() {
25
+ if (this.count === 0)
26
+ return [];
27
+ const result = [];
28
+ const start = this.count < this.capacity ? 0 : this.head;
29
+ for (let i = 0; i < this.count; i++) {
30
+ const idx = (start + i) % this.capacity;
31
+ result.push(this.buffer[idx]);
32
+ }
33
+ return result;
34
+ }
35
+ clear() {
36
+ this.buffer = new Array(this.capacity);
37
+ this.head = 0;
38
+ this.count = 0;
39
+ }
40
+ }
41
+ //# sourceMappingURL=ring-buffer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ring-buffer.js","sourceRoot":"","sources":["../../src/diagnostics/ring-buffer.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,UAAU;IACb,MAAM,CAAuB;IAC7B,IAAI,GAAG,CAAC,CAAC,CAAG,sBAAsB;IAClC,KAAK,GAAG,CAAC,CAAC;IACD,QAAQ,CAAS;IAElC,YAAY,QAAgB;QAC1B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,CAAgB,QAAQ,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,CAAC,IAAO;QACV,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC5C,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC;IACH,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,mCAAmC;IACnC,OAAO;QACL,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAChC,MAAM,MAAM,GAAQ,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,MAAM,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAM,CAAC,CAAC;QACrC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,CAAgB,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QACd,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACjB,CAAC;CACF"}
@@ -0,0 +1,19 @@
1
+ import type { TraceEntry, SessionMetadata } from './types.js';
2
+ /** Omit timestamp — it's auto-filled by record() */
3
+ type TraceInput = Omit<TraceEntry, 'timestamp'>;
4
+ /**
5
+ * In-memory session trace. Records MCP tool calls in a ring buffer.
6
+ * Nothing is written to disk until explicitly exported.
7
+ */
8
+ export declare class SessionTrace {
9
+ private buffer;
10
+ private metadata;
11
+ constructor(serverVersion: string, capacity?: number);
12
+ record(input: TraceInput): void;
13
+ getEntries(): TraceEntry[];
14
+ getErrorEntries(): TraceEntry[];
15
+ getMetadata(): SessionMetadata;
16
+ updateScenario(dir: string): void;
17
+ }
18
+ export {};
19
+ //# sourceMappingURL=session-trace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-trace.d.ts","sourceRoot":"","sources":["../../src/diagnostics/session-trace.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAI9D,oDAAoD;AACpD,KAAK,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;AAEhD;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,aAAa,EAAE,MAAM,EAAE,QAAQ,SAAmB;IAW9D,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAO/B,UAAU,IAAI,UAAU,EAAE;IAI1B,eAAe,IAAI,UAAU,EAAE;IAI/B,WAAW,IAAI,eAAe;IAI9B,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAGlC"}
@@ -0,0 +1,40 @@
1
+ import * as os from 'node:os';
2
+ import { RingBuffer } from './ring-buffer.js';
3
+ const DEFAULT_CAPACITY = 200;
4
+ /**
5
+ * In-memory session trace. Records MCP tool calls in a ring buffer.
6
+ * Nothing is written to disk until explicitly exported.
7
+ */
8
+ export class SessionTrace {
9
+ buffer;
10
+ metadata;
11
+ constructor(serverVersion, capacity = DEFAULT_CAPACITY) {
12
+ this.buffer = new RingBuffer(capacity);
13
+ this.metadata = {
14
+ serverVersion,
15
+ nodeVersion: process.version,
16
+ platform: os.platform(),
17
+ arch: os.arch(),
18
+ startedAt: new Date().toISOString(),
19
+ };
20
+ }
21
+ record(input) {
22
+ this.buffer.push({
23
+ ...input,
24
+ timestamp: new Date().toISOString(),
25
+ });
26
+ }
27
+ getEntries() {
28
+ return this.buffer.toArray();
29
+ }
30
+ getErrorEntries() {
31
+ return this.buffer.toArray().filter(e => e.isError);
32
+ }
33
+ getMetadata() {
34
+ return { ...this.metadata };
35
+ }
36
+ updateScenario(dir) {
37
+ this.metadata.scenarioDir = dir;
38
+ }
39
+ }
40
+ //# sourceMappingURL=session-trace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-trace.js","sourceRoot":"","sources":["../../src/diagnostics/session-trace.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAK7B;;;GAGG;AACH,MAAM,OAAO,YAAY;IACf,MAAM,CAAyB;IAC/B,QAAQ,CAAkB;IAElC,YAAY,aAAqB,EAAE,QAAQ,GAAG,gBAAgB;QAC5D,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,CAAa,QAAQ,CAAC,CAAC;QACnD,IAAI,CAAC,QAAQ,GAAG;YACd,aAAa;YACb,WAAW,EAAE,OAAO,CAAC,OAAO;YAC5B,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE;YACvB,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE;YACf,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,KAAiB;QACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACf,GAAG,KAAK;YACR,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC,CAAC;IACL,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;IAC/B,CAAC;IAED,eAAe;QACb,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACtD,CAAC;IAED,WAAW;QACT,OAAO,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,cAAc,CAAC,GAAW;QACxB,IAAI,CAAC,QAAQ,CAAC,WAAW,GAAG,GAAG,CAAC;IAClC,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { SessionTrace } from './session-trace.js';
3
+ /** Truncate string values in args to prevent huge trace entries */
4
+ export declare function sanitizeArgs(args: Record<string, unknown> | undefined): Record<string, unknown>;
5
+ /**
6
+ * Wrap all registered tool handlers to record calls to the session trace.
7
+ * Must be called after all tools are registered. Skips `export_bug_report`
8
+ * to avoid circular recording.
9
+ */
10
+ export declare function wrapAllTools(server: McpServer, trace: SessionTrace): void;
11
+ //# sourceMappingURL=tool-interceptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-interceptor.d.ts","sourceRoot":"","sources":["../../src/diagnostics/tool-interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAKvD,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAW/F;AAgBD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAkCzE"}