kevlar-4u 1.5.5 โ†’ 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +2 -0
  2. package/dist/__tests__/e2e.test.js +24 -14
  3. package/dist/__tests__/e2e.test.js.map +1 -1
  4. package/dist/__tests__/focusTopicTransform.test.js +2 -2
  5. package/dist/__tests__/focusTopicTransform.test.js.map +1 -1
  6. package/dist/__tests__/install.test.d.ts +2 -0
  7. package/dist/__tests__/install.test.d.ts.map +1 -0
  8. package/dist/__tests__/install.test.js +136 -0
  9. package/dist/__tests__/install.test.js.map +1 -0
  10. package/dist/__tests__/prompt-hash-baselines.test.js +3 -3
  11. package/dist/__tests__/reviewContentWizard.test.js +57 -68
  12. package/dist/__tests__/reviewContentWizard.test.js.map +1 -1
  13. package/dist/__tests__/strategy.test.js +13 -13
  14. package/dist/__tests__/strategy.test.js.map +1 -1
  15. package/dist/dao/IRuleRepository.d.ts +1 -1
  16. package/dist/dao/IRuleRepository.d.ts.map +1 -1
  17. package/dist/dao/RuleRepository.d.ts +1 -1
  18. package/dist/dao/RuleRepository.d.ts.map +1 -1
  19. package/dist/dao/RuleRepository.js +12 -5
  20. package/dist/dao/RuleRepository.js.map +1 -1
  21. package/dist/execution/aggregator.js +1 -1
  22. package/dist/execution/aggregator.js.map +1 -1
  23. package/dist/execution/dimensions.js +1 -1
  24. package/dist/execution/dimensions.js.map +1 -1
  25. package/dist/execution/focusTopicTransform.js +6 -6
  26. package/dist/execution/focusTopicTransform.js.map +1 -1
  27. package/dist/execution/modes/orchestration.js +1 -1
  28. package/dist/execution/modes/orchestration.js.map +1 -1
  29. package/dist/execution/parallel.js +1 -1
  30. package/dist/execution/parallel.js.map +1 -1
  31. package/dist/execution/reviewSteps.js +1 -1
  32. package/dist/execution/reviewSteps.js.map +1 -1
  33. package/dist/execution/rstRecommender.js +1 -1
  34. package/dist/execution/rstRecommender.js.map +1 -1
  35. package/dist/prompts/instructions.d.ts.map +1 -1
  36. package/dist/prompts/instructions.js +9 -0
  37. package/dist/prompts/instructions.js.map +1 -1
  38. package/dist/prompts/reviewWizard.d.ts +3 -3
  39. package/dist/prompts/reviewWizard.d.ts.map +1 -1
  40. package/dist/prompts/reviewWizard.js +17 -17
  41. package/dist/prompts/reviewWizard.js.map +1 -1
  42. package/dist/scripts/cli.js +2 -2
  43. package/dist/scripts/cli.js.map +1 -1
  44. package/dist/tools/checkUpdateTool.d.ts +4 -0
  45. package/dist/tools/checkUpdateTool.d.ts.map +1 -0
  46. package/dist/tools/checkUpdateTool.js +84 -0
  47. package/dist/tools/checkUpdateTool.js.map +1 -0
  48. package/dist/tools/createPersonaWizardTool.js +4 -4
  49. package/dist/tools/createPersonaWizardTool.js.map +1 -1
  50. package/dist/tools/index.d.ts.map +1 -1
  51. package/dist/tools/index.js +2 -0
  52. package/dist/tools/index.js.map +1 -1
  53. package/dist/tools/reviewContentWizardTool.d.ts.map +1 -1
  54. package/dist/tools/reviewContentWizardTool.js +154 -67
  55. package/dist/tools/reviewContentWizardTool.js.map +1 -1
  56. package/package.json +2 -2
  57. package/scripts/cli.ts +2 -2
  58. package/skills/templates/free.json +2 -2
package/README.md CHANGED
@@ -13,6 +13,8 @@
13
13
 
14
14
  ---
15
15
 
