spec-gen-cli 1.2.5 → 1.2.6

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 (32) hide show
  1. package/README.md +36 -2
  2. package/dist/cli/commands/mcp.d.ts +225 -0
  3. package/dist/cli/commands/mcp.d.ts.map +1 -1
  4. package/dist/cli/commands/mcp.js +116 -1
  5. package/dist/cli/commands/mcp.js.map +1 -1
  6. package/dist/cli/commands/refresh-stories.d.ts +10 -0
  7. package/dist/cli/commands/refresh-stories.d.ts.map +1 -0
  8. package/dist/cli/commands/refresh-stories.js +314 -0
  9. package/dist/cli/commands/refresh-stories.js.map +1 -0
  10. package/dist/cli/index.js +2 -0
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/core/analyzer/unified-search.d.ts +107 -0
  13. package/dist/core/analyzer/unified-search.d.ts.map +1 -0
  14. package/dist/core/analyzer/unified-search.js +237 -0
  15. package/dist/core/analyzer/unified-search.js.map +1 -0
  16. package/dist/core/generator/openspec-format-generator.js +1 -1
  17. package/dist/core/generator/openspec-format-generator.js.map +1 -1
  18. package/dist/core/services/chat-tools.d.ts.map +1 -1
  19. package/dist/core/services/chat-tools.js +54 -6
  20. package/dist/core/services/chat-tools.js.map +1 -1
  21. package/dist/core/services/mcp-handlers/change.d.ts +14 -0
  22. package/dist/core/services/mcp-handlers/change.d.ts.map +1 -0
  23. package/dist/core/services/mcp-handlers/change.js +416 -0
  24. package/dist/core/services/mcp-handlers/change.js.map +1 -0
  25. package/dist/core/services/mcp-handlers/semantic.d.ts +4 -0
  26. package/dist/core/services/mcp-handlers/semantic.d.ts.map +1 -1
  27. package/dist/core/services/mcp-handlers/semantic.js +101 -32
  28. package/dist/core/services/mcp-handlers/semantic.js.map +1 -1
  29. package/package.json +4 -1
  30. package/src/viewer/InteractiveGraphViewer.jsx +46 -4
  31. package/src/viewer/components/ChatPanel.jsx +2 -3
  32. package/src/viewer/components/ClusterGraph.jsx +22 -6
package/README.md CHANGED
@@ -476,6 +476,7 @@ Priority: CLI flags > environment variables > config file > provider defaults.
476
476
  | `spec-gen view` | Launch interactive graph & spec viewer in the browser | No |
477
477
  | `spec-gen mcp` | Start MCP server (stdio, for Cline / Claude Code) | No |
478
478
  | `spec-gen doctor` | Check environment and configuration for common issues | No |
479
+ | `spec-gen refresh-stories` | Re-annotate story files with stale risk context | No |
479
480
 
480
481
  ### Global Options
481
482
 
@@ -830,6 +831,8 @@ All tools run on **pure static analysis** -- no LLM quota consumed.
830
831
  | `check_spec_drift` | Detect code changes not reflected in OpenSpec specs. Compares git-changed files against spec coverage maps. Issues: gap / stale / uncovered / orphaned-spec / adr-gap. | Yes (generate) |
831
832
  | `search_specs` | Semantic search over OpenSpec specifications to find requirements, design notes, and architecture decisions by meaning. Returns linked source files for graph highlighting. Use this when asked "which spec covers X?" or "where should we implement Z?". Requires a spec index built with `spec-gen analyze` or `--reindex-specs`. | Yes (generate) |
832
833
  | `list_spec_domains` | List all OpenSpec domains available in this project. Use this to discover what domains exist before doing a targeted `search_specs` call. | Yes (generate) |
834
+ | `generate_change_proposal` | Given a story/task description, chains `orient` + `search_specs` + `analyze_impact` to produce a structured change proposal at `openspec/changes/{slug}/proposal.md` with affected domains, risk scores, and insertion points. | Yes |
835
+ | `annotate_story` | Reads a story/task markdown file, runs structural analysis, and patches a `## Risk Context` section in-place with domains, risk scores, blocking refactors, and insertion points. | Yes |
833
836
 
