spm-mcp 0.4.2 → 0.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.
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nano app types and pure utility functions.
|
|
3
|
+
* No external dependencies — extracted from supabase.ts to avoid
|
|
4
|
+
* shipping @supabase/supabase-js to npm users who never use it.
|
|
5
|
+
*/
|
|
6
|
+
export interface NanoApp {
|
|
7
|
+
key: string;
|
|
8
|
+
name: string;
|
|
9
|
+
description: string | null;
|
|
10
|
+
category: string | null;
|
|
11
|
+
flowType: string;
|
|
12
|
+
expectations: Expectation[];
|
|
13
|
+
}
|
|
14
|
+
export interface Expectation {
|
|
15
|
+
id: string;
|
|
16
|
+
slug: string;
|
|
17
|
+
name: string;
|
|
18
|
+
description: string | null;
|
|
19
|
+
orderIndex: number;
|
|
20
|
+
rules: Rule[];
|
|
21
|
+
}
|
|
22
|
+
export interface Rule {
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
description: string | null;
|
|
26
|
+
spec: string;
|
|
27
|
+
isDefault: boolean;
|
|
28
|
+
orderIndex: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Build the `rules` string for the expert agent payload.
|
|
32
|
+
* Mirrors buildExpectationRulesText() from src/lib/expectationUtils.ts
|
|
33
|
+
* and the SubappPage.tsx expectations assembly (lines 778-807).
|
|
34
|
+
*/
|
|
35
|
+
export declare function buildRulesPayload(nanoApp: NanoApp): string;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nano app types and pure utility functions.
|
|
3
|
+
* No external dependencies — extracted from supabase.ts to avoid
|
|
4
|
+
* shipping @supabase/supabase-js to npm users who never use it.
|
|
5
|
+
*/
|
|
6
|
+
// ── Pure functions (no network, no deps) ──
|
|
7
|
+
/**
|
|
8
|
+
* Build the `rules` string for the expert agent payload.
|
|
9
|
+
* Mirrors buildExpectationRulesText() from src/lib/expectationUtils.ts
|
|
10
|
+
* and the SubappPage.tsx expectations assembly (lines 778-807).
|
|
11
|
+
*/
|
|
12
|
+
export function buildRulesPayload(nanoApp) {
|
|
13
|
+
const expectationsText = nanoApp.expectations
|
|
14
|
+
.sort((a, b) => a.orderIndex - b.orderIndex)
|
|
15
|
+
.reduce((acc, section, idx) => {
|
|
16
|
+
const key = String(idx + 1);
|
|
17
|
+
const { rulesBlock, aiInstructions } = buildExpectationRulesText(section.rules);
|
|
18
|
+
acc[key] = {
|
|
19
|
+
sectionTitle: section.name || '',
|
|
20
|
+
isEdited: false,
|
|
21
|
+
currentExpectation: [
|
|
22
|
+
`Full Expectation: ${section.description || ''}`.trim(),
|
|
23
|
+
'',
|
|
24
|
+
'Detailed Requirements:',
|
|
25
|
+
'',
|
|
26
|
+
rulesBlock.trim(),
|
|
27
|
+
aiInstructions,
|
|
28
|
+
].join('\n').trim(),
|
|
29
|
+
previousExpectation: '',
|
|
30
|
+
};
|
|
31
|
+
return acc;
|
|
32
|
+
}, {});
|
|
33
|
+
return JSON.stringify(expectationsText);
|
|
34
|
+
}
|
|
35
|
+
// Minimum content length for a rule to be included (matches extension logic)
|
|
36
|
+
const MIN_RULE_CONTENT_LENGTH = 10;
|
|
37
|
+
const MINIMAL_PATTERNS = [
|
|
38
|
+
/^\.+$/,
|
|
39
|
+
/^[a-z]{1,3}$/i,
|
|
40
|
+
/^\s*$/,
|
|
41
|
+
/^[^\w\s]+$/,
|
|
42
|
+
];
|
|
43
|
+
function buildExpectationRulesText(rules) {
|
|
44
|
+
const filtered = rules
|
|
45
|
+
.filter(r => r.name !== 'AI Analysis Instructions')
|
|
46
|
+
.sort((a, b) => a.orderIndex - b.orderIndex)
|
|
47
|
+
.filter(rule => {
|
|
48
|
+
const content = rule.spec.trim();
|
|
49
|
+
if (content.length < MIN_RULE_CONTENT_LENGTH)
|
|
50
|
+
return false;
|
|
51
|
+
return !MINIMAL_PATTERNS.some(p => p.test(content));
|
|
52
|
+
});
|
|
53
|
+
const rulesBlock = filtered
|
|
54
|
+
.map((rule, i) => {
|
|
55
|
+
let content = rule.spec;
|
|
56
|
+
// Strip "For Content Generation" sections
|
|
57
|
+
const idx = content.indexOf('## For Content Generation');
|
|
58
|
+
if (idx !== -1)
|
|
59
|
+
content = content.slice(0, idx).trimEnd();
|
|
60
|
+
return `${i + 1}. ${rule.name}:\n${content}\n`;
|
|
61
|
+
})
|
|
62
|
+
.join('\n');
|
|
63
|
+
const aiRule = rules.find(r => r.name === 'AI Analysis Instructions');
|
|
64
|
+
const aiInstructions = aiRule?.spec
|
|
65
|
+
? `\n\nAdditional AI Instructions:\n${aiRule.spec}`
|
|
66
|
+
: '';
|
|
67
|
+
return { rulesBlock, aiInstructions };
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=nano-app-types.js.map
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* for the user/Claude to pick from.
|
|
9
9
|
*/
|
|
10
10
|
import { callExpertAgent, SpmApiError } from '../client/spm-api.js';
|
|
11
|
-
import { buildRulesPayload } from '../client/
|
|
11
|
+
import { buildRulesPayload } from '../client/nano-app-types.js';
|
|
12
12
|
import { callJsonEndpoint } from '../client/cloud-functions.js';
|
|
13
13
|
export const analyzeDefinition = {
|
|
14
14
|
name: 'spm_analyze',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spm-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Super Product Manager MCP Server - AI-powered product document analysis. Bring your own template or use 30 built-in expert reviews for PRDs, roadmaps, and PM documents.",
|
|
5
5
|
"author": "Super Product Manager <chiranjeevi.gunturi@superproductmanager.ai>",
|
|
6
6
|
"homepage": "https://superproductmanager.ai",
|
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
19
|
-
"@supabase/supabase-js": "^2.75.0",
|
|
20
|
-
"express": "^4.21.0",
|
|
21
19
|
"zod": "^4.3.6"
|
|
22
20
|
},
|
|
23
21
|
"devDependencies": {
|
|
22
|
+
"@supabase/supabase-js": "^2.75.0",
|
|
24
23
|
"@types/express": "^5.0.0",
|
|
25
24
|
"@types/node": "^22.10.0",
|
|
25
|
+
"express": "^4.21.0",
|
|
26
26
|
"typescript": "~5.7.0"
|
|
27
27
|
},
|
|
28
28
|
"keywords": [
|
|
@@ -38,10 +38,19 @@
|
|
|
38
38
|
"pm-tools",
|
|
39
39
|
"prd-review",
|
|
40
40
|
"prd-critique",
|
|
41
|
+
"prd-generator",
|
|
41
42
|
"document-review",
|
|
42
43
|
"document-analysis",
|
|
43
44
|
"ai-review",
|
|
44
|
-
"ai-agent"
|
|
45
|
+
"ai-agent",
|
|
46
|
+
"user-story-generator",
|
|
47
|
+
"swot-analysis",
|
|
48
|
+
"competitive-analysis",
|
|
49
|
+
"okr-generator",
|
|
50
|
+
"test-case-generator",
|
|
51
|
+
"release-notes-generator",
|
|
52
|
+
"problem-statement",
|
|
53
|
+
"product-roadmap"
|
|
45
54
|
],
|
|
46
55
|
"license": "MIT",
|
|
47
56
|
"engines": {
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nano app types and pure utility functions.
|
|
3
|
+
* No external dependencies — extracted from supabase.ts to avoid
|
|
4
|
+
* shipping @supabase/supabase-js to npm users who never use it.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// ── Types ──
|
|
8
|
+
|
|
9
|
+
export interface NanoApp {
|
|
10
|
+
key: string;
|
|
11
|
+
name: string;
|
|
12
|
+
description: string | null;
|
|
13
|
+
category: string | null;
|
|
14
|
+
flowType: string;
|
|
15
|
+
expectations: Expectation[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface Expectation {
|
|
19
|
+
id: string;
|
|
20
|
+
slug: string;
|
|
21
|
+
name: string;
|
|
22
|
+
description: string | null;
|
|
23
|
+
orderIndex: number;
|
|
24
|
+
rules: Rule[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface Rule {
|
|
28
|
+
id: string;
|
|
29
|
+
name: string;
|
|
30
|
+
description: string | null;
|
|
31
|
+
spec: string;
|
|
32
|
+
isDefault: boolean;
|
|
33
|
+
orderIndex: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ── Pure functions (no network, no deps) ──
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Build the `rules` string for the expert agent payload.
|
|
40
|
+
* Mirrors buildExpectationRulesText() from src/lib/expectationUtils.ts
|
|
41
|
+
* and the SubappPage.tsx expectations assembly (lines 778-807).
|
|
42
|
+
*/
|
|
43
|
+
export function buildRulesPayload(nanoApp: NanoApp): string {
|
|
44
|
+
const expectationsText = nanoApp.expectations
|
|
45
|
+
.sort((a, b) => a.orderIndex - b.orderIndex)
|
|
46
|
+
.reduce<Record<string, any>>((acc, section, idx) => {
|
|
47
|
+
const key = String(idx + 1);
|
|
48
|
+
const { rulesBlock, aiInstructions } = buildExpectationRulesText(section.rules);
|
|
49
|
+
|
|
50
|
+
acc[key] = {
|
|
51
|
+
sectionTitle: section.name || '',
|
|
52
|
+
isEdited: false,
|
|
53
|
+
currentExpectation: [
|
|
54
|
+
`Full Expectation: ${section.description || ''}`.trim(),
|
|
55
|
+
'',
|
|
56
|
+
'Detailed Requirements:',
|
|
57
|
+
'',
|
|
58
|
+
rulesBlock.trim(),
|
|
59
|
+
aiInstructions,
|
|
60
|
+
].join('\n').trim(),
|
|
61
|
+
previousExpectation: '',
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
return acc;
|
|
65
|
+
}, {});
|
|
66
|
+
|
|
67
|
+
return JSON.stringify(expectationsText);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Minimum content length for a rule to be included (matches extension logic)
|
|
71
|
+
const MIN_RULE_CONTENT_LENGTH = 10;
|
|
72
|
+
const MINIMAL_PATTERNS = [
|
|
73
|
+
/^\.+$/,
|
|
74
|
+
/^[a-z]{1,3}$/i,
|
|
75
|
+
/^\s*$/,
|
|
76
|
+
/^[^\w\s]+$/,
|
|
77
|
+
];
|
|
78
|
+
|
|
79
|
+
function buildExpectationRulesText(rules: Rule[]): { rulesBlock: string; aiInstructions: string } {
|
|
80
|
+
const filtered = rules
|
|
81
|
+
.filter(r => r.name !== 'AI Analysis Instructions')
|
|
82
|
+
.sort((a, b) => a.orderIndex - b.orderIndex)
|
|
83
|
+
.filter(rule => {
|
|
84
|
+
const content = rule.spec.trim();
|
|
85
|
+
if (content.length < MIN_RULE_CONTENT_LENGTH) return false;
|
|
86
|
+
return !MINIMAL_PATTERNS.some(p => p.test(content));
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const rulesBlock = filtered
|
|
90
|
+
.map((rule, i) => {
|
|
91
|
+
let content = rule.spec;
|
|
92
|
+
// Strip "For Content Generation" sections
|
|
93
|
+
const idx = content.indexOf('## For Content Generation');
|
|
94
|
+
if (idx !== -1) content = content.slice(0, idx).trimEnd();
|
|
95
|
+
return `${i + 1}. ${rule.name}:\n${content}\n`;
|
|
96
|
+
})
|
|
97
|
+
.join('\n');
|
|
98
|
+
|
|
99
|
+
const aiRule = rules.find(r => r.name === 'AI Analysis Instructions');
|
|
100
|
+
const aiInstructions = aiRule?.spec
|
|
101
|
+
? `\n\nAdditional AI Instructions:\n${aiRule.spec}`
|
|
102
|
+
: '';
|
|
103
|
+
|
|
104
|
+
return { rulesBlock, aiInstructions };
|
|
105
|
+
}
|
package/src/tools/analyze.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { callExpertAgent, SpmApiError } from '../client/spm-api.js';
|
|
12
|
-
import { buildRulesPayload, type NanoApp } from '../client/
|
|
12
|
+
import { buildRulesPayload, type NanoApp } from '../client/nano-app-types.js';
|
|
13
13
|
import { callJsonEndpoint } from '../client/cloud-functions.js';
|
|
14
14
|
|
|
15
15
|
export const analyzeDefinition = {
|