@rubytech/create-sitedesk-code 0.1.387 → 0.1.388

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 (201) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/config/brand.json +3 -3
  3. package/payload/platform/plugins/.claude-plugin/marketplace.json +0 -5
  4. package/payload/platform/plugins/whatsapp/references/channels-whatsapp.md +5 -3
  5. package/payload/platform/plugins/whatsapp/skills/manage-whatsapp-config/SKILL.md +2 -0
  6. package/payload/premium-plugins/.claude-plugin/marketplace.json +0 -15
  7. package/payload/server/server.js +169 -67
  8. package/payload/platform/plugins/sales/.claude-plugin/plugin.json +0 -8
  9. package/payload/platform/plugins/sales/PLUGIN.md +0 -106
  10. package/payload/platform/plugins/sales/references/close-tracking.md +0 -69
  11. package/payload/platform/plugins/sales/references/comparisons.md +0 -99
  12. package/payload/platform/plugins/sales/references/competitive-positioning.md +0 -51
  13. package/payload/platform/plugins/sales/references/faq.md +0 -73
  14. package/payload/platform/plugins/sales/references/objection-handling.md +0 -157
  15. package/payload/platform/plugins/sales/references/pricing.md +0 -101
  16. package/payload/premium-plugins/teaching/.claude-plugin/plugin.json +0 -8
  17. package/payload/premium-plugins/teaching/PLUGIN.md +0 -58
  18. package/payload/premium-plugins/teaching/skills/interactive-tutor/SKILL.md +0 -59
  19. package/payload/premium-plugins/teaching/skills/interactive-tutor/references/assessment.md +0 -70
  20. package/payload/premium-plugins/teaching/skills/interactive-tutor/references/classroom-conduct.md +0 -43
  21. package/payload/premium-plugins/teaching/skills/interactive-tutor/references/teaching-modes.md +0 -83
  22. package/payload/premium-plugins/teaching/skills/lesson-planner/SKILL.md +0 -48
  23. package/payload/premium-plugins/teaching/skills/lesson-planner/references/context-gathering.md +0 -41
  24. package/payload/premium-plugins/teaching/skills/lesson-planner/references/plan-structure.md +0 -94
  25. package/payload/premium-plugins/teaching/skills/study-pack-builder/SKILL.md +0 -52
  26. package/payload/premium-plugins/teaching/skills/study-pack-builder/references/disaggregation.md +0 -49
  27. package/payload/premium-plugins/teaching/skills/study-pack-builder/references/materials.md +0 -116
  28. package/payload/premium-plugins/venture-studio/.claude-plugin/plugin.json +0 -8
  29. package/payload/premium-plugins/venture-studio/PLUGIN.md +0 -128
  30. package/payload/premium-plugins/venture-studio/bin/scaffold.sh +0 -116
  31. package/payload/premium-plugins/venture-studio/skills/brand-pack/SKILL.md +0 -256
  32. package/payload/premium-plugins/venture-studio/skills/brand-pack/references/color-psychology.md +0 -118
  33. package/payload/premium-plugins/venture-studio/skills/investor-data-room/SKILL.md +0 -436
  34. package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/business-plan-template.md +0 -64
  35. package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/competitive-battlecard.md +0 -37
  36. package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/competitor-analysis.md +0 -32
  37. package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/compliance-research-checklist.md +0 -53
  38. package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/data-room-structure.md +0 -88
  39. package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/deck-blueprint-template.md +0 -39
  40. package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/design-tokens-application.md +0 -79
  41. package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/html-pdf-pipeline.md +0 -236
  42. package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/internal-workings-scrub.md +0 -33
  43. package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/monetization-strategy.md +0 -35
  44. package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/pricing-strategy.md +0 -37
  45. package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/strategy-frameworks.md +0 -46
  46. package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/termsheet-template.md +0 -88
  47. package/payload/premium-plugins/venture-studio/skills/investor-data-room/templates/prospectus/index.html +0 -1565
  48. package/payload/premium-plugins/venture-studio/skills/investor-data-room/templates/prospectus/render-pdf.mjs +0 -91
  49. package/payload/premium-plugins/venture-studio/skills/investor-data-room/templates/prospectus/term_sheet.html +0 -715
  50. package/payload/premium-plugins/venture-studio/skills/legal-essentials/SKILL.md +0 -65
  51. package/payload/premium-plugins/venture-studio/skills/office-hours/SKILL.md +0 -587
  52. package/payload/premium-plugins/venture-studio/skills/prototype-host/SKILL.md +0 -179
  53. package/payload/premium-plugins/venture-studio/skills/prototype-host/references/cloudflared-ingress-edit.md +0 -81
  54. package/payload/premium-plugins/venture-studio/skills/prototype-host/references/scaffold-frameworks.md +0 -60
  55. package/payload/premium-plugins/venture-studio/skills/prototype-host/references/systemd-user-service.md +0 -104
  56. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/SKILL.md +0 -342
  57. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/aarrr-metrics.md +0 -275
  58. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/assumption-testing.md +0 -93
  59. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/boolean-search.md +0 -308
  60. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/build-measure-learn.md +0 -262
  61. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/business-model-canvas.md +0 -171
  62. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/commitment-signals.md +0 -246
  63. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/design-thinking.md +0 -183
  64. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/earlyvangelist.md +0 -190
  65. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/first-principles.md +0 -58
  66. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/fishbone.md +0 -114
  67. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/five-whys.md +0 -43
  68. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/ice-scoring.md +0 -237
  69. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/innovation-accounting.md +0 -290
  70. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/jtbd.md +0 -105
  71. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/landing-page.md +0 -361
  72. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/market-sizing.md +0 -58
  73. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/market-type.md +0 -167
  74. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/mom-test.md +0 -193
  75. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/mvp-types.md +0 -200
  76. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/og-images.md +0 -239
  77. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/pareto.md +0 -103
  78. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/persona-development.md +0 -291
  79. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/pivot-types.md +0 -225
  80. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/positioning-statement.md +0 -179
  81. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/prd.md +0 -363
  82. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/pre-mortem.md +0 -74
  83. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/problem-validation.md +0 -253
  84. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/product-market-fit.md +0 -256
  85. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/research-synthesis.md +0 -276
  86. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/strategy-red-team.md +0 -41
  87. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/three-engines-of-growth.md +0 -248
  88. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/validation-tests.md +0 -89
  89. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/value-proposition-canvas.md +0 -121
  90. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/win-loss-analysis.md +0 -242
  91. package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/references/workflow-mapping.md +0 -271
  92. package/payload/premium-plugins/writer-craft/.claude-plugin/plugin.json +0 -21
  93. package/payload/premium-plugins/writer-craft/PLUGIN.md +0 -134
  94. package/payload/premium-plugins/writer-craft/agents/writer-craft--manuscript-reviewer.md +0 -108
  95. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/dist/index.d.ts +0 -8
  96. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/dist/index.d.ts.map +0 -1
  97. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/dist/index.js +0 -71
  98. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/dist/index.js.map +0 -1
  99. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/package.json +0 -7
  100. package/payload/premium-plugins/writer-craft/lib/mcp-spawn-tee/index.js +0 -193
  101. package/payload/premium-plugins/writer-craft/lib/mcp-spawn-tee/package.json +0 -3
  102. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/dist/index.d.ts +0 -51
  103. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/dist/index.d.ts.map +0 -1
  104. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/dist/index.js +0 -196
  105. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/dist/index.js.map +0 -1
  106. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/package.json +0 -7
  107. package/payload/premium-plugins/writer-craft/mcp/dist/cli/ingest-session-text.d.ts +0 -3
  108. package/payload/premium-plugins/writer-craft/mcp/dist/cli/ingest-session-text.d.ts.map +0 -1
  109. package/payload/premium-plugins/writer-craft/mcp/dist/cli/ingest-session-text.js +0 -58
  110. package/payload/premium-plugins/writer-craft/mcp/dist/cli/ingest-session-text.js.map +0 -1
  111. package/payload/premium-plugins/writer-craft/mcp/dist/index.d.ts +0 -3
  112. package/payload/premium-plugins/writer-craft/mcp/dist/index.d.ts.map +0 -1
  113. package/payload/premium-plugins/writer-craft/mcp/dist/index.js +0 -403
  114. package/payload/premium-plugins/writer-craft/mcp/dist/index.js.map +0 -1
  115. package/payload/premium-plugins/writer-craft/mcp/dist/lib/neo4j.d.ts +0 -14
  116. package/payload/premium-plugins/writer-craft/mcp/dist/lib/neo4j.d.ts.map +0 -1
  117. package/payload/premium-plugins/writer-craft/mcp/dist/lib/neo4j.js +0 -47
  118. package/payload/premium-plugins/writer-craft/mcp/dist/lib/neo4j.js.map +0 -1
  119. package/payload/premium-plugins/writer-craft/mcp/dist/lib/voice-corpus.d.ts +0 -117
  120. package/payload/premium-plugins/writer-craft/mcp/dist/lib/voice-corpus.d.ts.map +0 -1
  121. package/payload/premium-plugins/writer-craft/mcp/dist/lib/voice-corpus.js +0 -138
  122. package/payload/premium-plugins/writer-craft/mcp/dist/lib/voice-corpus.js.map +0 -1
  123. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-distil-profile.d.ts +0 -90
  124. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-distil-profile.d.ts.map +0 -1
  125. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-distil-profile.js +0 -609
  126. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-distil-profile.js.map +0 -1
  127. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-ingest-session-text.d.ts +0 -19
  128. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-ingest-session-text.d.ts.map +0 -1
  129. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-ingest-session-text.js +0 -124
  130. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-ingest-session-text.js.map +0 -1
  131. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-record-feedback.d.ts +0 -38
  132. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-record-feedback.d.ts.map +0 -1
  133. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-record-feedback.js +0 -93
  134. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-record-feedback.js.map +0 -1
  135. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-retrieve-conditioning.d.ts +0 -61
  136. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-retrieve-conditioning.d.ts.map +0 -1
  137. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-retrieve-conditioning.js +0 -171
  138. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-retrieve-conditioning.js.map +0 -1
  139. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-tag-content.d.ts +0 -35
  140. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-tag-content.d.ts.map +0 -1
  141. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-tag-content.js +0 -127
  142. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-tag-content.js.map +0 -1
  143. package/payload/premium-plugins/writer-craft/mcp/package-lock.json +0 -1327
  144. package/payload/premium-plugins/writer-craft/mcp/package.json +0 -19
  145. package/payload/premium-plugins/writer-craft/mcp/scripts/smoke.mjs +0 -420
  146. package/payload/premium-plugins/writer-craft/mcp/src/index.ts +0 -457
  147. package/payload/premium-plugins/writer-craft/mcp/src/lib/neo4j.ts +0 -56
  148. package/payload/premium-plugins/writer-craft/mcp/src/lib/voice-corpus.ts +0 -154
  149. package/payload/premium-plugins/writer-craft/mcp/src/tools/voice-distil-profile.ts +0 -833
  150. package/payload/premium-plugins/writer-craft/mcp/src/tools/voice-ingest-session-text.ts +0 -153
  151. package/payload/premium-plugins/writer-craft/mcp/src/tools/voice-record-feedback.ts +0 -148
  152. package/payload/premium-plugins/writer-craft/mcp/src/tools/voice-retrieve-conditioning.ts +0 -270
  153. package/payload/premium-plugins/writer-craft/mcp/src/tools/voice-tag-content.ts +0 -181
  154. package/payload/premium-plugins/writer-craft/mcp/tsconfig.json +0 -8
  155. package/payload/premium-plugins/writer-craft/skills/citation-style/SKILL.md +0 -94
  156. package/payload/premium-plugins/writer-craft/skills/citation-style/references/book-and-chapter-models.md +0 -77
  157. package/payload/premium-plugins/writer-craft/skills/citation-style/references/citation-rules.md +0 -103
  158. package/payload/premium-plugins/writer-craft/skills/citation-style/references/journal-article-models.md +0 -74
  159. package/payload/premium-plugins/writer-craft/skills/citation-style/references/other-source-models.md +0 -146
  160. package/payload/premium-plugins/writer-craft/skills/citation-style/references/reference-list-rules.md +0 -70
  161. package/payload/premium-plugins/writer-craft/skills/editorial-practice/SKILL.md +0 -108
  162. package/payload/premium-plugins/writer-craft/skills/editorial-practice/references/copyediting.md +0 -73
  163. package/payload/premium-plugins/writer-craft/skills/editorial-practice/references/developmental-editing.md +0 -85
  164. package/payload/premium-plugins/writer-craft/skills/editorial-practice/references/genre-specific-editing.md +0 -78
  165. package/payload/premium-plugins/writer-craft/skills/editorial-practice/references/line-editing.md +0 -55
  166. package/payload/premium-plugins/writer-craft/skills/editorial-practice/references/self-editing.md +0 -89
  167. package/payload/premium-plugins/writer-craft/skills/persuasive-storytelling/SKILL.md +0 -114
  168. package/payload/premium-plugins/writer-craft/skills/persuasive-storytelling/references/audience-analysis.md +0 -73
  169. package/payload/premium-plugins/writer-craft/skills/persuasive-storytelling/references/crafting-persuasive-story.md +0 -76
  170. package/payload/premium-plugins/writer-craft/skills/persuasive-storytelling/references/persuasion-case-studies.md +0 -67
  171. package/payload/premium-plugins/writer-craft/skills/persuasive-storytelling/references/transformation-framework.md +0 -86
  172. package/payload/premium-plugins/writer-craft/skills/point-of-view/SKILL.md +0 -97
  173. package/payload/premium-plugins/writer-craft/skills/point-of-view/references/indirect-narration.md +0 -72
  174. package/payload/premium-plugins/writer-craft/skills/point-of-view/references/pov-types-and-voice.md +0 -91
  175. package/payload/premium-plugins/writer-craft/skills/point-of-view/references/protagonist-filter.md +0 -71
  176. package/payload/premium-plugins/writer-craft/skills/point-of-view/references/tense-and-person.md +0 -85
  177. package/payload/premium-plugins/writer-craft/skills/prose-craft/SKILL.md +0 -100
  178. package/payload/premium-plugins/writer-craft/skills/prose-craft/references/punctuation-and-grammar.md +0 -72
  179. package/payload/premium-plugins/writer-craft/skills/prose-craft/references/repetition.md +0 -71
  180. package/payload/premium-plugins/writer-craft/skills/prose-craft/references/sound-and-rhythm.md +0 -64
  181. package/payload/premium-plugins/writer-craft/skills/prose-craft/references/word-economy.md +0 -93
  182. package/payload/premium-plugins/writer-craft/skills/reader-engagement/SKILL.md +0 -100
  183. package/payload/premium-plugins/writer-craft/skills/reader-engagement/references/cause-effect-setup-payoff.md +0 -79
  184. package/payload/premium-plugins/writer-craft/skills/reader-engagement/references/conflict-escalation.md +0 -81
  185. package/payload/premium-plugins/writer-craft/skills/reader-engagement/references/hooking-readers.md +0 -67
  186. package/payload/premium-plugins/writer-craft/skills/reader-engagement/references/neurochemistry-of-engagement.md +0 -94
  187. package/payload/premium-plugins/writer-craft/skills/review-manuscript/SKILL.md +0 -111
  188. package/payload/premium-plugins/writer-craft/skills/review-manuscript/references/review-manuscript-checklist.md +0 -119
  189. package/payload/premium-plugins/writer-craft/skills/review-prose/SKILL.md +0 -99
  190. package/payload/premium-plugins/writer-craft/skills/review-prose/references/prose-review-checklist.md +0 -112
  191. package/payload/premium-plugins/writer-craft/skills/review-scene/SKILL.md +0 -99
  192. package/payload/premium-plugins/writer-craft/skills/review-scene/references/scene-analysis-framework.md +0 -95
  193. package/payload/premium-plugins/writer-craft/skills/story-architecture/SKILL.md +0 -106
  194. package/payload/premium-plugins/writer-craft/skills/story-architecture/references/blueprinting-and-scene-cards.md +0 -118
  195. package/payload/premium-plugins/writer-craft/skills/story-architecture/references/inner-issue-and-protagonist-goal.md +0 -66
  196. package/payload/premium-plugins/writer-craft/skills/story-architecture/references/misbelief-desire-worldview.md +0 -87
  197. package/payload/premium-plugins/writer-craft/skills/story-architecture/references/origin-scenes-and-escalation.md +0 -82
  198. package/payload/premium-plugins/writer-craft/skills/story-blueprint/SKILL.md +0 -133
  199. package/payload/premium-plugins/writer-craft/skills/story-blueprint/references/blueprinting-exercises.md +0 -118
  200. package/payload/premium-plugins/writer-craft/skills/story-blueprint/references/blueprinting-process.md +0 -128
  201. package/payload/premium-plugins/writer-craft/skills/voice-mirror/SKILL.md +0 -241
