@pathmode/mcp-server 1.10.0 → 1.12.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/README.md CHANGED
@@ -61,6 +61,7 @@ That's it. No API key needed.
61
61
  id: "intent_17291..."
62
62
  version: 1
63
63
  status: "draft"
64
+ readiness: "passed 6/6"
64
65
  ---
65
66
  # Fix Checkout Payment Timeout
66
67
 
@@ -78,6 +79,8 @@ timeouts exceeding 3 seconds.
78
79
  - **Unknown provider status**: Hold order, notify user within 30s
79
80
  ```
80
81
 
82
+ The `readiness` line is the deterministic preflight verdict, stamped on every save — "passed 6/6", or "failed N/6" naming the blocking gates — so any agent reading the file knows whether the spec cleared the gate without re-running it. Specs exported from a Pathmode workspace also carry `source:` (the canonical intent URL — the file is a working copy of that record) and `evidence:` (how many linked evidence items back it).
83
+
81
84
  **.cursorrules** — Agent-directive format for Cursor:
82
85
  ```
83
86
  # CURRENT OBJECTIVE
@@ -94,7 +97,7 @@ Your implementation MUST satisfy ALL of these:
94
97
 
95
98
  ## Skill Pack for Claude Code
96
99
 
97
- The package also ships 7 Claude Code skills that auto-trigger based on what you ask — no slash commands required.
100
+ The package also ships 8 Claude Code skills that auto-trigger based on what you ask — no slash commands required.
98
101
 
99
102
  | Skill | Use when |
100
103
  |-------|----------|
