@schilling.mark.a/software-methodology 1.0.0 → 1.0.1

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 (69) hide show
  1. package/.github/copilot-instructions.md +159 -0
  2. package/README.md +172 -6
  3. package/docs/story-map/backbone.md +141 -0
  4. package/docs/story-map/releases/r1-walking-skeleton.md +152 -0
  5. package/docs/story-map/user-tasks/ACT-001-task-001.md +45 -0
  6. package/docs/story-map/user-tasks/ACT-001-task-002.md +48 -0
  7. package/docs/story-map/user-tasks/ACT-002-task-001.md +47 -0
  8. package/docs/story-map/user-tasks/ACT-002-task-002.md +47 -0
  9. package/docs/story-map/user-tasks/ACT-002-task-003.md +46 -0
  10. package/docs/story-map/user-tasks/ACT-003-task-001.md +47 -0
  11. package/docs/story-map/user-tasks/ACT-003-task-002.md +46 -0
  12. package/docs/story-map/user-tasks/ACT-003-task-003.md +49 -0
  13. package/docs/story-map/user-tasks/ACT-003-task-004.md +47 -0
  14. package/docs/story-map/user-tasks/ACT-004-task-001.md +48 -0
  15. package/docs/story-map/user-tasks/ACT-004-task-002.md +49 -0
  16. package/docs/story-map/user-tasks/ACT-004-task-003.md +47 -0
  17. package/docs/story-map/user-tasks/ACT-005-task-001.md +47 -0
  18. package/docs/story-map/user-tasks/ACT-005-task-002.md +48 -0
  19. package/docs/story-map/user-tasks/ACT-005-task-003.md +48 -0
  20. package/docs/story-map/user-tasks/ACT-005-task-004.md +48 -0
  21. package/docs/story-map/user-tasks/ACT-006-task-001.md +47 -0
  22. package/docs/story-map/user-tasks/ACT-006-task-002.md +46 -0
  23. package/docs/story-map/user-tasks/ACT-006-task-003.md +47 -0
  24. package/docs/story-map/user-tasks/ACT-006-task-004.md +46 -0
  25. package/docs/story-map/user-tasks/ACT-007-task-001.md +48 -0
  26. package/docs/story-map/user-tasks/ACT-007-task-002.md +47 -0
  27. package/docs/story-map/user-tasks/ACT-007-task-003.md +47 -0
  28. package/docs/story-map/user-tasks/ACT-007-task-004.md +48 -0
  29. package/docs/story-map/user-tasks/ACT-008-task-001.md +48 -0
  30. package/docs/story-map/user-tasks/ACT-008-task-002.md +48 -0
  31. package/docs/story-map/user-tasks/ACT-008-task-003.md +47 -0
  32. package/docs/story-map/user-tasks/ACT-008-task-004.md +48 -0
  33. package/docs/story-map/walking-skeleton.md +95 -0
  34. package/docs/value-proposition-canvas.md +171 -0
  35. package/features/mcp-server/query-vpc.feature +48 -0
  36. package/features/mcp-server/read-reference.feature +41 -0
  37. package/features/mcp-server/read-skill.feature +33 -0
  38. package/features/mcp-server/search-guidance.feature +42 -0
  39. package/features/mcp-server/suggest-next-step.feature +61 -0
  40. package/features/mcp-server/validate-gherkin.feature +54 -0
  41. package/mcp-server/QUICKSTART.md +172 -0
  42. package/mcp-server/README.md +171 -0
  43. package/mcp-server/dist/index.d.ts +12 -0
  44. package/mcp-server/dist/index.js +296 -0
  45. package/mcp-server/dist/repository.d.ts +59 -0
  46. package/mcp-server/dist/repository.js +211 -0
  47. package/mcp-server/dist/tools/gherkin-validator.d.ts +16 -0
  48. package/mcp-server/dist/tools/gherkin-validator.js +152 -0
  49. package/mcp-server/dist/tools/guidance-searcher.d.ts +11 -0
  50. package/mcp-server/dist/tools/guidance-searcher.js +34 -0
  51. package/mcp-server/dist/tools/next-step-suggester.d.ts +16 -0
  52. package/mcp-server/dist/tools/next-step-suggester.js +210 -0
  53. package/mcp-server/dist/tools/reference-reader.d.ts +17 -0
  54. package/mcp-server/dist/tools/reference-reader.js +57 -0
  55. package/mcp-server/dist/tools/skill-reader.d.ts +17 -0
  56. package/mcp-server/dist/tools/skill-reader.js +38 -0
  57. package/mcp-server/dist/tools/vpc-querier.d.ts +37 -0
  58. package/mcp-server/dist/tools/vpc-querier.js +158 -0
  59. package/mcp-server/package.json +42 -0
  60. package/mcp-server/src/index.ts +331 -0
  61. package/mcp-server/src/repository.ts +254 -0
  62. package/mcp-server/src/tools/gherkin-validator.ts +206 -0
  63. package/mcp-server/src/tools/guidance-searcher.ts +42 -0
  64. package/mcp-server/src/tools/next-step-suggester.ts +243 -0
  65. package/mcp-server/src/tools/reference-reader.ts +71 -0
  66. package/mcp-server/src/tools/skill-reader.ts +47 -0
  67. package/mcp-server/src/tools/vpc-querier.ts +201 -0
  68. package/mcp-server/tsconfig.json +17 -0
  69. package/package.json +8 -2