834
837
  ### Parameters
835
838
 
@@ -1005,6 +1008,21 @@ domain string Filter by domain name (e.g. "auth", "analyzer")
1005
1008
  section string Filter by section type: "requirements" | "purpose" | "design" | "architecture" | "entities"
1006
1009
  ```
1007
1010
 
1011
+ **`generate_change_proposal`**
1012
+ ```
1013
+ directory string Absolute path to the project directory
1014
+ description string Natural-language description of the change (story, intent, or spec delta)
1015
+ slug string URL-safe identifier for the proposal (e.g. "add-payment-retry")
1016
+ storyContent string Optional full story markdown to embed in the proposal
1017
+ ```
1018
+
1019
+ **`annotate_story`**
1020
+ ```
1021
+ directory string Absolute path to the project directory
1022
+ storyFilePath string Path to the story file (relative to project root or absolute)
1023
+ description string Natural-language summary of the story for structural analysis
1024
+ ```
1025
+
1008
1026
  ### Typical workflow
1009
1027
 
1010
1028
  **Scenario A -- Initial exploration**
@@ -1045,6 +1063,17 @@ section string Filter by section type: "requirements" | "purpose" | "design
1045
1063
  3. check_spec_drift({ directory }) # verify after implementation
1046
1064
  ```
1047
1065
 
1066
+ **Scenario E -- Agentic workflow (risk-gated implementation)**
1067
+ ```
1068
+ 1. generate_change_proposal({ directory, description, slug }) # proposal.md with risk + domains
1069
+ 2. annotate_story({ directory, storyFilePath, description }) # patch story with risk_context
1070
+ 3. orient({ directory, task: "..." }) # scope functions + insertion points
1071
+ 4. analyze_impact({ directory, symbol: "topFunction" }) # confirm risk before coding
1072
+ 5. check_spec_drift({ directory }) # verify after implementation
1073
+ ```
1074
+
1075
+ See [docs/agentic-workflows/](docs/agentic-workflows/) for full integration patterns with BMAD, Mistral Vibe, spec-kit, and Claude Code.
1076
+
1048
1077
  ## Interactive Graph Viewer
1049
1078
 
1050
1079
  `spec-gen view` launches a local React app that visualises your codebase analysis and lets you explore spec requirements side-by-side with the dependency graph.
