@waycraft/waypoint-mcp 0.1.0 → 0.1.2
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 +116 -21
- package/dist/index.js +69 -46
- package/package.json +10 -4
- package/dist/context.js +0 -79
- package/dist/tools/audit.js +0 -311
- package/dist/tools/build.js +0 -112
- package/dist/tools/compare.js +0 -92
- package/dist/tools/debug.js +0 -148
- package/dist/tools/design.js +0 -276
- package/dist/tools/document.js +0 -107
- package/dist/tools/fix.js +0 -103
- package/dist/tools/goal.js +0 -94
- package/dist/tools/improve.js +0 -99
- package/dist/tools/measure.js +0 -101
- package/dist/tools/plan.js +0 -107
- package/dist/tools/research.js +0 -104
- package/dist/tools/review.js +0 -123
- package/dist/tools/test.js +0 -107
package/dist/tools/design.js
DELETED
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
import { getBaseContext, getArtifact, saveArtifact } from "../context.js";
|
|
2
|
-
export const definition = {
|
|
3
|
-
name: "waypoint_design",
|
|
4
|
-
description: "Produce a design contract before building. Infers project tier (Prototype / Product / Platform) from the workspace and plan, confirms with one question, then prescribes patterns, structure, and anti-patterns for Build to follow.",
|
|
5
|
-
inputSchema: {
|
|
6
|
-
type: "object",
|
|
7
|
-
properties: {
|
|
8
|
-
workspacePath: {
|
|
9
|
-
type: "string",
|
|
10
|
-
description: "Absolute path to the workspace root.",
|
|
11
|
-
},
|
|
12
|
-
tier: {
|
|
13
|
-
type: "string",
|
|
14
|
-
enum: ["prototype", "product", "platform"],
|
|
15
|
-
description: "Explicitly set the project tier (optional). Omit to let waypoint_design infer it from the workspace and ask for confirmation.",
|
|
16
|
-
},
|
|
17
|
-
focus: {
|
|
18
|
-
type: "string",
|
|
19
|
-
description: "Specific area to produce design guidance for (optional). E.g. 'auth layer', 'data access', 'API structure'. Omit to cover the full plan.",
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
required: ["workspacePath"],
|
|
23
|
-
},
|
|
24
|
-
};
|
|
25
|
-
// ─── Tier inference ───────────────────────────────────────────────────────────
|
|
26
|
-
function inferTier(ctx, planArtifact) {
|
|
27
|
-
let score = 0;
|
|
28
|
-
const fileTree = ctx.fileTree ?? "";
|
|
29
|
-
const pkg = (() => {
|
|
30
|
-
try {
|
|
31
|
-
return JSON.parse(ctx.packageJson ?? "{}");
|
|
32
|
-
}
|
|
33
|
-
catch {
|
|
34
|
-
return {};
|
|
35
|
-
}
|
|
36
|
-
})();
|
|
37
|
-
const deps = Object.keys({ ...pkg.dependencies, ...pkg.devDependencies });
|
|
38
|
-
const allText = [fileTree, planArtifact ?? "", ctx.packageJson ?? ""].join("\n").toLowerCase();
|
|
39
|
-
const fileCount = (fileTree.match(/\n/g) ?? []).length;
|
|
40
|
-
if (fileCount > 40)
|
|
41
|
-
score += 2;
|
|
42
|
-
else if (fileCount > 15)
|
|
43
|
-
score += 1;
|
|
44
|
-
if (allText.includes("dockerfile") || allText.includes("docker-compose"))
|
|
45
|
-
score += 2;
|
|
46
|
-
if (allText.includes(".github/workflows") || allText.includes("ci.yml"))
|
|
47
|
-
score += 1;
|
|
48
|
-
if (allText.includes(".env.example") || allText.includes("config/"))
|
|
49
|
-
score += 1;
|
|
50
|
-
if (deps.some(d => ["prisma", "typeorm", "sequelize", "drizzle", "mongoose"].includes(d)))
|
|
51
|
-
score += 2;
|
|
52
|
-
if (deps.some(d => ["passport", "jsonwebtoken", "next-auth", "clerk"].includes(d)))
|
|
53
|
-
score += 1;
|
|
54
|
-
if (deps.some(d => ["jest", "vitest", "mocha", "playwright", "cypress"].includes(d)))
|
|
55
|
-
score += 1;
|
|
56
|
-
if (allText.includes("console.log") && fileCount < 10)
|
|
57
|
-
score -= 1;
|
|
58
|
-
if (allText.includes("todo") || allText.includes("fixme"))
|
|
59
|
-
score -= 1;
|
|
60
|
-
if (!ctx.packageJson)
|
|
61
|
-
score -= 1;
|
|
62
|
-
if (deps.some(d => ["@anthropic-ai/sdk", "openai", "langchain", "@langchain"].includes(d)))
|
|
63
|
-
score += 1;
|
|
64
|
-
if (score >= 6)
|
|
65
|
-
return { tier: "platform", confidence: "high" };
|
|
66
|
-
if (score >= 3)
|
|
67
|
-
return { tier: "product", confidence: score >= 4 ? "high" : "medium" };
|
|
68
|
-
return { tier: "prototype", confidence: score <= 1 ? "high" : "medium" };
|
|
69
|
-
}
|
|
70
|
-
// ─── Pattern sets per tier ────────────────────────────────────────────────────
|
|
71
|
-
const PATTERNS = {
|
|
72
|
-
prototype: {
|
|
73
|
-
label: "Prototype",
|
|
74
|
-
description: "Solo or exploratory — readable, no obvious traps. Avoid premature abstraction.",
|
|
75
|
-
structure: [
|
|
76
|
-
"Flat file structure — group by feature, not by layer",
|
|
77
|
-
"Single entry point (index.js / main.py)",
|
|
78
|
-
"Inline config via process.env — no config module needed yet",
|
|
79
|
-
],
|
|
80
|
-
apply: [
|
|
81
|
-
"Meaningful naming — variables and functions describe intent",
|
|
82
|
-
"No magic numbers — use named constants even in early code",
|
|
83
|
-
"Early returns to reduce nesting",
|
|
84
|
-
"Basic error handling — don't silently swallow errors",
|
|
85
|
-
],
|
|
86
|
-
avoid: [
|
|
87
|
-
"Dependency injection frameworks — premature at this scale",
|
|
88
|
-
"Layered architecture (controllers/services/repos) — adds overhead without benefit",
|
|
89
|
-
"Abstract base classes or interface hierarchies",
|
|
90
|
-
"Over-engineered config systems",
|
|
91
|
-
],
|
|
92
|
-
aiNative: [
|
|
93
|
-
"Prompt strings can live inline — extract to a prompts.js file when there are 3+",
|
|
94
|
-
"LLM calls should have at minimum a try/catch with a readable error message",
|
|
95
|
-
"No observability needed yet — console.log is fine",
|
|
96
|
-
],
|
|
97
|
-
},
|
|
98
|
-
product: {
|
|
99
|
-
label: "Product",
|
|
100
|
-
description: "Small team, real users, will grow — SOLID basics, modularity, testability.",
|
|
101
|
-
structure: [
|
|
102
|
-
"Feature-based folders at the top level (e.g. auth/, payments/, users/)",
|
|
103
|
-
"Within each feature: route/handler → service → repository/data-access",
|
|
104
|
-
"Shared utilities in lib/ or utils/ — no circular imports",
|
|
105
|
-
"Config module (config.js) as single source of truth for env vars",
|
|
106
|
-
"Separate entry point from app setup (index.js bootstraps, app.js configures)",
|
|
107
|
-
],
|
|
108
|
-
apply: [
|
|
109
|
-
"Single responsibility — each function/module does one thing",
|
|
110
|
-
"Dependency injection — pass dependencies as arguments, don't import globals into logic",
|
|
111
|
-
"Input validation at system boundaries (Zod, joi, or equivalent)",
|
|
112
|
-
"Centralized error handling — one error middleware, not scattered try/catches",
|
|
113
|
-
"Named exports over default exports — easier to refactor and trace",
|
|
114
|
-
"No direct DB calls in route handlers — always through a service",
|
|
115
|
-
],
|
|
116
|
-
avoid: [
|
|
117
|
-
"God modules — files over ~200 lines are a warning sign",
|
|
118
|
-
"Hardcoded secrets or environment-specific values in code",
|
|
119
|
-
"Shared mutable state across modules",
|
|
120
|
-
"Deep callback nesting — use async/await throughout",
|
|
121
|
-
"Direct SDK calls scattered across the codebase — wrap in a service",
|
|
122
|
-
],
|
|
123
|
-
aiNative: [
|
|
124
|
-
"Extract prompt strings to a dedicated prompts/ module — never inline in business logic",
|
|
125
|
-
"Wrap every LLM call in a resilience layer: retry on transient errors, timeout, fallback message",
|
|
126
|
-
"Agent tool functions must have single responsibility — one tool = one action",
|
|
127
|
-
"Log token usage at the service layer for cost visibility",
|
|
128
|
-
"Never put raw user input directly into a prompt — sanitize or structure first",
|
|
129
|
-
],
|
|
130
|
-
},
|
|
131
|
-
platform: {
|
|
132
|
-
label: "Platform",
|
|
133
|
-
description: "Multi-team, high scale, long-lived — full patterns, contracts, observability.",
|
|
134
|
-
structure: [
|
|
135
|
-
"Domain-driven folder structure — packages or modules per bounded context",
|
|
136
|
-
"Explicit interface contracts between layers (TypeScript interfaces or JSDoc types)",
|
|
137
|
-
"Shared kernel for cross-cutting concerns (logging, auth, config, errors)",
|
|
138
|
-
"Infrastructure layer isolated from domain logic (ports & adapters)",
|
|
139
|
-
"Separate read and write paths where contention is expected",
|
|
140
|
-
],
|
|
141
|
-
apply: [
|
|
142
|
-
"Full SOLID compliance — especially Open/Closed and Liskov",
|
|
143
|
-
"Repository pattern — domain logic never touches query syntax",
|
|
144
|
-
"Dependency inversion — depend on abstractions, inject implementations",
|
|
145
|
-
"Structured logging with correlation IDs on every request",
|
|
146
|
-
"Circuit breakers on all external service calls",
|
|
147
|
-
"Event-driven side effects — don't couple services via direct calls",
|
|
148
|
-
"Idempotency on all write operations that may be retried",
|
|
149
|
-
],
|
|
150
|
-
avoid: [
|
|
151
|
-
"Anemic domain models — logic belongs in the domain, not scattered in services",
|
|
152
|
-
"Shotgun surgery patterns — a single change requiring edits in 5+ files",
|
|
153
|
-
"Implicit service coupling — make dependencies explicit and injectable",
|
|
154
|
-
"Unversioned external contracts (APIs, events, schemas)",
|
|
155
|
-
"Synchronous calls to non-critical services in the request path",
|
|
156
|
-
],
|
|
157
|
-
aiNative: [
|
|
158
|
-
"Prompt versioning — treat prompts as versioned artifacts with changelogs",
|
|
159
|
-
"LLM call abstraction layer — swap providers without touching business logic",
|
|
160
|
-
"Structured output validation — never trust LLM output shape, always validate",
|
|
161
|
-
"Agent observability — trace each tool call with input, output, latency, tokens",
|
|
162
|
-
"Prompt injection hardening — sanitize all user-controlled content before interpolation",
|
|
163
|
-
"Async agent pipelines — long-running agent tasks should be queued, not blocking",
|
|
164
|
-
],
|
|
165
|
-
},
|
|
166
|
-
};
|
|
167
|
-
// ─── Confirmation prompt ──────────────────────────────────────────────────────
|
|
168
|
-
function confirmationPrompt(tier, confidence) {
|
|
169
|
-
const label = PATTERNS[tier].label;
|
|
170
|
-
if (confidence === "high") {
|
|
171
|
-
return `> **Tier inferred: ${label}** (high confidence)\n> If this is wrong, re-run \`waypoint_design\` with an explicit \`tier\` parameter.`;
|
|
172
|
-
}
|
|
173
|
-
const alternates = ["prototype", "product", "platform"].filter(t => t !== tier);
|
|
174
|
-
return [
|
|
175
|
-
`> **Tier inferred: ${label}** (medium confidence — mixed signals in the workspace)`,
|
|
176
|
-
`> If this doesn't match your intent, re-run \`waypoint_design\` with \`tier: "${alternates[0]}"\` or \`"${alternates[1]}"\`.`,
|
|
177
|
-
].join("\n");
|
|
178
|
-
}
|
|
179
|
-
// ─── Run ──────────────────────────────────────────────────────────────────────
|
|
180
|
-
export async function run(args) {
|
|
181
|
-
const { workspacePath, tier: explicitTier, focus } = args;
|
|
182
|
-
const ctx = await getBaseContext(workspacePath);
|
|
183
|
-
const planArtifact = await getArtifact(workspacePath, "plan.md");
|
|
184
|
-
const goalArtifact = await getArtifact(workspacePath, "goal.md");
|
|
185
|
-
const optionsArtifact = await getArtifact(workspacePath, "compare.md");
|
|
186
|
-
if (!planArtifact && !goalArtifact) {
|
|
187
|
-
return [
|
|
188
|
-
"## waypoint_design — No plan or goal found",
|
|
189
|
-
"",
|
|
190
|
-
"Run `waypoint_goal` → `waypoint_plan` before producing a design contract.",
|
|
191
|
-
"waypoint_design needs to know what you're building before it can prescribe how to build it.",
|
|
192
|
-
].join("\n");
|
|
193
|
-
}
|
|
194
|
-
const goalLine = goalArtifact?.match(/^# Goal\n+(.+)/m)?.[1] ?? "(goal not parsed)";
|
|
195
|
-
let tierKey;
|
|
196
|
-
let confidence;
|
|
197
|
-
let tierNote;
|
|
198
|
-
if (explicitTier) {
|
|
199
|
-
tierKey = explicitTier;
|
|
200
|
-
confidence = "explicit";
|
|
201
|
-
tierNote = `> **Tier set explicitly: ${PATTERNS[tierKey].label}**`;
|
|
202
|
-
}
|
|
203
|
-
else {
|
|
204
|
-
const inferred = inferTier(ctx, planArtifact);
|
|
205
|
-
tierKey = inferred.tier;
|
|
206
|
-
confidence = inferred.confidence;
|
|
207
|
-
tierNote = confirmationPrompt(tierKey, inferred.confidence);
|
|
208
|
-
}
|
|
209
|
-
const patterns = PATTERNS[tierKey];
|
|
210
|
-
const focusNote = focus ? `\n**Focus:** ${focus}` : "";
|
|
211
|
-
const hasOptions = !!optionsArtifact;
|
|
212
|
-
const optionsNote = !hasOptions
|
|
213
|
-
? "\n> ⚠️ No compare.md found — design contract is based on goal/plan only. Run `waypoint_compare` for richer context."
|
|
214
|
-
: "";
|
|
215
|
-
const artifact = [
|
|
216
|
-
"# Design",
|
|
217
|
-
"",
|
|
218
|
-
`**Goal:** ${goalLine}`,
|
|
219
|
-
focusNote,
|
|
220
|
-
`**Tier:** ${patterns.label} — ${patterns.description}`,
|
|
221
|
-
optionsNote,
|
|
222
|
-
"",
|
|
223
|
-
tierNote,
|
|
224
|
-
"",
|
|
225
|
-
"## Recommended structure",
|
|
226
|
-
...patterns.structure.map(s => `- ${s}`),
|
|
227
|
-
"",
|
|
228
|
-
"## Patterns to apply",
|
|
229
|
-
...patterns.apply.map(p => `- ${p}`),
|
|
230
|
-
"",
|
|
231
|
-
"## Anti-patterns to avoid",
|
|
232
|
-
...patterns.avoid.map(a => `- ❌ ${a}`),
|
|
233
|
-
"",
|
|
234
|
-
"## AI-native considerations",
|
|
235
|
-
...patterns.aiNative.map(n => `- ${n}`),
|
|
236
|
-
"",
|
|
237
|
-
"## Design decisions",
|
|
238
|
-
"<!-- Record any project-specific choices made here — deviations from the above and why -->",
|
|
239
|
-
"- ",
|
|
240
|
-
"",
|
|
241
|
-
"## Contract for Build",
|
|
242
|
-
"<!-- Summarise what Build must honour — fill this in before handing off -->",
|
|
243
|
-
"- [ ] Follow the recommended structure above",
|
|
244
|
-
"- [ ] Apply all patterns marked for this tier",
|
|
245
|
-
"- [ ] Avoid all listed anti-patterns",
|
|
246
|
-
"- [ ] ",
|
|
247
|
-
"",
|
|
248
|
-
`_Generated by waypoint_design (${patterns.label}) — ${new Date().toISOString()}_`,
|
|
249
|
-
]
|
|
250
|
-
.filter(l => l !== undefined)
|
|
251
|
-
.join("\n");
|
|
252
|
-
await saveArtifact(workspacePath, "design.md", artifact);
|
|
253
|
-
return [
|
|
254
|
-
"## waypoint_design — Design contract generated",
|
|
255
|
-
"",
|
|
256
|
-
`**Goal:** ${goalLine}`,
|
|
257
|
-
`**Tier:** ${patterns.label}`,
|
|
258
|
-
focus ? `**Focus:** ${focus}` : "",
|
|
259
|
-
!hasOptions ? "\n> No compare.md — run `waypoint_compare` for decision context." : "",
|
|
260
|
-
"",
|
|
261
|
-
"### Contract covers",
|
|
262
|
-
`- **Structure** — ${patterns.structure.length} recommendations`,
|
|
263
|
-
`- **Patterns to apply** — ${patterns.apply.length} rules`,
|
|
264
|
-
`- **Anti-patterns to avoid** — ${patterns.avoid.length} rules`,
|
|
265
|
-
`- **AI-native** — ${patterns.aiNative.length} considerations`,
|
|
266
|
-
"",
|
|
267
|
-
"### Artifact saved",
|
|
268
|
-
"`design.md` written to `.waypoint/design.md`.",
|
|
269
|
-
"Fill in **Design decisions** for any project-specific deviations, then complete the **Contract for Build** checklist.",
|
|
270
|
-
"",
|
|
271
|
-
"### Suggested next step",
|
|
272
|
-
"Run `waypoint_build` — it will read `design.md` as a constraint alongside `plan.md`.",
|
|
273
|
-
]
|
|
274
|
-
.filter(l => l !== undefined)
|
|
275
|
-
.join("\n");
|
|
276
|
-
}
|
package/dist/tools/document.js
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { getBaseContext, getArtifact, saveArtifact } from "../context.js";
|
|
2
|
-
export const definition = {
|
|
3
|
-
name: "waypoint_document",
|
|
4
|
-
description: "Generate documentation for the current state of the project.",
|
|
5
|
-
inputSchema: {
|
|
6
|
-
type: "object",
|
|
7
|
-
properties: {
|
|
8
|
-
workspacePath: {
|
|
9
|
-
type: "string",
|
|
10
|
-
description: "Absolute path to the workspace root.",
|
|
11
|
-
},
|
|
12
|
-
audience: {
|
|
13
|
-
type: "string",
|
|
14
|
-
description: "Intended audience for the documentation (optional). E.g. 'new contributors', 'end users', 'API consumers'.",
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
required: ["workspacePath"],
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
export async function run(args) {
|
|
21
|
-
const { workspacePath, audience } = args;
|
|
22
|
-
const ctx = await getBaseContext(workspacePath);
|
|
23
|
-
const goalArtifact = await getArtifact(workspacePath, "goal.md");
|
|
24
|
-
const buildArtifact = await getArtifact(workspacePath, "build.md");
|
|
25
|
-
const planArtifact = await getArtifact(workspacePath, "plan.md");
|
|
26
|
-
const goalLine = goalArtifact?.match(/^# Goal\n+(.+)/m)?.[1] ?? "(goal not defined)";
|
|
27
|
-
const pkgInfo = (() => {
|
|
28
|
-
try {
|
|
29
|
-
const p = JSON.parse(ctx.packageJson ?? "{}");
|
|
30
|
-
return { name: p.name ?? "this project", version: p.version ?? "0.0.0", description: p.description ?? "" };
|
|
31
|
-
}
|
|
32
|
-
catch {
|
|
33
|
-
return { name: "this project", version: "0.0.0", description: "" };
|
|
34
|
-
}
|
|
35
|
-
})();
|
|
36
|
-
const targetAudience = audience ?? "contributors and users";
|
|
37
|
-
const artifact = [
|
|
38
|
-
"# Documentation",
|
|
39
|
-
"",
|
|
40
|
-
`**Project:** ${pkgInfo.name} v${pkgInfo.version}`,
|
|
41
|
-
pkgInfo.description ? `**Description:** ${pkgInfo.description}` : "",
|
|
42
|
-
`**Audience:** ${targetAudience}`,
|
|
43
|
-
"",
|
|
44
|
-
"## What this is",
|
|
45
|
-
`<!-- 2-3 sentences explaining what ${pkgInfo.name} does and why it exists -->`,
|
|
46
|
-
goalLine !== "(goal not defined)" ? goalLine : "",
|
|
47
|
-
"",
|
|
48
|
-
"## How it works",
|
|
49
|
-
"<!-- High-level architecture or flow — no code, just concepts -->",
|
|
50
|
-
"",
|
|
51
|
-
"```",
|
|
52
|
-
ctx.fileTree,
|
|
53
|
-
"```",
|
|
54
|
-
"",
|
|
55
|
-
"## Getting started",
|
|
56
|
-
"",
|
|
57
|
-
"### Prerequisites",
|
|
58
|
-
"- ",
|
|
59
|
-
"",
|
|
60
|
-
"### Installation",
|
|
61
|
-
"```sh",
|
|
62
|
-
"# installation steps",
|
|
63
|
-
"```",
|
|
64
|
-
"",
|
|
65
|
-
"### Quick start",
|
|
66
|
-
"```sh",
|
|
67
|
-
"# minimal working example",
|
|
68
|
-
"```",
|
|
69
|
-
"",
|
|
70
|
-
"## Key concepts",
|
|
71
|
-
"<!-- Define the 3-5 concepts a reader must understand to use this effectively -->",
|
|
72
|
-
"",
|
|
73
|
-
"### Concept 1",
|
|
74
|
-
"<!-- What it is and why it matters -->",
|
|
75
|
-
"",
|
|
76
|
-
"## Reference",
|
|
77
|
-
"<!-- API, CLI flags, configuration options — one sub-section per entry point -->",
|
|
78
|
-
"",
|
|
79
|
-
"## Known limitations",
|
|
80
|
-
"- ",
|
|
81
|
-
"",
|
|
82
|
-
`_Generated by waypoint_document — ${new Date().toISOString()}_`,
|
|
83
|
-
]
|
|
84
|
-
.filter((l) => l !== undefined)
|
|
85
|
-
.join("\n");
|
|
86
|
-
await saveArtifact(workspacePath, "docs.md", artifact);
|
|
87
|
-
return [
|
|
88
|
-
"## waypoint_document — Documentation generated",
|
|
89
|
-
"",
|
|
90
|
-
`**Project:** ${pkgInfo.name} v${pkgInfo.version}`,
|
|
91
|
-
`**Audience:** ${targetAudience}`,
|
|
92
|
-
"",
|
|
93
|
-
"### Sections scaffolded",
|
|
94
|
-
"- **What this is** — project purpose pulled from goal.md",
|
|
95
|
-
"- **How it works** — architecture overview with file tree",
|
|
96
|
-
"- **Getting started** — prerequisites, install, quick start",
|
|
97
|
-
"- **Key concepts** — fill in 3-5 concepts readers need",
|
|
98
|
-
"- **Reference** — API/CLI/config reference",
|
|
99
|
-
"- **Known limitations** — be honest about what doesn't work yet",
|
|
100
|
-
"",
|
|
101
|
-
"### Artifact saved",
|
|
102
|
-
"`docs.md` written to `.waypoint/docs.md`.",
|
|
103
|
-
"",
|
|
104
|
-
"### Suggested next step",
|
|
105
|
-
"Run `waypoint_review` for a final quality check before shipping.",
|
|
106
|
-
].join("\n");
|
|
107
|
-
}
|
package/dist/tools/fix.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { getBaseContext, getArtifact, saveArtifact } from "../context.js";
|
|
2
|
-
export const definition = {
|
|
3
|
-
name: "waypoint_fix",
|
|
4
|
-
description: "Targeted bug patches with minimal footprint.",
|
|
5
|
-
inputSchema: {
|
|
6
|
-
type: "object",
|
|
7
|
-
properties: {
|
|
8
|
-
workspacePath: {
|
|
9
|
-
type: "string",
|
|
10
|
-
description: "Absolute path to the workspace root.",
|
|
11
|
-
},
|
|
12
|
-
bug: {
|
|
13
|
-
type: "string",
|
|
14
|
-
description: "Description of the bug to fix (optional). Omit to review existing fix.md.",
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
required: ["workspacePath"],
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
export async function run(args) {
|
|
21
|
-
const { workspacePath, bug } = args;
|
|
22
|
-
const ctx = await getBaseContext(workspacePath);
|
|
23
|
-
const buildArtifact = await getArtifact(workspacePath, "build.md");
|
|
24
|
-
const goalArtifact = await getArtifact(workspacePath, "goal.md");
|
|
25
|
-
const existingFix = await getArtifact(workspacePath, "fix.md");
|
|
26
|
-
if (!bug && !existingFix) {
|
|
27
|
-
return [
|
|
28
|
-
"## waypoint_fix — No bug description provided",
|
|
29
|
-
"",
|
|
30
|
-
"Call `waypoint_fix` with a `bug` parameter describing the problem.",
|
|
31
|
-
"Example: _\"Tool returns isError:true when workspacePath has spaces\"_",
|
|
32
|
-
"",
|
|
33
|
-
!buildArtifact ? "Run `waypoint_build` first to establish a build baseline." : "",
|
|
34
|
-
]
|
|
35
|
-
.filter(Boolean)
|
|
36
|
-
.join("\n");
|
|
37
|
-
}
|
|
38
|
-
const bugStatement = bug ?? existingFix?.match(/^## Bug\n+(.+)/m)?.[1] ?? "(bug not parsed)";
|
|
39
|
-
const goalLine = goalArtifact?.match(/^# Goal\n+(.+)/m)?.[1] ?? "(goal not parsed)";
|
|
40
|
-
const hasBuild = !!buildArtifact;
|
|
41
|
-
const artifact = [
|
|
42
|
-
"# Fix",
|
|
43
|
-
"",
|
|
44
|
-
`## Bug`,
|
|
45
|
-
bugStatement,
|
|
46
|
-
"",
|
|
47
|
-
`**Goal context:** ${goalLine}`,
|
|
48
|
-
!hasBuild ? "\n> ⚠️ No build.md found — fix has no established baseline." : "",
|
|
49
|
-
"",
|
|
50
|
-
"## Root cause hypothesis",
|
|
51
|
-
"<!-- What is causing this bug? Be specific. -->",
|
|
52
|
-
"- ",
|
|
53
|
-
"",
|
|
54
|
-
"## Fix approach",
|
|
55
|
-
"**Principle:** minimal footprint — change only what is necessary to fix this bug.",
|
|
56
|
-
"",
|
|
57
|
-
"### AI fix prompt",
|
|
58
|
-
"```",
|
|
59
|
-
`Fix the following bug: ${bugStatement}`,
|
|
60
|
-
"",
|
|
61
|
-
"Constraints:",
|
|
62
|
-
"- Change only the code required to fix this specific bug",
|
|
63
|
-
"- Do not refactor surrounding code",
|
|
64
|
-
"- Do not add features or improve unrelated behavior",
|
|
65
|
-
"- Verify the fix does not break adjacent functionality",
|
|
66
|
-
"```",
|
|
67
|
-
"",
|
|
68
|
-
"## Changes made",
|
|
69
|
-
"<!-- List exact files and lines changed -->",
|
|
70
|
-
"| File | Line(s) | Change |",
|
|
71
|
-
"|------|---------|--------|",
|
|
72
|
-
"| | | |",
|
|
73
|
-
"",
|
|
74
|
-
"## Verification",
|
|
75
|
-
"- [ ] Bug no longer reproduced with original steps",
|
|
76
|
-
"- [ ] No regressions in adjacent functionality",
|
|
77
|
-
"- [ ] Fix is the minimum change required",
|
|
78
|
-
"",
|
|
79
|
-
`_Generated by waypoint_fix — ${new Date().toISOString()}_`,
|
|
80
|
-
]
|
|
81
|
-
.filter((l) => l !== undefined)
|
|
82
|
-
.join("\n");
|
|
83
|
-
await saveArtifact(workspacePath, "fix.md", artifact);
|
|
84
|
-
return [
|
|
85
|
-
"## waypoint_fix — Fix guide generated",
|
|
86
|
-
"",
|
|
87
|
-
`**Bug:** ${bugStatement}`,
|
|
88
|
-
!hasBuild ? "\n> No build.md found — fix has no baseline context." : "",
|
|
89
|
-
"",
|
|
90
|
-
"### Approach",
|
|
91
|
-
"- Minimal footprint: only change what fixes this bug",
|
|
92
|
-
"- AI fix prompt included — paste into Claude Code or Cursor",
|
|
93
|
-
"- Verification checklist: confirm no regressions",
|
|
94
|
-
"",
|
|
95
|
-
"### Artifact saved",
|
|
96
|
-
"`fix.md` written to `.waypoint/fix.md`.",
|
|
97
|
-
"",
|
|
98
|
-
"### Suggested next step",
|
|
99
|
-
"Run `waypoint_test` after applying the fix to confirm no regressions.",
|
|
100
|
-
]
|
|
101
|
-
.filter((l) => l !== undefined)
|
|
102
|
-
.join("\n");
|
|
103
|
-
}
|
package/dist/tools/goal.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { getBaseContext, getArtifact, saveArtifact } from "../context.js";
|
|
2
|
-
export const definition = {
|
|
3
|
-
name: "waypoint_goal",
|
|
4
|
-
description: "Define or refine the project goal. Analyzes existing code and business logic if present.",
|
|
5
|
-
inputSchema: {
|
|
6
|
-
type: "object",
|
|
7
|
-
properties: {
|
|
8
|
-
workspacePath: {
|
|
9
|
-
type: "string",
|
|
10
|
-
description: "Absolute path to the workspace root.",
|
|
11
|
-
},
|
|
12
|
-
goal: {
|
|
13
|
-
type: "string",
|
|
14
|
-
description: "The goal to define or refine. Omit to review an existing goal.md.",
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
required: ["workspacePath"],
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
export async function run(args) {
|
|
21
|
-
const { workspacePath, goal } = args;
|
|
22
|
-
const ctx = await getBaseContext(workspacePath);
|
|
23
|
-
const existing = await getArtifact(workspacePath, "goal.md");
|
|
24
|
-
const goalStatement = goal ?? existing?.match(/^# Goal\n+(.+)/m)?.[1] ?? null;
|
|
25
|
-
const workspaceSummary = [
|
|
26
|
-
`**Path:** ${workspacePath}`,
|
|
27
|
-
ctx.packageJson
|
|
28
|
-
? `**Package:** ${(() => {
|
|
29
|
-
try {
|
|
30
|
-
const p = JSON.parse(ctx.packageJson);
|
|
31
|
-
return `${p.name ?? "unnamed"} v${p.version ?? "?"}`;
|
|
32
|
-
}
|
|
33
|
-
catch {
|
|
34
|
-
return "present (unparseable)";
|
|
35
|
-
}
|
|
36
|
-
})()}`
|
|
37
|
-
: "**Package:** none detected",
|
|
38
|
-
`**Files (2 levels):**\n\`\`\`\n${ctx.fileTree}\n\`\`\``,
|
|
39
|
-
Object.keys(ctx.waypointArtifacts).length > 0
|
|
40
|
-
? `**Existing .waypoint artifacts:** ${Object.keys(ctx.waypointArtifacts).join(", ")}`
|
|
41
|
-
: "**Existing .waypoint artifacts:** none",
|
|
42
|
-
].join("\n");
|
|
43
|
-
if (!goalStatement) {
|
|
44
|
-
return [
|
|
45
|
-
"## waypoint_goal — No goal defined yet",
|
|
46
|
-
"",
|
|
47
|
-
"### Workspace snapshot",
|
|
48
|
-
workspaceSummary,
|
|
49
|
-
"",
|
|
50
|
-
"### Next step",
|
|
51
|
-
"Call `waypoint_goal` again with a `goal` parameter describing what you want to achieve.",
|
|
52
|
-
"Example: _\"Add user authentication with email/password and OAuth\"_",
|
|
53
|
-
"",
|
|
54
|
-
"A clear goal should answer:",
|
|
55
|
-
"- What capability or outcome are we delivering?",
|
|
56
|
-
"- Who benefits and how?",
|
|
57
|
-
"- What does done look like?",
|
|
58
|
-
].join("\n");
|
|
59
|
-
}
|
|
60
|
-
const artifact = [
|
|
61
|
-
"# Goal",
|
|
62
|
-
"",
|
|
63
|
-
goalStatement,
|
|
64
|
-
"",
|
|
65
|
-
"## Success criteria",
|
|
66
|
-
"<!-- Define 2-4 measurable outcomes that confirm this goal is met -->",
|
|
67
|
-
"- [ ] ",
|
|
68
|
-
"",
|
|
69
|
-
"## Out of scope",
|
|
70
|
-
"<!-- Explicitly list what this goal does NOT cover -->",
|
|
71
|
-
"- ",
|
|
72
|
-
"",
|
|
73
|
-
"## Workspace observations",
|
|
74
|
-
workspaceSummary,
|
|
75
|
-
"",
|
|
76
|
-
`_Generated by waypoint_goal — ${new Date().toISOString()}_`,
|
|
77
|
-
].join("\n");
|
|
78
|
-
await saveArtifact(workspacePath, "goal.md", artifact);
|
|
79
|
-
return [
|
|
80
|
-
"## waypoint_goal — Goal captured",
|
|
81
|
-
"",
|
|
82
|
-
`**Goal:** ${goalStatement}`,
|
|
83
|
-
"",
|
|
84
|
-
"### Workspace snapshot",
|
|
85
|
-
workspaceSummary,
|
|
86
|
-
"",
|
|
87
|
-
"### Artifact saved",
|
|
88
|
-
"`goal.md` written to `.waypoint/goal.md`.",
|
|
89
|
-
"Fill in **Success criteria** and **Out of scope** before moving to `waypoint_research`.",
|
|
90
|
-
"",
|
|
91
|
-
"### Suggested next step",
|
|
92
|
-
"Run `waypoint_research` to surface best practices and open questions for this goal.",
|
|
93
|
-
].join("\n");
|
|
94
|
-
}
|
package/dist/tools/improve.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { getBaseContext, getArtifact, saveArtifact } from "../context.js";
|
|
2
|
-
export const definition = {
|
|
3
|
-
name: "waypoint_improve",
|
|
4
|
-
description: "Propose refinements. Distinguish must-haves from optional enhancements.",
|
|
5
|
-
inputSchema: {
|
|
6
|
-
type: "object",
|
|
7
|
-
properties: {
|
|
8
|
-
workspacePath: {
|
|
9
|
-
type: "string",
|
|
10
|
-
description: "Absolute path to the workspace root.",
|
|
11
|
-
},
|
|
12
|
-
area: {
|
|
13
|
-
type: "string",
|
|
14
|
-
description: "Specific area to improve (optional). Omit to generate improvements across all areas.",
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
required: ["workspacePath"],
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
export async function run(args) {
|
|
21
|
-
const { workspacePath, area } = args;
|
|
22
|
-
const ctx = await getBaseContext(workspacePath);
|
|
23
|
-
const goalArtifact = await getArtifact(workspacePath, "goal.md");
|
|
24
|
-
const measureArtifact = await getArtifact(workspacePath, "measure.md");
|
|
25
|
-
const buildArtifact = await getArtifact(workspacePath, "build.md");
|
|
26
|
-
if (!goalArtifact) {
|
|
27
|
-
return [
|
|
28
|
-
"## waypoint_improve — No goal found",
|
|
29
|
-
"",
|
|
30
|
-
"Run `waypoint_goal` first — improvements require a defined goal to improve toward.",
|
|
31
|
-
].join("\n");
|
|
32
|
-
}
|
|
33
|
-
const goalLine = goalArtifact.match(/^# Goal\n+(.+)/m)?.[1] ?? "(goal not parsed)";
|
|
34
|
-
const hasMeasure = !!measureArtifact;
|
|
35
|
-
const artifact = [
|
|
36
|
-
"# Improve",
|
|
37
|
-
"",
|
|
38
|
-
`**Goal:** ${goalLine}`,
|
|
39
|
-
area ? `**Area:** ${area}` : "",
|
|
40
|
-
!hasMeasure
|
|
41
|
-
? "\n> ⚠️ No measure.md found — running `waypoint_measure` first gives better improvement signals."
|
|
42
|
-
: "",
|
|
43
|
-
"",
|
|
44
|
-
"## Must-have improvements",
|
|
45
|
-
"<!-- Fixes that affect correctness, reliability, or core usability — do these now -->",
|
|
46
|
-
"- [ ] ",
|
|
47
|
-
"",
|
|
48
|
-
"## Should-have improvements",
|
|
49
|
-
"<!-- Meaningful quality improvements — do before next major release -->",
|
|
50
|
-
"- [ ] ",
|
|
51
|
-
"",
|
|
52
|
-
"## Nice-to-have enhancements",
|
|
53
|
-
"<!-- Optional upgrades — only if time and priority allow -->",
|
|
54
|
-
"- [ ] ",
|
|
55
|
-
"",
|
|
56
|
-
"## Out of scope",
|
|
57
|
-
"<!-- Improvements explicitly not being pursued and why -->",
|
|
58
|
-
"- ",
|
|
59
|
-
"",
|
|
60
|
-
"## Improvement prompts for AI coding tools",
|
|
61
|
-
"",
|
|
62
|
-
"### Refactor prompt",
|
|
63
|
-
"```",
|
|
64
|
-
`Improve the following area without changing behavior: ${area ?? goalLine}`,
|
|
65
|
-
"",
|
|
66
|
-
"Constraints:",
|
|
67
|
-
"- Do not change externally observable behavior",
|
|
68
|
-
"- Keep changes focused on the area being improved",
|
|
69
|
-
"- Prefer simplicity over cleverness",
|
|
70
|
-
"```",
|
|
71
|
-
"",
|
|
72
|
-
`_Generated by waypoint_improve — ${new Date().toISOString()}_`,
|
|
73
|
-
]
|
|
74
|
-
.filter((l) => l !== undefined)
|
|
75
|
-
.join("\n");
|
|
76
|
-
await saveArtifact(workspacePath, "improve.md", artifact);
|
|
77
|
-
return [
|
|
78
|
-
"## waypoint_improve — Improvement plan generated",
|
|
79
|
-
"",
|
|
80
|
-
`**Goal:** ${goalLine}`,
|
|
81
|
-
area ? `**Area:** ${area}` : "",
|
|
82
|
-
!hasMeasure
|
|
83
|
-
? "\n> No measure.md found — run `waypoint_measure` for data-driven improvements."
|
|
84
|
-
: "",
|
|
85
|
-
"",
|
|
86
|
-
"### Three tiers",
|
|
87
|
-
"- **Must-have** — correctness and reliability issues; do these now",
|
|
88
|
-
"- **Should-have** — meaningful quality improvements; do before next release",
|
|
89
|
-
"- **Nice-to-have** — optional enhancements; defer unless time allows",
|
|
90
|
-
"",
|
|
91
|
-
"### Artifact saved",
|
|
92
|
-
"`improve.md` written to `.waypoint/improve.md`.",
|
|
93
|
-
"",
|
|
94
|
-
"### Suggested next step",
|
|
95
|
-
"Run `waypoint_document` to document the improved state, or `waypoint_review` for a final quality check.",
|
|
96
|
-
]
|
|
97
|
-
.filter((l) => l !== undefined)
|
|
98
|
-
.join("\n");
|
|
99
|
-
}
|