@@ -163,7 +166,10 @@ Get your API key from **Settings > API Keys** in the [Pathmode app](https://path
163
166
  ### Local Mode (Offline)
164
167
 
165
168
  Local mode is the **default when no API key is configured**. It reads and writes `intent.md` in your
166
- project directory, and nothing leaves your machine. The plain block is a complete keyless setup:
169
+ project directory, and nothing leaves your machine. Local mode includes `check_intent_readiness`
170
+ the deterministic preflight that scores a spec against six calibrated gates and names the exact
171
+ blockers, with no model call (the same gate that runs at [preflight.pathmode.io](https://preflight.pathmode.io)).
172
+ The plain block is a complete keyless setup:
167
173
 
168
174
  ```json
169
175
  {
@@ -185,8 +185,25 @@ export interface ApiVerificationResult {
185
185
  category: string;
186
186
  status: string;
187
187
  reasoning: string;
188
+ basis?: 'artifact' | 'self_report' | 'none';
189
+ evidence?: {
190
+ path: string;
191
+ hunk?: string;
192
+ }[];
188
193
  }[];
189
194
  summary: string;
195
+ /** Whether the verdict was reached by reading a pull request or only the caller's own account. */
196
+ basis?: 'artifact' | 'self_report';
197
+ artifact?: {
198
+ kind: 'pr_diff' | 'self_report';
199
+ repo?: string;
200
+ prNumber?: number;
201
+ headSha?: string;
202
+ filesRead?: number;
203
+ filesOmitted?: number;
204
+ truncated?: boolean;
205
+ reason?: string;
206
+ };
190
207
  }
191
208
  export interface ApiEvidence {
192
209
  id: string;
@@ -316,5 +333,9 @@ export declare class PathmodeClient {
316
333
  linked: number;
317
334
  unlinked: number;
318
335
  }>;
319
- verifyImplementation(intentId: string, summary: string, codeChanges?: string): Promise<ApiVerificationResult>;
336
+ verifyImplementation(intentId: string, body: {
337
+ summary?: string;
338
+ prUrl?: string;
339
+ codeChanges?: string;
340
+ }): Promise<ApiVerificationResult>;
320
341
  }
@@ -1 +1 @@
1
- {"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/api-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/api-client.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -33742,10 +33742,10 @@ class PathmodeClient {
33742
33742
  });
33743
33743
  return res.json();
33744
33744
  }
33745
- async verifyImplementation(intentId, summary, codeChanges) {
33745
+ async verifyImplementation(intentId, body) {
33746
33746
  const res = await this.fetch(`/intents/${intentId}/verify`, {
33747
33747
  method: 'POST',
33748
- body: JSON.stringify({ summary, codeChanges }),
33748
+ body: JSON.stringify(body),
33749
33749
  });
33750
33750
  return res.json();
33751
33751
  }
@@ -34165,6 +34165,8 @@ function formatIntentMd(spec, opts = {}) {
34165
34165
  id: spec.id || `intent_${Date.now()}`,
34166
34166
  version: opts.version && opts.version >= 1 ? opts.version : 1,
34167
34167
  status: opts.status || 'draft',
34168
+ ...(opts.readiness ? { readiness: opts.readiness } : {}),
34169
+ ...(opts.source ? { source: opts.source } : {}),
34168
34170
  created: opts.created || now,
34169
34171
  updated: now,
34170
34172
  };
@@ -35003,6 +35005,254 @@ function mergePathmodeSection(existing, section) {
35003
35005
  }
35004
35006
 
35005
35007
 
35008
+ /***/ }),
35009
+
35010
+ /***/ 3079:
35011
+ /***/ ((__unused_webpack_module, exports) => {
35012
+
35013
+ "use strict";
35014
+
35015
+ /**
35016
+ * Deterministic intent readiness gate — the preflight.
35017
+ *
35018
+ * This is a PORT of the canonical gate in lib/intentReadiness.ts (the MCP package
35019
+ * cannot import app/lib code). Every regex and threshold below must stay
35020
+ * byte-identical to the source; lib/preflightReadinessParity.test.ts in the app
35021
+ * repo runs both implementations over the 98-item calibration corpus and the
35022
+ * Preflight demo specs, and fails CI on any divergence. Edit the app lib first,
35023
+ * then mirror the change here.
35024
+ *
35025
+ * Pure functions only: no I/O, no network, no model calls. The same spec gets
35026
+ * the same verdict every run — that determinism is the product claim on
35027
+ * https://preflight.pathmode.io, so keep it true.
35028
+ */
35029
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
35030
+ exports.READINESS_GATE_ORDER = exports.READINESS_BLOCKER_DESCRIPTIONS = void 0;
35031
+ exports.coerceText = coerceText;
35032
+ exports.asArray = asArray;
35033
+ exports.isTitleMeaningful = isTitleMeaningful;
35034
+ exports.isConstraintConcrete = isConstraintConcrete;
35035
+ exports.isVerificationCheckSubstantive = isVerificationCheckSubstantive;
35036
+ exports.isObjectiveSpecific = isObjectiveSpecific;
35037
+ exports.isOutcomeMeasurable = isOutcomeMeasurable;
35038
+ exports.computeReadinessVerdict = computeReadinessVerdict;
35039
+ exports.formatReadinessFrontmatter = formatReadinessFrontmatter;
35040
+ exports.formatReadinessVerdict = formatReadinessVerdict;
35041
+ // ── Text/shape coercion (mirrors lib/intentReadiness coerceText/asArray) ───
35042
+ function coerceText(value) {
35043
+ if (typeof value === 'string')
35044
+ return value;
35045
+ if (value && typeof value === 'object') {
35046
+ const o = value;
35047
+ const cand = o.description ?? o.rule ?? o.text ?? o.name ?? o.scenario ?? o.title ?? o.value ?? o.label ?? o.content;
35048
+ if (typeof cand === 'string')
35049
+ return cand;
35050
+ }
35051
+ return '';
35052
+ }
35053
+ function asArray(value) {
35054
+ if (Array.isArray(value))
35055
+ return value;
35056
+ if (value === null || value === undefined)
35057
+ return [];
35058
+ return [value];
35059
+ }
35060
+ /** Mirrors lib/intentSpecHelpers.outcomeText: outcomes arrive as strings or { text }. */
35061
+ function outcomeText(o) {
35062
+ if (typeof o === 'string')
35063
+ return o;
35064
+ const t = o?.text;
35065
+ return typeof t === 'string' ? t : '';
35066
+ }
35067
+ const PLACEHOLDER_INTENT_TITLES = new Set(['new intent', 'untitled intent']);
35068
+ const TEMPLATE_PATTERNS = [
35069
+ /\[your category\]/i,
35070
+ /^template$/i,
35071
+ /^placeholder$/i,
35072
+ /^todo$/i,
35073
+ /^tbd$/i,
35074
+ ];
35075
+ function isLikelyPlaceholderText(value) {
35076
+ const text = coerceText(value).trim();
35077
+ if (!text)
35078
+ return false;
35079
+ if (text.length <= 2)
35080
+ return true;
35081
+ return TEMPLATE_PATTERNS.some((pattern) => pattern.test(text));
35082
+ }
35083
+ // ── The six calibrated gates ────────────────────────────────────────────────
35084
+ const GENERIC_TITLE_WORDS = new Set([
35085
+ 'new', 'my', 'our', 'the', 'a', 'an', 'this', 'that', 'some', 'more', 'better',
35086
+ 'intent', 'intents', 'feature', 'features', 'idea', 'ideas', 'spec', 'specs',
35087
+ 'draft', 'drafts', 'test', 'tests', 'todo', 'tbd', 'wip', 'stuff', 'thing', 'things',
35088
+ 'untitled', 'placeholder', 'misc', 'general', 'various', 'update', 'updates',
35089
+ 'improvement', 'improvements', 'improve', 'fix', 'fixes', 'change', 'changes',
35090
+ 'work', 'item', 'items', 'task', 'tasks',
35091
+ ]);
35092
+ function isTitleMeaningful(title) {
35093
+ const t = coerceText(title).trim();
35094
+ if (!t)
35095
+ return false;
35096
+ if (PLACEHOLDER_INTENT_TITLES.has(t.toLowerCase()))
35097
+ return false;
35098
+ if (TEMPLATE_PATTERNS.some((pattern) => pattern.test(t)))
35099
+ return false;
35100
+ const words = t.split(/\s+/).filter(Boolean);
35101
+ if (words.length < 2)
35102
+ return false;
35103
+ return words.some((w) => !GENERIC_TITLE_WORDS.has(w.toLowerCase().replace(/[^a-z0-9-]/gi, '')));
35104
+ }
35105
+ const CONSTRAINT_MARKER_RE = /\b(never|must|not|no|don'?t|cannot|can'?t|forbidden|prohibit\w*|avoid|without|only|at most|at least|within|under|below|above|max\w*|limit\w*|cap(?:ped|s)?|quota|budget|respect\w*|comply|complian\w*|conform\w*|keep|stays?|remains?|preserve\w*|maintain\w*|require[sd]?|always|read[- ]only|backward[- ]?compatib\w*|p\d{2})\b/i;
35106
+ function isConstraintConcrete(value) {
35107
+ const t = coerceText(value).trim();
35108
+ if (t.length < 8)
35109
+ return false;
35110
+ return CONSTRAINT_MARKER_RE.test(t) || t.length >= 40;
35111
+ }
35112
+ function isVerificationCheckSubstantive(description) {
35113
+ const t = coerceText(description).trim();
35114
+ if (isLikelyPlaceholderText(t))
35115
+ return false;
35116
+ return t.split(/\s+/).filter(Boolean).length >= 3;
35117
+ }
35118
+ const ACTOR_RE = /\b(users?|customers?|clients?|teams?|developers?|admins?|administrators?|visitors?|subscribers?|buyers?|sellers?|operators?|managers?|patients?|agents?|founders?|owners?|leads?|members?|employees?|hires?|applicants?|candidates?|players?|creators?|curators?|seekers?|parents?|students?|teachers?|shoppers?|merchants?|reviewers?|engineers?|designers?|marketers?|recruiters?|stakeholders?|people|staff)\b/i;
35119
+ const ACTOR_STRUCT_RE = /\b(enable|allow|let|help|give|empower|support)\s+[A-Za-z]|\bfor\s+[a-z]+\s+(to|who|so)\b|\b[A-Za-z]+['’]s\b|\b[A-Z][a-z]{2,}\s+(can'?t|cannot|can|could|should|needs?|wants?|struggles?|fails?|miss\w*|lose|loses)\b/;
35120
+ const PROBLEM_RE = /\b(can'?t|cannot|unable|struggl\w*|fail\w*|drop\w*|abandon\w*|miss\w*|los\w*|break\w*|broken|block\w*|confus\w*|delay\w*|bottleneck|stale|stuck|friction|painful|manual\w*|error\w*|slow|waste\w*|risk\w*)\b/i;
35121
+ const CAPABILITY_RE = /\b(enable|allow|let|help|give|empower|provide|support|lift|raise|reduce|cut|eliminat\w*|increase|decrease|improve|streamlin\w*|automat\w*|speed up|accelerat\w*|guarantee|ensure|deliver|complete|clear|maintain|achieve|unlock|simplif\w*|consolidat\w*|surface|track|measure|see|view|access|find|understand|know|preview|schedule|resume|inspect|reorder|publish|reconcile|bulk|able to|act on)\b/i;
35122
+ const VAGUE_MARKER_RE = /\b(best[- ]in[- ]class|world[- ]class|seamless\w*|cutting[- ]edge|delight\w*|intuitive|robust|holistic|synerg\w*|revolutioniz\w*|next[- ]gen\w*|frictionless|game[- ]chang\w*|state[- ]of[- ]the[- ]art|leverage|do more|happ(y|ier|iness)|smoother|polished|magical|amazing|wow)\b/i;
35123
+ function isObjectiveSpecific(objective) {
35124
+ const t = coerceText(objective).trim();
35125
+ if (t.length <= 35)
35126
+ return false;
35127
+ if (VAGUE_MARKER_RE.test(t) && !OUTCOME_NUMERIC_RE.test(t))
35128
+ return false;
35129
+ const hasActor = ACTOR_RE.test(t) || ACTOR_STRUCT_RE.test(t);
35130
+ const hasIntent = PROBLEM_RE.test(t) || CAPABILITY_RE.test(t);
35131
+ return hasActor && hasIntent;
35132
+ }
35133
+ const OUTCOME_NUMERIC_RE = /\d|%|≥|≤|>=|<=/;
35134
+ const OUTCOME_METRIC_RE = /\b(under|within|at least|no more than|fewer than|less than|more than|reach\w*|drop\w*|ris\w*|grow\w*|increas\w*|decreas\w*|reduc\w*|eliminat\w*|stays?\s+(under|below|above|within)|from\s+.+\s+to\s+|success rate|completion rate|conversion|retention|adoption|rate\b|score|benchmark|baseline|per\s+\w+|time[- ]to)\b/i;
35135
+ const OUTCOME_CAPABILITY_RE = /\b([a-z]+s?|they|anyone|everyone)\s+(can|could|sees?|views?|receives?|gets?|is able|are able|able to)\b/i;
35136
+ const OUTCOME_STATE_RE = /\b(no longer|without\s+\w+|is fully|are fully|displays?|shows?|appears?|visible|notified|confirmed|enabled|disabled|redirected|prevented|blocked|templated|automated|documented|exists?|persists?|never|always|produces?\s+no\b|results?\s+in\s+no\b|with\s+no\b|free of)\b/i;
35137
+ const OUTCOME_SUBJECTIVE_RE = /\b(amazing|delight\w*|happ(y|ier|iness)|satisf\w*|quality|love[ds]?|world[- ]class|best[- ]in[- ]class|seamless\w*|intuitive|polished|magical|wow|delightful|engaging|meaningful\w*)\b/i;
35138
+ function isOutcomeMeasurable(text) {
35139
+ const t = coerceText(text).trim();
35140
+ if (!t)
35141
+ return false;
35142
+ if (OUTCOME_SUBJECTIVE_RE.test(t))
35143
+ return false;
35144
+ return OUTCOME_NUMERIC_RE.test(t) || OUTCOME_METRIC_RE.test(t) || OUTCOME_CAPABILITY_RE.test(t) || OUTCOME_STATE_RE.test(t);
35145
+ }
35146
+ // ── Verdict ─────────────────────────────────────────────────────────────────
35147
+ exports.READINESS_BLOCKER_DESCRIPTIONS = {
35148
+ objective: 'Objective is too vague — name the actor and the concrete failure they hit today.',
35149
+ goal: 'Title is missing or generic — name the intent in a short, specific noun phrase.',
35150
+ outcomes: 'Outcomes are not all measurable — at least two-thirds need a testable or observable threshold.',
35151
+ constraints: 'No hard constraint — name at least one thing that must never happen.',
35152
+ edgeCases: 'No edge case with a defined expected behavior.',
35153
+ verification: 'No concrete verification — describe at least one check specific enough to run.',
35154
+ };
35155
+ /** Display order for the gate strip (title first, matching the Preflight page). */
35156
+ exports.READINESS_GATE_ORDER = ['goal', 'objective', 'outcomes', 'constraints', 'edgeCases', 'verification'];
35157
+ /** Blocker emission order — byte-identical to lib/intentReadiness computeReviewSignals. */
35158
+ const BLOCKER_ORDER = ['objective', 'goal', 'outcomes', 'constraints', 'edgeCases', 'verification'];
35159
+ /** Flatten a verification field (checks[] plus legacy buckets) into check descriptions. */
35160
+ function verificationDescriptions(verification) {
35161
+ if (!verification || typeof verification !== 'object')
35162
+ return [];
35163
+ const v = verification;
35164
+ const out = [];
35165
+ for (const c of asArray(v.checks)) {
35166
+ const d = coerceText(c).trim();
35167
+ if (d)
35168
+ out.push(d);
35169
+ }
35170
+ for (const bucket of ['manualChecks', 'unitTests', 'e2eTests']) {
35171
+ for (const c of asArray(v[bucket])) {
35172
+ const d = coerceText(c).trim();
35173
+ if (d)
35174
+ out.push(d);
35175
+ }
35176
+ }
35177
+ return out;
35178
+ }
35179
+ /**
35180
+ * The preflight: six deterministic gates over an intent spec. Mirrors
35181
+ * lib/intentReadiness.computeReviewSignals with conversationFirst semantics
35182
+ * (the legacy phase-engagement signal never gates the verdict here).
35183
+ */
35184
+ function computeReadinessVerdict(spec) {
35185
+ const nonEmptyOutcomes = asArray(spec.outcomes).map(o => outcomeText(o).trim()).filter(Boolean);
35186
+ const testableOutcomeCount = nonEmptyOutcomes.filter(isOutcomeMeasurable).length;
35187
+ const signals = {
35188
+ goal: isTitleMeaningful(typeof spec.title === 'string' ? spec.title : coerceText(spec.title)),
35189
+ objective: isObjectiveSpecific(typeof spec.objective === 'string' ? spec.objective : coerceText(spec.objective)),
35190
+ outcomes: nonEmptyOutcomes.length >= 2 && testableOutcomeCount / Math.max(nonEmptyOutcomes.length, 1) >= 0.66,
35191
+ constraints: asArray(spec.constraints).some(isConstraintConcrete),
35192
+ edgeCases: asArray(spec.edgeCases).some((ec) => {
35193
+ const e = ec;
35194
+ return coerceText(e?.scenario).trim().length > 0 && coerceText(e?.expectedBehavior).trim().length > 0;
35195
+ }),
35196
+ verification: verificationDescriptions(spec.verification).some(isVerificationCheckSubstantive),
35197
+ };
35198
+ const failingBlockers = BLOCKER_ORDER
35199
+ .filter(k => !signals[k])
35200
+ .map(k => exports.READINESS_BLOCKER_DESCRIPTIONS[k]);
35201
+ return { ready: failingBlockers.length === 0, signals, failingBlockers };
35202
+ }
35203
+ const GATE_LABELS = {
35204
+ goal: 'Title',
35205
+ objective: 'Objective',
35206
+ outcomes: 'Outcomes',
35207
+ constraints: 'Constraints',
35208
+ edgeCases: 'Edge cases',
35209
+ verification: 'Verification',
35210
+ };
35211
+ /** Gate keys → short labels for the frontmatter blocking list. */
35212
+ const FRONTMATTER_GATE_LABELS = {
35213
+ goal: 'title',
35214
+ objective: 'objective',
35215
+ outcomes: 'outcomes',
35216
+ constraints: 'constraints',
35217
+ edgeCases: 'edge-cases',
35218
+ verification: 'verification',
35219
+ };
35220
+ /**
35221
+ * Single-line readiness value stamped into intent.md frontmatter, so the verdict travels
35222
+ * with the file: "passed 6/6" or "failed 4/6 — blocking: constraints, verification".
35223
+ * Deterministic and greppable. Mirrored in lib/intentReadiness.formatReadinessFrontmatter;
35224
+ * lib/preflightReadinessParity.test.ts fails CI if the two drift.
35225
+ */
35226
+ function formatReadinessFrontmatter(verdict) {
35227
+ const total = exports.READINESS_GATE_ORDER.length;
35228
+ const passed = exports.READINESS_GATE_ORDER.filter((k) => verdict.signals[k]).length;
35229
+ if (verdict.ready)
35230
+ return `passed ${passed}/${total}`;
35231
+ const blocking = exports.READINESS_GATE_ORDER.filter((k) => !verdict.signals[k]).map((k) => FRONTMATTER_GATE_LABELS[k]);
35232
+ return `failed ${passed}/${total} — blocking: ${blocking.join(', ')}`;
35233
+ }
35234
+ /** Human/agent-readable verdict block, stable enough to parse by line prefix. */
35235
+ function formatReadinessVerdict(verdict, specTitle) {
35236
+ const lines = [];
35237
+ const name = (specTitle || '').trim();
35238
+ if (verdict.ready) {
35239
+ lines.push(`✓ Preflight passed${name ? ` for "${name}"` : ''}. 6/6 checks. Ready to hand to an agent.`);
35240
+ }
35241
+ else {
35242
+ lines.push(`✗ Preflight failed${name ? ` for "${name}"` : ''}. ${verdict.failingBlockers.length}/6 checks blocking.`);
35243
+ for (const b of verdict.failingBlockers)
35244
+ lines.push(` ✗ ${b}`);
35245
+ }
35246
+ lines.push('');
35247
+ lines.push(exports.READINESS_GATE_ORDER.map(k => `${verdict.signals[k] ? '✓' : '·'} ${GATE_LABELS[k]}`).join(' '));
35248
+ if (!verdict.ready) {
35249
+ lines.push('');
35250
+ lines.push('Repair the failing fields (ask the user one targeted question per blocker), save with intent_save, and re-run check_intent_readiness. The verdict is deterministic: the same spec always gets the same result.');
35251
+ }
35252
+ return lines.join('\n');
35253
+ }
35254
+
35255
+
35006
35256
  /***/ }),
35007
35257
 
35008
35258
  /***/ 6137:
@@ -64931,7 +65181,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"$schema":"http://json-schema.org/dra
64931
65181
  /***/ ((module) => {
64932
65182
 
64933
65183
  "use strict";
64934
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@pathmode/mcp-server","version":"1.10.0","publishConfig":{"access":"public"},"mcpName":"io.github.pathmodeio/mcp-server","description":"Pathmode MCP Server — Build structured intent specs through Socratic AI conversation (zero-config), or connect to your Intent Layer for strategic context, dependency graphs, and implementation prompts.","main":"dist/index.js","bin":{"pathmode-mcp":"dist/index.js"},"files":["dist/","manifest.json","icon.svg","README.md","skills/"],"scripts":{"build":"rm -rf dist && ncc build src/index.ts -o dist","dev":"ts-node src/index.ts","prepublishOnly":"npm run build"},"keywords":["pathmode","mcp","model-context-protocol","claude-code","claude-code-skills","agent-skills","cursor","windsurf","intent-engineering","intent-compiler","ai-agents","product-development","dependency-graph","strategic-planning"],"author":"Pathmode","license":"MIT","type":"commonjs","engines":{"node":">=18.0.0"},"repository":{"type":"git","url":"git+https://github.com/pathmodeio/mcp-server.git","directory":"packages/mcp-server"},"homepage":"https://pathmode.io","dependencies":{"@modelcontextprotocol/sdk":"^1.12.1","gray-matter":"^4.0.3","zod":"^3.24.0"},"devDependencies":{"@types/node":"^25.1.0","@vercel/ncc":"^0.38.4","ts-node":"^10.9.2","typescript":"^5.9.3"}}');
65184
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@pathmode/mcp-server","version":"1.12.0","publishConfig":{"access":"public"},"mcpName":"io.github.pathmodeio/mcp-server","description":"Pathmode MCP Server — Build structured intent specs through Socratic AI conversation (zero-config), or connect to your Intent Layer for strategic context, dependency graphs, and implementation prompts.","main":"dist/index.js","bin":{"pathmode-mcp":"dist/index.js"},"files":["dist/","manifest.json","icon.svg","README.md","skills/"],"scripts":{"build":"rm -rf dist && ncc build src/index.ts -o dist","dev":"ts-node src/index.ts","prepublishOnly":"npm run build"},"keywords":["pathmode","mcp","model-context-protocol","claude-code","claude-code-skills","agent-skills","cursor","windsurf","intent-engineering","intent-compiler","ai-agents","product-development","dependency-graph","strategic-planning"],"author":"Pathmode","license":"MIT","type":"commonjs","engines":{"node":">=18.0.0"},"repository":{"type":"git","url":"git+https://github.com/pathmodeio/mcp-server.git","directory":"packages/mcp-server"},"homepage":"https://pathmode.io","dependencies":{"@modelcontextprotocol/sdk":"^1.12.1","gray-matter":"^4.0.3","zod":"^3.24.0"},"devDependencies":{"@types/node":"^25.1.0","@vercel/ncc":"^0.38.4","ts-node":"^10.9.2","typescript":"^5.9.3"}}');
64935
65185
 
64936
65186
  /***/ })
64937
65187
 
@@ -65027,6 +65277,7 @@ const path_1 = __nccwpck_require__(6928);
65027
65277
  const fs_1 = __nccwpck_require__(9896);
65028
65278
  const api_client_1 = __nccwpck_require__(7475);
65029
65279
  const local_reader_1 = __nccwpck_require__(3518);
65280
+ const readiness_1 = __nccwpck_require__(3079);
65030
65281
  const save_policy_1 = __nccwpck_require__(6137);
65031
65282
  const intent_compiler_1 = __nccwpck_require__(6488);
65032
65283
  const pathmode_section_1 = __nccwpck_require__(4681);
@@ -65895,24 +66146,56 @@ function startMcpServer() {
65895
66146
  });
65896
66147
  cloudOnly.registerTool('verify_implementation', {
65897
66148
  title: 'Verify Implementation',
65898
- description: 'AI-grade your implementation against the intent spec. Checks each outcome, constraint, constitution rule, and edge case. Returns pass/fail per item with reasoning and an overall score. Also logs the result as an implementation note.',
66149
+ description: 'Grade an implementation against the intent spec by reading the pull request. Pass prUrl and Pathmode fetches the diff itself and grades each outcome, constraint, constitution rule, edge case and verification check against what the code actually shows. Describing your own work instead is weaker evidence and the result says so. Returns pass/fail per item with reasoning, a score, and the basis the verdict rests on. Also logs the result as an implementation note.',
65899
66150
  inputSchema: {
65900
66151
  intentId: zod_1.z.string().describe('The intent ID to verify against'),
65901
- summary: zod_1.z.string().describe('Description of what was implemented and how'),
65902
- codeChanges: zod_1.z.string().optional().describe('Summary of code changes (file list, key modifications)'),
66152
+ prUrl: zod_1.z.string().optional().describe('Pull request URL (or owner/repo#123) containing the implementation. Strongly preferred: the diff is read from GitHub instead of taken on trust.'),
66153
+ summary: zod_1.z.string().optional().describe('What you implemented and how. Context for the grader, not evidence. Required only when there is no pull request to point at.'),
66154
+ codeChanges: zod_1.z.string().optional().describe('Deprecated, superseded by prUrl. A diff you paste about your own work is not independent evidence.'),
65903
66155
  },
65904
66156
  annotations: WRITE_OP,
65905
- }, async ({ intentId, summary, codeChanges }) => {
66157
+ }, async ({ intentId, prUrl, summary, codeChanges }) => {
65906
66158
  if (isLocalMode) {
65907
66159
  return { content: [{ type: 'text', text: 'Verification requires cloud mode.' }] };
65908
66160
  }
66161
+ if (!prUrl && !summary) {
66162
+ return { content: [{ type: 'text', text: 'Provide prUrl (preferred) or summary.' }] };
66163
+ }
65909
66164
  try {
65910
- const result = await requireCloudClient().verifyImplementation(intentId, summary, codeChanges);
65911
- let text = `Verification ${result.pass ? 'PASSED' : 'FAILED'} (score: ${result.score}/100)\n\n`;
66165
+ const result = await requireCloudClient().verifyImplementation(intentId, { summary, prUrl, codeChanges });
66166
+ let text = `Verification ${result.pass ? 'PASSED' : 'FAILED'} (score: ${result.score}/100)\n`;
66167
+ // Say what the verdict was actually based on. A run that could not read the code must not
66168
+ // read like one that did, or the score becomes a rubber stamp for a well-written summary.
66169
+ const a = result.artifact;
66170
+ if (a?.kind === 'pr_diff') {
66171
+ text += `Graded against ${a.repo}#${a.prNumber} at ${a.headSha?.slice(0, 8)}`
66172
+ + ` (${a.filesRead} file(s)${a.truncated ? `, ${a.filesOmitted} omitted for size` : ''})\n\n`;
66173
+ }
66174
+ else if (a) {
66175
+ text += `Graded on your own description, no code was read (${a.reason}).`
66176
+ + ` Pass a prUrl for a verdict grounded in the diff.\n\n`;
66177
+ }
66178
+ else {
66179
+ text += '\n';
66180
+ }
65912
66181
  text += `${result.summary}\n\n`;
65913
66182
  for (const r of result.results) {
65914
- const icon = r.status === 'pass' ? '[PASS]' : r.status === 'fail' ? '[FAIL]' : '[????]';
66183
+ const icon = r.status === 'pass' ? '[PASS]'
66184
+ : r.status === 'fail' ? '[FAIL]'
66185
+ : r.status === 'not_applicable' ? '[ -- ]'
66186
+ : '[????]';
65915
66187
  text += `${icon} [${r.category}] ${r.item}\n ${r.reasoning}\n`;
66188
+ // Citations are validated server-side against the diff; an item with none, on a run
66189
+ // that had a diff, says so rather than reading like an inspected verdict.
66190
+ if (r.status === 'not_applicable') {
66191
+ // An absence claim has nothing to cite, so a missing citation is not a gap here.
66192
+ }
66193
+ else if (r.evidence?.length) {
66194
+ text += ` cites: ${r.evidence.map(c => c.path).join(', ')}\n`;
66195
+ }
66196
+ else if (r.basis === 'none') {
66197
+ text += ` cites: nothing in the diff\n`;
66198
+ }
65916
66199
  }
65917
66200
  return { content: [{ type: 'text', text }] };
65918
66201
  }
@@ -66018,6 +66301,57 @@ function startMcpServer() {
66018
66301
  }],
