product-spec-mcp 0.3.30 → 0.3.32

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.
Files changed (2) hide show
  1. package/dist/index.cjs +52 -15
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -23784,7 +23784,18 @@ function buildPmGateClarification(decision) {
23784
23784
  defaultAssumptions: Object.fromEntries(questions.map((question) => [question.field, question.defaultAssumption]))
23785
23785
  };
23786
23786
  }
23787
- function formatPmGateInterrogatePrelude(decision) {
23787
+ function buildPmGateReadiness(decision, readiness) {
23788
+ const draftReadyNeed = decision.needType === "personal_local_tool" || decision.needType === "content_marketing_site" || decision.needType === "data_visualization_site";
23789
+ if (!draftReadyNeed) return readiness;
23790
+ return {
23791
+ ...readiness,
23792
+ score: Math.max(readiness.score, 64),
23793
+ status: "Draft Ready"
23794
+ };
23795
+ }
23796
+ function formatPmGateInterrogateResult(decision, readiness, clarification) {
23797
+ const canDraft = readiness.status !== "Not Ready";
23798
+ const nextStep = decision.needType === "personal_local_tool" ? "\u53EF\u4EE5\u6309\u9ED8\u8BA4\u5047\u8BBE\u76F4\u63A5\u8FDB\u5165 spec_compile \u751F\u6210 MVP \u8349\u6848\uFF1B\u5982\u679C\u8981\u95EE\u7528\u6237\uFF0C\u6700\u591A\u53EA\u95EE\u4E00\u53E5\uFF1A\u662F\u5426\u6309\u6D4F\u89C8\u5668\u672C\u5730\u4FDD\u5B58\u3001\u4E0D\u767B\u5F55\u4E0D\u505A\u540E\u53F0\u3001\u9875\u9762\u5185\u63D0\u9192\u7EE7\u7EED\uFF1F" : canDraft ? "\u53EF\u4EE5\u6309\u9ED8\u8BA4\u5047\u8BBE\u751F\u6210\u8349\u6848\uFF0C\u540C\u65F6\u53EA\u786E\u8BA4\u4F1A\u6539\u53D8\u67B6\u6784\u7684\u8FB9\u754C\u95EE\u9898\u3002" : "\u5148\u786E\u8BA4\u4F1A\u6539\u53D8\u67B6\u6784\u7684\u8FB9\u754C\u95EE\u9898\uFF0C\u518D\u8FDB\u5165 spec_compile\u3002";
23788
23799
  return `# PM Gate \u5224\u65AD\uFF1A${needTypeTitle(decision.needType)}
23789
23800
 
23790
23801
  - **\u9700\u6C42\u95E8:** ${decision.needType}
@@ -23800,7 +23811,27 @@ function formatPmGateInterrogatePrelude(decision) {
23800
23811
  ${decision.defaultAssumptions.map((item) => `- ${item}`).join("\n")}
23801
23812
 
23802
23813
  > \u5148\u786E\u8BA4\u4F7F\u7528\u8303\u56F4\u3001\u7EF4\u62A4\u65B9\u5F0F\u548C\u8BBF\u95EE\u8FB9\u754C\uFF1B\u4E0D\u8981\u5957\u7528\u65E0\u5173 domain \u6A21\u677F\u3002
23803
- `;
23814
+
23815
+ ## \u53EF\u6267\u884C\u72B6\u6001
23816
+
23817
+ - **Score:** ${readiness.score} / 100
23818
+ - **\u72B6\u6001:** ${readiness.status}
23819
+ - **\u4E0B\u4E00\u6B65:** ${nextStep}
23820
+
23821
+ ## \u8FB9\u754C\u95EE\u9898
23822
+
23823
+ ${clarification.questions.map(formatQuestion).join("\n\n")}
23824
+
23825
+ ## \u9ED8\u8BA4\u5047\u8BBE
23826
+
23827
+ ${Object.entries(clarification.defaultAssumptions).map(([field, value]) => `- **${field}:** ${value}`).join("\n")}`;
23828
+ }
23829
+ function formatQuestion(question) {
23830
+ return `### ${question.question}
23831
+ - **\u4E3E\u4E2A\u4F8B\u5B50:** ${question.example || "\u6309\u7528\u6237\u539F\u8BDD\u8865\u5145\u5373\u53EF\u3002"}
23832
+ - **\u4E3A\u4EC0\u4E48\u8981\u95EE:** ${question.whyImportant}
23833
+ - **\u63A8\u8350\u9009\u9879:** ${question.options.join(" / ")}
23834
+ - **\u9ED8\u8BA4\u5047\u8BBE:** \u5982\u679C\u4E0D\u56DE\u7B54\uFF0C\u9ED8\u8BA4\u4E3A\u300C${question.defaultAssumption}\u300D`;
23804
23835
  }
23805
23836
  function questionsForDecision(decision) {
23806
23837
  switch (decision.needType) {
@@ -23980,19 +24011,18 @@ function registerSpecInterrogate(server) {
23980
24011
  const technicalProfile = buildTechnicalProfile(input.raw_idea, input.known_context || {});
23981
24012
  const pmIntentDecision = decidePmIntent(input.raw_idea, input.known_context || {});
23982
24013
  const usePmGate = input.scenario !== "modify_ui" && shouldUsePmGateClarification(pmIntentDecision);
24014
+ const effectiveReadiness = usePmGate ? buildPmGateReadiness(pmIntentDecision, readiness) : readiness;
23983
24015
  const clarification = usePmGate ? buildPmGateClarification(pmIntentDecision) : generateClarification(
23984
24016
  input.raw_idea,
23985
- readiness,
24017
+ effectiveReadiness,
23986
24018
  input.scenario,
23987
24019
  input.target_platform,
23988
24020
  input.strictness,
23989
24021
  input.known_context
23990
24022
  );
23991
- const baseMarkdown = formatInterrogateResult(readiness, clarification);
23992
- const markdown = usePmGate ? `${formatPmGateInterrogatePrelude(pmIntentDecision)}
23993
- ${baseMarkdown}` : baseMarkdown;
24023
+ const markdown = usePmGate ? formatPmGateInterrogateResult(pmIntentDecision, effectiveReadiness, clarification) : formatInterrogateResult(effectiveReadiness, clarification);
23994
24024
  const structuredContent = buildInterrogateStructuredOutput(
23995
- readiness,
24025
+ effectiveReadiness,
23996
24026
  clarification,
23997
24027
  technicalProfile,
23998
24028
  usePmGate ? pmIntentDecision : void 0
@@ -24043,8 +24073,8 @@ function looseStringArray(description) {
24043
24073
  var SpecCompileInputSchema = external_exports.object({
24044
24074
  raw_idea: external_exports.string().describe("\u7528\u6237\u539F\u59CB\u60F3\u6CD5"),
24045
24075
  answers: external_exports.record(external_exports.string(), external_exports.any()).optional().describe("\u7528\u6237\u5BF9\u8FFD\u95EE\u7684\u56DE\u7B54"),
24046
- allow_assumptions: external_exports.union([external_exports.boolean(), looseBoolean]).optional().default(true).describe("\u662F\u5426\u5141\u8BB8\u4F7F\u7528\u9ED8\u8BA4\u5047\u8BBE"),
24047
- min_readiness_score: external_exports.union([external_exports.number(), looseNumber]).optional().default(70).describe("\u6700\u4F4E\u53EF\u63A5\u53D7\u7684 readiness \u5206\u6570")
24076
+ allow_assumptions: looseBoolean.optional().default(true).describe("\u662F\u5426\u5141\u8BB8\u4F7F\u7528\u9ED8\u8BA4\u5047\u8BBE"),
24077
+ min_readiness_score: looseNumber.optional().default(70).describe("\u6700\u4F4E\u53EF\u63A5\u53D7\u7684 readiness \u5206\u6570")
24048
24078
  });
24049
24079
 
24050
24080
  // src/schemas/outputs/specCompile.output.ts
@@ -24232,6 +24262,13 @@ function buildSpec(rawIdea, context, readiness) {
24232
24262
  if (hasStructuredAnswers) {
24233
24263
  assumptions.push("\u5F53\u524D\u8F93\u5165\u5305\u542B\u591A\u4E2A\u7ED3\u6784\u5316\u7B54\u6848\uFF0C\u4F46\u672A\u5339\u914D\u5230\u7A33\u5B9A domain pack\uFF1B\u4E0D\u8981\u628A\u5B83\u5957\u5165\u62A5\u540D\u3001\u7535\u5546\u3001\u9884\u7EA6\u3001\u5185\u5BB9\u793E\u533A\u3001\u5DE5\u5355\u6216\u77E5\u8BC6\u5E93\u6A21\u677F\u3002");
24234
24264
  }
24265
+ if (personalLocalTool) {
24266
+ assumptions.push(
24267
+ "\u6570\u636E\u9ED8\u8BA4\u4FDD\u5B58\u5728\u5F53\u524D\u6D4F\u89C8\u5668 localStorage \u4E2D\uFF0C\u5237\u65B0\u540E\u4FDD\u7559\uFF0C\u4F46\u4E0D\u505A\u8DE8\u8BBE\u5907\u540C\u6B65\u3002",
24268
+ "\u7B2C\u4E00\u7248\u9ED8\u8BA4\u4E0D\u9700\u8981\u767B\u5F55\u3001\u6CE8\u518C\u3001\u540E\u53F0\u7BA1\u7406\u6216\u7BA1\u7406\u5458\u89D2\u8272\u3002",
24269
+ "\u9875\u9762\u9AD8\u7EA7\u611F\u53EA\u4F5C\u4E3A UI \u98CE\u683C\u548C\u54CD\u5E94\u5F0F\u9A8C\u6536\u8981\u6C42\uFF0C\u4E0D\u4F5C\u4E3A\u540E\u7AEF\u6216\u670D\u52A1\u5668\u6570\u636E\u5E93\u4FE1\u53F7\u3002"
24270
+ );
24271
+ }
24235
24272
  const needsBackend = technicalProfile.needsBackend || normalizedContext.need_backend === true || normalizedContext.data_persistence === true || normalizedContext.user_roles === true || normalizedContext.backend_need === true;
24236
24273
  const dataModel = buildDataModel(normalizedContext, needsBackend, technicalProfile, rawIdea);
24237
24274
  const successCriteria = personalLocalTool ? buildLocalFirstSuccessCriteria(rawIdea) : ["\u6838\u5FC3\u529F\u80FD\u53EF\u7528", "\u65E0\u660E\u663E Bug", "\u7528\u6237\u4F53\u9A8C\u6D41\u7545"];
@@ -25799,7 +25836,7 @@ var ArchitectureDecideInputSchema = external_exports.object({
25799
25836
  product_type: external_exports.string().describe("\u4EA7\u54C1\u7C7B\u578B\u63CF\u8FF0"),
25800
25837
  platform: external_exports.enum(["web", "mini_program", "app", "backend"]).describe("\u76EE\u6807\u5E73\u53F0"),
25801
25838
  features: looseStringArray("\u529F\u80FD\u5217\u8868"),
25802
- commercial_intent: external_exports.union([external_exports.boolean(), looseBoolean]).optional().default(false).describe("\u662F\u5426\u6709\u5546\u4E1A\u5316\u610F\u56FE"),
25839
+ commercial_intent: looseBoolean.optional().default(false).describe("\u662F\u5426\u6709\u5546\u4E1A\u5316\u610F\u56FE"),
25803
25840
  expected_users: external_exports.enum(["individual", "small_team", "enterprise", "massive"]).optional().default("individual").describe("\u9884\u671F\u7528\u6237\u89C4\u6A21")
25804
25841
  });
25805
25842
 
@@ -26876,9 +26913,9 @@ var AcceptanceGenerateInputSchema = external_exports.object({
26876
26913
  product_type: external_exports.string().describe("\u4EA7\u54C1\u7C7B\u578B"),
26877
26914
  features: looseStringArray("\u529F\u80FD\u5217\u8868"),
26878
26915
  platform: external_exports.enum(["web", "mini_program", "app", "backend"]).describe("\u76EE\u6807\u5E73\u53F0"),
26879
- has_backend: external_exports.union([external_exports.boolean(), looseBoolean]).optional().default(false).describe("\u662F\u5426\u6709\u540E\u7AEF"),
26880
- has_payment: external_exports.union([external_exports.boolean(), looseBoolean]).optional().default(false).describe("\u662F\u5426\u6D89\u53CA\u652F\u4ED8"),
26881
- has_auth: external_exports.union([external_exports.boolean(), looseBoolean]).optional().default(false).describe("\u662F\u5426\u6D89\u53CA\u9274\u6743")
26916
+ has_backend: looseBoolean.optional().default(false).describe("\u662F\u5426\u6709\u540E\u7AEF"),
26917
+ has_payment: looseBoolean.optional().default(false).describe("\u662F\u5426\u6D89\u53CA\u652F\u4ED8"),
26918
+ has_auth: looseBoolean.optional().default(false).describe("\u662F\u5426\u6D89\u53CA\u9274\u6743")
26882
26919
  });
26883
26920
 
26884
26921
  // src/schemas/outputs/acceptanceGenerate.output.ts
@@ -27822,7 +27859,7 @@ var ProductSpecAssistInputSchema = external_exports.object({
27822
27859
  known_context: external_exports.record(external_exports.string(), external_exports.unknown()).optional().describe("\u5DF2\u6709\u4E0A\u4E0B\u6587"),
27823
27860
  preferred_platform: external_exports.enum(["web", "mini_program", "app", "backend", "unknown"]).optional().default("unknown").describe("\u7528\u6237\u5DF2\u77E5\u5E73\u53F0"),
27824
27861
  strictness: external_exports.enum(["light", "normal", "grill"]).optional().default("normal").describe("\u8FFD\u95EE\u5F3A\u5EA6"),
27825
- auto_execute: external_exports.union([external_exports.boolean(), looseBoolean]).optional().default(true).describe("\u662F\u5426\u5141\u8BB8\u81EA\u52A8\u8C03\u7528\u5BF9\u5E94 engine")
27862
+ auto_execute: looseBoolean.optional().default(true).describe("\u662F\u5426\u5141\u8BB8\u81EA\u52A8\u8C03\u7528\u5BF9\u5E94 engine")
27826
27863
  });
27827
27864
 
27828
27865
  // src/schemas/outputs/productSpecAssist.output.ts
@@ -29939,7 +29976,7 @@ function registerProductSpecAssist(server) {
29939
29976
  function createServer() {
29940
29977
  const server = new McpServer({
29941
29978
  name: "product-spec-mcp",
29942
- version: "0.3.30"
29979
+ version: "0.3.32"
29943
29980
  });
29944
29981
  registerSpecInterrogate(server);
29945
29982
  registerSpecCompile(server);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "product-spec-mcp",
3
- "version": "0.3.30",
3
+ "version": "0.3.32",
4
4
  "description": "MCP Server for product specification - requirement interrogation, architecture decision, UI translation, debug guidance, and acceptance generation",
5
5
  "type": "commonjs",
6
6
  "main": "dist/index.cjs",