@pathmode/mcp-server 1.27.0 → 1.27.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.
package/dist/index.js
CHANGED
|
@@ -41215,6 +41215,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
41215
41215
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
41216
41216
|
};
|
|
41217
41217
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
41218
|
+
exports.parseFrontmatter = parseFrontmatter;
|
|
41218
41219
|
exports.readLocalIntents = readLocalIntents;
|
|
41219
41220
|
exports.readIntentMeta = readIntentMeta;
|
|
41220
41221
|
exports.readIntentFile = readIntentFile;
|
|
@@ -41225,6 +41226,57 @@ const path_1 = __importDefault(__nccwpck_require__(6928));
|
|
|
41225
41226
|
const gray_matter_1 = __importDefault(__nccwpck_require__(9599));
|
|
41226
41227
|
const measurement_schema_1 = __nccwpck_require__(1635);
|
|
41227
41228
|
const serializeIntentMd_1 = __nccwpck_require__(229);
|
|
41229
|
+
/**
|
|
41230
|
+
* The ONLY front matter parser in the CLI and MCP server. Every `matter()` call routes through
|
|
41231
|
+
* here; do not call gray-matter directly.
|
|
41232
|
+
*
|
|
41233
|
+
* gray-matter lets the *document* pick its parser: a file opening `---js` is handed to the
|
|
41234
|
+
* javascript engine and **evaluated at parse time**. Both entry points read files the user does
|
|
41235
|
+
* not control — `pathmode preflight` runs on any repo and advertises that it only reads, and
|
|
41236
|
+
* `check_intent_readiness` is annotated READ_ONLY so agent clients auto-approve it. So a hostile
|
|
41237
|
+
* `intent.md` meant arbitrary code execution with the developer's own privileges.
|
|
41238
|
+
*
|
|
41239
|
+
* Two layers, because either alone is escapable:
|
|
41240
|
+
* 1. Reject the language token before gray-matter sees the document. This is an allowlist, so a
|
|
41241
|
+
* newly-registered engine cannot reopen the hole.
|
|
41242
|
+
* 2. Override the javascript engines anyway, in case a delimiter form reaches them another way.
|
|
41243
|
+
*
|
|
41244
|
+
* Non-YAML front matter throws rather than parsing as empty: silently dropping it would let a
|
|
41245
|
+
* crafted file blank its own identity and slip past intent_save's different-id collision guard.
|
|
41246
|
+
*/
|
|
41247
|
+
const ALLOWED_FRONTMATTER_LANGUAGES = new Set(['', 'yaml', 'yml', 'json']);
|
|
41248
|
+
function refuseEngine() {
|
|
41249
|
+
throw new Error('Refusing to parse executable front matter: only YAML and JSON front matter is supported.');
|
|
41250
|
+
}
|
|
41251
|
+
/**
|
|
41252
|
+
* The language token on the opening delimiter, lowercased, or null when the document has no
|
|
41253
|
+
* front matter at all. Mirrors gray-matter's own tokenising, including the cases that surprised
|
|
41254
|
+
* us: a BOM still opens front matter, `\r\n` leaves a stray `\r`, and `---JS` / `---<tab>js` both
|
|
41255
|
+
* resolve to the javascript engine. Leading whitespace or a fourth dash do NOT open front matter.
|
|
41256
|
+
*/
|
|
41257
|
+
function detectFrontmatterLanguage(content) {
|
|
41258
|
+
const withoutBom = content.charCodeAt(0) === 0xfeff ? content.slice(1) : content;
|
|
41259
|
+
if (!withoutBom.startsWith('---'))
|
|
41260
|
+
return null;
|
|
41261
|
+
// A fourth dash means this is a horizontal rule, not a delimiter. gray-matter bails on the
|
|
41262
|
+
// same test (index.js: `if (str.charAt(openLen) === open.slice(-1)) return file`), and the
|
|
41263
|
+
// guard has to agree with it: reading `----js` as the language `-js` would refuse a document
|
|
41264
|
+
// gray-matter parses happily, breaking valid files instead of hostile ones.
|
|
41265
|
+
if (withoutBom.charAt(3) === '-')
|
|
41266
|
+
return null;
|
|
41267
|
+
const lineEnd = withoutBom.indexOf('\n');
|
|
41268
|
+
const firstLine = lineEnd === -1 ? withoutBom : withoutBom.slice(0, lineEnd);
|
|
41269
|
+
return firstLine.slice(3).replace(/\r$/, '').trim().toLowerCase();
|
|
41270
|
+
}
|
|
41271
|
+
function parseFrontmatter(content) {
|
|
41272
|
+
const language = detectFrontmatterLanguage(content);
|
|
41273
|
+
if (language !== null && !ALLOWED_FRONTMATTER_LANGUAGES.has(language)) {
|
|
41274
|
+
throw new Error(`Refusing to parse "${language}" front matter: only YAML and JSON front matter is supported.`);
|
|
41275
|
+
}
|
|
41276
|
+
return (0, gray_matter_1.default)(content, {
|
|
41277
|
+
engines: { javascript: refuseEngine, js: refuseEngine },
|
|
41278
|
+
});
|
|
41279
|
+
}
|
|
41228
41280
|
const CONFIRMATION_HEADER_RE = /^\*\*(objective|outcomes)\*\*\s*[—–-]\s*(confirmed|waived)\s+by\s+(agent|human)\s*$/i;
|
|
41229
41281
|
const CONFIRMATION_FIELD_RE = /^\s*[-*]\s+(actor|problem|outcome|observable|reason|anchor|at)\s*:\s*(.+)$/i;
|
|
41230
41282
|
/**
|
|
@@ -41294,7 +41346,7 @@ function readIntentMeta(filePath) {
|
|
|
41294
41346
|
if (!fs_1.default.existsSync(filePath))
|
|
41295
41347
|
return null;
|
|
41296
41348
|
try {
|
|
41297
|
-
const { data } = (
|
|
41349
|
+
const { data } = parseFrontmatter(fs_1.default.readFileSync(filePath, 'utf-8'));
|
|
41298
41350
|
const version = Number(data.version);
|
|
41299
41351
|
return {
|
|
41300
41352
|
id: typeof data.id === 'string' && data.id.trim() ? data.id.trim() : null,
|
|
@@ -41395,7 +41447,7 @@ function frontmatterEdgeCases(v) {
|
|
|
41395
41447
|
.filter((e) => e.scenario || e.expectedBehavior);
|
|
41396
41448
|
}
|
|
41397
41449
|
function parseIntentMarkdown(content, fallbackId = 'intent') {
|
|
41398
|
-
const { data, content: rawBody } = (
|
|
41450
|
+
const { data, content: rawBody } = parseFrontmatter(content);
|
|
41399
41451
|
const body = stripHtmlComments(stripFencedBlocks(rawBody));
|
|
41400
41452
|
const sections = splitSections(body);
|
|
41401
41453
|
// The public schema allows verification as a flat string array; read it as manual checks
|
|
@@ -73150,7 +73202,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"$schema":"http://json-schema.org/dra
|
|
|
73150
73202
|
/***/ ((module) => {
|
|
73151
73203
|
|
|
73152
73204
|
"use strict";
|
|
73153
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"@pathmode/mcp-server","version":"1.27.
|
|
73205
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"@pathmode/mcp-server","version":"1.27.1","publishConfig":{"access":"public"},"mcpName":"io.github.pathmodeio/mcp-server","description":"Deterministic intent preflight before your agent builds: six calibrated gates, keyless, no model call. Draft and sharpen specs in conversation, or connect a Pathmode workspace to sync intent and evidence across a team.","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"},"homepage":"https://pathmode.io","dependencies":{"@modelcontextprotocol/sdk":"^1.12.1","gray-matter":"^4.0.3","zod":"^3.24.0"},"overrides":{"@hono/node-server":"^1.19.17","body-parser":"^2.3.0","fast-uri":"^3.1.6","hono":"^4.13.5","ip-address":"^10.7.0","js-yaml":"^3.15.2"},"devDependencies":{"@types/node":"^25.1.0","@vercel/ncc":"^0.38.4","ts-node":"^10.9.2","typescript":"^5.9.3"}}');
|
|
73154
73206
|
|
|
73155
73207
|
/***/ })
|
|
73156
73208
|
|
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
* as a single item: three outcomes read back as one, `## Scope` vanished entirely, and
|
|
9
9
|
* `## Verification` produced `{}`. See round-trip.test.ts for the regression guard.
|
|
10
10
|
*/
|
|
11
|
+
import matter from 'gray-matter';
|
|
11
12
|
import type { OutcomeMeasurementDefinition } from './api-client';
|
|
13
|
+
export declare function parseFrontmatter(content: string): matter.GrayMatterFile<string>;
|
|
12
14
|
export type LocalVerificationKind = 'fastest' | 'manual' | 'shipped-signal' | 'regression-guard' | 'test';
|
|
13
15
|
export interface LocalVerificationCheck {
|
|
14
16
|
kind: LocalVerificationKind;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-reader.d.ts","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/local-reader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"local-reader.d.ts","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/local-reader.ts"],"names":[],"mappings":"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"}
|
package/manifest.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"manifest_version": "0.3",
|
|
3
3
|
"name": "pathmode",
|
|
4
4
|
"display_name": "Pathmode",
|
|
5
|
-
"version": "1.27.
|
|
5
|
+
"version": "1.27.1",
|
|
6
6
|
"description": "Deterministic preflight for the intent you hand to a coding agent: six calibrated gates, the exact blockers named, no model call, no key needed.",
|
|
7
7
|
"long_description": "Pathmode MCP Server runs a deterministic preflight before your coding agent builds: check_intent_readiness scores an intent spec against six calibrated gates (title, objective, outcomes, constraints, edge cases, verification) and names the exact blockers, with no model call and no account. Keyless local mode works out of the box; specs live in intent.md in your repo, plain markdown you own, and skills for drafting, pressure-testing, and handing off intent ride along. Connect a Pathmode workspace with an API key to sync intent and evidence across a team, analyze dependency graphs, and verify pull requests against the outcomes you agreed to.",
|
|
8
8
|
"author": {
|