66019
66302
  };
66020
66303
  });
66304
+ server.registerTool('check_intent_readiness', {
66305
+ title: 'Check Intent Readiness (Preflight)',
66306
+ description: 'Run the deterministic preflight on an intent spec before handing it to an implementation agent. Six calibrated checks — title, objective, outcomes, constraints, edge cases, verification — computed by pure functions: no model call, no network, the same spec always gets the same verdict. Pass a spec inline to check before saving, pass intentId to check a specific saved intent, or pass nothing to check the current intent. A failing verdict names the exact blockers; repair the fields and re-run. This is the gate that runs at preflight.pathmode.io.',
66307
+ inputSchema: {
66308
+ spec: zod_1.z.object(intentSpecSchema).optional().describe('Check this spec directly (before saving). When omitted, the current intent is checked instead.'),
66309
+ intentId: zod_1.z.string().optional().describe('Check a specific saved intent by id. Ignored when spec is passed.'),
66310
+ },
66311
+ annotations: READ_ONLY,
66312
+ }, async ({ spec, intentId }) => {
66313
+ let subject = spec;
66314
+ let sourceNote = 'inline spec';
66315
+ if (!subject) {
66316
+ if (isLocalMode) {
66317
+ const intents = (0, local_reader_1.readLocalIntents)();
66318
+ subject = intentId ? intents.find(i => i.id === intentId) : pickCurrentIntent(intents);
66319
+ sourceNote = intentId ? `local intent ${intentId}` : 'current local intent (intent.md)';
66320
+ if (!subject) {
66321
+ return {
66322
+ content: [{
66323
+ type: 'text',
66324
+ text: intentId
66325
+ ? `No local intent with id "${intentId}". Check intent.md or .pathmode/intents/.`
66326
+ : 'No intent found. Write one first (intent_save), or pass the spec inline to preflight it before saving.',
66327
+ }],
66328
+ };
66329
+ }
66330
+ }
66331
+ else {
66332
+ const cloud = requireCloudClient();
66333
+ const intents = await cloud.listIntents();
66334
+ subject = intentId ? intents.find((i) => i.id === intentId) : pickCurrentIntent(intents);
66335
+ sourceNote = intentId ? `intent ${intentId}` : 'current intent';
66336
+ if (!subject) {
66337
+ return {
66338
+ content: [{
66339
+ type: 'text',
66340
+ text: intentId ? `No intent with id "${intentId}" in this workspace.` : 'No intents found in workspace.',
66341
+ }],
66342
+ };
66343
+ }
66344
+ }
66345
+ }
66346
+ const verdict = (0, readiness_1.computeReadinessVerdict)(subject);
66347
+ const title = (0, readiness_1.coerceText)(subject.title);
66348
+ return {
66349
+ content: [{
66350
+ type: 'text',
66351
+ text: `${(0, readiness_1.formatReadinessVerdict)(verdict, title)}\n\nChecked: ${sourceNote}.`,
66352
+ }],
66353
+ };
66354
+ });
66021
66355
  server.tool('intent_save', 'Save an intent spec to intent.md in the project root. Called after building a spec through conversation. Re-saving the same intent bumps its version and preserves its status; it never silently replaces a different intent.', {
66022
66356
  spec: zod_1.z.object(intentSpecSchema),
66023
66357
  path: zod_1.z.string().optional().describe('File path relative to the project root. Must stay inside the project (absolute paths and ".." are rejected). Defaults to intent.md'),
@@ -66046,13 +66380,20 @@ function startMcpServer() {
66046
66380
  };
66047
66381
  }
66048
66382
  const { id, version, status, created } = decision;
66049
- const content = (0, intent_compiler_1.formatIntentMd)({ ...spec, id }, { version, status, created });
66383
+ // The preflight verdict travels with the file: stamped into frontmatter on every save,
66384
+ // recomputed from the spec alone (deterministic). A failing verdict never blocks the
66385
+ // save — the gate reports, the user decides.
66386
+ const verdict = (0, readiness_1.computeReadinessVerdict)(spec);
66387
+ const content = (0, intent_compiler_1.formatIntentMd)({ ...spec, id }, { version, status, created, readiness: (0, readiness_1.formatReadinessFrontmatter)(verdict) });
66050
66388
  (0, fs_1.writeFileSync)(filePath, content, 'utf-8');
66051
66389
  const action = decision.action === 'update' ? `Updated intent spec (v${version})` : 'Saved intent spec';
66390
+ const readinessNote = verdict.ready
66391
+ ? ''
66392
+ : `\n\n${(0, readiness_1.formatReadinessVerdict)(verdict, spec.title)}`;
66052
66393
  return {
66053
66394
  content: [{
66054
66395
  type: 'text',
66055
- text: `✓ ${action} at ${filePath}\n id: ${id} · status: ${status}\n\nTo connect this to Pathmode for dependency tracking and team collaboration, visit pathmode.io`,
66396
+ text: `✓ ${action} at ${filePath}\n id: ${id} · status: ${status} · readiness: ${(0, readiness_1.formatReadinessFrontmatter)(verdict)}${readinessNote}\n\nTo connect this to Pathmode for dependency tracking and team collaboration, visit pathmode.io`,
66056
66397
  }],
66057
66398
  };
66058
66399
  });
