@pathmode/mcp-server 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +2 -2
- package/dist/api-client.d.ts +13 -3
- package/dist/api-client.d.ts.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +407 -24
- package/dist/intent-compiler.d.ts +48 -0
- package/dist/intent-compiler.d.ts.map +1 -0
- package/dist/local-reader.d.ts +1 -1
- package/dist/local-reader.d.ts.map +1 -1
- package/icon.svg +7 -0
- package/manifest.json +10 -8
- package/package.json +5 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pathmode Oy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -236,8 +236,8 @@ This MCP server connects to the Pathmode API (`pathmode.io`) to read and write i
|
|
|
236
236
|
|
|
237
237
|
## Support
|
|
238
238
|
|
|
239
|
-
- Issues: [github.com/
|
|
240
|
-
- Documentation: [
|
|
239
|
+
- Issues: [github.com/pathmodeio/mcp-server/issues](https://github.com/pathmodeio/mcp-server/issues)
|
|
240
|
+
- Documentation: [github.com/pathmodeio/mcp-server](https://github.com/pathmodeio/mcp-server#readme)
|
|
241
241
|
|
|
242
242
|
## License
|
|
243
243
|
|
package/dist/api-client.d.ts
CHANGED
|
@@ -17,12 +17,11 @@ export interface ApiIntent {
|
|
|
17
17
|
version: number;
|
|
18
18
|
objective: string;
|
|
19
19
|
problemSeverity?: string;
|
|
20
|
-
|
|
20
|
+
title: string;
|
|
21
21
|
outcomes: string[];
|
|
22
22
|
healthMetrics: string[];
|
|
23
23
|
strategicAlignment?: string;
|
|
24
24
|
alignmentNotes?: string;
|
|
25
|
-
preconditions: Record<string, any>;
|
|
26
25
|
context: Record<string, any>;
|
|
27
26
|
constraints: string[];
|
|
28
27
|
verification: Record<string, any>;
|
|
@@ -74,7 +73,18 @@ export declare class PathmodeClient {
|
|
|
74
73
|
prompt: string;
|
|
75
74
|
json: object;
|
|
76
75
|
}>;
|
|
77
|
-
updateIntentStatus(id: string, status: string): Promise<
|
|
76
|
+
updateIntentStatus(id: string, status: string): Promise<{
|
|
77
|
+
id: string;
|
|
78
|
+
status: string;
|
|
79
|
+
updatedAt: string;
|
|
80
|
+
shippedAt?: string;
|
|
81
|
+
verifiedAt?: string;
|
|
82
|
+
verificationChecklist?: {
|
|
83
|
+
text: string;
|
|
84
|
+
category: string;
|
|
85
|
+
}[];
|
|
86
|
+
verificationChecklistCount?: number;
|
|
87
|
+
}>;
|
|
78
88
|
logNote(intentId: string, note: string, source?: string): Promise<any>;
|
|
79
89
|
getWorkspace(): Promise<ApiWorkspace>;
|
|
80
90
|
getConstitution(): Promise<any>;
|
package/dist/api-client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/api-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,cAAc;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,SAAS;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,
|
|
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.d.ts
CHANGED
|
@@ -6,13 +6,15 @@
|
|
|
6
6
|
* npx @pathmode/mcp-server # Cloud mode (uses ~/.pathmode/config.json)
|
|
7
7
|
* npx @pathmode/mcp-server --local # Local mode (reads intent.md from cwd)
|
|
8
8
|
*
|
|
9
|
+
* The Intent Compiler (compile-intent prompt, intent_save, intent_export tools)
|
|
10
|
+
* works without an API key — zero-config intent spec building in Claude Code.
|
|
11
|
+
*
|
|
9
12
|
* Add to .claude/settings.json:
|
|
10
13
|
* {
|
|
11
14
|
* "mcpServers": {
|
|
12
15
|
* "pathmode": {
|
|
13
16
|
* "command": "npx",
|
|
14
|
-
* "args": ["@pathmode/mcp-server"]
|
|
15
|
-
* "env": { "PATHMODE_API_KEY": "pm_live_..." }
|
|
17
|
+
* "args": ["@pathmode/mcp-server"]
|
|
16
18
|
* }
|
|
17
19
|
* }
|
|
18
20
|
* }
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/index.ts"],"names":[],"mappings":"AACA
|
|
1
|
+
{"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/index.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;GAoBG"}
|
package/dist/index.js
CHANGED
|
@@ -11468,6 +11468,297 @@ class PathmodeClient {
|
|
|
11468
11468
|
exports.PathmodeClient = PathmodeClient;
|
|
11469
11469
|
|
|
11470
11470
|
|
|
11471
|
+
/***/ }),
|
|
11472
|
+
|
|
11473
|
+
/***/ 6488:
|
|
11474
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
11475
|
+
|
|
11476
|
+
"use strict";
|
|
11477
|
+
|
|
11478
|
+
/**
|
|
11479
|
+
* Intent Compiler — Zero-config intent spec builder for Claude Code.
|
|
11480
|
+
*
|
|
11481
|
+
* Provides:
|
|
11482
|
+
* 1. A Socratic conversation prompt that turns Claude into a product thinking partner
|
|
11483
|
+
* 2. Format generators for intent.md, .cursorrules, and CLAUDE.md
|
|
11484
|
+
*
|
|
11485
|
+
* Architecture: Claude Code IS the conversation engine. This module only provides
|
|
11486
|
+
* the personality prompt and file format generators. No AI API calls happen here.
|
|
11487
|
+
*/
|
|
11488
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
11489
|
+
exports.getCompileIntentPrompt = getCompileIntentPrompt;
|
|
11490
|
+
exports.formatIntentMd = formatIntentMd;
|
|
11491
|
+
exports.formatCursorRules = formatCursorRules;
|
|
11492
|
+
exports.formatClaudeMdSection = formatClaudeMdSection;
|
|
11493
|
+
// ============================================================
|
|
11494
|
+
// Compile Intent Prompt
|
|
11495
|
+
// ============================================================
|
|
11496
|
+
/**
|
|
11497
|
+
* Returns the system prompt that turns Claude into a Socratic intent interviewer.
|
|
11498
|
+
* Adapted from intentDesignerMachine.ts conversationFirstPreamble for terminal use.
|
|
11499
|
+
*/
|
|
11500
|
+
function getCompileIntentPrompt() {
|
|
11501
|
+
return `You are a sharp product thinking partner. Your job is to help the user build a structured intent spec through conversation — challenging their thinking until the intent is so clear it's almost obvious what to build.
|
|
11502
|
+
|
|
11503
|
+
RULES:
|
|
11504
|
+
- Push back on vague language. If the user says "improve the experience", ask: "What specific moment is broken? What would the user see differently?"
|
|
11505
|
+
- Ask ONE pointed question at a time. Never list 3 questions.
|
|
11506
|
+
- When the user gives a clear answer, propose how you'd write that as a spec field. Explain WHY you worded it that way.
|
|
11507
|
+
- Look for inconsistencies between what they say the problem is and what outcomes they propose.
|
|
11508
|
+
- Be direct and concise. No pleasantries. No "Great question!" or "That's a good point!"
|
|
11509
|
+
- When the spec has existing content, critique it before adding more. Quality over quantity.
|
|
11510
|
+
|
|
11511
|
+
VOICE:
|
|
11512
|
+
- Short sentences. Direct. Like a smart colleague, not a consultant.
|
|
11513
|
+
- Use concrete examples when challenging: "When you say 'faster', do you mean 2 seconds or 20 seconds?"
|
|
11514
|
+
- When you write spec fields, use precise language. No filler words.
|
|
11515
|
+
|
|
11516
|
+
CONVERSATION FLOW (guidance, not rigid steps):
|
|
11517
|
+
1. **Problem** — What's broken? What's the pain? What happens today that shouldn't?
|
|
11518
|
+
2. **Goal** — What specific user outcome would solve this? Make it concrete and singular.
|
|
11519
|
+
3. **Outcomes** — Observable, testable state changes. Not activities, not implementations.
|
|
11520
|
+
4. **Edge Cases** — What's the most embarrassing way this could fail in a demo?
|
|
11521
|
+
5. **Review** — Play devil's advocate. What's missing? What would you cut?
|
|
11522
|
+
|
|
11523
|
+
You are NOT bound by this order. Follow the user's thinking wherever it goes. If they start with edge cases, work backwards to the objective.
|
|
11524
|
+
|
|
11525
|
+
BUILDING THE SPEC:
|
|
11526
|
+
As the conversation progresses, keep a mental model of the spec fields:
|
|
11527
|
+
- **Title**: Short name for the intent (what is this?)
|
|
11528
|
+
- **Objective**: Why this matters — the problem and who has it
|
|
11529
|
+
- **Outcomes**: 2-5 observable, testable results (not activities)
|
|
11530
|
+
- **Constraints**: Hard limits the implementation must respect
|
|
11531
|
+
- **Edge Cases**: Scenario + expected behavior pairs
|
|
11532
|
+
- **Health Metrics**: What to monitor after shipping (optional)
|
|
11533
|
+
- **Verification**: How to confirm it actually works (optional)
|
|
11534
|
+
|
|
11535
|
+
When you have enough clarity on ANY field, state it clearly:
|
|
11536
|
+
> **Proposed Objective**: "Reduce failed deliveries in multi-unit buildings from 23% to under 5% by fixing address resolution at the driver app level."
|
|
11537
|
+
|
|
11538
|
+
Then ask if that captures it or needs refinement.
|
|
11539
|
+
|
|
11540
|
+
WHEN THE SPEC FEELS READY:
|
|
11541
|
+
Once you have at minimum a title, objective, and 2+ outcomes:
|
|
11542
|
+
1. Present the full spec as a summary for the user to review
|
|
11543
|
+
2. Ask if they want to save it
|
|
11544
|
+
3. When confirmed, call the \`intent_save\` tool with the complete spec
|
|
11545
|
+
4. Ask if they also want to export it as \`.cursorrules\` or \`CLAUDE.md\` for AI agent consumption — if yes, call \`intent_export\`
|
|
11546
|
+
5. Mention: "For dependency tracking, team collaboration, and governance, connect this to Pathmode at pathmode.io"
|
|
11547
|
+
|
|
11548
|
+
IMPORTANT:
|
|
11549
|
+
- The spec fields in \`intent_save\` must use this exact structure:
|
|
11550
|
+
- title: string
|
|
11551
|
+
- objective: string
|
|
11552
|
+
- outcomes: string[] (list of outcome statements)
|
|
11553
|
+
- constraints: string[] (optional)
|
|
11554
|
+
- edgeCases: { scenario: string, expectedBehavior: string }[] (optional)
|
|
11555
|
+
- healthMetrics: string[] (optional)
|
|
11556
|
+
- verification: { manualChecks?: string[], unitTests?: string[], e2eTests?: string[] } (optional)
|
|
11557
|
+
|
|
11558
|
+
Now, ask the user what they're working on. If they've already described something, dig into it.`;
|
|
11559
|
+
}
|
|
11560
|
+
// ============================================================
|
|
11561
|
+
// Format: intent.md
|
|
11562
|
+
// ============================================================
|
|
11563
|
+
/**
|
|
11564
|
+
* Generate intent.md content with YAML frontmatter.
|
|
11565
|
+
* Adapted from lib/agentPromptGenerator.ts generateIntentMd().
|
|
11566
|
+
*/
|
|
11567
|
+
function formatIntentMd(spec) {
|
|
11568
|
+
const now = new Date().toISOString();
|
|
11569
|
+
const frontmatter = {
|
|
11570
|
+
id: spec.id || `intent_${Date.now()}`,
|
|
11571
|
+
version: 1,
|
|
11572
|
+
status: 'draft',
|
|
11573
|
+
created: now,
|
|
11574
|
+
updated: now,
|
|
11575
|
+
};
|
|
11576
|
+
const yamlLines = Object.entries(frontmatter)
|
|
11577
|
+
.map(([key, value]) => `${key}: ${typeof value === 'string' ? `"${value}"` : value}`)
|
|
11578
|
+
.join('\n');
|
|
11579
|
+
const sections = [];
|
|
11580
|
+
sections.push('---');
|
|
11581
|
+
sections.push(yamlLines);
|
|
11582
|
+
sections.push('---');
|
|
11583
|
+
sections.push('');
|
|
11584
|
+
sections.push(`# ${spec.title || 'Untitled Intent'}`);
|
|
11585
|
+
if (spec.objective) {
|
|
11586
|
+
sections.push('');
|
|
11587
|
+
sections.push('## Objective');
|
|
11588
|
+
sections.push(spec.objective);
|
|
11589
|
+
}
|
|
11590
|
+
if (spec.outcomes?.length) {
|
|
11591
|
+
sections.push('');
|
|
11592
|
+
sections.push('## Outcomes');
|
|
11593
|
+
for (const outcome of spec.outcomes) {
|
|
11594
|
+
sections.push(`- [ ] ${outcome}`);
|
|
11595
|
+
}
|
|
11596
|
+
}
|
|
11597
|
+
if (spec.constraints?.length) {
|
|
11598
|
+
sections.push('');
|
|
11599
|
+
sections.push('## Constraints');
|
|
11600
|
+
for (const constraint of spec.constraints) {
|
|
11601
|
+
sections.push(`- ${constraint}`);
|
|
11602
|
+
}
|
|
11603
|
+
}
|
|
11604
|
+
if (spec.edgeCases?.length) {
|
|
11605
|
+
sections.push('');
|
|
11606
|
+
sections.push('## Edge Cases');
|
|
11607
|
+
for (const ec of spec.edgeCases) {
|
|
11608
|
+
sections.push(`- **${ec.scenario}**: ${ec.expectedBehavior}`);
|
|
11609
|
+
}
|
|
11610
|
+
}
|
|
11611
|
+
if (spec.healthMetrics?.length) {
|
|
11612
|
+
sections.push('');
|
|
11613
|
+
sections.push('## Health Metrics');
|
|
11614
|
+
for (const metric of spec.healthMetrics) {
|
|
11615
|
+
sections.push(`- ${metric}`);
|
|
11616
|
+
}
|
|
11617
|
+
}
|
|
11618
|
+
if (spec.verification) {
|
|
11619
|
+
const { e2eTests, unitTests, manualChecks } = spec.verification;
|
|
11620
|
+
const hasContent = e2eTests?.length || unitTests?.length || manualChecks?.length;
|
|
11621
|
+
if (hasContent) {
|
|
11622
|
+
sections.push('');
|
|
11623
|
+
sections.push('## Verification');
|
|
11624
|
+
if (e2eTests?.length) {
|
|
11625
|
+
sections.push('**E2E Tests**:');
|
|
11626
|
+
for (const t of e2eTests)
|
|
11627
|
+
sections.push(`- [ ] ${t}`);
|
|
11628
|
+
}
|
|
11629
|
+
if (unitTests?.length) {
|
|
11630
|
+
sections.push('**Unit Tests**:');
|
|
11631
|
+
for (const t of unitTests)
|
|
11632
|
+
sections.push(`- [ ] ${t}`);
|
|
11633
|
+
}
|
|
11634
|
+
if (manualChecks?.length) {
|
|
11635
|
+
sections.push('**Manual Checks**:');
|
|
11636
|
+
for (const t of manualChecks)
|
|
11637
|
+
sections.push(`- [ ] ${t}`);
|
|
11638
|
+
}
|
|
11639
|
+
}
|
|
11640
|
+
}
|
|
11641
|
+
sections.push('');
|
|
11642
|
+
return sections.join('\n');
|
|
11643
|
+
}
|
|
11644
|
+
// ============================================================
|
|
11645
|
+
// Format: .cursorrules
|
|
11646
|
+
// ============================================================
|
|
11647
|
+
/**
|
|
11648
|
+
* Generate .cursorrules content for a single intent.
|
|
11649
|
+
* Adapted from lib/agentPromptGenerator.ts generateCursorRules().
|
|
11650
|
+
*/
|
|
11651
|
+
function formatCursorRules(spec) {
|
|
11652
|
+
const sections = [];
|
|
11653
|
+
sections.push('# Pathmode Intent Rules');
|
|
11654
|
+
sections.push(`# Generated at ${new Date().toISOString()}`);
|
|
11655
|
+
sections.push('# Regenerate with: intentspec pull (or use Pathmode MCP compile-intent prompt)');
|
|
11656
|
+
// Current objective
|
|
11657
|
+
sections.push('');
|
|
11658
|
+
sections.push('# CURRENT OBJECTIVE');
|
|
11659
|
+
sections.push(`You are implementing: "${spec.title || 'Untitled Feature'}"`);
|
|
11660
|
+
if (spec.objective) {
|
|
11661
|
+
sections.push('');
|
|
11662
|
+
sections.push('# WHY');
|
|
11663
|
+
sections.push(spec.objective);
|
|
11664
|
+
}
|
|
11665
|
+
if (spec.outcomes?.length) {
|
|
11666
|
+
sections.push('');
|
|
11667
|
+
sections.push('# SUCCESS OUTCOMES');
|
|
11668
|
+
sections.push('Your implementation MUST satisfy ALL of these:');
|
|
11669
|
+
for (const outcome of spec.outcomes) {
|
|
11670
|
+
sections.push(`- ${outcome}`);
|
|
11671
|
+
}
|
|
11672
|
+
}
|
|
11673
|
+
if (spec.constraints?.length) {
|
|
11674
|
+
sections.push('');
|
|
11675
|
+
sections.push('# CONSTRAINTS');
|
|
11676
|
+
sections.push('These are mandatory rules. You MUST NOT violate them:');
|
|
11677
|
+
for (const constraint of spec.constraints) {
|
|
11678
|
+
sections.push(`- ${constraint}`);
|
|
11679
|
+
}
|
|
11680
|
+
}
|
|
11681
|
+
if (spec.edgeCases?.length) {
|
|
11682
|
+
sections.push('');
|
|
11683
|
+
sections.push('# EDGE CASES');
|
|
11684
|
+
sections.push('Handle these scenarios:');
|
|
11685
|
+
for (const ec of spec.edgeCases) {
|
|
11686
|
+
sections.push(`- ${ec.scenario} → ${ec.expectedBehavior}`);
|
|
11687
|
+
}
|
|
11688
|
+
}
|
|
11689
|
+
if (spec.healthMetrics?.length) {
|
|
11690
|
+
sections.push('');
|
|
11691
|
+
sections.push('# HEALTH METRICS');
|
|
11692
|
+
sections.push('Monitor these after shipping:');
|
|
11693
|
+
for (const metric of spec.healthMetrics) {
|
|
11694
|
+
sections.push(`- ${metric}`);
|
|
11695
|
+
}
|
|
11696
|
+
}
|
|
11697
|
+
if (spec.verification) {
|
|
11698
|
+
const { e2eTests, unitTests, manualChecks } = spec.verification;
|
|
11699
|
+
const hasContent = e2eTests?.length || unitTests?.length || manualChecks?.length;
|
|
11700
|
+
if (hasContent) {
|
|
11701
|
+
sections.push('');
|
|
11702
|
+
sections.push('# VERIFICATION');
|
|
11703
|
+
sections.push('After implementation, verify:');
|
|
11704
|
+
if (e2eTests?.length) {
|
|
11705
|
+
for (const t of e2eTests)
|
|
11706
|
+
sections.push(`- [e2e] ${t}`);
|
|
11707
|
+
}
|
|
11708
|
+
if (unitTests?.length) {
|
|
11709
|
+
for (const t of unitTests)
|
|
11710
|
+
sections.push(`- [unit] ${t}`);
|
|
11711
|
+
}
|
|
11712
|
+
if (manualChecks?.length) {
|
|
11713
|
+
for (const t of manualChecks)
|
|
11714
|
+
sections.push(`- [manual] ${t}`);
|
|
11715
|
+
}
|
|
11716
|
+
}
|
|
11717
|
+
}
|
|
11718
|
+
sections.push('');
|
|
11719
|
+
return sections.join('\n');
|
|
11720
|
+
}
|
|
11721
|
+
// ============================================================
|
|
11722
|
+
// Format: CLAUDE.md section
|
|
11723
|
+
// ============================================================
|
|
11724
|
+
/**
|
|
11725
|
+
* Generate a CLAUDE.md section wrapped in PATHMODE markers.
|
|
11726
|
+
* Can be appended to an existing CLAUDE.md or used standalone.
|
|
11727
|
+
* Adapted from lib/agentPromptGenerator.ts generateClaudeMdContent().
|
|
11728
|
+
*/
|
|
11729
|
+
function formatClaudeMdSection(spec) {
|
|
11730
|
+
const sections = [];
|
|
11731
|
+
sections.push('<!-- PATHMODE:START - Do not edit this section manually -->');
|
|
11732
|
+
sections.push('# Pathmode Intent Context');
|
|
11733
|
+
sections.push(`_Generated at ${new Date().toISOString()} | [pathmode.io](https://pathmode.io)_`);
|
|
11734
|
+
sections.push('');
|
|
11735
|
+
sections.push('## Active Intent');
|
|
11736
|
+
sections.push(`### ${spec.title || 'Untitled Intent'}`);
|
|
11737
|
+
sections.push(`**Status**: draft`);
|
|
11738
|
+
if (spec.objective) {
|
|
11739
|
+
sections.push(`**Objective**: ${spec.objective}`);
|
|
11740
|
+
}
|
|
11741
|
+
if (spec.outcomes?.length) {
|
|
11742
|
+
sections.push('**Outcomes**:');
|
|
11743
|
+
sections.push(spec.outcomes.map(o => `- [ ] ${o}`).join('\n'));
|
|
11744
|
+
}
|
|
11745
|
+
if (spec.constraints?.length) {
|
|
11746
|
+
sections.push('**Constraints**:');
|
|
11747
|
+
sections.push(spec.constraints.map(c => `- ${c}`).join('\n'));
|
|
11748
|
+
}
|
|
11749
|
+
if (spec.edgeCases?.length) {
|
|
11750
|
+
sections.push('**Edge Cases**:');
|
|
11751
|
+
sections.push(spec.edgeCases.map(ec => `- **${ec.scenario}**: ${ec.expectedBehavior}`).join('\n'));
|
|
11752
|
+
}
|
|
11753
|
+
if (spec.healthMetrics?.length) {
|
|
11754
|
+
sections.push('**Health Metrics**:');
|
|
11755
|
+
sections.push(spec.healthMetrics.map(m => `- ${m}`).join('\n'));
|
|
11756
|
+
}
|
|
11757
|
+
sections.push('<!-- PATHMODE:END -->');
|
|
11758
|
+
return sections.join('\n\n');
|
|
11759
|
+
}
|
|
11760
|
+
|
|
11761
|
+
|
|
11471
11762
|
/***/ }),
|
|
11472
11763
|
|
|
11473
11764
|
/***/ 3518:
|
|
@@ -11528,7 +11819,7 @@ function readIntentFile(filePath) {
|
|
|
11528
11819
|
status: data.status || 'draft',
|
|
11529
11820
|
version: data.version || 1,
|
|
11530
11821
|
objective: data.objective || extractSection(body, 'Objective') || '',
|
|
11531
|
-
|
|
11822
|
+
title: data.title || data.userGoal || extractTitle(body) || 'Untitled Intent',
|
|
11532
11823
|
stageName: data.stage || undefined,
|
|
11533
11824
|
severity: data.severity || undefined,
|
|
11534
11825
|
outcomes,
|
|
@@ -39392,13 +39683,15 @@ var exports = __webpack_exports__;
|
|
|
39392
39683
|
* npx @pathmode/mcp-server # Cloud mode (uses ~/.pathmode/config.json)
|
|
39393
39684
|
* npx @pathmode/mcp-server --local # Local mode (reads intent.md from cwd)
|
|
39394
39685
|
*
|
|
39686
|
+
* The Intent Compiler (compile-intent prompt, intent_save, intent_export tools)
|
|
39687
|
+
* works without an API key — zero-config intent spec building in Claude Code.
|
|
39688
|
+
*
|
|
39395
39689
|
* Add to .claude/settings.json:
|
|
39396
39690
|
* {
|
|
39397
39691
|
* "mcpServers": {
|
|
39398
39692
|
* "pathmode": {
|
|
39399
39693
|
* "command": "npx",
|
|
39400
|
-
* "args": ["@pathmode/mcp-server"]
|
|
39401
|
-
* "env": { "PATHMODE_API_KEY": "pm_live_..." }
|
|
39694
|
+
* "args": ["@pathmode/mcp-server"]
|
|
39402
39695
|
* }
|
|
39403
39696
|
* }
|
|
39404
39697
|
* }
|
|
@@ -39407,27 +39700,26 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
|
39407
39700
|
const mcp_js_1 = __nccwpck_require__(3886);
|
|
39408
39701
|
const stdio_js_1 = __nccwpck_require__(4239);
|
|
39409
39702
|
const zod_1 = __nccwpck_require__(924);
|
|
39703
|
+
const path_1 = __nccwpck_require__(6928);
|
|
39704
|
+
const fs_1 = __nccwpck_require__(9896);
|
|
39410
39705
|
const api_client_1 = __nccwpck_require__(7475);
|
|
39411
39706
|
const local_reader_1 = __nccwpck_require__(3518);
|
|
39707
|
+
const intent_compiler_1 = __nccwpck_require__(6488);
|
|
39412
39708
|
const isLocalMode = process.argv.includes('--local');
|
|
39413
39709
|
let client = null;
|
|
39414
39710
|
if (!isLocalMode) {
|
|
39415
39711
|
const config = (0, api_client_1.loadConfig)();
|
|
39416
|
-
if (
|
|
39417
|
-
|
|
39418
|
-
' 1. Run `intentspec login` to configure\n' +
|
|
39419
|
-
' 2. Set PATHMODE_API_KEY environment variable\n' +
|
|
39420
|
-
' 3. Use --local flag for offline mode');
|
|
39421
|
-
process.exit(1);
|
|
39712
|
+
if (config) {
|
|
39713
|
+
client = new api_client_1.PathmodeClient(config);
|
|
39422
39714
|
}
|
|
39423
|
-
|
|
39715
|
+
// No exit — Intent Compiler tools work without an API key
|
|
39424
39716
|
}
|
|
39425
39717
|
// ============================================================
|
|
39426
39718
|
// Server Setup
|
|
39427
39719
|
// ============================================================
|
|
39428
39720
|
const server = new mcp_js_1.McpServer({
|
|
39429
39721
|
name: 'pathmode',
|
|
39430
|
-
version: '1.
|
|
39722
|
+
version: '1.2.0',
|
|
39431
39723
|
});
|
|
39432
39724
|
// Annotation presets
|
|
39433
39725
|
const READ_ONLY = { readOnlyHint: true, openWorldHint: true };
|
|
@@ -39521,7 +39813,7 @@ server.registerTool('get_intent_relations', {
|
|
|
39521
39813
|
type: 'text',
|
|
39522
39814
|
text: JSON.stringify({
|
|
39523
39815
|
intentId: intent.id,
|
|
39524
|
-
|
|
39816
|
+
title: intent.title,
|
|
39525
39817
|
relations: intent.relations,
|
|
39526
39818
|
}, null, 2)
|
|
39527
39819
|
}]
|
|
@@ -39540,7 +39832,7 @@ server.registerTool('search_intents', {
|
|
|
39540
39832
|
const intents = (0, local_reader_1.readLocalIntents)();
|
|
39541
39833
|
const q = query.toLowerCase();
|
|
39542
39834
|
const matches = intents.filter(i => {
|
|
39543
|
-
const text = [i.
|
|
39835
|
+
const text = [i.title, i.objective, ...i.outcomes, ...i.constraints].join(' ').toLowerCase();
|
|
39544
39836
|
return text.includes(q) && (!status || i.status === status);
|
|
39545
39837
|
});
|
|
39546
39838
|
return { content: [{ type: 'text', text: JSON.stringify({ results: matches, count: matches.length, query }, null, 2) }] };
|
|
@@ -39549,12 +39841,12 @@ server.registerTool('search_intents', {
|
|
|
39549
39841
|
const intents = await client.listIntents(status);
|
|
39550
39842
|
const q = query.toLowerCase();
|
|
39551
39843
|
const matches = intents.filter(i => {
|
|
39552
|
-
const text = [i.
|
|
39844
|
+
const text = [i.title, i.objective, ...(i.outcomes || []), ...(i.constraints || [])].join(' ').toLowerCase();
|
|
39553
39845
|
return text.includes(q);
|
|
39554
39846
|
});
|
|
39555
39847
|
const results = matches.map(i => ({
|
|
39556
39848
|
id: i.id,
|
|
39557
|
-
|
|
39849
|
+
title: i.title,
|
|
39558
39850
|
objective: i.objective,
|
|
39559
39851
|
status: i.status,
|
|
39560
39852
|
stageName: i.stageName,
|
|
@@ -39697,7 +39989,7 @@ server.registerTool('analyze_intent_graph', {
|
|
|
39697
39989
|
for (const [id, dependents] of reverse) {
|
|
39698
39990
|
if (dependents.size >= 3) {
|
|
39699
39991
|
const spec = specMap.get(id);
|
|
39700
|
-
bottlenecks.push({ id,
|
|
39992
|
+
bottlenecks.push({ id, title: spec?.title || 'Untitled', dependentCount: dependents.size, status: spec?.status || 'unknown' });
|
|
39701
39993
|
}
|
|
39702
39994
|
}
|
|
39703
39995
|
// Orphans
|
|
@@ -39715,19 +40007,19 @@ server.registerTool('analyze_intent_graph', {
|
|
|
39715
40007
|
if (type === 'critical-path') {
|
|
39716
40008
|
const pathDetails = criticalPath.map(id => {
|
|
39717
40009
|
const s = specMap.get(id);
|
|
39718
|
-
return { id,
|
|
40010
|
+
return { id, title: s?.title || 'Untitled', status: s?.status || 'unknown' };
|
|
39719
40011
|
});
|
|
39720
40012
|
return { content: [{ type: 'text', text: JSON.stringify({ criticalPath: pathDetails, length: criticalPath.length }, null, 2) }] };
|
|
39721
40013
|
}
|
|
39722
40014
|
if (type === 'risks') {
|
|
39723
40015
|
const risks = [];
|
|
39724
40016
|
for (const cycle of cycles) {
|
|
39725
|
-
const names = cycle.slice(0, -1).map(id => specMap.get(id)?.
|
|
40017
|
+
const names = cycle.slice(0, -1).map(id => specMap.get(id)?.title || 'Untitled');
|
|
39726
40018
|
risks.push({ type: 'cycle', severity: 'critical', message: `Circular dependency: ${names.join(' \u2192 ')}` });
|
|
39727
40019
|
}
|
|
39728
40020
|
for (const b of bottlenecks) {
|
|
39729
40021
|
const isDraft = b.status === 'draft' || b.status === 'validated';
|
|
39730
|
-
risks.push({ type: 'bottleneck', severity: isDraft ? 'critical' : 'warning', message: `"${b.
|
|
40022
|
+
risks.push({ type: 'bottleneck', severity: isDraft ? 'critical' : 'warning', message: `"${b.title}" blocks ${b.dependentCount} intents${isDraft ? ` and is still ${b.status}` : ''}` });
|
|
39731
40023
|
}
|
|
39732
40024
|
return { content: [{ type: 'text', text: JSON.stringify({ risks }, null, 2) }] };
|
|
39733
40025
|
}
|
|
@@ -39736,9 +40028,9 @@ server.registerTool('analyze_intent_graph', {
|
|
|
39736
40028
|
summary: { total: intents.length, statusDistribution: statusDist },
|
|
39737
40029
|
criticalPath: criticalPath.map(id => {
|
|
39738
40030
|
const s = specMap.get(id);
|
|
39739
|
-
return { id,
|
|
40031
|
+
return { id, title: s?.title || 'Untitled', status: s?.status || 'unknown' };
|
|
39740
40032
|
}),
|
|
39741
|
-
cycles: cycles.map(c => c.slice(0, -1).map(id => ({ id,
|
|
40033
|
+
cycles: cycles.map(c => c.slice(0, -1).map(id => ({ id, title: specMap.get(id)?.title || 'Untitled' }))),
|
|
39742
40034
|
bottlenecks,
|
|
39743
40035
|
orphanCount: orphans.length,
|
|
39744
40036
|
};
|
|
@@ -39825,7 +40117,7 @@ server.registerTool('get_constitution', {
|
|
|
39825
40117
|
// ============================================================
|
|
39826
40118
|
server.registerTool('update_intent_status', {
|
|
39827
40119
|
title: 'Update Intent Status',
|
|
39828
|
-
description: 'Update the status of an intent. Use this to mark an intent as shipped after implementation, or verified after testing.',
|
|
40120
|
+
description: 'Update the status of an intent. Use this to mark an intent as shipped after implementation, or verified after testing. For shipped/verified transitions, the response includes a verification checklist of outcomes, constitution rules, and health metrics that should be confirmed.',
|
|
39829
40121
|
inputSchema: {
|
|
39830
40122
|
intentId: zod_1.z.string().describe('The intent ID to update'),
|
|
39831
40123
|
status: zod_1.z.enum(['draft', 'validated', 'approved', 'shipped', 'verified']).describe('The new status'),
|
|
@@ -39836,10 +40128,19 @@ server.registerTool('update_intent_status', {
|
|
|
39836
40128
|
return { content: [{ type: 'text', text: 'Status updates are not available in local mode. Use cloud mode.' }] };
|
|
39837
40129
|
}
|
|
39838
40130
|
const result = await client.updateIntentStatus(intentId, status);
|
|
40131
|
+
let responseText = `Intent ${intentId} status updated to "${status}".`;
|
|
40132
|
+
// Surface verification checklist for shipped/verified transitions
|
|
40133
|
+
if (result.verificationChecklist && result.verificationChecklist.length > 0) {
|
|
40134
|
+
responseText += `\n\nVerification Checklist (${result.verificationChecklistCount} items to verify):`;
|
|
40135
|
+
for (const item of result.verificationChecklist) {
|
|
40136
|
+
responseText += `\n [ ] [${item.category}] ${item.text}`;
|
|
40137
|
+
}
|
|
40138
|
+
responseText += `\n\nThese items should be verified. Use log_implementation_note to record verification results.`;
|
|
40139
|
+
}
|
|
39839
40140
|
return {
|
|
39840
40141
|
content: [{
|
|
39841
40142
|
type: 'text',
|
|
39842
|
-
text:
|
|
40143
|
+
text: responseText
|
|
39843
40144
|
}]
|
|
39844
40145
|
};
|
|
39845
40146
|
});
|
|
@@ -39902,6 +40203,88 @@ server.prompt('what-next', 'Suggest the highest-priority intent to work on next,
|
|
|
39902
40203
|
};
|
|
39903
40204
|
});
|
|
39904
40205
|
// ============================================================
|
|
40206
|
+
// Intent Compiler — Zero-config tools (no API key needed)
|
|
40207
|
+
// ============================================================
|
|
40208
|
+
const intentSpecSchema = {
|
|
40209
|
+
title: zod_1.z.string().describe('Short name for the intent'),
|
|
40210
|
+
objective: zod_1.z.string().describe('Why this matters — the problem and who has it'),
|
|
40211
|
+
outcomes: zod_1.z.array(zod_1.z.string()).describe('Observable, testable state changes'),
|
|
40212
|
+
constraints: zod_1.z.array(zod_1.z.string()).optional().describe('Hard limits the implementation must respect'),
|
|
40213
|
+
edgeCases: zod_1.z.array(zod_1.z.object({
|
|
40214
|
+
scenario: zod_1.z.string(),
|
|
40215
|
+
expectedBehavior: zod_1.z.string(),
|
|
40216
|
+
})).optional().describe('Failure modes and boundary conditions'),
|
|
40217
|
+
healthMetrics: zod_1.z.array(zod_1.z.string()).optional().describe('What to monitor after shipping'),
|
|
40218
|
+
verification: zod_1.z.object({
|
|
40219
|
+
manualChecks: zod_1.z.array(zod_1.z.string()).optional(),
|
|
40220
|
+
unitTests: zod_1.z.array(zod_1.z.string()).optional(),
|
|
40221
|
+
e2eTests: zod_1.z.array(zod_1.z.string()).optional(),
|
|
40222
|
+
}).optional().describe('How to confirm it works'),
|
|
40223
|
+
};
|
|
40224
|
+
server.prompt('compile-intent', 'Start a Socratic conversation to build a structured intent spec from user feedback or a problem description. No Pathmode account needed.', {}, async () => {
|
|
40225
|
+
return {
|
|
40226
|
+
messages: [{
|
|
40227
|
+
role: 'user',
|
|
40228
|
+
content: {
|
|
40229
|
+
type: 'text',
|
|
40230
|
+
text: (0, intent_compiler_1.getCompileIntentPrompt)(),
|
|
40231
|
+
},
|
|
40232
|
+
}],
|
|
40233
|
+
};
|
|
40234
|
+
});
|
|
40235
|
+
server.tool('intent_save', 'Save an intent spec to intent.md in the project root. Called after building a spec through conversation.', {
|
|
40236
|
+
spec: zod_1.z.object(intentSpecSchema),
|
|
40237
|
+
path: zod_1.z.string().optional().describe('File path relative to cwd. Defaults to intent.md'),
|
|
40238
|
+
}, async ({ spec, path }) => {
|
|
40239
|
+
const filePath = (0, path_1.resolve)(process.cwd(), path || 'intent.md');
|
|
40240
|
+
const content = (0, intent_compiler_1.formatIntentMd)({ ...spec, id: `intent_${Date.now()}` });
|
|
40241
|
+
(0, fs_1.writeFileSync)(filePath, content, 'utf-8');
|
|
40242
|
+
return {
|
|
40243
|
+
content: [{
|
|
40244
|
+
type: 'text',
|
|
40245
|
+
text: `✓ Saved intent spec to ${filePath}\n\nTo connect this to Pathmode for dependency tracking and team collaboration, visit pathmode.io`,
|
|
40246
|
+
}],
|
|
40247
|
+
};
|
|
40248
|
+
});
|
|
40249
|
+
server.tool('intent_export', 'Export an intent spec as .cursorrules or CLAUDE.md section for AI agent consumption.', {
|
|
40250
|
+
format: zod_1.z.enum(['cursorrules', 'claude-md']).describe('Export format'),
|
|
40251
|
+
spec: zod_1.z.object(intentSpecSchema),
|
|
40252
|
+
path: zod_1.z.string().optional().describe('Output file path. Defaults to .cursorrules or CLAUDE.md'),
|
|
40253
|
+
}, async ({ format, spec, path }) => {
|
|
40254
|
+
if (format === 'cursorrules') {
|
|
40255
|
+
const content = (0, intent_compiler_1.formatCursorRules)(spec);
|
|
40256
|
+
const filePath = (0, path_1.resolve)(process.cwd(), path || '.cursorrules');
|
|
40257
|
+
(0, fs_1.writeFileSync)(filePath, content, 'utf-8');
|
|
40258
|
+
return {
|
|
40259
|
+
content: [{
|
|
40260
|
+
type: 'text',
|
|
40261
|
+
text: `✓ Exported .cursorrules to ${filePath}\n\nCursor and other AI agents will now see this intent as their implementation context.`,
|
|
40262
|
+
}],
|
|
40263
|
+
};
|
|
40264
|
+
}
|
|
40265
|
+
else {
|
|
40266
|
+
const section = (0, intent_compiler_1.formatClaudeMdSection)(spec);
|
|
40267
|
+
const filePath = (0, path_1.resolve)(process.cwd(), path || 'CLAUDE.md');
|
|
40268
|
+
// Append or replace PATHMODE section in existing file
|
|
40269
|
+
let existing = '';
|
|
40270
|
+
try {
|
|
40271
|
+
existing = (0, fs_1.readFileSync)(filePath, 'utf-8');
|
|
40272
|
+
}
|
|
40273
|
+
catch { /* file doesn't exist yet */ }
|
|
40274
|
+
const marker = /<!-- PATHMODE:START -->[\s\S]*?<!-- PATHMODE:END -->/;
|
|
40275
|
+
const updated = marker.test(existing)
|
|
40276
|
+
? existing.replace(marker, section)
|
|
40277
|
+
: existing ? existing + '\n\n' + section : section;
|
|
40278
|
+
(0, fs_1.writeFileSync)(filePath, updated, 'utf-8');
|
|
40279
|
+
return {
|
|
40280
|
+
content: [{
|
|
40281
|
+
type: 'text',
|
|
40282
|
+
text: `✓ Exported CLAUDE.md section to ${filePath}\n\nClaude Code will now see this intent as context in every conversation.`,
|
|
40283
|
+
}],
|
|
40284
|
+
};
|
|
40285
|
+
}
|
|
40286
|
+
});
|
|
40287
|
+
// ============================================================
|
|
39905
40288
|
// Resources
|
|
39906
40289
|
// ============================================================
|
|
39907
40290
|
server.resource('intent://current', 'intent://current', async (uri) => {
|
|
@@ -39938,7 +40321,7 @@ server.resource('intent://graph', 'intent://graph', async (uri) => {
|
|
|
39938
40321
|
const intents = await client.listIntents();
|
|
39939
40322
|
const graph = intents.map(i => ({
|
|
39940
40323
|
id: i.id,
|
|
39941
|
-
|
|
40324
|
+
title: i.title,
|
|
39942
40325
|
status: i.status,
|
|
39943
40326
|
relations: i.relations,
|
|
39944
40327
|
}));
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intent Compiler — Zero-config intent spec builder for Claude Code.
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* 1. A Socratic conversation prompt that turns Claude into a product thinking partner
|
|
6
|
+
* 2. Format generators for intent.md, .cursorrules, and CLAUDE.md
|
|
7
|
+
*
|
|
8
|
+
* Architecture: Claude Code IS the conversation engine. This module only provides
|
|
9
|
+
* the personality prompt and file format generators. No AI API calls happen here.
|
|
10
|
+
*/
|
|
11
|
+
export interface IntentFields {
|
|
12
|
+
id?: string;
|
|
13
|
+
title: string;
|
|
14
|
+
objective: string;
|
|
15
|
+
outcomes: string[];
|
|
16
|
+
constraints?: string[];
|
|
17
|
+
edgeCases?: {
|
|
18
|
+
scenario: string;
|
|
19
|
+
expectedBehavior: string;
|
|
20
|
+
}[];
|
|
21
|
+
healthMetrics?: string[];
|
|
22
|
+
verification?: {
|
|
23
|
+
manualChecks?: string[];
|
|
24
|
+
unitTests?: string[];
|
|
25
|
+
e2eTests?: string[];
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Returns the system prompt that turns Claude into a Socratic intent interviewer.
|
|
30
|
+
* Adapted from intentDesignerMachine.ts conversationFirstPreamble for terminal use.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getCompileIntentPrompt(): string;
|
|
33
|
+
/**
|
|
34
|
+
* Generate intent.md content with YAML frontmatter.
|
|
35
|
+
* Adapted from lib/agentPromptGenerator.ts generateIntentMd().
|
|
36
|
+
*/
|
|
37
|
+
export declare function formatIntentMd(spec: IntentFields): string;
|
|
38
|
+
/**
|
|
39
|
+
* Generate .cursorrules content for a single intent.
|
|
40
|
+
* Adapted from lib/agentPromptGenerator.ts generateCursorRules().
|
|
41
|
+
*/
|
|
42
|
+
export declare function formatCursorRules(spec: IntentFields): string;
|
|
43
|
+
/**
|
|
44
|
+
* Generate a CLAUDE.md section wrapped in PATHMODE markers.
|
|
45
|
+
* Can be appended to an existing CLAUDE.md or used standalone.
|
|
46
|
+
* Adapted from lib/agentPromptGenerator.ts generateClaudeMdContent().
|
|
47
|
+
*/
|
|
48
|
+
export declare function formatClaudeMdSection(spec: IntentFields): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/intent-compiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,MAAM,WAAW,YAAY;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC7D,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE;QACX,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACvB,CAAC;CACL;AAMD;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CA2D/C;AAOD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAkFzD;AAOD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CA2E5D;AAOD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAyChE"}
|
package/dist/local-reader.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/local-reader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,
|
|
1
|
+
{"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/local-reader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5D,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAClC,MAAM,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,WAAW,EAAE,CAmBhD"}
|
package/icon.svg
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
|
2
|
+
<path d="M50 50 L95 25 L95 75 L50 100 Z" fill="#3A8A8C" />
|
|
3
|
+
<path d="M50 50 L5 75 L5 25 L50 0 Z" fill="#C94C56" />
|
|
4
|
+
<path d="M5 75 L50 100 L50 50 Z" fill="#A87693" />
|
|
5
|
+
<path d="M50 0 L95 25 L50 50 Z" fill="#3D476D" />
|
|
6
|
+
<path d="M45 40 L65 50 L45 60 Z" fill="#ffffff" fill-opacity="0.9" />
|
|
7
|
+
</svg>
|
package/manifest.json
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"manifest_version": "0.3",
|
|
3
3
|
"name": "pathmode",
|
|
4
4
|
"display_name": "Pathmode",
|
|
5
|
-
"version": "1.
|
|
6
|
-
"description": "
|
|
7
|
-
"long_description": "Pathmode MCP Server
|
|
5
|
+
"version": "1.2.0",
|
|
6
|
+
"description": "Build structured intent specs through Socratic AI conversation, or connect to your Intent Layer for strategic context and dependency graphs.",
|
|
7
|
+
"long_description": "Pathmode MCP Server includes the Intent Compiler — a zero-config Socratic conversation that helps you build structured intent specs (objectives, outcomes, constraints, edge cases) right in Claude Code. No signup needed. For teams, connect to your Pathmode workspace for dependency graph analysis (critical path, bottlenecks, cycles), workspace strategy context, and governance — so AI agents build the right thing, not just any thing.",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "Pathmode",
|
|
10
10
|
"url": "https://pathmode.io"
|
|
@@ -12,14 +12,16 @@
|
|
|
12
12
|
"homepage": "https://pathmode.io",
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
|
-
"url": "https://github.com/
|
|
15
|
+
"url": "https://github.com/pathmodeio/mcp-server"
|
|
16
16
|
},
|
|
17
|
-
"documentation": "https://github.com/
|
|
18
|
-
"support": "https://github.com/
|
|
17
|
+
"documentation": "https://github.com/pathmodeio/mcp-server#readme",
|
|
18
|
+
"support": "https://github.com/pathmodeio/mcp-server/issues",
|
|
19
19
|
"license": "MIT",
|
|
20
|
+
"icon": "icon.svg",
|
|
20
21
|
"keywords": [
|
|
21
22
|
"pathmode",
|
|
22
23
|
"intent-engineering",
|
|
24
|
+
"intent-compiler",
|
|
23
25
|
"product-development",
|
|
24
26
|
"dependency-graph",
|
|
25
27
|
"ai-agents",
|
|
@@ -43,9 +45,9 @@
|
|
|
43
45
|
"api_key": {
|
|
44
46
|
"type": "string",
|
|
45
47
|
"title": "Pathmode API Key",
|
|
46
|
-
"description": "Your Pathmode API key (starts with pm_live_). Get
|
|
48
|
+
"description": "Optional. Your Pathmode API key (starts with pm_live_) for team features. The Intent Compiler works without it. Get a key from Settings > API Keys in the Pathmode app.",
|
|
47
49
|
"sensitive": true,
|
|
48
|
-
"required":
|
|
50
|
+
"required": false
|
|
49
51
|
}
|
|
50
52
|
},
|
|
51
53
|
"compatibility": {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pathmode/mcp-server",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Pathmode MCP Server —
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"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.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"pathmode-mcp": "./dist/index.js"
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"dist/",
|
|
11
11
|
"manifest.json",
|
|
12
|
+
"icon.svg",
|
|
12
13
|
"README.md"
|
|
13
14
|
],
|
|
14
15
|
"scripts": {
|
|
@@ -24,6 +25,7 @@
|
|
|
24
25
|
"cursor",
|
|
25
26
|
"windsurf",
|
|
26
27
|
"intent-engineering",
|
|
28
|
+
"intent-compiler",
|
|
27
29
|
"ai-agents",
|
|
28
30
|
"product-development",
|
|
29
31
|
"dependency-graph",
|
|
@@ -37,7 +39,7 @@
|
|
|
37
39
|
},
|
|
38
40
|
"repository": {
|
|
39
41
|
"type": "git",
|
|
40
|
-
"url": "git+https://github.com/
|
|
42
|
+
"url": "git+https://github.com/pathmodeio/mcp-server.git"
|
|
41
43
|
},
|
|
42
44
|
"homepage": "https://pathmode.io",
|
|
43
45
|
"dependencies": {
|