16
+ > ๐Ÿ”’ **Privacy & Security**: Kevlar-4u runs **100% locally** on your machine. No content is ever sent to any server. No telemetry, no analytics, no data collection. The source code is fully open (AGPL-3.0) and auditable on [GitHub](https://github.com/ChurzeXo/kevlar-4u). Pro features use an optional cloud sync for rule updates only โ€” your content and review results never leave your device.
17
+
16
18
  Drop any content you're about to publish โ€” **articles, tweets, video scripts, product intros, press releases, announcements, Reddit posts, V2EX posts, Hacker News headlines** โ€” directly into Kevlar-4u. It won't just say "looks good." Instead, it'll **question, misinterpret, roast, nitpick, and comprehension-test** your content, just like the real internet.
17
19
 
18
20
  Writers often suffer from the **"curse of knowledge"**:
@@ -50,7 +50,7 @@ describe("End-to-End integration test", () => {
50
50
  server.connect(serverTransport),
51
51
  ]);
52
52
  try {
53
- // Step 1: Start wizard with content โ†’ waitingForReviewDecision
53
+ // Step 1: Start wizard โ†’ waitingForRegionSelection
54
54
  const step1 = await client.callTool({
55
55
  name: "review_content_wizard",
56
56
  arguments: {
@@ -61,41 +61,51 @@ describe("End-to-End integration test", () => {
61
61
  assert.ok(Array.isArray(step1.content), "Step 1 response should have content array");
62
62
  assert.equal(step1.content[0].type, "text");
63
63
  const step1Text = step1.content[0].text;
64
- assert.ok(step1Text.includes("่ฏท้€‰ๆ‹ฉไธ‹ไธ€ๆญฅ๏ผš"), "Should ask for the next review action");
65
- assert.ok(step1Text.includes("1. ่ฟ›ๅ…ฅใ€Œๅคๅฎกใ€"), "Should offer review as the next action");
66
- assert.ok(step1Text.includes("currentStep: waitingForReviewDecision"), "Should be in review decision step");
64
+ assert.ok(step1Text.includes("่ฏทๅ‘Š็Ÿฅๆœฌๆฌกๅ†…ๅฎน่ฎกๅˆ’ๆŽจๅนฟ็š„็›ฎๆ ‡ๅ›ฝๅฎถๆˆ–ๅœฐๅŒบ"), "Should ask for target regions");
65
+ assert.ok(step1Text.includes("currentStep: waitingForRegionSelection"), "Should be in region selection step");
67
66
  // Extract sessionId
68
67
  const sessionIdMatch = step1Text.match(/sessionId:\s*([a-z0-9-]+)/);
69
68
  assert.ok(sessionIdMatch, "Should include sessionId");
70
69
  const sessionId = sessionIdMatch[1];
71
- // Step 2: confirm review โ†’ waitingForReviewerConfirmation
70
+ // Step 2: Select regions โ†’ waitingForReviewDecision (Free tier)
72
71
  const step2 = await client.callTool({
73
72
  name: "review_content_wizard",
74
73
  arguments: {
75
74
  sessionId,
76
- userMessage: "ๅผ€ๅง‹ๅคๅฎก",
75
+ userMessage: "ๅ…จ็ƒ",
77
76
  },
78
77
  });
79
78
  assert.ok(step2, "Step 2 response should exist");
80
- assert.ok(Array.isArray(step2.content), "Step 2 response should have content array");
81
- assert.equal(step2.content[0].type, "text");
82
79
  const step2Text = step2.content[0].text;
83
- assert.ok(step2Text.includes("ๅฝ“ๅ‰ๅ…ฑๆœ‰ 1 ไฝ่ฏ„ๅฎกๅ‘˜"), "Should show persona count");
84
- assert.ok(step2Text.includes("currentStep: waitingForReviewerConfirmation"), "Should be in reviewer confirmation step");
85
- // Step 3: "ๅผ€ๅง‹ๅคๅฎก" โ†’ executes review
80
+ assert.ok(step2Text.includes("่ฏท้€‰ๆ‹ฉ"), "Should ask for the next review action");
81
+ assert.ok(step2Text.includes("1. ่ˆ†่ฎบไปฟ็œŸๆŽจๆผ”"), "Should offer review as the next action");
82
+ assert.ok(step2Text.includes("currentStep: waitingForReviewDecision"), "Should be in review decision step");
83
+ // Step 3: confirm review โ†’ waitingForReviewerConfirmation
86
84
  const step3 = await client.callTool({
87
85
  name: "review_content_wizard",
88
86
  arguments: {
89
87
  sessionId,
90
- userMessage: "ๅผ€ๅง‹ๅคๅฎก",
88
+ userMessage: "ๅผ€ๅง‹่ˆ†่ฎบไปฟ็œŸๆŽจๆผ”",
91
89
  },
92
90
  });
93
91
  assert.ok(step3, "Step 3 response should exist");
94
92
  assert.ok(Array.isArray(step3.content), "Step 3 response should have content array");
95
93
  assert.equal(step3.content[0].type, "text");
96
94
  const step3Text = step3.content[0].text;
97
- assert.ok(step3Text.includes("E2E Tester"), "Should include persona name in report");
98
- assert.ok(step3Text.includes("่ฟ™ๆ˜ฏไธ€ไธช็”จไบŽ E2E ๆต‹่ฏ•็š„ๆ–‡ๆœฌ"), "Should include the provided content");
95
+ assert.ok(step3Text.includes("ๅฝ“ๅ‰ๅ…ฑๆœ‰ 1 ไฝ่ฏ„ๅฎกๅ‘˜"), "Should show persona count");
96
+ assert.ok(step3Text.includes("currentStep: waitingForReviewerConfirmation"), "Should be in reviewer confirmation step");
97
+ // Step 4: "ๅผ€ๅง‹่ˆ†่ฎบไปฟ็œŸๆŽจๆผ”" โ†’ executes review
98
+ const step4 = await client.callTool({
99
+ name: "review_content_wizard",
100
+ arguments: {
101
+ sessionId,
102
+ userMessage: "ๅผ€ๅง‹่ˆ†่ฎบไปฟ็œŸๆŽจๆผ”",
103
+ },
104
+ });
105
+ assert.ok(step4, "Step 4 response should exist");
106
+ const step4Text = step4.content[0].text;
107
+ assert.ok(step4Text.includes("E2E Tester"), "Should include persona name in report");
108
+ assert.ok(step4Text.includes("่ฟ™ๆ˜ฏไธ€ไธช็”จไบŽ E2E ๆต‹่ฏ•็š„ๆ–‡ๆœฌ"), "Should include the provided content");
99
109
  }
100
110
  finally {
101
111
  await client.close();
@@ -1 +1 @@
1
- {"version":3,"file":"e2e.test.js","sourceRoot":"","sources":["../../src/__tests__/e2e.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"e2e.test.js","sourceRoot":"","sources":["../../src/__tests__/e2e.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAE/E,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAC3C,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;AAEtF,IAAI,MAAc,CAAC;AAEnB,UAAU,CAAC,GAAG,EAAE;IACd,OAAO,CAAC,GAAG,CAAC,sBAAsB,GAAG,GAAG,CAAC;IACzC,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC;IAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpD,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,WAAW,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACtD,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,MAAM,CAAC;AACzC,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,GAAG,EAAE;IACb,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IACrC,OAAO,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;AAC5C,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,MAAM,GAAG,MAAM,kBAAkB,EAAE,CAAC;QAE1C,sBAAsB;QACtB,MAAM,IAAI,GAAgB;YACxB,EAAE,EAAE,aAAa;YACjB,IAAI,EAAE,YAAY;YAClB,OAAO,EAAE,YAAY;YACrB,OAAO,EAAE,OAAO;YAChB,MAAM,EAAE,aAAa;YACrB,IAAI,EAAE,CAAC,KAAK,CAAC;YACb,WAAW,EAAE,kBAAkB;YAC/B,SAAS,EAAE,MAAM;SAClB,CAAC;QACF,MAAM,gBAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,wBAAwB,CAAC,CAAC;QAC/D,uBAAuB,EAAE,CAAC;QAE1B,MAAM,CAAC,eAAe,EAAE,eAAe,CAAC,GAAG,iBAAiB,CAAC,gBAAgB,EAAE,CAAC;QAEhF,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,OAAO,EAAE,EAC7C,EAAE,YAAY,EAAE,EAAE,EAAE,CACrB,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC;YAC/B,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC;SAChC,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,mDAAmD;YACnD,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC;gBAClC,IAAI,EAAE,uBAAuB;gBAC7B,SAAS,EAAE;oBACT,WAAW,EAAE,0BAA0B;iBACxC;aACF,CAAC,CAAC;YAEH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,8BAA8B,CAAC,CAAC;YACjD,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,2CAA2C,CAAC,CAAC;YACrF,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAE5C,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACxC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,+BAA+B,CAAC,CAAC;YACtF,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,wCAAwC,CAAC,EAAE,oCAAoC,CAAC,CAAC;YAE9G,oBAAoB;YACpB,MAAM,cAAc,GAAG,SAAS,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;YACpE,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC;YACtD,MAAM,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;YAEpC,gEAAgE;YAChE,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC;gBAClC,IAAI,EAAE,uBAAuB;gBAC7B,SAAS,EAAE;oBACT,SAAS;oBACT,WAAW,EAAE,IAAI;iBAClB;aACF,CAAC,CAAC;YAEH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,8BAA8B,CAAC,CAAC;YACjD,MAAM,SAAS,GAAI,KAAK,CAAC,OAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACjD,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,uCAAuC,CAAC,CAAC;YAC9E,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,wCAAwC,CAAC,CAAC;YACrF,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,uCAAuC,CAAC,EAAE,mCAAmC,CAAC,CAAC;YAE5G,0DAA0D;YAC1D,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC;gBAClC,IAAI,EAAE,uBAAuB;gBAC7B,SAAS,EAAE;oBACT,SAAS;oBACT,WAAW,EAAE,UAAU;iBACxB;aACF,CAAC,CAAC;YAEH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,8BAA8B,CAAC,CAAC;YACjD,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,2CAA2C,CAAC,CAAC;YACrF,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC5C,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACxC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,2BAA2B,CAAC,CAAC;YAC1E,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,6CAA6C,CAAC,EAAE,yCAAyC,CAAC,CAAC;YAExH,uCAAuC;YACvC,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC;gBAClC,IAAI,EAAE,uBAAuB;gBAC7B,SAAS,EAAE;oBACT,SAAS;oBACT,WAAW,EAAE,UAAU;iBACxB;aACF,CAAC,CAAC;YAEH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,8BAA8B,CAAC,CAAC;YACjD,MAAM,SAAS,GAAI,KAAK,CAAC,OAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACjD,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,uCAAuC,CAAC,CAAC;YACrF,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,qCAAqC,CAAC,CAAC;QAC3F,CAAC;gBAAS,CAAC;YACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YACrB,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,MAAM,GAAG,MAAM,kBAAkB,EAAE,CAAC;QAC1C,MAAM,CAAC,eAAe,EAAE,eAAe,CAAC,GAAG,iBAAiB,CAAC,gBAAgB,EAAE,CAAC;QAEhF,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,OAAO,EAAE,EAC7C,EAAE,YAAY,EAAE,EAAE,EAAE,CACrB,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC;YAC/B,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC;SAChC,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC;gBACrC,IAAI,EAAE,uBAAuB;gBAC7B,SAAS,EAAE;oBACT,WAAW,EAAE,QAAQ;iBACtB;aACF,CAAC,CAAC;YAEH,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,uBAAuB,CAAC,CAAC;YAC7C,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,oCAAoC,CAAC,CAAC;YAEjF,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC5C,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,4BAA4B,CAAC,CAAC;QACtE,CAAC;gBAAS,CAAC;YACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YACrB,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -37,10 +37,10 @@ describe("Focus Topic transformation", () => {
37
37
  sourceAuditor: "ๅˆ่ง„ๅ“จๅ…ต",
38
38
  sourceKeyword: "ๅ…จ็ฝ‘็ฌฌไธ€",
39
39
  matchedTrigger: "overhyped",
40
- prompt: "่ฏฅๆ–‡ๆœฌๅœจๅˆๅฎกไธญ่ขซๆฃ€ๆต‹ๅ‡บๅœจ็ฌฌ 1 ๆฎตๅญ˜ๅœจโ€œ่ฟ‡ๅบฆๅŒ…่ฃ…ใ€ๅนๅ˜˜ๅŠŸ่ƒฝโ€็š„ๅซŒ็–‘ใ€‚่ฏทไปฅไฝ ๅˆป่–„ใ€็†ๆ€ง็š„่ง†่ง’๏ผŒๆญป็ฃ•่ฏฅๆฎต่ฝๆ˜ฏๅฆๅœจโ€œ็”ป้ฅผโ€ๆˆ–็ผบไนไบ‹ๅฎžไพๆฎใ€‚",
40
+ prompt: "่ฏฅๆ–‡ๆœฌๅœจๅ…ญ็ปด้ฃŽ้™ฉๆฃ€ๆต‹ไธญ่ขซๆฃ€ๆต‹ๅ‡บๅœจ็ฌฌ 1 ๆฎตๅญ˜ๅœจโ€œ่ฟ‡ๅบฆๅŒ…่ฃ…ใ€ๅนๅ˜˜ๅŠŸ่ƒฝโ€็š„ๅซŒ็–‘ใ€‚่ฏทไปฅไฝ ๅˆป่–„ใ€็†ๆ€ง็š„่ง†่ง’๏ผŒๆญป็ฃ•่ฏฅๆฎต่ฝๆ˜ฏๅฆๅœจโ€œ็”ป้ฅผโ€ๆˆ–็ผบไนไบ‹ๅฎžไพๆฎใ€‚",
41
41
  },
42
42
  ]);
43
- assert.match(section, /็‹™ๅ‡ปๆ‰‹ๅฎš็‚นๅคๅฎก็„ฆ็‚น/);
43
+ assert.match(section, /่ˆ†่ฎบไปฟ็œŸๆŽจๆผ”็„ฆ็‚น/);
44
44
  assert.match(section, /ๆ—็™ฝๆ็คบ/);
45
45
  assert.doesNotMatch(section, /ๅŸบๆœฌ็›˜|็ณป็ปŸ่ฟ่ง„ไปฃ็ |legal_compliance/);
46
46
  });
@@ -1 +1 @@
1
- {"version":3,"file":"focusTopicTransform.test.js","sourceRoot":"","sources":["../../src/__tests__/focusTopicTransform.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,OAAO,EACL,0BAA0B,EAC1B,8BAA8B,GAC/B,MAAM,qCAAqC,CAAC;AAG7C,MAAM,GAAG,GAAc;IACrB,UAAU,EAAE,CAAC,yBAAyB,CAAC;IACvC,QAAQ,EAAE,CAAC,WAAW,CAAC;IACvB,YAAY,EAAE,OAAO;IACrB,eAAe,EAAE,aAAa;CAC/B,CAAC;AAEF,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC1C,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,MAAM,GAAG,8BAA8B,CAC3C;YACE,UAAU,EAAE;gBACV;oBACE,EAAE,EAAE,kBAAkB;oBACtB,IAAI,EAAE,MAAM;oBACZ,QAAQ,EAAE;wBACR;4BACE,OAAO,EAAE,MAAM;4BACf,OAAO,EAAE,UAAU;4BACnB,eAAe,EAAE,iBAAiB;4BAClC,cAAc,EAAE,IAAI;yBACrB;qBACF;iBACF;aACF;SACF,EACD,GAAG,CACJ,CAAC;QAEF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACrC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,gCAAgC,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,MAAM,OAAO,GAAG,0BAA0B,CAAC;YACzC;gBACE,aAAa,EAAE,MAAM;gBACrB,aAAa,EAAE,MAAM;gBACrB,cAAc,EAAE,WAAW;gBAC3B,MAAM,EAAE,oEAAoE;aAC7E;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC9B,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,6BAA6B,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"focusTopicTransform.test.js","sourceRoot":"","sources":["../../src/__tests__/focusTopicTransform.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,OAAO,EACL,0BAA0B,EAC1B,8BAA8B,GAC/B,MAAM,qCAAqC,CAAC;AAG7C,MAAM,GAAG,GAAc;IACrB,UAAU,EAAE,CAAC,yBAAyB,CAAC;IACvC,QAAQ,EAAE,CAAC,WAAW,CAAC;IACvB,YAAY,EAAE,OAAO;IACrB,eAAe,EAAE,aAAa;CAC/B,CAAC;AAEF,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC1C,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,MAAM,GAAG,8BAA8B,CAC3C;YACE,UAAU,EAAE;gBACV;oBACE,EAAE,EAAE,kBAAkB;oBACtB,IAAI,EAAE,MAAM;oBACZ,QAAQ,EAAE;wBACR;4BACE,OAAO,EAAE,MAAM;4BACf,OAAO,EAAE,UAAU;4BACnB,eAAe,EAAE,iBAAiB;4BAClC,cAAc,EAAE,IAAI;yBACrB;qBACF;iBACF;aACF;SACF,EACD,GAAG,CACJ,CAAC;QAEF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACrC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,gCAAgC,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,MAAM,OAAO,GAAG,0BAA0B,CAAC;YACzC;gBACE,aAAa,EAAE,MAAM;gBACrB,aAAa,EAAE,MAAM;gBACrB,cAAc,EAAE,WAAW;gBAC3B,MAAM,EAAE,wEAAwE;aACjF;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC9B,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,6BAA6B,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=install.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/install.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,136 @@
1
+ import { describe, it } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ // โ”€โ”€ Schema validators โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
4
+ function isValidJsonMcpServers(entry) {
5
+ return (typeof entry.command === "string" &&
6
+ Array.isArray(entry.args) &&
7
+ entry.args.every((a) => typeof a === "string"));
8
+ }
9
+ function isValidJsonMcpLocal(entry) {
10
+ return (entry.type === "local" &&
11
+ Array.isArray(entry.command) &&
12
+ entry.command.every((c) => typeof c === "string") &&
13
+ entry.enabled === true);
14
+ }
15
+ function isValidTomlMcp(content) {
16
+ const lines = content.split("\n");
17
+ return (lines.some((l) => l.trim().startsWith(`[mcp_servers."kevlar-4u"]`)) &&
18
+ lines.some((l) => l.trim().startsWith("command = ")) &&
19
+ lines.some((l) => l.trim().startsWith("args = [")));
20
+ }
21
+ // โ”€โ”€ Import the actual builder functions โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
22
+ // Replicate the getMcpEntry logic inline to avoid importing CLI scripts
23
+ function getMcpEntry(format, cmd, args) {
24
+ if (format === "json-mcp-local") {
25
+ return { type: "local", command: [cmd, ...args], enabled: true };
26
+ }
27
+ const entry = { command: cmd, args };
28
+ if (format === "json-mcpServers" && cmd === "npx") {
29
+ // Some clients (Cursor, CodeBuddy) add type: "stdio"
30
+ }
31
+ return entry;
32
+ }
33
+ function mergeTomlBlock(cmd, args) {
34
+ const serverName = "kevlar-4u";
35
+ return (`[mcp_servers."${serverName}"]\n` +
36
+ `command = "${cmd}"\n` +
37
+ `args = [${args.map((a) => `"${a}"`).join(", ")}]`);
38
+ }
39
+ // โ”€โ”€ Test scenarios โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
40
+ const REMOTE_CMD = "npx";
41
+ const REMOTE_ARGS = ["-y", "kevlar-4u@latest", "--stdio"];
42
+ const LOCAL_CMD = "node";
43
+ const LOCAL_ARGS = ["/usr/local/lib/kevlar-4u/dist/index.js", "--stdio"];
44
+ describe("MCP client config format validation", () => {
45
+ describe("npx remote install", () => {
46
+ it("Claude Desktop (json-mcpServers) produces valid format", () => {
47
+ const entry = getMcpEntry("json-mcpServers", REMOTE_CMD, REMOTE_ARGS);
48
+ assert.ok(isValidJsonMcpServers(entry), `Invalid: ${JSON.stringify(entry)}`);
49
+ assert.equal(entry.command, "npx");
50
+ assert.deepEqual(entry.args, REMOTE_ARGS);
51
+ });
52
+ it("Cursor (json-mcpServers + stdio) produces valid format", () => {
53
+ const entry = getMcpEntry("json-mcpServers", REMOTE_CMD, REMOTE_ARGS);
54
+ // Cursor requires type: "stdio" but base format should still validate
55
+ assert.ok(isValidJsonMcpServers(entry));
56
+ });
57
+ it("Windsurf (json-mcpServers) produces valid format", () => {
58
+ const entry = getMcpEntry("json-mcpServers", REMOTE_CMD, REMOTE_ARGS);
59
+ assert.ok(isValidJsonMcpServers(entry));
60
+ });
61
+ it("OpenCode (json-mcp-local) produces valid format", () => {
62
+ const entry = getMcpEntry("json-mcp-local", REMOTE_CMD, REMOTE_ARGS);
63
+ assert.ok(isValidJsonMcpLocal(entry), `Invalid: ${JSON.stringify(entry)}`);
64
+ assert.equal(entry.type, "local");
65
+ assert.equal(entry.enabled, true);
66
+ assert.ok(entry.command.includes("npx"));
67
+ });
68
+ it("OpenCode (json-mcp-local) with npx command works", () => {
69
+ // Regression: OpenCode previously failed when cmd was "npx"
70
+ const entry = getMcpEntry("json-mcp-local", "npx", ["-y", "kevlar-4u@latest", "--stdio"]);
71
+ assert.ok(isValidJsonMcpLocal(entry), `Invalid: ${JSON.stringify(entry)}`);
72
+ });
73
+ it("Codex (toml-mcp) produces valid format", () => {
74
+ const content = mergeTomlBlock(REMOTE_CMD, REMOTE_ARGS);
75
+ assert.ok(isValidTomlMcp(content), `Invalid TOML:\n${content}`);
76
+ });
77
+ it("Antigravity (json-mcpServers) produces valid format", () => {
78
+ const entry = getMcpEntry("json-mcpServers", REMOTE_CMD, REMOTE_ARGS);
79
+ assert.ok(isValidJsonMcpServers(entry));
80
+ });
81
+ it("CodeBuddy CN (json-mcpServers) produces valid format", () => {
82
+ const entry = getMcpEntry("json-mcpServers", REMOTE_CMD, REMOTE_ARGS);
83
+ assert.ok(isValidJsonMcpServers(entry));
84
+ });
85
+ it("WorkBuddy (json-mcpServers) produces valid format", () => {
86
+ const entry = getMcpEntry("json-mcpServers", REMOTE_CMD, REMOTE_ARGS);
87
+ assert.ok(isValidJsonMcpServers(entry));
88
+ });
89
+ });
90
+ describe("node local install", () => {
91
+ it("OpenCode (json-mcp-local) with node command works", () => {
92
+ const entry = getMcpEntry("json-mcp-local", LOCAL_CMD, LOCAL_ARGS);
93
+ assert.ok(isValidJsonMcpLocal(entry));
94
+ assert.ok(entry.command.includes("node"));
95
+ });
96
+ it("all json-mcpServers clients work with local install", () => {
97
+ for (const client of ["json-mcpServers"]) {
98
+ const entry = getMcpEntry(client, LOCAL_CMD, LOCAL_ARGS);
99
+ assert.ok(isValidJsonMcpServers(entry));
100
+ }
101
+ });
102
+ it("local install TOML is valid", () => {
103
+ const content = mergeTomlBlock(LOCAL_CMD, LOCAL_ARGS);
104
+ assert.ok(isValidTomlMcp(content));
105
+ });
106
+ });
107
+ describe("coverage: all 8 clients generate valid config", () => {
108
+ const clients = [
109
+ { name: "Claude Desktop", format: "json-mcpServers" },
110
+ { name: "Cursor", format: "json-mcpServers" },
111
+ { name: "Windsurf", format: "json-mcpServers" },
112
+ { name: "OpenCode", format: "json-mcp-local" },
113
+ { name: "Codex", format: "toml-mcp" },
114
+ { name: "Antigravity", format: "json-mcpServers" },
115
+ { name: "CodeBuddy CN", format: "json-mcpServers" },
116
+ { name: "WorkBuddy", format: "json-mcpServers" },
117
+ ];
118
+ for (const client of clients) {
119
+ it(`${client.name} (${client.format}) โ†’ valid`, () => {
120
+ if (client.format === "toml-mcp") {
121
+ const content = mergeTomlBlock(REMOTE_CMD, REMOTE_ARGS);
122
+ assert.ok(isValidTomlMcp(content), `${client.name}: invalid TOML`);
123
+ }
124
+ else if (client.format === "json-mcp-local") {
125
+ const entry = getMcpEntry(client.format, REMOTE_CMD, REMOTE_ARGS);
126
+ assert.ok(isValidJsonMcpLocal(entry), `${client.name}: ${JSON.stringify(entry)}`);
127
+ }
128
+ else {
129
+ const entry = getMcpEntry(client.format, REMOTE_CMD, REMOTE_ARGS);
130
+ assert.ok(isValidJsonMcpServers(entry), `${client.name}: ${JSON.stringify(entry)}`);
131
+ }
132
+ });
133
+ }
134
+ });
135
+ });
136
+ //# sourceMappingURL=install.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.test.js","sourceRoot":"","sources":["../../src/__tests__/install.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,8EAA8E;AAE9E,SAAS,qBAAqB,CAAC,KAA8B;IAC3D,OAAO,CACL,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;QACjC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CACxD,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,KAA8B;IACzD,OAAO,CACL,KAAK,CAAC,IAAI,KAAK,OAAO;QACtB,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;QAC5B,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;QAC1D,KAAK,CAAC,OAAO,KAAK,IAAI,CACvB,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,OAAe;IACrC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,OAAO,CACL,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,2BAA2B,CAAC,CAAC;QACnE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QACpD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CACnD,CAAC;AACJ,CAAC;AAED,8EAA8E;AAE9E,wEAAwE;AACxE,SAAS,WAAW,CAAC,MAAc,EAAE,GAAW,EAAE,IAAc;IAC9D,IAAI,MAAM,KAAK,gBAAgB,EAAE,CAAC;QAChC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACnE,CAAC;IACD,MAAM,KAAK,GAA4B,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IAC9D,IAAI,MAAM,KAAK,iBAAiB,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QAClD,qDAAqD;IACvD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CAAC,GAAW,EAAE,IAAc;IACjD,MAAM,UAAU,GAAG,WAAW,CAAC;IAC/B,OAAO,CACL,iBAAiB,UAAU,MAAM;QACjC,cAAc,GAAG,KAAK;QACtB,WAAW,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACnD,CAAC;AACJ,CAAC;AAED,6EAA6E;AAE7E,MAAM,UAAU,GAAG,KAAK,CAAC;AACzB,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,kBAAkB,EAAE,SAAS,CAAC,CAAC;AAC1D,MAAM,SAAS,GAAG,MAAM,CAAC;AACzB,MAAM,UAAU,GAAG,CAAC,wCAAwC,EAAE,SAAS,CAAC,CAAC;AAEzE,QAAQ,CAAC,qCAAqC,EAAE,GAAG,EAAE;IACnD,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;YAChE,MAAM,KAAK,GAAG,WAAW,CAAC,iBAAiB,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;YACtE,MAAM,CAAC,EAAE,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,YAAY,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC7E,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACnC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;YAChE,MAAM,KAAK,GAAG,WAAW,CAAC,iBAAiB,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;YACtE,sEAAsE;YACtE,MAAM,CAAC,EAAE,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,MAAM,KAAK,GAAG,WAAW,CAAC,iBAAiB,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;YACtE,MAAM,CAAC,EAAE,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,KAAK,GAAG,WAAW,CAAC,gBAAgB,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;YACrE,MAAM,CAAC,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,YAAY,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC3E,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAClC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAClC,MAAM,CAAC,EAAE,CAAE,KAAK,CAAC,OAAoB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,4DAA4D;YAC5D,MAAM,KAAK,GAAG,WAAW,CAAC,gBAAgB,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,kBAAkB,EAAE,SAAS,CAAC,CAAC,CAAC;YAC1F,MAAM,CAAC,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,YAAY,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC7E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;YACxD,MAAM,CAAC,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,kBAAkB,OAAO,EAAE,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;YAC7D,MAAM,KAAK,GAAG,WAAW,CAAC,iBAAiB,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;YACtE,MAAM,CAAC,EAAE,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;YAC9D,MAAM,KAAK,GAAG,WAAW,CAAC,iBAAiB,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;YACtE,MAAM,CAAC,EAAE,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;YAC3D,MAAM,KAAK,GAAG,WAAW,CAAC,iBAAiB,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;YACtE,MAAM,CAAC,EAAE,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;YAC3D,MAAM,KAAK,GAAG,WAAW,CAAC,gBAAgB,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;YACnE,MAAM,CAAC,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;YACtC,MAAM,CAAC,EAAE,CAAE,KAAK,CAAC,OAAoB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;YAC7D,KAAK,MAAM,MAAM,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBACzC,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;gBACzD,MAAM,CAAC,EAAE,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;YACrC,MAAM,OAAO,GAAG,cAAc,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;YACtD,MAAM,CAAC,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,+CAA+C,EAAE,GAAG,EAAE;QAC7D,MAAM,OAAO,GAAG;YACd,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,iBAAiB,EAAE;YACrD,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,iBAAiB,EAAE;YAC7C,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,iBAAiB,EAAE;YAC/C,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE;YAC9C,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE;YACrC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,iBAAiB,EAAE;YAClD,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB,EAAE;YACnD,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,iBAAiB,EAAE;SACjD,CAAC;QAEF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,WAAW,EAAE,GAAG,EAAE;gBACnD,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;oBACjC,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;oBACxD,MAAM,CAAC,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,gBAAgB,CAAC,CAAC;gBACrE,CAAC;qBAAM,IAAI,MAAM,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;oBAC9C,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;oBAClE,MAAM,CAAC,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACpF,CAAC;qBAAM,CAAC;oBACN,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;oBAClE,MAAM,CAAC,EAAE,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACtF,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -30,7 +30,7 @@ describe("Prompt expansion hash baselines (Step 1)", () => {
30
30
  it("buildPreAuditFinalizerPrompt with Free segments (loaded from file)", () => {
31
31
  const prompt = buildPreAuditFinalizerPrompt(SAMPLE_AUDITORS, [], FREE_SEGMENTS);
32
32
  const hash = sha256(prompt);
33
- assert.equal(hash, "2095b3d74401d57d062abb1912d05ffdbc9c335ff916f2d8429fcd4e00a8afae", "Free finalizer prompt hash changed โ€” template content drift detected");
33
+ assert.equal(hash, "7d8e861c036f4408365368410682f146a577493eb2084c337b2947d1caac0e05", "Free finalizer prompt hash changed โ€” template content drift detected");
34
34
  });
35
35
  it("buildPreAuditFinalizerPrompt with Pro segments (falls back to Free tier)", () => {
36
36
  const proPrompt = buildPreAuditFinalizerPrompt(SAMPLE_AUDITORS, [{ event: "test", date: "2024" }], PRO_SEGMENTS);
@@ -49,12 +49,12 @@ describe("Prompt expansion hash baselines (Step 1)", () => {
49
49
  step0Result: { wildTranslations: [], blackAtoms: ["ๆต‹่ฏ•"], attackCandidates: [], precedents: [] },
50
50
  });
51
51
  const hash = sha256(msg);
52
- assert.equal(hash, "69ffd459bfbe301a2f21cbaa145a26da935f88660bf576daf41a6678f480c0e0", "Auditor message hash changed");
52
+ assert.equal(hash, "d45712e519c22a96467aebaceb43f9998dade6f450ad463f0943988c208e1343", "Auditor message hash changed");
53
53
  });
54
54
  it("buildOrchestrationFinalizerPrompt with Free segments (loaded from file)", () => {
55
55
  const prompt = buildOrchestrationFinalizerPrompt(SAMPLE_CONTENT, SAMPLE_AUDITORS, [], { triggered: [], overallMultiplier: 1.0, levelUpgrades: [] }, { bareOnly: [], fullOnly: [], stable: [] }, [{ event: "test", date: "2024" }], FREE_SEGMENTS);
56
56
  const hash = sha256(prompt);
57
- assert.equal(hash, "72606698ae6d31fa431158a1af3fe664a644b81d3959422965b9828824433b57", "Free orchestration finalizer hash changed โ€” template content drift detected");
57
+ assert.equal(hash, "b88bf8af0106a34097133fcf9553d2fa6385835f1401f6ae7a9489f5824eab86", "Free orchestration finalizer hash changed โ€” template content drift detected");
58
58
  });
59
59
  it("buildOrchestrationFinalizerPrompt with Pro segments (falls back to Free)", () => {
60
60
  const proPrompt = buildOrchestrationFinalizerPrompt(SAMPLE_CONTENT, SAMPLE_AUDITORS, [], { triggered: [], overallMultiplier: 1.0, levelUpgrades: [] }, { bareOnly: [], fullOnly: [], stable: [] }, [{ event: "test", date: "2024" }], PRO_SEGMENTS);