@@ -83,6 +83,10 @@ export interface IntentMdOptions {
83
83
  status?: string;
84
84
  /** Original `created` timestamp. Preserved across updates; defaults to now. */
85
85
  created?: string;
86
+ /** Preflight verdict line ("passed 6/6" / "failed 4/6 — blocking: …"), recomputed at save time. */
87
+ readiness?: string;
88
+ /** Canonical record URL (cloud intents). Omitted when this file is the only copy. */
89
+ source?: string;
86
90
  }
87
91
  /**
88
92
  * Generate intent.md content with YAML frontmatter.
@@ -1 +1 @@
1
- {"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/intent-compiler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/intent-compiler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Deterministic intent readiness gate — the preflight.
3
+ *
4
+ * This is a PORT of the canonical gate in lib/intentReadiness.ts (the MCP package
5
+ * cannot import app/lib code). Every regex and threshold below must stay
6
+ * byte-identical to the source; lib/preflightReadinessParity.test.ts in the app
7
+ * repo runs both implementations over the 98-item calibration corpus and the
8
+ * Preflight demo specs, and fails CI on any divergence. Edit the app lib first,
9
+ * then mirror the change here.
10
+ *
11
+ * Pure functions only: no I/O, no network, no model calls. The same spec gets
12
+ * the same verdict every run — that determinism is the product claim on
13
+ * https://preflight.pathmode.io, so keep it true.
14
+ */
15
+ export declare function coerceText(value: unknown): string;
16
+ export declare function asArray<T>(value: T | T[] | null | undefined): T[];
17
+ export declare function isTitleMeaningful(title: string | null | undefined): boolean;
18
+ export declare function isConstraintConcrete(value: unknown): boolean;
19
+ export declare function isVerificationCheckSubstantive(description: string | null | undefined): boolean;
20
+ export declare function isObjectiveSpecific(objective: string | null | undefined): boolean;
21
+ export declare function isOutcomeMeasurable(text: string): boolean;
22
+ export declare const READINESS_BLOCKER_DESCRIPTIONS: Record<string, string>;
23
+ /** Display order for the gate strip (title first, matching the Preflight page). */
24
+ export declare const READINESS_GATE_ORDER: readonly ["goal", "objective", "outcomes", "constraints", "edgeCases", "verification"];
25
+ /** Loose spec shape: covers LocalIntent, cloud intent JSON, and hand-built specs. */
26
+ export interface ReadinessSpecInput {
27
+ title?: unknown;
28
+ objective?: unknown;
29
+ outcomes?: unknown;
30
+ constraints?: unknown;
31
+ edgeCases?: unknown;
32
+ verification?: unknown;
33
+ }
34
+ export interface ReadinessVerdict {
35
+ ready: boolean;
36
+ signals: Record<string, boolean>;
37
+ failingBlockers: string[];
38
+ }
39
+ /**
40
+ * The preflight: six deterministic gates over an intent spec. Mirrors
41
+ * lib/intentReadiness.computeReviewSignals with conversationFirst semantics
42
+ * (the legacy phase-engagement signal never gates the verdict here).
43
+ */
44
+ export declare function computeReadinessVerdict(spec: ReadinessSpecInput): ReadinessVerdict;
45
+ /**
46
+ * Single-line readiness value stamped into intent.md frontmatter, so the verdict travels
47
+ * with the file: "passed 6/6" or "failed 4/6 — blocking: constraints, verification".
48
+ * Deterministic and greppable. Mirrored in lib/intentReadiness.formatReadinessFrontmatter;
49
+ * lib/preflightReadinessParity.test.ts fails CI if the two drift.
50
+ */
51
+ export declare function formatReadinessFrontmatter(verdict: ReadinessVerdict): string;
52
+ /** Human/agent-readable verdict block, stable enough to parse by line prefix. */
53
+ export declare function formatReadinessVerdict(verdict: ReadinessVerdict, specTitle?: string): string;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/readiness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQjD;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,GAAG,CAAC,EAAE,CAIjE;AAoCD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAQ3E;AAID,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAI5D;AAED,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAI9F;AAQD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAOjF;AAQD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKzD;AAID,eAAO,MAAM,8BAA8B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAOjE,CAAC;AAEF,mFAAmF;AACnF,eAAO,MAAM,oBAAoB,wFAAyF,CAAC;AAK3H,qFAAqF;AACrF,MAAM,WAAW,kBAAkB;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,eAAe,EAAE,MAAM,EAAE,CAAC;CAC7B;AAoBD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,kBAAkB,GAAG,gBAAgB,CAkBlF;AAqBD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAM5E;AAED,iFAAiF;AACjF,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,gBAAgB,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAgB5F"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pathmode/mcp-server",
3
- "version": "1.10.0",
3
+ "version": "1.12.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
package/skills/README.md CHANGED
@@ -12,6 +12,7 @@ Listed in lifecycle order — most projects use them in roughly this sequence.
12
12
  |-------|----------|