@@ -1385,6 +1414,10 @@ for (const [key, req] of Object.entries(requirements)) {
1385
1414
  | [examples/openspec-analysis/](examples/openspec-analysis/) | Static analysis output from `spec-gen analyze` |
1386
1415
  | [examples/openspec-cli/](examples/openspec-cli/) | Specifications generated with `spec-gen generate` |
1387
1416
  | [examples/drift-demo/](examples/drift-demo/) | Sample project configured for drift detection |
1417
+ | [examples/bmad/](examples/bmad/) | BMAD Method integration — agents, tasks, templates for brownfield codebases |
1418
+ | [examples/mistral-vibe/](examples/mistral-vibe/) | Mistral Vibe skills for analyze, generate, plan-refactor, implement-story |
1419
+ | [examples/spec-kit/](examples/spec-kit/) | spec-kit extension with `before_implement` / `after_implement` hooks |
1420
+ | [examples/gsd/](examples/gsd/) | Get-Shit-Done Claude Code commands for orient + drift |
1388
1421
 
1389
1422
  ## Development
1390
1423
 
@@ -1392,11 +1425,11 @@ for (const [key, req] of Object.entries(requirements)) {
1392
1425
  npm install # Install dependencies
1393
1426
  npm run dev # Development mode (watch)
1394
1427
  npm run build # Build
1395
- npm run test:run # Run tests (2059 unit tests)
1428
+ npm run test:run # Run tests (2200+ unit tests)
1396
1429
  npm run typecheck # Type check
1397
1430
  ```
1398
1431
 
1399
- 2050+ unit tests covering static analysis, call graph (including Swift), refactor analysis, spec mapping, drift detection, LLM enhancement, ADR generation, MCP handlers, cross-file edge synthesis, and the full CLI.
1432
+ 2200+ unit tests covering static analysis, call graph (including Swift), refactor analysis, spec mapping, drift detection, LLM enhancement, ADR generation, MCP handlers, change proposals, cross-file edge synthesis, and the full CLI.
1400
1433
 
1401
1434
  ## Links
1402
1435
 
@@ -1406,5 +1439,6 @@ npm run typecheck # Type check
1406
1439
  - [OpenSpec Integration](docs/OPENSPEC-INTEGRATION.md) - How spec-gen integrates with OpenSpec
1407
1440
  - [OpenSpec Format](docs/OPENSPEC-FORMAT.md) - Spec format reference
1408
1441
  - [Philosophy](docs/PHILOSOPHY.md) - "Archaeology over Creativity"
1442
+ - [Agentic Workflows](docs/agentic-workflows/) - Integration patterns for BMAD, Mistral Vibe, spec-kit, GSD
1409
1443
  - [Troubleshooting](docs/TROUBLESHOOTING.md) - Common issues and solutions
1410
1444
  - [AGENTS.md](AGENTS.md) - LLM system prompt for direct prompting
@@ -67,6 +67,9 @@ export declare const TOOL_DEFINITIONS: ({
67
67
  language?: undefined;
68
68
  query?: undefined;
69
69
  section?: undefined;
70
+ slug?: undefined;
71
+ storyContent?: undefined;
72
+ storyFilePath?: undefined;
70
73
  };
71
74
  required: string[];
72
75
  };
@@ -111,6 +114,9 @@ export declare const TOOL_DEFINITIONS: ({
111
114
  language?: undefined;
112
115
  query?: undefined;
113
116
  section?: undefined;
117
+ slug?: undefined;
118
+ storyContent?: undefined;
119
+ storyFilePath?: undefined;
114
120
  };
115
121
  required: string[];
116
122
  };
@@ -152,6 +158,9 @@ export declare const TOOL_DEFINITIONS: ({
152
158
  language?: undefined;
153
159
  query?: undefined;
154
160
  section?: undefined;
161
+ slug?: undefined;
162
+ storyContent?: undefined;
163
+ storyFilePath?: undefined;
155
164
  };
156
165
  required: string[];
157
166
  };
@@ -196,6 +205,9 @@ export declare const TOOL_DEFINITIONS: ({
196
205
  language?: undefined;
197
206
  query?: undefined;
198
207
  section?: undefined;
208
+ slug?: undefined;
209
+ storyContent?: undefined;
210
+ storyFilePath?: undefined;
199
211
  };
200
212
  required: string[];
201
213
  };
@@ -251,6 +263,9 @@ export declare const TOOL_DEFINITIONS: ({
251
263
  language?: undefined;
252
264
  query?: undefined;
253
265
  section?: undefined;
266
+ slug?: undefined;
267
+ storyContent?: undefined;
268
+ storyFilePath?: undefined;
254
269
  };
255
270
  required: string[];
256
271
  };
@@ -304,6 +319,9 @@ export declare const TOOL_DEFINITIONS: ({
304
319
  language?: undefined;
305
320
  query?: undefined;
306
321
  section?: undefined;
322
+ slug?: undefined;
323
+ storyContent?: undefined;
324
+ storyFilePath?: undefined;
307
325
  };
308
326
  required: string[];
309
327
  };
@@ -351,6 +369,9 @@ export declare const TOOL_DEFINITIONS: ({
351
369
  language?: undefined;
352
370
  query?: undefined;
353
371
  section?: undefined;
372
+ slug?: undefined;
373
+ storyContent?: undefined;
374
+ storyFilePath?: undefined;
354
375
  };
355
376
  required: string[];
356
377
  };
@@ -414,6 +435,9 @@ export declare const TOOL_DEFINITIONS: ({
414
435
  language?: undefined;
415
436
  query?: undefined;
416
437
  section?: undefined;
438
+ slug?: undefined;
439
+ storyContent?: undefined;
440
+ storyFilePath?: undefined;
417
441
  };
418
442
  required: string[];
419
443
  };
@@ -461,6 +485,9 @@ export declare const TOOL_DEFINITIONS: ({
461
485
  language?: undefined;
462
486
  query?: undefined;
463
487
  section?: undefined;
488
+ slug?: undefined;
489
+ storyContent?: undefined;
490
+ storyFilePath?: undefined;
464
491
  };
465
492
  required: string[];
466
493
  };
@@ -508,6 +535,9 @@ export declare const TOOL_DEFINITIONS: ({
508
535
  language?: undefined;
509
536
  query?: undefined;
510
537
  section?: undefined;
538
+ slug?: undefined;
539
+ storyContent?: undefined;
540
+ storyFilePath?: undefined;
511
541
  };
512
542
  required: string[];
513
543
  };
@@ -559,6 +589,9 @@ export declare const TOOL_DEFINITIONS: ({
559
589
  language?: undefined;
560
590
  query?: undefined;
561
591
  section?: undefined;
592
+ slug?: undefined;
593
+ storyContent?: undefined;
594
+ storyFilePath?: undefined;
562
595
  };
563
596
  required: string[];
564
597
  };
@@ -606,6 +639,9 @@ export declare const TOOL_DEFINITIONS: ({
606
639
  language?: undefined;
607
640
  query?: undefined;
608
641
  section?: undefined;
642
+ slug?: undefined;
643
+ storyContent?: undefined;
644
+ storyFilePath?: undefined;
609
645
  };
610
646
  required: string[];
611
647
  };
@@ -650,6 +686,9 @@ export declare const TOOL_DEFINITIONS: ({
650
686
  language?: undefined;
651
687
  query?: undefined;
652
688
  section?: undefined;
689
+ slug?: undefined;
690
+ storyContent?: undefined;
691
+ storyFilePath?: undefined;
653
692
  };
654
693
  required: string[];
655
694
  };
@@ -697,6 +736,9 @@ export declare const TOOL_DEFINITIONS: ({
697
736
  language?: undefined;
698
737
  query?: undefined;
699
738
  section?: undefined;
739
+ slug?: undefined;
740
+ storyContent?: undefined;
741
+ storyFilePath?: undefined;
700
742
  };
701
743
  required: string[];
702
744
  };
@@ -747,6 +789,9 @@ export declare const TOOL_DEFINITIONS: ({
747
789
  fanOutThreshold?: undefined;
748
790
  query?: undefined;
749
791
  section?: undefined;
792
+ slug?: undefined;
793
+ storyContent?: undefined;
794
+ storyFilePath?: undefined;
750
795
  };
751
796
  required: string[];
752
797
  };
@@ -800,6 +845,9 @@ export declare const TOOL_DEFINITIONS: ({
800
845
  fanOutThreshold?: undefined;
801
846
  description?: undefined;
802
847
  section?: undefined;
848
+ slug?: undefined;
849
+ storyContent?: undefined;
850
+ storyFilePath?: undefined;
803
851
  };
804
852
  required: string[];
805
853
  };
@@ -853,6 +901,68 @@ export declare const TOOL_DEFINITIONS: ({
853
901
  fanOutThreshold?: undefined;
854
902
  description?: undefined;
855
903
  language?: undefined;
904
+ slug?: undefined;
905
+ storyContent?: undefined;
906
+ storyFilePath?: undefined;
907
+ };
908
+ required: string[];
909
+ };
910
+ } | {
911
+ name: string;
912
+ description: string;
913
+ inputSchema: {
914
+ type: string;
915
+ properties: {
916
+ directory: {
917
+ type: string;
918
+ description: string;
919
+ };
920
+ query: {
921
+ type: string;
922
+ description: string;
923
+ };
924
+ limit: {
925
+ type: string;
926
+ description: string;
927
+ };
928
+ language: {
929
+ type: string;
930
+ description: string;
931
+ };
932
+ domain: {
933
+ type: string;
934
+ description: string;
935
+ };
936
+ section: {
937
+ type: string;
938
+ description: string;
939
+ };
940
+ task?: undefined;
941
+ force?: undefined;
942
+ filePattern?: undefined;
943
+ functionName?: undefined;
944
+ direction?: undefined;
945
+ maxDepth?: undefined;
946
+ format?: undefined;
947
+ entryFunction?: undefined;
948
+ targetFunction?: undefined;
949
+ maxPaths?: undefined;
950
+ orphansOnly?: undefined;
951
+ base?: undefined;
952
+ files?: undefined;
953
+ domains?: undefined;
954
+ failOn?: undefined;
955
+ maxFiles?: undefined;
956
+ symbol?: undefined;
957
+ depth?: undefined;
958
+ sortBy?: undefined;
959
+ minFanIn?: undefined;
960
+ filePath?: undefined;
961
+ fanOutThreshold?: undefined;
962
+ description?: undefined;
963
+ slug?: undefined;
964
+ storyContent?: undefined;
965
+ storyFilePath?: undefined;
856
966
  };
857
967
  required: string[];
858
968
  };
@@ -897,6 +1007,9 @@ export declare const TOOL_DEFINITIONS: ({
897
1007
  language?: undefined;
898
1008
  query?: undefined;
899
1009
  section?: undefined;
1010
+ slug?: undefined;
1011
+ storyContent?: undefined;
1012
+ storyFilePath?: undefined;
900
1013
  };
901
1014
  required: string[];
902
1015
  };
@@ -944,6 +1057,9 @@ export declare const TOOL_DEFINITIONS: ({
944
1057
  language?: undefined;
945
1058
  query?: undefined;
946
1059
  section?: undefined;
1060
+ slug?: undefined;
1061
+ storyContent?: undefined;
1062
+ storyFilePath?: undefined;
947
1063
  };
948
1064
  required: string[];
949
1065
  };
@@ -992,6 +1108,112 @@ export declare const TOOL_DEFINITIONS: ({
992
1108
  language?: undefined;
993
1109
  query?: undefined;
994
1110
  section?: undefined;
1111
+ slug?: undefined;
1112
+ storyContent?: undefined;
1113
+ storyFilePath?: undefined;
1114
+ };
1115
+ required: string[];
1116
+ };
1117
+ } | {
1118
+ name: string;
1119
+ description: string;
1120
+ inputSchema: {
1121
+ type: string;
1122
+ properties: {
1123
+ directory: {
1124
+ type: string;
1125
+ description: string;
1126
+ };
1127
+ description: {
1128
+ type: string;
1129
+ description: string;
1130
+ };
1131
+ slug: {
1132
+ type: string;
1133
+ description: string;
1134
+ };
1135
+ storyContent: {
1136
+ type: string;
1137
+ description: string;
1138
+ };
1139
+ task?: undefined;
1140
+ limit?: undefined;
1141
+ force?: undefined;
1142
+ filePattern?: undefined;
1143
+ functionName?: undefined;
1144
+ direction?: undefined;
1145
+ maxDepth?: undefined;
1146
+ format?: undefined;
1147
+ entryFunction?: undefined;
1148
+ targetFunction?: undefined;
1149
+ maxPaths?: undefined;
1150
+ domain?: undefined;
1151
+ orphansOnly?: undefined;
1152
+ base?: undefined;
1153
+ files?: undefined;
1154
+ domains?: undefined;
1155
+ failOn?: undefined;
1156
+ maxFiles?: undefined;
1157
+ symbol?: undefined;
1158
+ depth?: undefined;
1159
+ sortBy?: undefined;
1160
+ minFanIn?: undefined;
1161
+ filePath?: undefined;
1162
+ fanOutThreshold?: undefined;
1163
+ language?: undefined;
1164
+ query?: undefined;
1165
+ section?: undefined;
1166
+ storyFilePath?: undefined;
1167
+ };
1168
+ required: string[];
1169
+ };
1170
+ } | {
1171
+ name: string;
1172
+ description: string;
1173
+ inputSchema: {
1174
+ type: string;
1175
+ properties: {
1176
+ directory: {
1177
+ type: string;
1178
+ description: string;
1179
+ };
1180
+ storyFilePath: {
1181
+ type: string;
1182
+ description: string;
1183
+ };
1184
+ description: {
1185
+ type: string;
1186
+ description: string;
1187
+ };
1188
+ task?: undefined;
1189
+ limit?: undefined;
1190
+ force?: undefined;
1191
+ filePattern?: undefined;
1192
+ functionName?: undefined;
1193
+ direction?: undefined;
1194
+ maxDepth?: undefined;
1195
+ format?: undefined;
1196
+ entryFunction?: undefined;
1197
+ targetFunction?: undefined;
1198
+ maxPaths?: undefined;
1199
+ domain?: undefined;
1200
+ orphansOnly?: undefined;
1201
+ base?: undefined;
1202
+ files?: undefined;
1203
+ domains?: undefined;
1204
+ failOn?: undefined;
1205
+ maxFiles?: undefined;
1206
+ symbol?: undefined;
1207
+ depth?: undefined;
1208
+ sortBy?: undefined;
1209
+ minFanIn?: undefined;
1210
+ filePath?: undefined;
1211
+ fanOutThreshold?: undefined;
1212
+ language?: undefined;
1213
+ query?: undefined;
1214
+ section?: undefined;
1215
+ slug?: undefined;
1216
+ storyContent?: undefined;
995
1217
  };
996
1218
  required: string[];
997
1219
  };
@@ -1036,6 +1258,9 @@ export declare const TOOL_DEFINITIONS: ({
1036
1258
  description?: undefined;
1037
1259
  language?: undefined;
1038
1260
  section?: undefined;
1261
+ slug?: undefined;
1262
+ storyContent?: undefined;
1263
+ storyFilePath?: undefined;
1039
1264
  };
1040
1265
  required: string[];
1041
1266
  };
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAEhG,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,kCAAkC,EAClC,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,iBAAiB,EAGlB,MAAM,8CAA8C,CAAC;AAEtD,OAAO,EACL,qBAAqB,EACrB,6BAA6B,EAC7B,uBAAuB,EACvB,wBAAwB,EACxB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,yBAAyB,EAG1B,MAAM,8CAA8C,CAAC;AAGtD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,CAAC;AAG/C,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,kCAAkC,EAClC,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,EACxB,gBAAgB,EAChB,4BAA4B,EAC5B,iBAAiB,EACjB,qBAAqB,EACrB,6BAA6B,EAC7B,uBAAuB,EACvB,wBAAwB,EACxB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,yBAAyB,GAC1B,CAAC;AAMF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAsoB5B,CAAC;AAmLF,eAAO,MAAM,UAAU,SAK0C,CAAC"}
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAEhG,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,kCAAkC,EAClC,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,iBAAiB,EAIlB,MAAM,8CAA8C,CAAC;AAGtD,OAAO,EACL,qBAAqB,EACrB,6BAA6B,EAC7B,uBAAuB,EACvB,wBAAwB,EACxB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,yBAAyB,EAG1B,MAAM,8CAA8C,CAAC;AAGtD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,CAAC;AAG/C,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,kCAAkC,EAClC,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,EACxB,gBAAgB,EAChB,4BAA4B,EAC5B,iBAAiB,EACjB,qBAAqB,EACrB,6BAA6B,EAC7B,uBAAuB,EACvB,wBAAwB,EACxB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,yBAAyB,GAC1B,CAAC;AAMF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAovB5B,CAAC;AA+LF,eAAO,MAAM,UAAU,SAK0C,CAAC"}
@@ -23,8 +23,9 @@ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextpro
23
23
  import { sanitizeMcpError, validateDirectory } from '../../core/services/mcp-handlers/utils.js';
24
24
  import { DEFAULT_DRIFT_MAX_FILES } from '../../constants.js';
25
25
  import { handleGetCallGraph, handleGetSubgraph, handleAnalyzeImpact, handleGetLowRiskRefactorCandidates, handleGetLeafFunctions, handleGetCriticalHubs, handleGetGodFunctions, handleGetFileDependencies, handleTraceExecutionPath, } from '../../core/services/mcp-handlers/graph.js';
26
- import { handleSearchCode, handleSuggestInsertionPoints, handleSearchSpecs, handleListSpecDomains, handleGetSpec, } from '../../core/services/mcp-handlers/semantic.js';
26
+ import { handleSearchCode, handleSuggestInsertionPoints, handleSearchSpecs, handleListSpecDomains, handleGetSpec, handleUnifiedSearch, } from '../../core/services/mcp-handlers/semantic.js';
27
27
  import { handleOrient } from '../../core/services/mcp-handlers/orient.js';
28
+ import { handleGenerateChangeProposal, handleAnnotateStory } from '../../core/services/mcp-handlers/change.js';
28
29
  import { handleAnalyzeCodebase, handleGetArchitectureOverview, handleGetRefactorReport, handleGetDuplicateReport, handleGetSignatures, handleGetMapping, handleCheckSpecDrift, handleGetFunctionSkeleton, handleGetFunctionBody, handleGetDecisions, } from '../../core/services/mcp-handlers/analysis.js';
29
30
  // Re-export utilities for tests
30
31
  export { sanitizeMcpError, validateDirectory };
@@ -569,6 +570,45 @@ export const TOOL_DEFINITIONS = [
569
570
  required: ['directory', 'query'],
570
571
  },
571
572
  },
573
+ {
574
+ name: 'search_unified',
575
+ description: 'USE THIS WHEN: you want to find where something is implemented AND what the spec says about it ' +
576
+ 'in a single call. Searches both code functions and spec requirements simultaneously, then ' +
577
+ 'cross-boosts results that are linked through mapping.json — so a function that implements a ' +
578
+ 'matching requirement ranks higher than one found by code search alone. ' +
579
+ 'Returns results with type "code", "spec", or "both" and a mappingBoost score. ' +
580
+ 'Requires "spec-gen analyze --embed" and a prior "spec-gen generate" run.',
581
+ inputSchema: {
582
+ type: 'object',
583
+ properties: {
584
+ directory: {
585
+ type: 'string',
586
+ description: 'Absolute path to the project directory',
587
+ },
588
+ query: {
589
+ type: 'string',
590
+ description: 'Natural language query, e.g. "validate user authentication"',
591
+ },
592
+ limit: {
593
+ type: 'number',
594
+ description: 'Maximum number of results to return (default: 10)',
595
+ },
596
+ language: {
597
+ type: 'string',
598
+ description: 'Filter code results by language (e.g. "TypeScript")',
599
+ },
600
+ domain: {
601
+ type: 'string',
602
+ description: 'Filter spec results by domain name',
603
+ },
604
+ section: {
605
+ type: 'string',
606
+ description: 'Filter spec results by section type: "requirements", "purpose", etc.',
607
+ },
608
+ },
609
+ required: ['directory', 'query'],
610
+ },
611
+ },
572
612
  {
573
613
  name: 'get_spec',
574
614
  description: 'Return the full content of a spec domain\'s specification file (spec.md) and the ' +
@@ -632,6 +672,69 @@ export const TOOL_DEFINITIONS = [
632
672
  required: ['directory', 'filePath'],
633
673
  },
634
674
  },
675
+ {
676
+ name: 'generate_change_proposal',
677
+ description: 'USE THIS WHEN: you have a BMAD story, a feature description, or a spec delta request, ' +
678
+ 'and want to create a structured OpenSpec change proposal before writing any code. ' +
679
+ 'Combines orient + search_specs + analyze_impact to produce a pre-filled ' +
680
+ 'openspec/changes/{slug}/proposal.md — no LLM required. ' +
681
+ 'Output includes affected domains, touched requirements, risk scores, and insertion points. ' +
682
+ 'Run analyze_codebase first; spec index optional (degrades gracefully).',
683
+ inputSchema: {
684
+ type: 'object',
685
+ properties: {
686
+ directory: {
687
+ type: 'string',
688
+ description: 'Absolute path to the project directory',
689
+ },
690
+ description: {
691
+ type: 'string',
692
+ description: 'Intent of the change — story title + primary AC, or a free-form feature description. ' +
693
+ 'e.g. "add retry logic to payment processing — must retry up to 3 times on timeout"',
694
+ },
695
+ slug: {
696
+ type: 'string',
697
+ description: 'Change identifier used as the directory name, e.g. "add-payment-retry". ' +
698
+ 'Will be lowercased and hyphenated automatically.',
699
+ },
700
+ storyContent: {
701
+ type: 'string',
702
+ description: 'Optional: full BMAD story content (markdown). If provided, it is embedded verbatim ' +
703
+ 'in the proposal for traceability.',
704
+ },
705
+ },
706
+ required: ['directory', 'description', 'slug'],
707
+ },
708
+ },
709
+ {
710
+ name: 'annotate_story',
711
+ description: 'USE THIS WHEN: you have a BMAD story file and want to auto-populate its risk_context ' +
712
+ 'section with structural analysis from the codebase. ' +
713
+ 'Reads the story file, runs orient + analyze_impact, writes the risk_context block ' +
714
+ 'directly into the file (replaces existing section or inserts it). ' +
715
+ 'Run by the Architect Agent after writing stories — eliminates manual copy-paste of ' +
716
+ 'generate_change_proposal output. Run analyze_codebase first.',
717
+ inputSchema: {
718
+ type: 'object',
719
+ properties: {
720
+ directory: {
721
+ type: 'string',
722
+ description: 'Absolute path to the project directory',
723
+ },
724
+ storyFilePath: {
725
+ type: 'string',
726
+ description: 'Path to the BMAD story markdown file — relative to the project directory ' +
727
+ 'or absolute. e.g. ".bmad-method/stories/001-add-payment-retry.md"',
728
+ },
729
+ description: {
730
+ type: 'string',
731
+ description: 'Story intent for structural analysis — use story title + primary AC. ' +
732
+ 'e.g. "add payment retry — must retry up to 3 times on timeout"',
733
+ },
734
+ },
735
+ required: ['directory', 'storyFilePath', 'description'],
736
+ },
737
+ },
635
738
  {
636
739
  name: 'get_decisions',
637
740
  description: 'List or search Architecture Decision Records (ADRs) stored in openspec/decisions/. ' +
@@ -758,6 +861,10 @@ async function startMcpServer(options = {}) {
758
861
  const { directory, query, limit = 10, domain, section } = args;
759
862
  result = await handleSearchSpecs(directory, query, limit, domain, section);
760
863
  }
864
+ else if (name === 'search_unified') {
865
+ const { directory, query, limit = 10, language, domain, section } = args;
866
+ result = await handleUnifiedSearch(directory, query, limit, language, domain, section);
867
+ }
761
868
  else if (name === 'list_spec_domains') {
762
869
  const { directory } = args;
763
870
  result = await handleListSpecDomains(directory);
@@ -774,6 +881,14 @@ async function startMcpServer(options = {}) {
774
881
  const { directory, filePath, direction = 'both' } = args;
775
882
  result = await handleGetFileDependencies(directory, filePath, direction);
776
883
  }
884
+ else if (name === 'generate_change_proposal') {
885
+ const { directory, description, slug, storyContent } = args;
886
+ result = await handleGenerateChangeProposal(directory, description, slug, storyContent);
887
+ }
888
+ else if (name === 'annotate_story') {
889
+ const { directory, storyFilePath, description } = args;
890
+ result = await handleAnnotateStory(directory, storyFilePath, description);
891
+ }
777
892
  else if (name === 'get_decisions') {
778
893
  const { directory, query } = args;
779
894
  result = await handleGetDecisions(directory, query);