@pathmode/mcp-server 1.4.4 → 1.5.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 +24 -1
- package/dist/api-client.d.ts +18 -2
- package/dist/api-client.d.ts.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +444 -84
- package/dist/install-skills.d.ts +13 -0
- package/dist/install-skills.d.ts.map +1 -0
- package/dist/intent-compiler.d.ts.map +1 -1
- package/dist/local-reader.d.ts +4 -0
- package/dist/local-reader.d.ts.map +1 -1
- package/manifest.json +2 -2
- package/package.json +8 -2
- package/skills/README.md +77 -0
- package/skills/compile-intent/SKILL.md +57 -0
- package/skills/grill-intent/SKILL.md +45 -0
- package/skills/handoff-intent/SKILL.md +51 -0
- package/skills/review-against-intent/SKILL.md +52 -0
- package/skills/setup-pathmode-workflow/SKILL.md +81 -0
- package/skills/split-intent-to-issues/SKILL.md +92 -0
- package/skills/verify-intent/SKILL.md +76 -0
package/dist/index.js
CHANGED
|
@@ -25565,7 +25565,7 @@ class Ajv {
|
|
|
25565
25565
|
constructor(opts = {}) {
|
|
25566
25566
|
this.schemas = {};
|
|
25567
25567
|
this.refs = {};
|
|
25568
|
-
this.formats =
|
|
25568
|
+
this.formats = Object.create(null);
|
|
25569
25569
|
this._compilations = new Set();
|
|
25570
25570
|
this._loading = {};
|
|
25571
25571
|
this._cache = new Map();
|
|
@@ -28017,6 +28017,7 @@ exports["default"] = def;
|
|
|
28017
28017
|
|
|
28018
28018
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
28019
28019
|
const code_1 = __nccwpck_require__(8484);
|
|
28020
|
+
const util_1 = __nccwpck_require__(4464);
|
|
28020
28021
|
const codegen_1 = __nccwpck_require__(1436);
|
|
28021
28022
|
const error = {
|
|
28022
28023
|
message: ({ schemaCode }) => (0, codegen_1.str) `must match pattern "${schemaCode}"`,
|
|
@@ -28029,11 +28030,19 @@ const def = {
|
|
|
28029
28030
|
$data: true,
|
|
28030
28031
|
error,
|
|
28031
28032
|
code(cxt) {
|
|
28032
|
-
const { data, $data, schema, schemaCode, it } = cxt;
|
|
28033
|
-
// TODO regexp should be wrapped in try/catchs
|
|
28033
|
+
const { gen, data, $data, schema, schemaCode, it } = cxt;
|
|
28034
28034
|
const u = it.opts.unicodeRegExp ? "u" : "";
|
|
28035
|
-
|
|
28036
|
-
|
|
28035
|
+
if ($data) {
|
|
28036
|
+
const { regExp } = it.opts.code;
|
|
28037
|
+
const regExpCode = regExp.code === "new RegExp" ? (0, codegen_1._) `new RegExp` : (0, util_1.useFunc)(gen, regExp);
|
|
28038
|
+
const valid = gen.let("valid");
|
|
28039
|
+
gen.try(() => gen.assign(valid, (0, codegen_1._) `${regExpCode}(${schemaCode}, ${u}).test(${data})`), () => gen.assign(valid, false));
|
|
28040
|
+
cxt.fail$data((0, codegen_1._) `!${valid}`);
|
|
28041
|
+
}
|
|
28042
|
+
else {
|
|
28043
|
+
const regExp = (0, code_1.usePattern)(cxt, schema);
|
|
28044
|
+
cxt.fail$data((0, codegen_1._) `!${regExp}.test(${data})`);
|
|
28045
|
+
}
|
|
28037
28046
|
},
|
|
28038
28047
|
};
|
|
28039
28048
|
exports["default"] = def;
|
|
@@ -33531,6 +33540,7 @@ exports.loadConfig = loadConfig;
|
|
|
33531
33540
|
const fs_1 = __importDefault(__nccwpck_require__(9896));
|
|
33532
33541
|
const path_1 = __importDefault(__nccwpck_require__(6928));
|
|
33533
33542
|
const os_1 = __importDefault(__nccwpck_require__(857));
|
|
33543
|
+
const isDebug = process.env.PATHMODE_MCP_DEBUG === '1';
|
|
33534
33544
|
const CONFIG_DIR = path_1.default.join(os_1.default.homedir(), '.pathmode');
|
|
33535
33545
|
const CONFIG_FILE = path_1.default.join(CONFIG_DIR, 'config.json');
|
|
33536
33546
|
function loadConfig() {
|
|
@@ -33563,7 +33573,8 @@ class PathmodeClient {
|
|
|
33563
33573
|
}
|
|
33564
33574
|
async fetch(path, options = {}) {
|
|
33565
33575
|
const url = `${this.apiUrl}/api/v1${path}`;
|
|
33566
|
-
|
|
33576
|
+
if (isDebug)
|
|
33577
|
+
console.error(`[pathmode-mcp] fetch: ${url}`);
|
|
33567
33578
|
const response = await fetch(url, {
|
|
33568
33579
|
...options,
|
|
33569
33580
|
headers: {
|
|
@@ -33574,7 +33585,7 @@ class PathmodeClient {
|
|
|
33574
33585
|
});
|
|
33575
33586
|
if (!response.ok) {
|
|
33576
33587
|
const body = await response.json().catch(() => ({ error: response.statusText }));
|
|
33577
|
-
console.error(`[pathmode-mcp] ${response.status}: ${
|
|
33588
|
+
console.error(`[pathmode-mcp] API error ${response.status}: ${body.error || response.statusText}`);
|
|
33578
33589
|
throw new Error(`API error (${response.status}): ${body.error || response.statusText}`);
|
|
33579
33590
|
}
|
|
33580
33591
|
return response;
|
|
@@ -33678,6 +33689,198 @@ class PathmodeClient {
|
|
|
33678
33689
|
exports.PathmodeClient = PathmodeClient;
|
|
33679
33690
|
|
|
33680
33691
|
|
|
33692
|
+
/***/ }),
|
|
33693
|
+
|
|
33694
|
+
/***/ 3783:
|
|
33695
|
+
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
33696
|
+
|
|
33697
|
+
"use strict";
|
|
33698
|
+
|
|
33699
|
+
/**
|
|
33700
|
+
* Pathmode MCP Install Skills Command
|
|
33701
|
+
*
|
|
33702
|
+
* Copies the bundled Claude Code skill pack into .claude/skills/
|
|
33703
|
+
* (project-local, default) or ~/.claude/skills/ (global, with --global).
|
|
33704
|
+
*
|
|
33705
|
+
* Usage:
|
|
33706
|
+
* npx @pathmode/mcp-server install-skills
|
|
33707
|
+
* npx @pathmode/mcp-server install-skills --global
|
|
33708
|
+
* npx @pathmode/mcp-server install-skills --force
|
|
33709
|
+
*/
|
|
33710
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
33711
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
33712
|
+
};
|
|
33713
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
33714
|
+
exports.isInstallSkillsCommand = isInstallSkillsCommand;
|
|
33715
|
+
exports.runInstallSkills = runInstallSkills;
|
|
33716
|
+
const fs_1 = __importDefault(__nccwpck_require__(9896));
|
|
33717
|
+
const path_1 = __importDefault(__nccwpck_require__(6928));
|
|
33718
|
+
const os_1 = __importDefault(__nccwpck_require__(857));
|
|
33719
|
+
const BOLD = '\x1b[1m';
|
|
33720
|
+
const DIM = '\x1b[2m';
|
|
33721
|
+
const GREEN = '\x1b[32m';
|
|
33722
|
+
const RED = '\x1b[31m';
|
|
33723
|
+
const YELLOW = '\x1b[33m';
|
|
33724
|
+
const CYAN = '\x1b[36m';
|
|
33725
|
+
const RESET = '\x1b[0m';
|
|
33726
|
+
function log(msg) { console.log(msg); }
|
|
33727
|
+
function success(msg) { console.log(` ${GREEN}✓${RESET} ${msg}`); }
|
|
33728
|
+
function warn(msg) { console.log(` ${YELLOW}!${RESET} ${msg}`); }
|
|
33729
|
+
function fail(msg) { console.log(` ${RED}✗${RESET} ${msg}`); }
|
|
33730
|
+
function isInstallSkillsCommand(argv = process.argv) {
|
|
33731
|
+
return argv.includes('install-skills');
|
|
33732
|
+
}
|
|
33733
|
+
function getInstallSkillsArgs(argv = process.argv) {
|
|
33734
|
+
const idx = argv.findIndex(a => a === 'install-skills');
|
|
33735
|
+
return idx === -1 ? [] : argv.slice(idx + 1);
|
|
33736
|
+
}
|
|
33737
|
+
function shortenPath(p) {
|
|
33738
|
+
const home = os_1.default.homedir();
|
|
33739
|
+
return p.startsWith(home) ? '~' + p.slice(home.length) : p;
|
|
33740
|
+
}
|
|
33741
|
+
/**
|
|
33742
|
+
* Locate the bundled skills/ directory.
|
|
33743
|
+
*
|
|
33744
|
+
* When installed via npm, this file is at <pkg>/dist/install-skills.js
|
|
33745
|
+
* and skills/ sits at <pkg>/skills/. When running from source (ts-node),
|
|
33746
|
+
* this file is at <pkg>/src/install-skills.ts and skills/ is at <pkg>/skills/.
|
|
33747
|
+
*
|
|
33748
|
+
* Either way, going up one level from __dirname and joining "skills" finds it.
|
|
33749
|
+
*/
|
|
33750
|
+
function findSkillsDir() {
|
|
33751
|
+
const candidates = [
|
|
33752
|
+
path_1.default.resolve(__dirname, '..', 'skills'), // npm install layout (dist/ -> ../skills)
|
|
33753
|
+
path_1.default.resolve(__dirname, '..', '..', 'skills'), // edge case if bundled deeper
|
|
33754
|
+
];
|
|
33755
|
+
for (const c of candidates) {
|
|
33756
|
+
if (!fs_1.default.existsSync(c) || !fs_1.default.statSync(c).isDirectory())
|
|
33757
|
+
continue;
|
|
33758
|
+
// Sanity check: directory must contain at least one <name>/SKILL.md
|
|
33759
|
+
const entries = fs_1.default.readdirSync(c);
|
|
33760
|
+
const hasSkill = entries.some(e => fs_1.default.existsSync(path_1.default.join(c, e, 'SKILL.md')));
|
|
33761
|
+
if (hasSkill)
|
|
33762
|
+
return c;
|
|
33763
|
+
}
|
|
33764
|
+
return null;
|
|
33765
|
+
}
|
|
33766
|
+
function copyRecursive(src, dest) {
|
|
33767
|
+
if (!fs_1.default.existsSync(dest)) {
|
|
33768
|
+
fs_1.default.mkdirSync(dest, { recursive: true });
|
|
33769
|
+
}
|
|
33770
|
+
const entries = fs_1.default.readdirSync(src, { withFileTypes: true });
|
|
33771
|
+
for (const e of entries) {
|
|
33772
|
+
const srcPath = path_1.default.join(src, e.name);
|
|
33773
|
+
const destPath = path_1.default.join(dest, e.name);
|
|
33774
|
+
if (e.isDirectory()) {
|
|
33775
|
+
copyRecursive(srcPath, destPath);
|
|
33776
|
+
}
|
|
33777
|
+
else {
|
|
33778
|
+
fs_1.default.copyFileSync(srcPath, destPath);
|
|
33779
|
+
}
|
|
33780
|
+
}
|
|
33781
|
+
}
|
|
33782
|
+
async function runInstallSkills() {
|
|
33783
|
+
const args = getInstallSkillsArgs();
|
|
33784
|
+
const isGlobal = args.includes('--global');
|
|
33785
|
+
const isForce = args.includes('--force');
|
|
33786
|
+
const wantsHelp = args.includes('--help') || args.includes('-h');
|
|
33787
|
+
log('');
|
|
33788
|
+
log(`${BOLD}Pathmode Skills Install${RESET}`);
|
|
33789
|
+
log(`${DIM}──────────────────────${RESET}`);
|
|
33790
|
+
log('');
|
|
33791
|
+
if (wantsHelp) {
|
|
33792
|
+
log(`Usage: ${CYAN}npx @pathmode/mcp-server install-skills${RESET} [options]`);
|
|
33793
|
+
log('');
|
|
33794
|
+
log('Options:');
|
|
33795
|
+
log(` ${BOLD}--global${RESET} Install into ~/.claude/skills/ instead of ./.claude/skills/`);
|
|
33796
|
+
log(` ${BOLD}--force${RESET} Overwrite existing skill directories`);
|
|
33797
|
+
log(` ${BOLD}--help${RESET} Show this message`);
|
|
33798
|
+
log('');
|
|
33799
|
+
log('Copies the bundled Claude Code skill pack into your skills directory.');
|
|
33800
|
+
log('Skills auto-trigger when your natural-language request matches their description —');
|
|
33801
|
+
log('no slash commands needed.');
|
|
33802
|
+
log('');
|
|
33803
|
+
return;
|
|
33804
|
+
}
|
|
33805
|
+
const skillsDir = findSkillsDir();
|
|
33806
|
+
if (!skillsDir) {
|
|
33807
|
+
fail('Could not locate the bundled skills/ directory.');
|
|
33808
|
+
log(` Expected to find it at <package-root>/skills/ relative to ${shortenPath(__dirname)}.`);
|
|
33809
|
+
log(` If you cloned this repo and are running from source, ensure ${BOLD}skills/${RESET} exists at the package root.`);
|
|
33810
|
+
log('');
|
|
33811
|
+
process.exit(1);
|
|
33812
|
+
}
|
|
33813
|
+
const targetDir = isGlobal
|
|
33814
|
+
? path_1.default.join(os_1.default.homedir(), '.claude', 'skills')
|
|
33815
|
+
: path_1.default.join(process.cwd(), '.claude', 'skills');
|
|
33816
|
+
log(` Source: ${DIM}${shortenPath(skillsDir)}${RESET}`);
|
|
33817
|
+
log(` Target: ${DIM}${shortenPath(targetDir)}${RESET}`);
|
|
33818
|
+
log('');
|
|
33819
|
+
if (!fs_1.default.existsSync(targetDir)) {
|
|
33820
|
+
try {
|
|
33821
|
+
fs_1.default.mkdirSync(targetDir, { recursive: true });
|
|
33822
|
+
}
|
|
33823
|
+
catch (err) {
|
|
33824
|
+
fail(`Could not create target directory: ${err.message}`);
|
|
33825
|
+
log('');
|
|
33826
|
+
process.exit(1);
|
|
33827
|
+
}
|
|
33828
|
+
}
|
|
33829
|
+
const entries = fs_1.default.readdirSync(skillsDir, { withFileTypes: true });
|
|
33830
|
+
let installed = 0;
|
|
33831
|
+
let skipped = 0;
|
|
33832
|
+
let overwritten = 0;
|
|
33833
|
+
for (const e of entries) {
|
|
33834
|
+
if (!e.isDirectory())
|
|
33835
|
+
continue;
|
|
33836
|
+
// Only copy directories that contain a SKILL.md
|
|
33837
|
+
const skillFile = path_1.default.join(skillsDir, e.name, 'SKILL.md');
|
|
33838
|
+
if (!fs_1.default.existsSync(skillFile))
|
|
33839
|
+
continue;
|
|
33840
|
+
const destPath = path_1.default.join(targetDir, e.name);
|
|
33841
|
+
const existsAlready = fs_1.default.existsSync(destPath);
|
|
33842
|
+
if (existsAlready && !isForce) {
|
|
33843
|
+
warn(`${e.name} ${DIM}(already installed — pass --force to overwrite)${RESET}`);
|
|
33844
|
+
skipped++;
|
|
33845
|
+
continue;
|
|
33846
|
+
}
|
|
33847
|
+
try {
|
|
33848
|
+
if (existsAlready && isForce) {
|
|
33849
|
+
fs_1.default.rmSync(destPath, { recursive: true, force: true });
|
|
33850
|
+
}
|
|
33851
|
+
copyRecursive(path_1.default.join(skillsDir, e.name), destPath);
|
|
33852
|
+
success(e.name);
|
|
33853
|
+
if (existsAlready)
|
|
33854
|
+
overwritten++;
|
|
33855
|
+
else
|
|
33856
|
+
installed++;
|
|
33857
|
+
}
|
|
33858
|
+
catch (err) {
|
|
33859
|
+
fail(`${e.name} — ${err.message}`);
|
|
33860
|
+
}
|
|
33861
|
+
}
|
|
33862
|
+
log('');
|
|
33863
|
+
const lines = [];
|
|
33864
|
+
if (installed > 0)
|
|
33865
|
+
lines.push(`${BOLD}${installed}${RESET} installed`);
|
|
33866
|
+
if (overwritten > 0)
|
|
33867
|
+
lines.push(`${BOLD}${overwritten}${RESET} updated`);
|
|
33868
|
+
if (skipped > 0)
|
|
33869
|
+
lines.push(`${BOLD}${skipped}${RESET} skipped`);
|
|
33870
|
+
log(` ${lines.join(' · ') || 'No skills processed.'}`);
|
|
33871
|
+
log('');
|
|
33872
|
+
if (installed + overwritten > 0) {
|
|
33873
|
+
log(` ${BOLD}Next:${RESET} Restart Claude Code so the new skills register at session start.`);
|
|
33874
|
+
log(` Then try: ${CYAN}"help me write a spec for [your problem]"${RESET}`);
|
|
33875
|
+
log('');
|
|
33876
|
+
}
|
|
33877
|
+
else if (skipped > 0) {
|
|
33878
|
+
log(` All skills already installed. Run with ${BOLD}--force${RESET} to overwrite.`);
|
|
33879
|
+
log('');
|
|
33880
|
+
}
|
|
33881
|
+
}
|
|
33882
|
+
|
|
33883
|
+
|
|
33681
33884
|
/***/ }),
|
|
33682
33885
|
|
|
33683
33886
|
/***/ 6488:
|
|
@@ -33810,6 +34013,7 @@ IMPORTANT:
|
|
|
33810
34013
|
- constraints: string[] (optional)
|
|
33811
34014
|
- edgeCases: { scenario: string, expectedBehavior: string }[] (optional)
|
|
33812
34015
|
- healthMetrics: string[] (optional)
|
|
34016
|
+
- scope: { inScope?: string[], outOfScope?: string[] } (optional)
|
|
33813
34017
|
- verification: { manualChecks?: string[], unitTests?: string[], e2eTests?: string[] } (optional)
|
|
33814
34018
|
|
|
33815
34019
|
Now, start the conversation. If they haven't provided one yet, ask for the concrete evidence (quote, metric, or ticket) driving this work.`;
|
|
@@ -34111,6 +34315,14 @@ function readIntentFile(filePath) {
|
|
|
34111
34315
|
const constraints = extractListSection(body, 'Constraints');
|
|
34112
34316
|
const healthMetrics = extractListSection(body, 'Health Metrics');
|
|
34113
34317
|
const edgeCases = extractEdgeCases(body);
|
|
34318
|
+
const scope = extractScope(body);
|
|
34319
|
+
const parsedVerification = extractVerification(body);
|
|
34320
|
+
const frontmatterVerification = data.verification && typeof data.verification === 'object'
|
|
34321
|
+
? data.verification
|
|
34322
|
+
: null;
|
|
34323
|
+
const verification = Object.keys(parsedVerification).length > 0
|
|
34324
|
+
? parsedVerification
|
|
34325
|
+
: (frontmatterVerification || {});
|
|
34114
34326
|
return {
|
|
34115
34327
|
id: data.id || path_1.default.basename(filePath, '.md'),
|
|
34116
34328
|
status: data.status || 'draft',
|
|
@@ -34123,7 +34335,8 @@ function readIntentFile(filePath) {
|
|
|
34123
34335
|
constraints,
|
|
34124
34336
|
edgeCases,
|
|
34125
34337
|
healthMetrics,
|
|
34126
|
-
|
|
34338
|
+
scope: scope || undefined,
|
|
34339
|
+
verification,
|
|
34127
34340
|
source: 'local',
|
|
34128
34341
|
};
|
|
34129
34342
|
}
|
|
@@ -34177,6 +34390,72 @@ function extractEdgeCases(body) {
|
|
|
34177
34390
|
}
|
|
34178
34391
|
return cases;
|
|
34179
34392
|
}
|
|
34393
|
+
/**
|
|
34394
|
+
* Extract Scope section with **In scope:** and **Out of scope:** sub-lists.
|
|
34395
|
+
* Matches the format emitted by formatIntentMd().
|
|
34396
|
+
*/
|
|
34397
|
+
function extractScope(body) {
|
|
34398
|
+
const section = extractSection(body, 'Scope');
|
|
34399
|
+
if (!section)
|
|
34400
|
+
return null;
|
|
34401
|
+
const inScope = [];
|
|
34402
|
+
const outOfScope = [];
|
|
34403
|
+
let target = null;
|
|
34404
|
+
for (const line of section.split('\n')) {
|
|
34405
|
+
if (/^\*\*In scope[:\*]*/.test(line.trim())) {
|
|
34406
|
+
target = inScope;
|
|
34407
|
+
continue;
|
|
34408
|
+
}
|
|
34409
|
+
if (/^\*\*Out of scope[:\*]*/.test(line.trim())) {
|
|
34410
|
+
target = outOfScope;
|
|
34411
|
+
continue;
|
|
34412
|
+
}
|
|
34413
|
+
if (target && line.match(/^[-*]\s/)) {
|
|
34414
|
+
target.push(line.replace(/^[-*]\s+/, '').trim());
|
|
34415
|
+
}
|
|
34416
|
+
}
|
|
34417
|
+
if (inScope.length === 0 && outOfScope.length === 0)
|
|
34418
|
+
return null;
|
|
34419
|
+
const result = {};
|
|
34420
|
+
if (inScope.length > 0)
|
|
34421
|
+
result.inScope = inScope;
|
|
34422
|
+
if (outOfScope.length > 0)
|
|
34423
|
+
result.outOfScope = outOfScope;
|
|
34424
|
+
return result;
|
|
34425
|
+
}
|
|
34426
|
+
/**
|
|
34427
|
+
* Extract Verification section with **E2E Tests**, **Unit Tests**, **Manual Checks** sub-lists.
|
|
34428
|
+
* Matches the format emitted by formatIntentMd().
|
|
34429
|
+
*/
|
|
34430
|
+
function extractVerification(body) {
|
|
34431
|
+
const section = extractSection(body, 'Verification');
|
|
34432
|
+
if (!section)
|
|
34433
|
+
return {};
|
|
34434
|
+
const result = {};
|
|
34435
|
+
let currentKey = null;
|
|
34436
|
+
for (const line of section.split('\n')) {
|
|
34437
|
+
const trimmed = line.trim();
|
|
34438
|
+
if (/^\*\*E2E Tests?\*?\*?:?/.test(trimmed)) {
|
|
34439
|
+
currentKey = 'e2eTests';
|
|
34440
|
+
result[currentKey] = [];
|
|
34441
|
+
continue;
|
|
34442
|
+
}
|
|
34443
|
+
if (/^\*\*Unit Tests?\*?\*?:?/.test(trimmed)) {
|
|
34444
|
+
currentKey = 'unitTests';
|
|
34445
|
+
result[currentKey] = [];
|
|
34446
|
+
continue;
|
|
34447
|
+
}
|
|
34448
|
+
if (/^\*\*Manual Checks?\*?\*?:?/.test(trimmed)) {
|
|
34449
|
+
currentKey = 'manualChecks';
|
|
34450
|
+
result[currentKey] = [];
|
|
34451
|
+
continue;
|
|
34452
|
+
}
|
|
34453
|
+
if (currentKey && trimmed.match(/^[-*]\s/)) {
|
|
34454
|
+
result[currentKey].push(trimmed.replace(/^[-*]\s+(\[.\]\s+)?/, '').trim());
|
|
34455
|
+
}
|
|
34456
|
+
}
|
|
34457
|
+
return result;
|
|
34458
|
+
}
|
|
34180
34459
|
|
|
34181
34460
|
|
|
34182
34461
|
/***/ }),
|
|
@@ -64047,9 +64326,11 @@ var exports = __webpack_exports__;
|
|
|
64047
64326
|
* Connects Claude Code, Cursor, and other AI agents to your Intent Layer.
|
|
64048
64327
|
*
|
|
64049
64328
|
* Usage:
|
|
64050
|
-
* npx @pathmode/mcp-server
|
|
64051
|
-
* npx @pathmode/mcp-server --local
|
|
64052
|
-
* npx @pathmode/mcp-server setup pm_live_xxx
|
|
64329
|
+
* npx @pathmode/mcp-server # Cloud mode (uses ~/.pathmode/config.json)
|
|
64330
|
+
* npx @pathmode/mcp-server --local # Local mode (reads intent.md from cwd)
|
|
64331
|
+
* npx @pathmode/mcp-server setup pm_live_xxx # Auto-configure your tools
|
|
64332
|
+
* npx @pathmode/mcp-server install-skills # Copy the skill pack into .claude/skills/
|
|
64333
|
+
* npx @pathmode/mcp-server install-skills --global # Install into ~/.claude/skills/ instead
|
|
64053
64334
|
*
|
|
64054
64335
|
* The Intent Compiler (compile-intent prompt, intent_save, intent_export tools)
|
|
64055
64336
|
* works without an API key — zero-config intent spec building in Claude Code.
|
|
@@ -64088,16 +64369,23 @@ const api_client_1 = __nccwpck_require__(7475);
|
|
|
64088
64369
|
const local_reader_1 = __nccwpck_require__(3518);
|
|
64089
64370
|
const intent_compiler_1 = __nccwpck_require__(6488);
|
|
64090
64371
|
const setup_1 = __nccwpck_require__(8294);
|
|
64372
|
+
const install_skills_1 = __nccwpck_require__(3783);
|
|
64091
64373
|
// ─── Subcommand routing ───────────────────────────────────────
|
|
64092
|
-
// `setup`
|
|
64093
|
-
// before StdioServerTransport claims stdout for JSON-RPC.
|
|
64094
|
-
// We call startMcpServer() only when NOT in
|
|
64374
|
+
// Human-readable subcommands (`setup`, `install-skills`) use stdout
|
|
64375
|
+
// and must run before StdioServerTransport claims stdout for JSON-RPC.
|
|
64376
|
+
// We call startMcpServer() only when NOT in a subcommand.
|
|
64095
64377
|
if ((0, setup_1.isSetupCommand)()) {
|
|
64096
64378
|
(0, setup_1.runSetup)().then(() => process.exit(0)).catch((err) => {
|
|
64097
64379
|
console.error(err);
|
|
64098
64380
|
process.exit(1);
|
|
64099
64381
|
});
|
|
64100
64382
|
}
|
|
64383
|
+
else if ((0, install_skills_1.isInstallSkillsCommand)()) {
|
|
64384
|
+
(0, install_skills_1.runInstallSkills)().then(() => process.exit(0)).catch((err) => {
|
|
64385
|
+
console.error(err);
|
|
64386
|
+
process.exit(1);
|
|
64387
|
+
});
|
|
64388
|
+
}
|
|
64101
64389
|
else {
|
|
64102
64390
|
startMcpServer();
|
|
64103
64391
|
}
|
|
@@ -64105,9 +64393,12 @@ function startMcpServer() {
|
|
|
64105
64393
|
// ─── MCP Server ───────────────────────────────────────────────
|
|
64106
64394
|
const isLocalMode = process.argv.includes('--local');
|
|
64107
64395
|
let client = null;
|
|
64396
|
+
const isDebug = process.env.PATHMODE_MCP_DEBUG === '1';
|
|
64108
64397
|
if (!isLocalMode) {
|
|
64109
64398
|
const config = (0, api_client_1.loadConfig)();
|
|
64110
|
-
|
|
64399
|
+
if (isDebug) {
|
|
64400
|
+
console.error(`[pathmode-mcp] API key present: ${!!config?.apiKey}, url: ${config?.apiUrl || 'none'}`);
|
|
64401
|
+
}
|
|
64111
64402
|
if (config) {
|
|
64112
64403
|
client = new api_client_1.PathmodeClient(config);
|
|
64113
64404
|
}
|
|
@@ -64118,38 +64409,74 @@ function startMcpServer() {
|
|
|
64118
64409
|
// ============================================================
|
|
64119
64410
|
const server = new mcp_js_1.McpServer({
|
|
64120
64411
|
name: 'pathmode',
|
|
64121
|
-
version: '1.
|
|
64412
|
+
version: '1.4.5',
|
|
64122
64413
|
});
|
|
64123
64414
|
// Annotation presets
|
|
64124
64415
|
const READ_ONLY = { readOnlyHint: true, openWorldHint: true };
|
|
64125
64416
|
const WRITE_OP = { readOnlyHint: false, destructiveHint: false, openWorldHint: true };
|
|
64417
|
+
// Cloud-mode guard — returns a clean error instead of crashing on client!
|
|
64418
|
+
const CLOUD_REQUIRED_MSG = 'This tool requires a Pathmode API key. Run `npx @pathmode/mcp-server setup pm_live_xxx` to connect, or set the PATHMODE_API_KEY environment variable.';
|
|
64419
|
+
function requireCloudClient() {
|
|
64420
|
+
if (!client)
|
|
64421
|
+
throw new CloudClientError();
|
|
64422
|
+
return client;
|
|
64423
|
+
}
|
|
64424
|
+
class CloudClientError extends Error {
|
|
64425
|
+
constructor() { super(CLOUD_REQUIRED_MSG); this.name = 'CloudClientError'; }
|
|
64426
|
+
}
|
|
64427
|
+
function normalizeText(value) {
|
|
64428
|
+
return (value || '').trim();
|
|
64429
|
+
}
|
|
64430
|
+
// Keep this selection heuristic aligned with the canonical readiness rules in
|
|
64431
|
+
// /Users/jannelammi/code/Pathmode/lib/intentReadiness.ts. The MCP package cannot
|
|
64432
|
+
// import app/lib code directly, so this mirrors only the minimum logic needed
|
|
64433
|
+
// for get_current_intent fallback behavior.
|
|
64434
|
+
function isPlaceholderIntent(intent) {
|
|
64435
|
+
const title = normalizeText(intent.title).toLowerCase();
|
|
64436
|
+
const objective = normalizeText(intent.objective);
|
|
64437
|
+
const outcomeCount = (intent.outcomes || []).filter((outcome) => normalizeText(typeof outcome === 'string' ? outcome : outcome?.text).length > 0).length;
|
|
64438
|
+
return title === 'new intent' || title === 'untitled intent' || objective.length < 15 || outcomeCount === 0;
|
|
64439
|
+
}
|
|
64440
|
+
function pickCurrentIntent(intents) {
|
|
64441
|
+
const approvedReady = intents.find((intent) => intent.status === 'approved' && !isPlaceholderIntent(intent));
|
|
64442
|
+
if (approvedReady)
|
|
64443
|
+
return approvedReady;
|
|
64444
|
+
const anyReady = intents.find((intent) => !isPlaceholderIntent(intent));
|
|
64445
|
+
if (anyReady)
|
|
64446
|
+
return anyReady;
|
|
64447
|
+
return intents[0];
|
|
64448
|
+
}
|
|
64449
|
+
// Note: The MCP SDK catches errors thrown in tool handlers and returns them as
|
|
64450
|
+
// error text results. CloudClientError thrown by requireCloudClient() will
|
|
64451
|
+
// surface its message to the client without crashing the server.
|
|
64126
64452
|
// ============================================================
|
|
64127
64453
|
// Tools — Read Operations
|
|
64128
64454
|
// ============================================================
|
|
64129
64455
|
server.registerTool('get_current_intent', {
|
|
64130
64456
|
title: 'Get Current Intent',
|
|
64131
|
-
description: 'Get the currently active intent
|
|
64457
|
+
description: 'Get the currently active intent, preferring approved intents with real objective/outcome content over empty stubs. Returns the full IntentSpec with objective, outcomes, constraints, and edge cases.',
|
|
64132
64458
|
inputSchema: { status: zod_1.z.string().optional().describe('Filter by status: draft, validated, approved, shipped, verified') },
|
|
64133
64459
|
annotations: READ_ONLY,
|
|
64134
64460
|
}, async ({ status }) => {
|
|
64135
64461
|
if (isLocalMode) {
|
|
64136
64462
|
const intents = (0, local_reader_1.readLocalIntents)();
|
|
64137
64463
|
const filtered = status ? intents.filter(i => i.status === status) : intents;
|
|
64138
|
-
const current = filtered
|
|
64464
|
+
const current = pickCurrentIntent(filtered);
|
|
64139
64465
|
if (!current) {
|
|
64140
64466
|
return { content: [{ type: 'text', text: 'No intents found locally.' }] };
|
|
64141
64467
|
}
|
|
64142
64468
|
return { content: [{ type: 'text', text: JSON.stringify(current, null, 2) }] };
|
|
64143
64469
|
}
|
|
64144
|
-
const
|
|
64470
|
+
const cloud = requireCloudClient();
|
|
64471
|
+
const intents = await cloud.listIntents(status || 'approved');
|
|
64145
64472
|
if (intents.length === 0) {
|
|
64146
|
-
const allIntents = await
|
|
64473
|
+
const allIntents = await cloud.listIntents();
|
|
64147
64474
|
if (allIntents.length === 0) {
|
|
64148
64475
|
return { content: [{ type: 'text', text: 'No intents found in workspace.' }] };
|
|
64149
64476
|
}
|
|
64150
|
-
return { content: [{ type: 'text', text: JSON.stringify(allIntents
|
|
64477
|
+
return { content: [{ type: 'text', text: JSON.stringify(pickCurrentIntent(allIntents), null, 2) }] };
|
|
64151
64478
|
}
|
|
64152
|
-
return { content: [{ type: 'text', text: JSON.stringify(intents
|
|
64479
|
+
return { content: [{ type: 'text', text: JSON.stringify(pickCurrentIntent(intents), null, 2) }] };
|
|
64153
64480
|
});
|
|
64154
64481
|
server.registerTool('list_intents', {
|
|
64155
64482
|
title: 'List Intents',
|
|
@@ -64167,7 +64494,8 @@ function startMcpServer() {
|
|
|
64167
64494
|
}]
|
|
64168
64495
|
};
|
|
64169
64496
|
}
|
|
64170
|
-
const
|
|
64497
|
+
const cloud = requireCloudClient();
|
|
64498
|
+
const intents = await cloud.listIntents(status);
|
|
64171
64499
|
return {
|
|
64172
64500
|
content: [{
|
|
64173
64501
|
type: 'text',
|
|
@@ -64190,7 +64518,7 @@ function startMcpServer() {
|
|
|
64190
64518
|
return { content: [{ type: 'text', text: JSON.stringify(intent, null, 2) }] };
|
|
64191
64519
|
}
|
|
64192
64520
|
try {
|
|
64193
|
-
const intent = await
|
|
64521
|
+
const intent = await requireCloudClient().getIntent(intentId);
|
|
64194
64522
|
return { content: [{ type: 'text', text: JSON.stringify(intent, null, 2) }] };
|
|
64195
64523
|
}
|
|
64196
64524
|
catch (e) {
|
|
@@ -64206,7 +64534,7 @@ function startMcpServer() {
|
|
|
64206
64534
|
if (isLocalMode) {
|
|
64207
64535
|
return { content: [{ type: 'text', text: 'Relations are not available in local mode.' }] };
|
|
64208
64536
|
}
|
|
64209
|
-
const intent = await
|
|
64537
|
+
const intent = await requireCloudClient().getIntent(intentId);
|
|
64210
64538
|
return {
|
|
64211
64539
|
content: [{
|
|
64212
64540
|
type: 'text',
|
|
@@ -64237,7 +64565,7 @@ function startMcpServer() {
|
|
|
64237
64565
|
return { content: [{ type: 'text', text: JSON.stringify({ results: matches, count: matches.length, query }, null, 2) }] };
|
|
64238
64566
|
}
|
|
64239
64567
|
try {
|
|
64240
|
-
const intents = await
|
|
64568
|
+
const intents = await requireCloudClient().listIntents(status);
|
|
64241
64569
|
const q = query.toLowerCase();
|
|
64242
64570
|
const matches = intents.filter(i => {
|
|
64243
64571
|
const text = [i.title, i.objective, ...(i.outcomes || []).map((o) => typeof o === 'string' ? o : o.text), ...(i.constraints || [])].join(' ').toLowerCase();
|
|
@@ -64269,7 +64597,7 @@ function startMcpServer() {
|
|
|
64269
64597
|
return { content: [{ type: 'text', text: 'Graph analysis requires cloud mode.' }] };
|
|
64270
64598
|
}
|
|
64271
64599
|
try {
|
|
64272
|
-
const intents = await
|
|
64600
|
+
const intents = await requireCloudClient().listIntents();
|
|
64273
64601
|
if (intents.length === 0) {
|
|
64274
64602
|
return { content: [{ type: 'text', text: 'No intents found in workspace.' }] };
|
|
64275
64603
|
}
|
|
@@ -64297,7 +64625,7 @@ function startMcpServer() {
|
|
|
64297
64625
|
}
|
|
64298
64626
|
}
|
|
64299
64627
|
}
|
|
64300
|
-
// Detect cycles
|
|
64628
|
+
// Detect cycles (iterative DFS with neighbor iterators)
|
|
64301
64629
|
const WHITE = 0, GRAY = 1, BLACK = 2;
|
|
64302
64630
|
const color = new Map();
|
|
64303
64631
|
const parent = new Map();
|
|
@@ -64307,31 +64635,36 @@ function startMcpServer() {
|
|
|
64307
64635
|
for (const startId of forward.keys()) {
|
|
64308
64636
|
if (color.get(startId) !== WHITE)
|
|
64309
64637
|
continue;
|
|
64310
|
-
|
|
64638
|
+
// Each stack frame: [nodeId, iterator over its neighbors]
|
|
64639
|
+
const stack = [];
|
|
64640
|
+
color.set(startId, GRAY);
|
|
64311
64641
|
parent.set(startId, null);
|
|
64642
|
+
stack.push([startId, (forward.get(startId) || new Set()).values()]);
|
|
64312
64643
|
while (stack.length > 0) {
|
|
64313
|
-
const id = stack[stack.length - 1];
|
|
64314
|
-
|
|
64315
|
-
|
|
64316
|
-
|
|
64317
|
-
|
|
64318
|
-
|
|
64319
|
-
|
|
64320
|
-
|
|
64321
|
-
|
|
64322
|
-
|
|
64323
|
-
|
|
64324
|
-
|
|
64325
|
-
|
|
64326
|
-
|
|
64327
|
-
|
|
64328
|
-
|
|
64329
|
-
cycle.reverse();
|
|
64330
|
-
cycles.push(cycle);
|
|
64644
|
+
const [id, iter] = stack[stack.length - 1];
|
|
64645
|
+
const next = iter.next();
|
|
64646
|
+
if (!next.done) {
|
|
64647
|
+
const dep = next.value;
|
|
64648
|
+
if (color.get(dep) === WHITE) {
|
|
64649
|
+
color.set(dep, GRAY);
|
|
64650
|
+
parent.set(dep, id);
|
|
64651
|
+
stack.push([dep, (forward.get(dep) || new Set()).values()]);
|
|
64652
|
+
}
|
|
64653
|
+
else if (color.get(dep) === GRAY) {
|
|
64654
|
+
// Back edge — extract cycle from parent chain
|
|
64655
|
+
const cycle = [dep];
|
|
64656
|
+
let cur = id;
|
|
64657
|
+
while (cur !== dep) {
|
|
64658
|
+
cycle.push(cur);
|
|
64659
|
+
cur = parent.get(cur);
|
|
64331
64660
|
}
|
|
64661
|
+
cycle.push(dep);
|
|
64662
|
+
cycle.reverse();
|
|
64663
|
+
cycles.push(cycle);
|
|
64332
64664
|
}
|
|
64333
64665
|
}
|
|
64334
64666
|
else {
|
|
64667
|
+
// All neighbors explored — mark finished
|
|
64335
64668
|
color.set(id, BLACK);
|
|
64336
64669
|
stack.pop();
|
|
64337
64670
|
}
|
|
@@ -64453,7 +64786,7 @@ function startMcpServer() {
|
|
|
64453
64786
|
return { content: [{ type: 'text', text: 'Export requires cloud mode. Use PATHMODE_API_KEY to connect.' }] };
|
|
64454
64787
|
}
|
|
64455
64788
|
try {
|
|
64456
|
-
const content = await
|
|
64789
|
+
const content = await requireCloudClient().exportContext(format, intentId, productId);
|
|
64457
64790
|
return { content: [{ type: 'text', text: content }] };
|
|
64458
64791
|
}
|
|
64459
64792
|
catch (e) {
|
|
@@ -64472,7 +64805,7 @@ function startMcpServer() {
|
|
|
64472
64805
|
if (isLocalMode) {
|
|
64473
64806
|
return { content: [{ type: 'text', text: 'Agent prompts require cloud mode for full context generation.' }] };
|
|
64474
64807
|
}
|
|
64475
|
-
const result = await
|
|
64808
|
+
const result = await requireCloudClient().getIntentPrompt(intentId, 'claude-code', mode || 'execute');
|
|
64476
64809
|
return {
|
|
64477
64810
|
content: [{
|
|
64478
64811
|
type: 'text',
|
|
@@ -64488,7 +64821,7 @@ function startMcpServer() {
|
|
|
64488
64821
|
if (isLocalMode) {
|
|
64489
64822
|
return { content: [{ type: 'text', text: 'Workspace details are not available in local mode.' }] };
|
|
64490
64823
|
}
|
|
64491
|
-
const workspace = await
|
|
64824
|
+
const workspace = await requireCloudClient().getWorkspace();
|
|
64492
64825
|
return {
|
|
64493
64826
|
content: [{
|
|
64494
64827
|
type: 'text',
|
|
@@ -64504,7 +64837,7 @@ function startMcpServer() {
|
|
|
64504
64837
|
if (isLocalMode) {
|
|
64505
64838
|
return { content: [{ type: 'text', text: 'Constitution rules are not available in local mode.' }] };
|
|
64506
64839
|
}
|
|
64507
|
-
const result = await
|
|
64840
|
+
const result = await requireCloudClient().getConstitution();
|
|
64508
64841
|
return {
|
|
64509
64842
|
content: [{
|
|
64510
64843
|
type: 'text',
|
|
@@ -64527,7 +64860,7 @@ function startMcpServer() {
|
|
|
64527
64860
|
if (isLocalMode) {
|
|
64528
64861
|
return { content: [{ type: 'text', text: 'Status updates are not available in local mode. Use cloud mode.' }] };
|
|
64529
64862
|
}
|
|
64530
|
-
const result = await
|
|
64863
|
+
const result = await requireCloudClient().updateIntentStatus(intentId, status);
|
|
64531
64864
|
let responseText = `Intent ${intentId} status updated to "${status}".`;
|
|
64532
64865
|
// Surface verification checklist for shipped/verified transitions
|
|
64533
64866
|
if (result.verificationChecklist && result.verificationChecklist.length > 0) {
|
|
@@ -64556,7 +64889,7 @@ function startMcpServer() {
|
|
|
64556
64889
|
if (isLocalMode) {
|
|
64557
64890
|
return { content: [{ type: 'text', text: 'Notes are not available in local mode. Use cloud mode.' }] };
|
|
64558
64891
|
}
|
|
64559
|
-
const result = await
|
|
64892
|
+
const result = await requireCloudClient().logNote(intentId, note, 'mcp');
|
|
64560
64893
|
return {
|
|
64561
64894
|
content: [{
|
|
64562
64895
|
type: 'text',
|
|
@@ -64590,7 +64923,7 @@ function startMcpServer() {
|
|
|
64590
64923
|
if (isLocalMode) {
|
|
64591
64924
|
return { content: [{ type: 'text', text: 'Creating intents requires cloud mode. Use PATHMODE_API_KEY to connect.' }] };
|
|
64592
64925
|
}
|
|
64593
|
-
const result = await
|
|
64926
|
+
const result = await requireCloudClient().createIntent({ productId, ...rest });
|
|
64594
64927
|
return {
|
|
64595
64928
|
content: [{
|
|
64596
64929
|
type: 'text',
|
|
@@ -64624,7 +64957,7 @@ function startMcpServer() {
|
|
|
64624
64957
|
if (isLocalMode) {
|
|
64625
64958
|
return { content: [{ type: 'text', text: 'Updating intents requires cloud mode.' }] };
|
|
64626
64959
|
}
|
|
64627
|
-
const result = await
|
|
64960
|
+
const result = await requireCloudClient().updateIntent(intentId, updates);
|
|
64628
64961
|
const changedFields = Object.keys(updates).filter(k => updates[k] !== undefined);
|
|
64629
64962
|
return {
|
|
64630
64963
|
content: [{
|
|
@@ -64649,7 +64982,7 @@ function startMcpServer() {
|
|
|
64649
64982
|
if (isLocalMode) {
|
|
64650
64983
|
return { content: [{ type: 'text', text: 'Evidence queries require cloud mode.' }] };
|
|
64651
64984
|
}
|
|
64652
|
-
const result = await
|
|
64985
|
+
const result = await requireCloudClient().queryEvidence(filters);
|
|
64653
64986
|
return {
|
|
64654
64987
|
content: [{
|
|
64655
64988
|
type: 'text',
|
|
@@ -64669,14 +65002,14 @@ function startMcpServer() {
|
|
|
64669
65002
|
severity: zod_1.z.enum(['low', 'medium', 'high', 'critical']).optional().describe('Severity level (required for friction type)'),
|
|
64670
65003
|
sentiment: zod_1.z.enum(['positive', 'negative', 'neutral', 'mixed']).optional().describe('Emotional sentiment'),
|
|
64671
65004
|
tags: zod_1.z.array(zod_1.z.string()).optional().describe('Category tags (e.g., ["Onboarding", "Performance"])'),
|
|
64672
|
-
stage: zod_1.z.string().optional().describe('
|
|
65005
|
+
stage: zod_1.z.string().optional().describe('Workflow stage (e.g., "Discovery", "Checkout")'),
|
|
64673
65006
|
},
|
|
64674
65007
|
annotations: WRITE_OP,
|
|
64675
65008
|
}, async ({ productId, ...rest }) => {
|
|
64676
65009
|
if (isLocalMode) {
|
|
64677
65010
|
return { content: [{ type: 'text', text: 'Creating evidence requires cloud mode.' }] };
|
|
64678
65011
|
}
|
|
64679
|
-
const result = await
|
|
65012
|
+
const result = await requireCloudClient().createEvidence({ productId, ...rest });
|
|
64680
65013
|
return {
|
|
64681
65014
|
content: [{
|
|
64682
65015
|
type: 'text',
|
|
@@ -64697,7 +65030,7 @@ function startMcpServer() {
|
|
|
64697
65030
|
if (isLocalMode) {
|
|
64698
65031
|
return { content: [{ type: 'text', text: 'Evidence linking requires cloud mode.' }] };
|
|
64699
65032
|
}
|
|
64700
|
-
const result = await
|
|
65033
|
+
const result = await requireCloudClient().linkEvidence(intentId, { link, unlink });
|
|
64701
65034
|
const actions = [];
|
|
64702
65035
|
if (link && link.length > 0)
|
|
64703
65036
|
actions.push(`linked ${result.linked} evidence items`);
|
|
@@ -64724,7 +65057,7 @@ function startMcpServer() {
|
|
|
64724
65057
|
return { content: [{ type: 'text', text: 'Verification requires cloud mode.' }] };
|
|
64725
65058
|
}
|
|
64726
65059
|
try {
|
|
64727
|
-
const result = await
|
|
65060
|
+
const result = await requireCloudClient().verifyImplementation(intentId, summary, codeChanges);
|
|
64728
65061
|
let text = `Verification ${result.pass ? 'PASSED' : 'FAILED'} (score: ${result.score}/100)\n\n`;
|
|
64729
65062
|
text += `${result.summary}\n\n`;
|
|
64730
65063
|
for (const r of result.results) {
|
|
@@ -64801,6 +65134,10 @@ function startMcpServer() {
|
|
|
64801
65134
|
expectedBehavior: zod_1.z.string(),
|
|
64802
65135
|
})).optional().describe('Failure modes and boundary conditions'),
|
|
64803
65136
|
healthMetrics: zod_1.z.array(zod_1.z.string()).optional().describe('What to monitor after shipping'),
|
|
65137
|
+
scope: zod_1.z.object({
|
|
65138
|
+
inScope: zod_1.z.array(zod_1.z.string()).optional().describe('What is in scope for this intent'),
|
|
65139
|
+
outOfScope: zod_1.z.array(zod_1.z.string()).optional().describe('What is explicitly out of scope'),
|
|
65140
|
+
}).optional().describe('Scope boundaries — what to build and what to avoid'),
|
|
64804
65141
|
verification: zod_1.z.object({
|
|
64805
65142
|
manualChecks: zod_1.z.array(zod_1.z.string()).optional(),
|
|
64806
65143
|
unitTests: zod_1.z.array(zod_1.z.string()).optional(),
|
|
@@ -64884,15 +65221,27 @@ function startMcpServer() {
|
|
|
64884
65221
|
}]
|
|
64885
65222
|
};
|
|
64886
65223
|
}
|
|
64887
|
-
|
|
64888
|
-
|
|
64889
|
-
|
|
64890
|
-
|
|
64891
|
-
|
|
64892
|
-
|
|
64893
|
-
|
|
64894
|
-
|
|
64895
|
-
|
|
65224
|
+
try {
|
|
65225
|
+
const cloud = requireCloudClient();
|
|
65226
|
+
const intents = await cloud.listIntents('approved');
|
|
65227
|
+
const current = intents[0] || (await cloud.listIntents())[0] || null;
|
|
65228
|
+
return {
|
|
65229
|
+
contents: [{
|
|
65230
|
+
uri: uri.href,
|
|
65231
|
+
mimeType: 'application/json',
|
|
65232
|
+
text: JSON.stringify(current, null, 2),
|
|
65233
|
+
}]
|
|
65234
|
+
};
|
|
65235
|
+
}
|
|
65236
|
+
catch {
|
|
65237
|
+
return {
|
|
65238
|
+
contents: [{
|
|
65239
|
+
uri: uri.href,
|
|
65240
|
+
mimeType: 'application/json',
|
|
65241
|
+
text: JSON.stringify({ error: CLOUD_REQUIRED_MSG }),
|
|
65242
|
+
}]
|
|
65243
|
+
};
|
|
65244
|
+
}
|
|
64896
65245
|
});
|
|
64897
65246
|
server.resource('intent://graph', 'intent://graph', async (uri) => {
|
|
64898
65247
|
if (isLocalMode) {
|
|
@@ -64904,20 +65253,31 @@ function startMcpServer() {
|
|
|
64904
65253
|
}]
|
|
64905
65254
|
};
|
|
64906
65255
|
}
|
|
64907
|
-
|
|
64908
|
-
|
|
64909
|
-
|
|
64910
|
-
|
|
64911
|
-
|
|
64912
|
-
|
|
64913
|
-
|
|
64914
|
-
|
|
64915
|
-
|
|
64916
|
-
|
|
64917
|
-
|
|
64918
|
-
|
|
64919
|
-
|
|
64920
|
-
|
|
65256
|
+
try {
|
|
65257
|
+
const intents = await requireCloudClient().listIntents();
|
|
65258
|
+
const graph = intents.map(i => ({
|
|
65259
|
+
id: i.id,
|
|
65260
|
+
title: i.title,
|
|
65261
|
+
status: i.status,
|
|
65262
|
+
relations: i.relations,
|
|
65263
|
+
}));
|
|
65264
|
+
return {
|
|
65265
|
+
contents: [{
|
|
65266
|
+
uri: uri.href,
|
|
65267
|
+
mimeType: 'application/json',
|
|
65268
|
+
text: JSON.stringify(graph, null, 2),
|
|
65269
|
+
}]
|
|
65270
|
+
};
|
|
65271
|
+
}
|
|
65272
|
+
catch {
|
|
65273
|
+
return {
|
|
65274
|
+
contents: [{
|
|
65275
|
+
uri: uri.href,
|
|
65276
|
+
mimeType: 'application/json',
|
|
65277
|
+
text: JSON.stringify({ error: CLOUD_REQUIRED_MSG }),
|
|
65278
|
+
}]
|
|
65279
|
+
};
|
|
65280
|
+
}
|
|
64921
65281
|
});
|
|
64922
65282
|
server.resource('intent://workspace-strategy', 'intent://workspace-strategy', async (uri) => {
|
|
64923
65283
|
if (isLocalMode) {
|
|
@@ -64930,7 +65290,7 @@ function startMcpServer() {
|
|
|
64930
65290
|
};
|
|
64931
65291
|
}
|
|
64932
65292
|
try {
|
|
64933
|
-
const workspace = await
|
|
65293
|
+
const workspace = await requireCloudClient().getWorkspace();
|
|
64934
65294
|
return {
|
|
64935
65295
|
contents: [{
|
|
64936
65296
|
uri: uri.href,
|