@@ -0,0 +1,243 @@
1
+ import { MethodologyRepository } from "../repository.js";
2
+ import { promises as fs } from "fs";
3
+ import { join } from "path";
4
+
5
+ export class NextStepSuggester {
6
+ constructor(private repository: MethodologyRepository) {}
7
+
8
+ async suggest(projectPath?: string) {
9
+ const context = await this.analyzeProjectContext(projectPath);
10
+ const suggestion = this.determineSuggestion(context);
11
+
12
+ return {
13
+ content: [
14
+ {
15
+ type: "text" as const,
16
+ text: suggestion,
17
+ },
18
+ ],
19
+ };
20
+ }
21
+
22
+ private async analyzeProjectContext(projectPath?: string): Promise<{
23
+ hasVPC: boolean;
24
+ hasBMC: boolean;
25
+ hasStoryMap: boolean;
26
+ hasFeatureFiles: boolean;
27
+ hasTests: boolean;
28
+ testsPassing: boolean;
29
+ hasPipeline: boolean;
30
+ }> {
31
+ const docsPath = projectPath ? join(projectPath, "docs") : join(process.cwd(), "docs");
32
+
33
+ try {
34
+ const vpcContent = await this.repository.readVPC();
35
+ const storyMapContent = await this.repository.readStoryMap();
36
+ const featureFiles = await this.repository.listFeatureFiles(projectPath);
37
+
38
+ return {
39
+ hasVPC: !!vpcContent,
40
+ hasBMC: await this.fileExists(join(docsPath, "business-model-canvas.md")),
41
+ hasStoryMap: !!storyMapContent,
42
+ hasFeatureFiles: featureFiles.length > 0,
43
+ hasTests: await this.hasTestFiles(projectPath),
44
+ testsPassing: false, // TODO: Implement test execution check
45
+ hasPipeline: await this.hasPipelineConfig(projectPath),
46
+ };
47
+ } catch {
48
+ return {
49
+ hasVPC: false,
50
+ hasBMC: false,
51
+ hasStoryMap: false,
52
+ hasFeatureFiles: false,
53
+ hasTests: false,
54
+ testsPassing: false,
55
+ hasPipeline: false,
56
+ };
57
+ }
58
+ }
59
+
60
+ private determineSuggestion(context: {
61
+ hasVPC: boolean;
62
+ hasBMC: boolean;
63
+ hasStoryMap: boolean;
64
+ hasFeatureFiles: boolean;
65
+ hasTests: boolean;
66
+ testsPassing: boolean;
67
+ hasPipeline: boolean;
68
+ }): string {
69
+ if (!context.hasVPC) {
70
+ return `# Next Step: Create Value Proposition Canvas
71
+
72
+ You should start by defining business value using the Value Proposition Canvas.
73
+
74
+ **Why:** The VPC establishes the foundation for all downstream work. It defines customer segments, jobs, pains, and gains that inform every feature decision.
75
+
76
+ **Reference:** product-strategy/SKILL.md
77
+
78
+ **What to create:** /docs/value-proposition-canvas.md
79
+
80
+ The VPC should include:
81
+ - Customer segments (who are your users?)
82
+ - Customer jobs (what are they trying to accomplish?)
83
+ - Pains (what frustrates them?)
84
+ - Gains (what success looks like)
85
+ - Pain relievers (how your product helps)
86
+ - Gain creators (how your product delivers value)`;
87
+ }
88
+
89
+ if (!context.hasStoryMap) {
90
+ return `# Next Step: Create Story Map Backbone
91
+
92
+ You have a Value Proposition Canvas. Now organize user activities into a story map.
93
+
94
+ **Why:** The story map backbone organizes work by user activities (derived from VPC customer jobs) rather than technical components.
95
+
96
+ **Reference:** story-mapping/SKILL.md
97
+
98
+ **What to create:** /docs/story-map/backbone.md
99
+
100
+ Each customer job from the VPC becomes one user activity in the backbone.`;
101
+ }
102
+
103
+ if (!context.hasFeatureFiles) {
104
+ return `# Next Step: Write Gherkin Scenarios
105
+
106
+ You have a story map. Now specify behavior using concrete examples.
107
+
108
+ **Why:** Gherkin scenarios define "done" before implementation starts. They become executable acceptance tests.
109
+
110
+ **Reference:** bdd-specification/SKILL.md
111
+
112
+ **What to create:** /features/*.feature
113
+
114
+ Each scenario should:
115
+ - Use Given-When-Then format
116
+ - Trace "So that" clause to a VPC gain
117
+ - Specify observable user outcomes`;
118
+ }
119
+
120
+ if (!context.hasTests) {
121
+ return `# Next Step: Write Failing Acceptance Test (RED Phase)
122
+
123
+ You have Gherkin scenarios. Now write automated tests that verify them.
124
+
125
+ **Why:** Test-first development defines success criteria before implementation. Tests fail initially because the feature doesn't exist yet.
126
+
127
+ **Reference:** atdd-workflow/red-phase.md
128
+
129
+ **What to do:**
130
+ 1. Pick one Gherkin scenario
131
+ 2. Write automated test that verifies it
132
+ 3. Run test and confirm it fails with clear error message
133
+ 4. Proceed to GREEN phase once RED phase passes`;
134
+ }
135
+
136
+ if (context.hasTests && !context.testsPassing) {
137
+ return `# Next Step: Make Tests Pass (GREEN Phase)
138
+
139
+ You have failing tests. Now implement minimum code to make them pass.
140
+
141
+ **Why:** GREEN phase focuses on making it work, not making it perfect. Simplicity first, optimization later.
142
+
143
+ **Reference:** atdd-workflow/green-phase.md
144
+
145
+ **What to do:**
146
+ 1. Write simplest implementation that passes the test
147
+ 2. No premature optimization
148
+ 3. No "future-proofing"
149
+ 4. Run tests until they pass
150
+ 5. Proceed to REFACTOR phase once tests are green`;
151
+ }
152
+
153
+ if (context.testsPassing) {
154
+ return `# Next Step: Refactor for Maintainability
155
+
156
+ You have passing tests. Now improve code structure.
157
+
158
+ **Why:** REFACTOR phase is where clean code principles apply. With tests protecting you, safely improve structure.
159
+
160
+ **References:**
161
+ - atdd-workflow/refactor-phase.md
162
+ - clean-code/solid.md
163
+
164
+ **What to do:**
165
+ 1. Keep tests green throughout refactoring
166
+ 2. Apply SOLID principles
167
+ 3. Extract duplications
168
+ 4. Use ubiquitous language
169
+ 5. Reference clean-code patterns as needed`;
170
+ }
171
+
172
+ if (!context.hasPipeline) {
173
+ return `# Next Step: Set Up CI/CD Pipeline
174
+
175
+ You have tested code. Now automate deployment.
176
+
177
+ **Why:** Automated pipeline builds, tests, and deploys code without manual steps. Makes frequent delivery safe and easy.
178
+
179
+ **Reference:** cicd-pipeline/SKILL.md
180
+
181
+ **What to create:** Pipeline configuration (e.g., .github/workflows/ci.yml)
182
+
183
+ Pipeline should include:
184
+ - Build stage
185
+ - Test stage (runs all tests)
186
+ - Deploy stage (on successful tests)`;
187
+ }
188
+
189
+ return `# Next Step: Measure and Improve
190
+
191
+ You have a complete delivery workflow. Now collect data and iterate.
192
+
193
+ **Why:** Continuous improvement validates that delivered features create expected value and identifies process improvements.
194
+
195
+ **Reference:** continuous-improvement/SKILL.md
196
+
197
+ **What to do:**
198
+ 1. Define success metrics (connects to VPC gains)
199
+ 2. Collect measurement data
200
+ 3. Perform root cause analysis when issues arise
201
+ 4. Update upstream artifacts based on learnings`;
202
+ }
203
+
204
+ private async fileExists(path: string): Promise<boolean> {
205
+ try {
206
+ await fs.access(path);
207
+ return true;
208
+ } catch {
209
+ return false;
210
+ }
211
+ }
212
+
213
+ private async hasTestFiles(projectPath?: string): Promise<boolean> {
214
+ const testDirs = ["test", "tests", "spec", "__tests__"];
215
+ const basePath = projectPath || process.cwd();
216
+
217
+ for (const dir of testDirs) {
218
+ if (await this.fileExists(join(basePath, dir))) {
219
+ return true;
220
+ }
221
+ }
222
+
223
+ return false;
224
+ }
225
+
226
+ private async hasPipelineConfig(projectPath?: string): Promise<boolean> {
227
+ const pipelineFiles = [
228
+ ".github/workflows",
229
+ ".gitlab-ci.yml",
230
+ "Jenkinsfile",
231
+ ".circleci/config.yml",
232
+ ];
233
+ const basePath = projectPath || process.cwd();
234
+
235
+ for (const file of pipelineFiles) {
236
+ if (await this.fileExists(join(basePath, file))) {
237
+ return true;
238
+ }
239
+ }
240
+
241
+ return false;
242
+ }
243
+ }
@@ -0,0 +1,71 @@
1
+ import { MethodologyRepository } from "../repository.js";
2
+
3
+ export class ReferenceReader {
4
+ constructor(private repository: MethodologyRepository) {}
5
+
6
+ async readReference(referencePath: string) {
7
+ // Parse path like "clean-code/solid.md"
8
+ const parts = referencePath.split("/");
9
+ if (parts.length !== 2) {
10
+ throw new Error(
11
+ "Reference path must be in format 'skill-name/reference-name.md'"
12
+ );
13
+ }
14
+
15
+ const [skillName, referenceName] = parts;
16
+
17
+ try {
18
+ const content = await this.repository.readReference(skillName, referenceName);
19
+
20
+ return {
21
+ content: [
22
+ {
23
+ type: "text" as const,
24
+ text: content,
25
+ },
26
+ ],
27
+ };
28
+ } catch (error) {
29
+ const references = await this.repository.listReferences(skillName);
30
+
31
+ if (references.length === 0) {
32
+ throw new Error(
33
+ `Skill '${skillName}' has no reference documents or doesn't exist`
34
+ );
35
+ }
36
+
37
+ const availableRefs = references.map((r) => r.name).join(", ");
38
+ throw new Error(
39
+ `Reference '${referenceName}' not found in skill '${skillName}'. Available references: ${availableRefs}`
40
+ );
41
+ }
42
+ }
43
+
44
+ async listReferences(skillName: string) {
45
+ const references = await this.repository.listReferences(skillName);
46
+
47
+ if (references.length === 0) {
48
+ return {
49
+ content: [
50
+ {
51
+ type: "text" as const,
52
+ text: `Skill '${skillName}' has no reference documents.`,
53
+ },
54
+ ],
55
+ };
56
+ }
57
+
58
+ const text = references
59
+ .map((ref) => `- ${ref.name}`)
60
+ .join("\n");
61
+
62
+ return {
63
+ content: [
64
+ {
65
+ type: "text" as const,
66
+ text: `# References for ${skillName} (${references.length})\n\n${text}`,
67
+ },
68
+ ],
69
+ };
70
+ }
71
+ }
@@ -0,0 +1,47 @@
1
+ import { MethodologyRepository } from "../repository.js";
2
+
3
+ export class SkillReader {
4
+ constructor(private repository: MethodologyRepository) {}
5
+
6
+ async readSkill(skillName: string) {
7
+ try {
8
+ const content = await this.repository.readSkill(skillName);
9
+
10
+ return {
11
+ content: [
12
+ {
13
+ type: "text" as const,
14
+ text: content,
15
+ },
16
+ ],
17
+ };
18
+ } catch (error) {
19
+ const skills = await this.repository.listSkills();
20
+ const availableSkills = skills.map((s) => s.name).join(", ");
21
+
22
+ throw new Error(
23
+ `Skill '${skillName}' not found. Available skills: ${availableSkills}`
24
+ );
25
+ }
26
+ }
27
+
28
+ async listSkills() {
29
+ const skills = await this.repository.listSkills();
30
+
31
+ const text = skills
32
+ .map(
33
+ (skill) =>
34
+ `**${skill.displayName}** (${skill.name}):\n ${skill.description}`
35
+ )
36
+ .join("\n\n");
37
+
38
+ return {
39
+ content: [
40
+ {
41
+ type: "text" as const,
42
+ text: `# Available Skills (${skills.length})\n\n${text}`,
43
+ },
44
+ ],
45
+ };
46
+ }
47
+ }
@@ -0,0 +1,201 @@
1
+ import { MethodologyRepository } from "../repository.js";
2
+
3
+ interface VPCSegment {
4
+ name: string;
5
+ customerJobs: string[];
6
+ pains: string[];
7
+ gains: string[];
8
+ }
9
+
10
+ export class VPCQuerier {
11
+ constructor(private repository: MethodologyRepository) {}
12
+
13
+ async getSegments() {
14
+ const vpc = await this.repository.readVPC();
15
+ const segments = this.parseSegments(vpc);
16
+
17
+ const text = segments.map((s) => `- ${s.name}`).join("\n");
18
+
19
+ return {
20
+ content: [
21
+ {
22
+ type: "text" as const,
23
+ text: `# Customer Segments (${segments.length})\n\n${text}`,
24
+ },
25
+ ],
26
+ };
27
+ }
28
+
29
+ async getCustomerJobs(segmentName: string) {
30
+ const vpc = await this.repository.readVPC();
31
+ const segments = this.parseSegments(vpc);
32
+ const segment = segments.find((s) => s.name === segmentName);
33
+
34
+ if (!segment) {
35
+ const available = segments.map((s) => s.name).join(", ");
36
+ throw new Error(
37
+ `Segment '${segmentName}' not found. Available segments: ${available}`
38
+ );
39
+ }
40
+
41
+ const text = segment.customerJobs
42
+ .map((job, i) => `${i + 1}. ${job}`)
43
+ .join("\n");
44
+
45
+ return {
46
+ content: [
47
+ {
48
+ type: "text" as const,
49
+ text: `# Customer Jobs for ${segmentName}\n\n${text}`,
50
+ },
51
+ ],
52
+ };
53
+ }
54
+
55
+ async getPains(segmentName: string) {
56
+ const vpc = await this.repository.readVPC();
57
+ const segments = this.parseSegments(vpc);
58
+ const segment = segments.find((s) => s.name === segmentName);
59
+
60
+ if (!segment) {
61
+ const available = segments.map((s) => s.name).join(", ");
62
+ throw new Error(
63
+ `Segment '${segmentName}' not found. Available segments: ${available}`
64
+ );
65
+ }
66
+
67
+ const text = segment.pains
68
+ .map((pain, i) => `${i + 1}. ${pain}`)
69
+ .join("\n");
70
+
71
+ return {
72
+ content: [
73
+ {
74
+ type: "text" as const,
75
+ text: `# Pains for ${segmentName}\n\n${text}`,
76
+ },
77
+ ],
78
+ };
79
+ }
80
+
81
+ async getGains(segmentName: string) {
82
+ const vpc = await this.repository.readVPC();
83
+ const segments = this.parseSegments(vpc);
84
+ const segment = segments.find((s) => s.name === segmentName);
85
+
86
+ if (!segment) {
87
+ const available = segments.map((s) => s.name).join(", ");
88
+ throw new Error(
89
+ `Segment '${segmentName}' not found. Available segments: ${available}`
90
+ );
91
+ }
92
+
93
+ const text = segment.gains
94
+ .map((gain, i) => `${i + 1}. ${gain}`)
95
+ .join("\n");
96
+
97
+ return {
98
+ content: [
99
+ {
100
+ type: "text" as const,
101
+ text: `# Gains for ${segmentName}\n\n${text}`,
102
+ },
103
+ ],
104
+ };
105
+ }
106
+
107
+ async search(query: string) {
108
+ const vpc = await this.repository.readVPC();
109
+ const segments = this.parseSegments(vpc);
110
+ const results: Array<{ segment: string; type: "pain" | "gain"; text: string }> = [];
111
+
112
+ const queryLower = query.toLowerCase();
113
+
114
+ for (const segment of segments) {
115
+ for (const pain of segment.pains) {
116
+ if (pain.toLowerCase().includes(queryLower)) {
117
+ results.push({ segment: segment.name, type: "pain", text: pain });
118
+ }
119
+ }
120
+ for (const gain of segment.gains) {
121
+ if (gain.toLowerCase().includes(queryLower)) {
122
+ results.push({ segment: segment.name, type: "gain", text: gain });
123
+ }
124
+ }
125
+ }
126
+
127
+ if (results.length === 0) {
128
+ return {
129
+ content: [
130
+ {
131
+ type: "text" as const,
132
+ text: `No results found for '${query}' in Value Proposition Canvas.`,
133
+ },
134
+ ],
135
+ };
136
+ }
137
+
138
+ const text = results
139
+ .map((r) => `**[${r.segment}] ${r.type.toUpperCase()}:** ${r.text}`)
140
+ .join("\n\n");
141
+
142
+ return {
143
+ content: [
144
+ {
145
+ type: "text" as const,
146
+ text: `# VPC Search Results for '${query}'\n\n${text}`,
147
+ },
148
+ ],
149
+ };
150
+ }
151
+
152
+ private parseSegments(vpcContent: string): VPCSegment[] {
153
+ const segments: VPCSegment[] = [];
154
+ const segmentRegex = /## Segment: (.+?)\n/g;
155
+
156
+ let match;
157
+ const segmentStarts: Array<{ name: string; index: number }> = [];
158
+
159
+ while ((match = segmentRegex.exec(vpcContent)) !== null) {
160
+ segmentStarts.push({ name: match[1], index: match.index });
161
+ }
162
+
163
+ for (let i = 0; i < segmentStarts.length; i++) {
164
+ const start = segmentStarts[i];
165
+ const end = i + 1 < segmentStarts.length ? segmentStarts[i + 1].index : vpcContent.length;
166
+ const segmentContent = vpcContent.slice(start.index, end);
167
+
168
+ segments.push({
169
+ name: start.name,
170
+ customerJobs: this.extractList(segmentContent, "#### Customer Jobs"),
171
+ pains: this.extractList(segmentContent, "#### Pains"),
172
+ gains: this.extractList(segmentContent, "#### Gains"),
173
+ });
174
+ }
175
+
176
+ return segments;
177
+ }
178
+
179
+ private extractList(content: string, heading: string): string[] {
180
+ const headingIndex = content.indexOf(heading);
181
+ if (headingIndex === -1) return [];
182
+
183
+ const afterHeading = content.slice(headingIndex + heading.length);
184
+ const nextHeadingIndex = afterHeading.search(/####|###|##/);
185
+ const section = nextHeadingIndex === -1
186
+ ? afterHeading
187
+ : afterHeading.slice(0, nextHeadingIndex);
188
+
189
+ const lines = section.split("\n");
190
+ const items: string[] = [];
191
+
192
+ for (const line of lines) {
193
+ const match = line.match(/^\d+\.\s+\*\*(.+?)\*\*\s*—\s*(.+)/);
194
+ if (match) {
195
+ items.push(`${match[1]} — ${match[2]}`);
196
+ }
197
+ }
198
+
199
+ return items;
200
+ }
201
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "Node16",
5
+ "moduleResolution": "Node16",
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "resolveJsonModule": true,
13
+ "declaration": true
14
+ },
15
+ "include": ["src/**/*"],
16
+ "exclude": ["node_modules", "dist"]
17
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schilling.mark.a/software-methodology",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Comprehensive software development methodology from product strategy through production deployment. Eleven skills covering Business Model Canvas, UX research, story mapping, BDD/ATDD, clean code, CI/CD, and continuous improvement.",
5
5
  "keywords": [
6
6
  "methodology",
@@ -16,7 +16,8 @@
16
16
  "cicd",
17
17
  "continuous-improvement",
18
18
  "claude-code",
19
- "github-copilot"
19
+ "github-copilot",
20
+ "mcp-server"
20
21
  ],
21
22
  "author": "Mark Schilling",
22
23
  "repository": {
@@ -28,9 +29,14 @@
28
29
  "bugs": {
29
30
  "url": "https://github.com/MarkSchilling/software-methodology/issues"
30
31
  },
32
+ "workspaces": [
33
+ "mcp-server"
34
+ ],
31
35
  "files": [
32
36
  "dist/",
33
37
  "docs/",
38
+ "features/",
39
+ "mcp-server/",
34
40
  "project-templates/",
35
41
  ".github/copilot-instructions.md",
36
42
  "README.md",