@@ -1,19 +0,0 @@
1
- {
2
- "name": "@maxy/writer-craft-mcp",
3
- "version": "0.1.0",
4
- "private": true,
5
- "type": "module",
6
- "main": "dist/index.js",
7
- "scripts": {
8
- "build": "tsc",
9
- "smoke": "node scripts/smoke.mjs"
10
- },
11
- "dependencies": {
12
- "@modelcontextprotocol/sdk": "^1.12.1",
13
- "neo4j-driver": "^5.28.1"
14
- },
15
- "devDependencies": {
16
- "typescript": "^5.7.0",
17
- "@types/node": "^22.0.0"
18
- }
19
- }
@@ -1,420 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Boot + shape smoke test for the writer-craft MCP server.
4
- *
5
- * Verifies without a live Neo4j connection:
6
- * 1. Cypher forbidden-pattern gate (Task 458 fold-in): no NULLS LAST /
7
- * NULLS FIRST / RETURNING patterns in the Cypher emitted by tool sources.
8
- * 2. Every compiled tool module loads without throwing.
9
- * 3. Every exported handler is a function with the expected name.
10
- * 4. AUTHORSHIP_MODES enum covers the five spec-required values.
11
- * 5. TAGGABLE_PRIMARY_LABELS covers the three content labels.
12
- * 6. FORMAT_VALUES covers the six writing-format values (Task 462).
13
- * 7. voiceCorpusWhereWithFormat() appends the format predicate;
14
- * voiceCorpusWhereWithFormatAndAuthor() also appends the author predicate,
15
- * and ORG_USER_ID / profileUserIdForScope map scope→userId (Task 676).
16
- * * 8. voice-retrieve-conditioning discriminates error from no-data (Task 493):
17
- * status:"error" on blank identity and on a forced lookup throw, never
18
- * collapsing a failed lookup into the no-data payload. Personal scope
19
- * requires the caller's userId; org scope is account-wide and resolves
20
- * identity from accountId alone, so a blank userId must not trip the
21
- * missing-identity guard for org scope (Task 975).
22
- * 9. voice-tag-content validates mode and format enums, requires format,
23
- * returns zero counts on empty nodeIds, and requires voiceAuthor when
24
- * there are nodes to tag; resolveVoiceAuthor defaults to the operator
25
- * (Task 676).
26
- * 11. voice-ingest-session-text: filterOperatorText() keeps real turns
27
- * and excludes slash commands, paste blocks, and system reminders.
28
- *
29
- * Exit code: 0 on pass, 1 on any assertion failure.
30
- */
31
- import { strict as assert } from "node:assert";
32
- import { readFileSync } from "node:fs";
33
- import { join, dirname } from "node:path";
34
- import { fileURLToPath } from "node:url";
35
- import { readdirSync } from "node:fs";
36
-
37
- const __dirname = dirname(fileURLToPath(import.meta.url));
38
- const TOOLS_SRC = join(__dirname, "../src/tools");
39
- const LIB_SRC = join(__dirname, "../src/lib");
40
-
41
- const errors = [];
42
- function check(name, fn) {
43
- try {
44
- const result = fn();
45
- if (result && typeof result.then === "function") {
46
- return result.then(
47
- () => console.log(` ok ${name}`),
48
- (err) => {
49
- errors.push({ name, err });
50
- console.error(` FAIL ${name}: ${err.message}`);
51
- },
52
- );
53
- }
54
- console.log(` ok ${name}`);
55
- } catch (err) {
56
- errors.push({ name, err });
57
- console.error(` FAIL ${name}: ${err.message}`);
58
- }
59
- }
60
-
61
- console.log("[writer-craft smoke] starting");
62
-
63
- // ---------------------------------------------------------------------------
64
- // 1. Cypher forbidden-pattern gate (Task 458).
65
- // No NULLS LAST / NULLS FIRST / RETURNING in tool source files.
66
- // These patterns are Postgres-isms; neo4j-driver silently ignores or
67
- // errors on them. The gate runs on .ts source files so it catches issues
68
- // before compilation.
69
- // ---------------------------------------------------------------------------
70
- console.log("\n-- Cypher gate --");
71
- const FORBIDDEN_PATTERNS = [/NULLS\s+LAST/i, /NULLS\s+FIRST/i, /\bRETURNING\b/];
72
-
73
- function scanFile(filePath) {
74
- const content = readFileSync(filePath, "utf-8");
75
- const hits = [];
76
- for (const pat of FORBIDDEN_PATTERNS) {
77
- if (pat.test(content)) hits.push(pat.toString());
78
- }
79
- return hits;
80
- }
81
-
82
- function scanDir(dirPath) {
83
- const allHits = {};
84
- for (const entry of readdirSync(dirPath)) {
85
- if (!entry.endsWith(".ts")) continue;
86
- const filePath = join(dirPath, entry);
87
- const hits = scanFile(filePath);
88
- if (hits.length > 0) allHits[filePath] = hits;
89
- }
90
- return allHits;
91
- }
92
-
93
- await check("no forbidden Cypher patterns in tool sources", () => {
94
- const toolHits = scanDir(TOOLS_SRC);
95
- const libHits = scanDir(LIB_SRC);
96
- const allHits = { ...toolHits, ...libHits };
97
- const fileList = Object.keys(allHits);
98
- assert.equal(
99
- fileList.length,
100
- 0,
101
- `Forbidden Cypher patterns found:\n${fileList.map((f) => ` ${f}: ${allHits[f].join(", ")}`).join("\n")}`,
102
- );
103
- });
104
-
105
- // ---------------------------------------------------------------------------
106
- // 2. Module load + export shape checks.
107
- // ---------------------------------------------------------------------------
108
- console.log("\n-- Module shapes --");
109
- const tagMod = await import("../dist/tools/voice-tag-content.js");
110
- const distilMod = await import("../dist/tools/voice-distil-profile.js");
111
- const retrieveMod = await import("../dist/tools/voice-retrieve-conditioning.js");
112
- const feedbackMod = await import("../dist/tools/voice-record-feedback.js");
113
- const ingestMod = await import("../dist/tools/voice-ingest-session-text.js");
114
- const corpusMod = await import("../dist/lib/voice-corpus.js");
115
-
116
- await check("voice-tag-content exports voiceTagContent function", () => {
117
- assert.equal(typeof tagMod.voiceTagContent, "function");
118
- });
119
- await check("voice-tag-content exports AUTHORSHIP_MODES set of 5", () => {
120
- const expected = [
121
- "human-only",
122
- "human-led-agent-assisted",
123
- "agent-led-human-reviewed",
124
- "agent-only",
125
- "unknown",
126
- ];
127
- assert.equal(tagMod.AUTHORSHIP_MODES.size, 5);
128
- for (const m of expected) assert.ok(tagMod.AUTHORSHIP_MODES.has(m), `missing ${m}`);
129
- });
130
- await check("voice-distil-profile exports voiceDistilProfile function", () => {
131
- assert.equal(typeof distilMod.voiceDistilProfile, "function");
132
- });
133
- await check("voice-retrieve-conditioning exports voiceRetrieveConditioning function", () => {
134
- assert.equal(typeof retrieveMod.voiceRetrieveConditioning, "function");
135
- });
136
- await check("voice-record-feedback exports voiceRecordFeedback function", () => {
137
- assert.equal(typeof feedbackMod.voiceRecordFeedback, "function");
138
- });
139
- await check("voice-ingest-session-text exports required functions", () => {
140
- assert.equal(typeof ingestMod.voiceIngestSessionText, "function");
141
- assert.equal(typeof ingestMod.filterOperatorText, "function");
142
- });
143
-
144
- // ---------------------------------------------------------------------------
145
- // 3. voice-corpus exports — format axis (Task 462).
146
- // ---------------------------------------------------------------------------
147
- console.log("\n-- voice-corpus format exports --");
148
- await check("VOICE_CORPUS_WHERE is non-empty string with both predicates", () => {
149
- assert.equal(typeof corpusMod.VOICE_CORPUS_WHERE, "string");
150
- assert.ok(corpusMod.VOICE_CORPUS_WHERE.includes("authorshipMode IN"));
151
- assert.ok(corpusMod.VOICE_CORPUS_WHERE.includes("human-only"));
152
- assert.ok(corpusMod.VOICE_CORPUS_WHERE.includes("Section"));
153
- });
154
- await check("TAGGABLE_PRIMARY_LABELS covers the three content labels", () => {
155
- const labels = [...corpusMod.TAGGABLE_PRIMARY_LABELS];
156
- assert.deepEqual(labels.sort(), ["KnowledgeDocument", "Message", "SocialPost"]);
157
- });
158
- await check("FORMAT_VALUES covers all six writing formats", () => {
159
- const expected = ["text", "email", "social-post", "article", "marketing-copy", "note"];
160
- const actual = [...corpusMod.FORMAT_VALUES].sort();
161
- assert.deepEqual(actual.sort(), expected.sort());
162
- });
163
- await check("voiceCorpusWhereWithFormat appends format predicate", () => {
164
- const result = corpusMod.voiceCorpusWhereWithFormat("email");
165
- assert.ok(typeof result === "string");
166
- assert.ok(result.includes(corpusMod.VOICE_CORPUS_WHERE));
167
- assert.ok(result.includes("n.format = $format"));
168
- assert.ok(result.includes("email") || result.includes("$format"));
169
- });
170
- await check("voiceCorpusWhereWithFormatAndAuthor appends format + author predicates (Task 676)", () => {
171
- const result = corpusMod.voiceCorpusWhereWithFormatAndAuthor("article");
172
- assert.ok(result.includes(corpusMod.VOICE_CORPUS_WHERE));
173
- assert.ok(result.includes("n.format = $format"));
174
- assert.ok(result.includes("n.voiceAuthor = $voiceAuthor"));
175
- });
176
- await check("ORG_USER_ID sentinel + profileUserIdForScope map scope→userId (Task 676)", () => {
177
- assert.equal(corpusMod.ORG_USER_ID, "__org__");
178
- assert.equal(corpusMod.profileUserIdForScope("org", "ua"), "__org__");
179
- assert.equal(corpusMod.profileUserIdForScope("personal", "ua"), "ua");
180
- });
181
-
182
- // ---------------------------------------------------------------------------
183
- // 4. deriveFormat is gone (Task 471) — format is operator-supplied editorial.
184
- // ---------------------------------------------------------------------------
185
- console.log("\n-- format is operator-supplied --");
186
- await check("deriveFormat export is removed from voice-corpus", () => {
187
- assert.equal(corpusMod.deriveFormat, undefined);
188
- });
189
-
190
- // ---------------------------------------------------------------------------
191
- // 5. Error-vs-no-data discrimination for voice-retrieve-conditioning (Task 493).
192
- // Blank identity and a forced lookup failure must both return status:"error",
193
- // distinct from the genuine no-data state — so the drafting agent never
194
- // reports "no profile exists" when the lookup actually errored.
195
- // ---------------------------------------------------------------------------
196
- console.log("\n-- error-vs-no-data discrimination --");
197
- await check(
198
- "voice-retrieve-conditioning returns status:error on missing accountId",
199
- async () => {
200
- const result = await retrieveMod.voiceRetrieveConditioning({
201
- accountId: "",
202
- userId: "u",
203
- brief: { format: "text", length: "short" },
204
- });
205
- assert.equal(result.status, "error");
206
- assert.equal(result.styleCard, null);
207
- assert.deepEqual(result.exemplars, []);
208
- },
209
- );
210
- await check(
211
- "voice-retrieve-conditioning returns status:error on missing userId (personal scope)",
212
- async () => {
213
- // Default scope is personal, which genuinely needs the caller's userId.
214
- const result = await retrieveMod.voiceRetrieveConditioning({
215
- accountId: "acc",
216
- userId: "",
217
- brief: { format: "email", length: "long" },
218
- });
219
- assert.equal(result.status, "error");
220
- assert.equal(result.error, "missing accountId/userId");
221
- assert.equal(result.styleCard, null);
222
- assert.deepEqual(result.exemplars, []);
223
- },
224
- );
225
- await check(
226
- "voice-retrieve-conditioning org scope does not require a userId (Task 975)",
227
- async () => {
228
- // org scope is account-wide (keyed on ORG_USER_ID + accountId) and never
229
- // reads a userId, so a blank userId must NOT trip the missing-identity
230
- // guard. Force the Neo4j lookup to fail so the guard's absence is provable:
231
- // the call reaches the lookup and returns the connection error, never
232
- // "missing accountId/userId". Save/restore the env + reset the singleton.
233
- const { closeDriver } = await import("../dist/lib/neo4j.js");
234
- const savedUri = process.env.NEO4J_URI;
235
- try {
236
- process.env.NEO4J_URI = "";
237
- await closeDriver();
238
- const result = await retrieveMod.voiceRetrieveConditioning({
239
- accountId: "acc",
240
- userId: "",
241
- brief: { format: "article", length: "long", scope: "org" },
242
- });
243
- assert.equal(result.status, "error");
244
- assert.notEqual(
245
- result.error,
246
- "missing accountId/userId",
247
- "org scope must not trip the missing-identity guard on a blank userId",
248
- );
249
- } finally {
250
- if (savedUri === undefined) delete process.env.NEO4J_URI;
251
- else process.env.NEO4J_URI = savedUri;
252
- await closeDriver();
253
- }
254
- },
255
- );
256
- await check(
257
- "voice-retrieve-conditioning returns status:error (not no-data) when the lookup throws",
258
- async () => {
259
- // Force the Neo4j call to fail: an empty NEO4J_URI makes getSession()
260
- // throw inside the try block. Save/restore the env and reset the driver
261
- // singleton so neither this check nor later checks inherit the empty URI.
262
- const { closeDriver } = await import("../dist/lib/neo4j.js");
263
- const savedUri = process.env.NEO4J_URI;
264
- try {
265
- process.env.NEO4J_URI = "";
266
- await closeDriver();
267
- const result = await retrieveMod.voiceRetrieveConditioning({
268
- accountId: "acc",
269
- userId: "user",
270
- brief: { format: "text", length: "short" },
271
- });
272
- assert.equal(result.status, "error");
273
- assert.notEqual(result.status, "no-data");
274
- assert.equal(result.styleCard, null);
275
- assert.deepEqual(result.exemplars, []);
276
- } finally {
277
- if (savedUri === undefined) delete process.env.NEO4J_URI;
278
- else process.env.NEO4J_URI = savedUri;
279
- await closeDriver();
280
- }
281
- },
282
- );
283
-
284
- // ---------------------------------------------------------------------------
285
- // 6. voice-tag-content enum validation.
286
- // ---------------------------------------------------------------------------
287
- console.log("\n-- voice-tag-content validation --");
288
- await check("voice-tag-content rejects an invalid mode", async () => {
289
- await assert.rejects(
290
- () =>
291
- tagMod.voiceTagContent({
292
- nodeIds: ["x"],
293
- mode: "not-a-mode",
294
- accountId: "acc",
295
- format: "text",
296
- }),
297
- /invalid authorshipMode/,
298
- );
299
- });
300
- await check("voice-tag-content rejects an invalid format", async () => {
301
- await assert.rejects(
302
- () =>
303
- tagMod.voiceTagContent({
304
- nodeIds: ["x"],
305
- mode: "human-only",
306
- accountId: "acc",
307
- format: "bad-format",
308
- }),
309
- /invalid format/,
310
- );
311
- });
312
- await check("voice-tag-content rejects empty accountId", async () => {
313
- await assert.rejects(
314
- () =>
315
- tagMod.voiceTagContent({
316
- nodeIds: ["x"],
317
- mode: "human-only",
318
- accountId: "",
319
- format: "text",
320
- }),
321
- /accountId is required/,
322
- );
323
- });
324
- await check("voice-tag-content rejects missing format", async () => {
325
- await assert.rejects(
326
- () =>
327
- tagMod.voiceTagContent({
328
- nodeIds: ["x"],
329
- mode: "human-only",
330
- accountId: "acc",
331
- }),
332
- /format is required/,
333
- );
334
- });
335
- await check("voice-tag-content returns zero counts on empty nodeIds (no DB hit)", async () => {
336
- const result = await tagMod.voiceTagContent({
337
- nodeIds: [],
338
- mode: "human-only",
339
- accountId: "acc",
340
- format: "text",
341
- });
342
- assert.deepEqual(result, { updated: 0, skipped: 0, skippedReasons: {} });
343
- });
344
- await check("voice-tag-content requires voiceAuthor when there are nodes to tag (Task 676)", async () => {
345
- await assert.rejects(
346
- () =>
347
- tagMod.voiceTagContent({
348
- nodeIds: ["x"],
349
- mode: "human-only",
350
- accountId: "acc",
351
- format: "text",
352
- }),
353
- /voiceAuthor is required/,
354
- );
355
- });
356
- await check("resolveVoiceAuthor: explicit author wins, omitted defaults to operator, neither throws (Task 676)", () => {
357
- assert.equal(tagMod.resolveVoiceAuthor("B", "ua"), "B");
358
- assert.equal(tagMod.resolveVoiceAuthor(undefined, "ua"), "ua");
359
- assert.equal(tagMod.resolveVoiceAuthor(" ", "ua"), "ua");
360
- assert.throws(() => tagMod.resolveVoiceAuthor(undefined, null));
361
- });
362
-
363
- // ---------------------------------------------------------------------------
364
- // 7. voice-ingest-session-text: operator-turn filter (no DB required).
365
- // ---------------------------------------------------------------------------
366
- console.log("\n-- operator-turn filter --");
367
-
368
- await check("filterOperatorText: real turn is kept (and trimmed)", () => {
369
- assert.equal(ingestMod.filterOperatorText(" Hello world "), "Hello world");
370
- });
371
- await check("filterOperatorText: slash command is excluded", () => {
372
- assert.equal(ingestMod.filterOperatorText("/end"), null);
373
- });
374
- await check("filterOperatorText: system-reminder is excluded", () => {
375
- assert.equal(
376
- ingestMod.filterOperatorText("<system-reminder>some injected text</system-reminder>"),
377
- null,
378
- );
379
- });
380
- await check("filterOperatorText: empty / whitespace-only is excluded", () => {
381
- assert.equal(ingestMod.filterOperatorText(" "), null);
382
- });
383
- await check("filterOperatorText: non-string is excluded", () => {
384
- assert.equal(ingestMod.filterOperatorText(undefined), null);
385
- assert.equal(ingestMod.filterOperatorText(42), null);
386
- });
387
- await check("filterOperatorText: paste block >= 4096 chars is excluded", () => {
388
- assert.equal(ingestMod.filterOperatorText("x".repeat(4096)), null);
389
- assert.equal(ingestMod.filterOperatorText("x".repeat(4097)), null);
390
- });
391
- await check("filterOperatorText: 4095 chars is included", () => {
392
- const body = "x".repeat(4095);
393
- assert.equal(ingestMod.filterOperatorText(body), body);
394
- });
395
-
396
- // turns-array semantics: a mixed array filters down to the real turns.
397
- await check(
398
- "turns array: 3 real turns + 3 excluded → filterOperatorText keeps 3",
399
- () => {
400
- const turns = [
401
- "First real turn",
402
- "Second real turn",
403
- "/end", // slash command
404
- "<system-reminder>injected</system-reminder>", // harness injection
405
- "Third real turn",
406
- " ", // whitespace only
407
- ];
408
- const kept = turns.map((t) => ingestMod.filterOperatorText(t)).filter((t) => t !== null);
409
- assert.deepEqual(kept, ["First real turn", "Second real turn", "Third real turn"]);
410
- },
411
- );
412
-
413
- // ---------------------------------------------------------------------------
414
- // Final summary.
415
- // ---------------------------------------------------------------------------
416
- if (errors.length > 0) {
417
- console.error(`\n[writer-craft smoke] FAILED — ${errors.length} assertion(s)`);
418
- process.exit(1);
419
- }
420
- console.log("\n[writer-craft smoke] all passed");