@waycraft/waypoint-mcp 0.1.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.
- package/LICENSE +21 -0
- package/README.md +110 -0
- package/dist/context.js +79 -0
- package/dist/index.js +46 -0
- package/dist/tools/audit.js +311 -0
- package/dist/tools/build.js +112 -0
- package/dist/tools/compare.js +92 -0
- package/dist/tools/debug.js +148 -0
- package/dist/tools/design.js +276 -0
- package/dist/tools/document.js +107 -0
- package/dist/tools/fix.js +103 -0
- package/dist/tools/goal.js +94 -0
- package/dist/tools/improve.js +99 -0
- package/dist/tools/measure.js +101 -0
- package/dist/tools/plan.js +107 -0
- package/dist/tools/research.js +104 -0
- package/dist/tools/review.js +123 -0
- package/dist/tools/test.js +107 -0
- package/package.json +38 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { getBaseContext, getArtifact, saveArtifact } from "../context.js";
|
|
2
|
+
export const definition = {
|
|
3
|
+
name: "waypoint_review",
|
|
4
|
+
description: "Final quality check before shipping or handoff. Reads all prior artifacts.",
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: "object",
|
|
7
|
+
properties: {
|
|
8
|
+
workspacePath: {
|
|
9
|
+
type: "string",
|
|
10
|
+
description: "Absolute path to the workspace root.",
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
required: ["workspacePath"],
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
const ALL_ARTIFACTS = [
|
|
17
|
+
"goal.md",
|
|
18
|
+
"research.md",
|
|
19
|
+
"compare.md",
|
|
20
|
+
"plan.md",
|
|
21
|
+
"design.md",
|
|
22
|
+
"build.md",
|
|
23
|
+
"test.md",
|
|
24
|
+
"fix.md",
|
|
25
|
+
"debug.md",
|
|
26
|
+
"audit.md",
|
|
27
|
+
"measure.md",
|
|
28
|
+
"improve.md",
|
|
29
|
+
"docs.md",
|
|
30
|
+
];
|
|
31
|
+
export async function run(args) {
|
|
32
|
+
const { workspacePath } = args;
|
|
33
|
+
const ctx = await getBaseContext(workspacePath);
|
|
34
|
+
const goalArtifact = await getArtifact(workspacePath, "goal.md");
|
|
35
|
+
if (!goalArtifact) {
|
|
36
|
+
return [
|
|
37
|
+
"## waypoint_review — No goal found",
|
|
38
|
+
"",
|
|
39
|
+
"Run `waypoint_goal` first — review requires a defined goal to evaluate against.",
|
|
40
|
+
].join("\n");
|
|
41
|
+
}
|
|
42
|
+
const goalLine = goalArtifact.match(/^# Goal\n+(.+)/m)?.[1] ?? "(goal not parsed)";
|
|
43
|
+
// inventory all artifacts
|
|
44
|
+
const inventory = [];
|
|
45
|
+
for (const name of ALL_ARTIFACTS) {
|
|
46
|
+
const content = await getArtifact(workspacePath, name);
|
|
47
|
+
inventory.push({ name, present: !!content });
|
|
48
|
+
}
|
|
49
|
+
const present = inventory.filter((a) => a.present);
|
|
50
|
+
const missing = inventory.filter((a) => !a.present);
|
|
51
|
+
const inventoryRows = inventory.map((a) => `| ${a.name} | ${a.present ? "✅" : "❌"} |`);
|
|
52
|
+
const artifact = [
|
|
53
|
+
"# Review",
|
|
54
|
+
"",
|
|
55
|
+
`**Goal:** ${goalLine}`,
|
|
56
|
+
"",
|
|
57
|
+
"## Artifact inventory",
|
|
58
|
+
"| Artifact | Present |",
|
|
59
|
+
"|----------|---------|",
|
|
60
|
+
...inventoryRows,
|
|
61
|
+
"",
|
|
62
|
+
`**${present.length} of ${ALL_ARTIFACTS.length} artifacts present.**`,
|
|
63
|
+
missing.length > 0
|
|
64
|
+
? `Missing: ${missing.map((a) => a.name).join(", ")}`
|
|
65
|
+
: "All artifacts present.",
|
|
66
|
+
"",
|
|
67
|
+
"## Pre-ship checklist",
|
|
68
|
+
"<!-- Work through these before marking done -->",
|
|
69
|
+
"",
|
|
70
|
+
"### Goal",
|
|
71
|
+
"- [ ] Goal is clearly stated and success criteria are defined",
|
|
72
|
+
"- [ ] All success criteria are met (see measure.md)",
|
|
73
|
+
"",
|
|
74
|
+
"### Code quality",
|
|
75
|
+
"- [ ] No dead code or commented-out blocks",
|
|
76
|
+
"- [ ] No hardcoded values that should be configuration",
|
|
77
|
+
"- [ ] Error states produce safe, clear output",
|
|
78
|
+
"",
|
|
79
|
+
"### Tests",
|
|
80
|
+
"- [ ] Happy path tested",
|
|
81
|
+
"- [ ] Edge cases tested",
|
|
82
|
+
"- [ ] No known failing tests",
|
|
83
|
+
"",
|
|
84
|
+
"### Documentation",
|
|
85
|
+
"- [ ] README or docs.md reflects current state",
|
|
86
|
+
"- [ ] Breaking changes documented",
|
|
87
|
+
"",
|
|
88
|
+
"### Security",
|
|
89
|
+
"- [ ] No secrets or credentials in code or artifacts",
|
|
90
|
+
"- [ ] Input validation at system boundaries",
|
|
91
|
+
"",
|
|
92
|
+
"## Reviewer notes",
|
|
93
|
+
"<!-- Open issues, questions for the team, or follow-up items -->",
|
|
94
|
+
"- ",
|
|
95
|
+
"",
|
|
96
|
+
"## Verdict",
|
|
97
|
+
"<!-- ✅ Ready to ship | ⚠️ Ship with caveats | ❌ Not ready -->",
|
|
98
|
+
"**Verdict:** ",
|
|
99
|
+
"**Rationale:** ",
|
|
100
|
+
"",
|
|
101
|
+
`_Generated by waypoint_review — ${new Date().toISOString()}_`,
|
|
102
|
+
].join("\n");
|
|
103
|
+
await saveArtifact(workspacePath, "review.md", artifact);
|
|
104
|
+
return [
|
|
105
|
+
"## waypoint_review — Final review generated",
|
|
106
|
+
"",
|
|
107
|
+
`**Goal:** ${goalLine}`,
|
|
108
|
+
"",
|
|
109
|
+
`### Artifact inventory: ${present.length}/${ALL_ARTIFACTS.length} present`,
|
|
110
|
+
...inventory.map((a) => `- ${a.present ? "✅" : "❌"} ${a.name}`),
|
|
111
|
+
"",
|
|
112
|
+
"### Pre-ship checklist covers",
|
|
113
|
+
"Goal, code quality, tests, documentation, security",
|
|
114
|
+
"",
|
|
115
|
+
"### Artifact saved",
|
|
116
|
+
"`review.md` written to `.waypoint/review.md`.",
|
|
117
|
+
"Complete the checklist and record your verdict.",
|
|
118
|
+
"",
|
|
119
|
+
missing.length > 0
|
|
120
|
+
? `### Missing artifacts\nConsider running: ${missing.map((a) => `\`waypoint_${a.name.replace(".md", "")}\``).join(", ")}`
|
|
121
|
+
: "### All artifacts present — ready for final checklist.",
|
|
122
|
+
].join("\n");
|
|
123
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { getBaseContext, getArtifact, saveArtifact } from "../context.js";
|
|
2
|
+
export const definition = {
|
|
3
|
+
name: "waypoint_test",
|
|
4
|
+
description: "Verify feature-level requirements. Generate test checklists and prompts.",
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: "object",
|
|
7
|
+
properties: {
|
|
8
|
+
workspacePath: {
|
|
9
|
+
type: "string",
|
|
10
|
+
description: "Absolute path to the workspace root.",
|
|
11
|
+
},
|
|
12
|
+
feature: {
|
|
13
|
+
type: "string",
|
|
14
|
+
description: "Specific feature or behavior to test (optional). Omit to test all built features.",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
required: ["workspacePath"],
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
export async function run(args) {
|
|
21
|
+
const { workspacePath, feature } = args;
|
|
22
|
+
const ctx = await getBaseContext(workspacePath);
|
|
23
|
+
const buildArtifact = await getArtifact(workspacePath, "build.md");
|
|
24
|
+
const goalArtifact = await getArtifact(workspacePath, "goal.md");
|
|
25
|
+
if (!buildArtifact && !goalArtifact) {
|
|
26
|
+
return [
|
|
27
|
+
"## waypoint_test — No build or goal found",
|
|
28
|
+
"",
|
|
29
|
+
"Run `waypoint_build` before testing.",
|
|
30
|
+
].join("\n");
|
|
31
|
+
}
|
|
32
|
+
const goalLine = goalArtifact?.match(/^# Goal\n+(.+)/m)?.[1] ?? "(goal not parsed)";
|
|
33
|
+
const hasBuild = !!buildArtifact;
|
|
34
|
+
const focus = feature ?? goalLine;
|
|
35
|
+
const artifact = [
|
|
36
|
+
"# Test",
|
|
37
|
+
"",
|
|
38
|
+
`**Goal:** ${goalLine}`,
|
|
39
|
+
feature ? `**Feature under test:** ${feature}` : "",
|
|
40
|
+
!hasBuild ? "\n> ⚠️ No build.md found — test coverage may be incomplete." : "",
|
|
41
|
+
"",
|
|
42
|
+
"## Feature checklist",
|
|
43
|
+
"<!-- Verify each feature works as intended from a user perspective -->",
|
|
44
|
+
`- [ ] ${focus} — happy path works end to end`,
|
|
45
|
+
"- [ ] Edge cases handled correctly",
|
|
46
|
+
"- [ ] Error states produce clear, safe output",
|
|
47
|
+
"- [ ] No regressions in adjacent functionality",
|
|
48
|
+
"",
|
|
49
|
+
"## Test prompts for AI coding tools",
|
|
50
|
+
"",
|
|
51
|
+
"### Unit test prompt",
|
|
52
|
+
"```",
|
|
53
|
+
`Write unit tests for: ${focus}`,
|
|
54
|
+
"Requirements:",
|
|
55
|
+
"- Test the happy path",
|
|
56
|
+
"- Test at least 2 edge cases",
|
|
57
|
+
"- Test error/failure paths",
|
|
58
|
+
"- No mocks unless absolutely necessary",
|
|
59
|
+
"```",
|
|
60
|
+
"",
|
|
61
|
+
"### Integration test prompt",
|
|
62
|
+
"```",
|
|
63
|
+
`Write integration tests for: ${focus}`,
|
|
64
|
+
"Requirements:",
|
|
65
|
+
"- Exercise the full stack from entry point to output",
|
|
66
|
+
"- Verify against real data or fixtures, not mocks",
|
|
67
|
+
"- Assert on observable behavior, not implementation details",
|
|
68
|
+
"```",
|
|
69
|
+
"",
|
|
70
|
+
"## Manual test cases",
|
|
71
|
+
"<!-- Scenarios that are hard to automate -->",
|
|
72
|
+
"| Scenario | Steps | Expected | Actual | Pass? |",
|
|
73
|
+
"|----------|-------|----------|--------|-------|",
|
|
74
|
+
"| Happy path | | | | |",
|
|
75
|
+
"| Empty input | | | | |",
|
|
76
|
+
"| Invalid input | | | | |",
|
|
77
|
+
"",
|
|
78
|
+
"## Known gaps",
|
|
79
|
+
"<!-- Tests not written yet and why -->",
|
|
80
|
+
"- ",
|
|
81
|
+
"",
|
|
82
|
+
`_Generated by waypoint_test — ${new Date().toISOString()}_`,
|
|
83
|
+
]
|
|
84
|
+
.filter((l) => l !== undefined)
|
|
85
|
+
.join("\n");
|
|
86
|
+
await saveArtifact(workspacePath, "test.md", artifact);
|
|
87
|
+
return [
|
|
88
|
+
"## waypoint_test — Test plan generated",
|
|
89
|
+
"",
|
|
90
|
+
`**Goal:** ${goalLine}`,
|
|
91
|
+
feature ? `**Feature:** ${feature}` : "",
|
|
92
|
+
!hasBuild ? "\n> No build.md found — test plan may be incomplete." : "",
|
|
93
|
+
"",
|
|
94
|
+
"### Coverage areas",
|
|
95
|
+
"- **Feature checklist** — happy path, edge cases, errors, regressions",
|
|
96
|
+
"- **AI test prompts** — unit and integration test generation",
|
|
97
|
+
"- **Manual test cases** — scenarios needing human verification",
|
|
98
|
+
"",
|
|
99
|
+
"### Artifact saved",
|
|
100
|
+
"`test.md` written to `.waypoint/test.md`.",
|
|
101
|
+
"",
|
|
102
|
+
"### Suggested next step",
|
|
103
|
+
"If tests reveal bugs, run `waypoint_fix`. Otherwise run `waypoint_measure` to evaluate overall success.",
|
|
104
|
+
]
|
|
105
|
+
.filter((l) => l !== undefined)
|
|
106
|
+
.join("\n");
|
|
107
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@waycraft/waypoint-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A structured development protocol as an MCP server. 14 tools that guide any project from goal to ship.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"mcp",
|
|
9
|
+
"claude",
|
|
10
|
+
"claude-code",
|
|
11
|
+
"engineering",
|
|
12
|
+
"development-process",
|
|
13
|
+
"protocol",
|
|
14
|
+
"ai-native",
|
|
15
|
+
"workflow"
|
|
16
|
+
],
|
|
17
|
+
"bin": {
|
|
18
|
+
"waypoint-mcp": "dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc",
|
|
25
|
+
"start": "node dist/index.js",
|
|
26
|
+
"dev": "tsx src/index.ts",
|
|
27
|
+
"test": "tsx tests/goal.test.ts && tsx tests/research.test.ts && tsx tests/compare.test.ts && tsx tests/plan.test.ts && tsx tests/build.test.ts && tsx tests/test.test.ts && tsx tests/fix.test.ts && tsx tests/debug.test.ts && tsx tests/measure.test.ts && tsx tests/improve.test.ts && tsx tests/document.test.ts && tsx tests/review.test.ts",
|
|
28
|
+
"prepare": "npm run build"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^22.0.0",
|
|
35
|
+
"tsx": "^4.0.0",
|
|
36
|
+
"typescript": "^5.0.0"
|
|
37
|
+
}
|
|
38
|
+
}
|