13
13
  | `setup-pathmode-workflow` | First-time setup — capturing test commands, issue tracker, status conventions |
14
14
  | `compile-intent` | Building a structured spec for what to ship |
15
+ | `preflight` | Deterministic readiness verdict before an agent builds — six gates, exact blockers, no model call |
15
16
  | `verify-intent` | Designing the executable feedback loop for a spec (fastest check, manual fallback, shipped signal) |
16
17
  | `grill-intent` | Stress-testing an existing spec for weaknesses before code is written |
17
18
  | `split-intent-to-issues` | Breaking a spec into paste-ready Linear / Jira / GitHub Issues tickets |
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: preflight
3
+ description: Run the deterministic readiness check on an intent spec before an agent builds against it. Six calibrated gates, computed by pure functions — no model judgment, same spec always gets the same verdict. Use before implementing an intent, before handing a spec to another agent, or whenever the user asks "is this spec ready?".
4
+ ---
5
+
6
+ <what-to-do>
7
+
8
+ Call the `check_intent_readiness` MCP tool (Pathmode). With no arguments it checks the current intent (`intent.md` in local mode, the active workspace intent in cloud mode). Pass `spec` inline to preflight a draft before saving it, or `intentId` for a specific saved intent.
9
+
10
+ Show the user the verdict block exactly as returned — the blocker strings are the calibrated gate output, do not paraphrase them.
11
+
12
+ If the verdict fails: repair, one blocker at a time. For each failing gate, ask the user ONE targeted question, and propose your best-guess answer from the spec and the codebase so they can correct rather than compose. Apply the agreed fix to the spec (`intent_save` in local mode), then re-run `check_intent_readiness`. Stop when the verdict passes or the user explicitly accepts a named gap.
13
+
14
+ If the verdict passes: say so and stop. Do not invent extra requirements beyond the six gates.
15
+
16
+ </what-to-do>
17
+
18
+ <supporting-info>
19
+
20
+ ## What the six gates check
21
+
22
+ 1. **Title** — a short, specific noun phrase, not a placeholder or generic label ("Bulk edit" passes; "New feature" fails).
23
+ 2. **Objective** — names an actor and a concrete problem or capability; rejects buzzword-dressed vagueness with no number.
24
+ 3. **Outcomes** — at least two, and at least two-thirds measurable: a threshold, an observable capability, or a concrete state change. "Users are happier" fails.
25
+ 4. **Constraints** — at least one violable statement, something an implementation could actually break ("Never double-charge on retry"). Bare adjectives fail.
26
+ 5. **Edge cases** — at least one scenario with a defined expected behavior.
27
+ 6. **Verification** — at least one check concrete enough to run without asking the author.
28
+
29
+ ## Why deterministic matters
30
+
31
+ The gate is pure functions over the spec text: no model call, no network. Re-running never changes the verdict unless the spec changed. That makes it a floor you can put in front of any implementation work — and it means a passing verdict is reproducible evidence, not an opinion. The same gate runs live at preflight.pathmode.io.
32
+
33
+ Every `intent_save` also stamps the verdict into the file's frontmatter as `readiness:` ("passed 6/6", or "failed N/6" with the blocking gates named), so anyone reading intent.md — human or agent — sees the gate state without re-running anything. A failing verdict never blocks the save; the gate reports, the user decides.
34
+
35
+ ## Division of labor with the other skills
36
+
37
+ - `preflight` — deterministic verdict: IS the spec ready? Cheap, run it first and often.
38
+ - `grill-intent` — adversarial model-driven review: is the spec WISE? Run it when preflight passes but the stakes are high.
39
+ - `compile-intent` — builds a spec from a vague problem. Preflight what it produces.
40
+
41
+ </supporting-info>