@rubytech/create-maxy-code 0.1.170 → 0.1.171

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 (37) hide show
  1. package/dist/__tests__/premium-mcp-discover.test.js +42 -0
  2. package/dist/lib/premium-mcp-discover.js +9 -2
  3. package/package.json +1 -1
  4. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/dist/index.d.ts +51 -0
  5. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/dist/index.d.ts.map +1 -0
  6. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/dist/index.js +196 -0
  7. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/dist/index.js.map +1 -0
  8. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/package.json +7 -0
  9. package/payload/premium-plugins/writer-craft/mcp/dist/index.d.ts +3 -0
  10. package/payload/premium-plugins/writer-craft/mcp/dist/index.d.ts.map +1 -0
  11. package/payload/premium-plugins/writer-craft/mcp/dist/index.js +257 -0
  12. package/payload/premium-plugins/writer-craft/mcp/dist/index.js.map +1 -0
  13. package/payload/premium-plugins/writer-craft/mcp/dist/lib/neo4j.d.ts +14 -0
  14. package/payload/premium-plugins/writer-craft/mcp/dist/lib/neo4j.d.ts.map +1 -0
  15. package/payload/premium-plugins/writer-craft/mcp/dist/lib/neo4j.js +47 -0
  16. package/payload/premium-plugins/writer-craft/mcp/dist/lib/neo4j.js.map +1 -0
  17. package/payload/premium-plugins/writer-craft/mcp/dist/lib/voice-corpus.d.ts +42 -0
  18. package/payload/premium-plugins/writer-craft/mcp/dist/lib/voice-corpus.d.ts.map +1 -0
  19. package/payload/premium-plugins/writer-craft/mcp/dist/lib/voice-corpus.js +54 -0
  20. package/payload/premium-plugins/writer-craft/mcp/dist/lib/voice-corpus.js.map +1 -0
  21. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-distil-profile.d.ts +36 -0
  22. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-distil-profile.d.ts.map +1 -0
  23. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-distil-profile.js +225 -0
  24. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-distil-profile.js.map +1 -0
  25. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-record-feedback.d.ts +26 -0
  26. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-record-feedback.d.ts.map +1 -0
  27. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-record-feedback.js +74 -0
  28. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-record-feedback.js.map +1 -0
  29. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-retrieve-conditioning.d.ts +22 -0
  30. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-retrieve-conditioning.d.ts.map +1 -0
  31. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-retrieve-conditioning.js +102 -0
  32. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-retrieve-conditioning.js.map +1 -0
  33. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-tag-content.d.ts +14 -0
  34. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-tag-content.d.ts.map +1 -0
  35. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-tag-content.js +84 -0
  36. package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-tag-content.js.map +1 -0
  37. package/payload/premium-plugins/writer-craft/mcp/package-lock.json +1327 -0
@@ -0,0 +1,102 @@
1
+ /**
2
+ * voice-retrieve-conditioning — return the operator's style card plus K
3
+ * voice-matched exemplars for a drafting brief.
4
+ *
5
+ * Retrieval order (best to worst):
6
+ * 1. If brief.topic is provided AND keyword search on the human-only corpus
7
+ * returns ≥K matches → use those (ordered by recency).
8
+ * 2. Otherwise, return the K most-recent human-only nodes.
9
+ *
10
+ * Embeddings are not used in v1: the corpus is small (single operator's
11
+ * personal writing — typically <500 docs), and recency-with-keyword-filter
12
+ * is both faster and more predictable than vector ANN at that scale.
13
+ * Vector-search is a Task 365-follow-up if the corpus grows beyond the
14
+ * 500-doc breakeven point.
15
+ *
16
+ * Graceful degradation: missing profile, empty corpus, and DB errors all
17
+ * return `{styleCard: null, exemplars: []}` rather than throwing — the
18
+ * calling drafting skill falls back to its existing default register.
19
+ */
20
+ import { getSession } from "../lib/neo4j.js";
21
+ import { VOICE_CORPUS_WHERE } from "../lib/voice-corpus.js";
22
+ const DEFAULT_TOKEN_BUDGET_SHORT = 16_000;
23
+ const DEFAULT_TOKEN_BUDGET_LONG = 96_000;
24
+ const CHARS_PER_TOKEN = 4;
25
+ const EMPTY = { styleCard: null, exemplars: [] };
26
+ export async function voiceRetrieveConditioning(params) {
27
+ const { accountId, adminUserId, brief } = params;
28
+ if (!accountId || !adminUserId)
29
+ return EMPTY;
30
+ const k = brief.format === "long" ? 15 : 5;
31
+ const tokenBudget = params.tokenBudget ??
32
+ (brief.format === "long" ? DEFAULT_TOKEN_BUDGET_LONG : DEFAULT_TOKEN_BUDGET_SHORT);
33
+ const charBudget = tokenBudget * CHARS_PER_TOKEN;
34
+ const session = getSession();
35
+ try {
36
+ // 1. Style card.
37
+ const profile = await session.run(`MATCH (a:AdminUser {accountId: $accountId, adminUserId: $adminUserId})
38
+ OPTIONAL MATCH (a)-[:HAS_VOICE_PROFILE]->(p:VoiceProfile)
39
+ RETURN p.styleCard AS styleCard`, { accountId, adminUserId });
40
+ const styleCard = profile.records[0]?.get("styleCard") ?? null;
41
+ // 2. Exemplars. Keyword-aware filter when brief.topic is set.
42
+ const topic = (brief.topic ?? "").trim();
43
+ const usesTopic = topic.length > 0;
44
+ const cypher = usesTopic
45
+ ? `MATCH (n)
46
+ WHERE ${VOICE_CORPUS_WHERE}
47
+ AND toLower(coalesce(n.body, n.abstract, n.subject, n.title, n.summary, '')) CONTAINS toLower($topic)
48
+ WITH n, coalesce(n.dateSent, n.datePublished, n.firstMessageAt, n.dateCreated, n.createdAt) AS ts
49
+ RETURN elementId(n) AS id,
50
+ labels(n) AS labels,
51
+ coalesce(n.body, n.abstract, n.subject, n.title, n.summary, '') AS body,
52
+ coalesce(n.subject, n.title, n.name, '') AS source,
53
+ ts
54
+ ORDER BY ts DESC NULLS LAST
55
+ LIMIT $k`
56
+ : `MATCH (n)
57
+ WHERE ${VOICE_CORPUS_WHERE}
58
+ WITH n, coalesce(n.dateSent, n.datePublished, n.firstMessageAt, n.dateCreated, n.createdAt) AS ts
59
+ RETURN elementId(n) AS id,
60
+ labels(n) AS labels,
61
+ coalesce(n.body, n.abstract, n.subject, n.title, n.summary, '') AS body,
62
+ coalesce(n.subject, n.title, n.name, '') AS source,
63
+ ts
64
+ ORDER BY ts DESC NULLS LAST
65
+ LIMIT $k`;
66
+ const result = await session.run(cypher, {
67
+ accountId,
68
+ topic,
69
+ k,
70
+ });
71
+ let charsUsed = 0;
72
+ const exemplars = [];
73
+ for (const r of result.records) {
74
+ const body = r.get("body") ?? "";
75
+ if (body.length === 0)
76
+ continue;
77
+ const labels = r.get("labels") ?? [];
78
+ const label = labels.find((l) => ["KnowledgeDocument", "Message", "SocialPost", "Conversation"].includes(l)) ?? labels[0] ?? "Unknown";
79
+ const remaining = charBudget - charsUsed;
80
+ if (remaining <= 0)
81
+ break;
82
+ const truncated = body.length > remaining ? body.slice(0, remaining) : body;
83
+ exemplars.push({
84
+ nodeId: r.get("id"),
85
+ label,
86
+ body: truncated,
87
+ source: (r.get("source") ?? "").slice(0, 200),
88
+ });
89
+ charsUsed += truncated.length;
90
+ }
91
+ process.stderr.write(`[voice-retrieve] task=${brief.topic ?? brief.format} styleCardBytes=${styleCard?.length ?? 0} exemplarCount=${exemplars.length} tokenBudget=${tokenBudget}\n`);
92
+ return { styleCard, exemplars };
93
+ }
94
+ catch (err) {
95
+ process.stderr.write(`[voice-retrieve] error: ${err instanceof Error ? err.message : String(err)}\n`);
96
+ return EMPTY;
97
+ }
98
+ finally {
99
+ await session.close();
100
+ }
101
+ }
102
+ //# sourceMappingURL=voice-retrieve-conditioning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-retrieve-conditioning.js","sourceRoot":"","sources":["../../src/tools/voice-retrieve-conditioning.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export type AuthorshipMode = "human-only" | "human-led-agent-assisted" | "agent-led-human-reviewed" | "agent-only" | "unknown";
2
+ export declare const AUTHORSHIP_MODES: ReadonlySet<AuthorshipMode>;
3
+ export interface VoiceTagContentParams {
4
+ nodeIds: string[];
5
+ mode: AuthorshipMode;
6
+ accountId: string;
7
+ }
8
+ export interface VoiceTagContentResult {
9
+ updated: number;
10
+ skipped: number;
11
+ skippedReasons: Record<string, number>;
12
+ }
13
+ export declare function voiceTagContent(params: VoiceTagContentParams): Promise<VoiceTagContentResult>;
14
+ //# sourceMappingURL=voice-tag-content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-tag-content.d.ts","sourceRoot":"","sources":["../../src/tools/voice-tag-content.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,cAAc,GACtB,YAAY,GACZ,0BAA0B,GAC1B,0BAA0B,GAC1B,YAAY,GACZ,SAAS,CAAC;AAEd,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,cAAc,CAMvD,CAAC;AAEH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED,wBAAsB,eAAe,CACnC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CA4EhC"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * voice-tag-content — set `authorshipMode` on one or many content nodes.
3
+ *
4
+ * The tool routes through neo4j directly with an account-scoped MERGE so
5
+ * the operator can only mutate their own nodes. We do not go through
6
+ * `memory-update` because that tool re-embeds and re-validates on every
7
+ * call — overkill for a single-property authorship stamp.
8
+ */
9
+ import { getSession } from "../lib/neo4j.js";
10
+ import { TAGGABLE_PRIMARY_LABELS } from "../lib/voice-corpus.js";
11
+ export const AUTHORSHIP_MODES = new Set([
12
+ "human-only",
13
+ "human-led-agent-assisted",
14
+ "agent-led-human-reviewed",
15
+ "agent-only",
16
+ "unknown",
17
+ ]);
18
+ export async function voiceTagContent(params) {
19
+ const { nodeIds, mode, accountId } = params;
20
+ if (!AUTHORSHIP_MODES.has(mode)) {
21
+ throw new Error(`voice-tag-content: invalid authorshipMode '${mode}'. Valid values: ${[
22
+ ...AUTHORSHIP_MODES,
23
+ ].join(", ")}`);
24
+ }
25
+ if (!accountId) {
26
+ throw new Error("voice-tag-content: accountId is required");
27
+ }
28
+ if (!Array.isArray(nodeIds) || nodeIds.length === 0) {
29
+ return { updated: 0, skipped: 0, skippedReasons: {} };
30
+ }
31
+ const session = getSession();
32
+ const now = new Date().toISOString();
33
+ const skippedReasons = {};
34
+ let updated = 0;
35
+ try {
36
+ // Bulk update in batches of 50 to keep transaction latency bounded.
37
+ const BATCH = 50;
38
+ for (let i = 0; i < nodeIds.length; i += BATCH) {
39
+ const batch = nodeIds.slice(i, i + BATCH);
40
+ const result = await session.run(
41
+ // Tag any of the four primary content labels, or a conversation-
42
+ // document :Section chunk (parent :KnowledgeDocument carries
43
+ // `conversationIdentity`). The EXISTS sub-pattern guards against
44
+ // accidentally tagging document-path :Section rows AND parent
45
+ // `:Conversation` / `:AdminConversation` nodes (which are not
46
+ // body-bearing content).
47
+ `UNWIND $ids AS id
48
+ MATCH (n) WHERE elementId(n) = id AND n.accountId = $accountId
49
+ WITH n
50
+ WHERE any(lbl IN labels(n) WHERE lbl IN $primaryLabels)
51
+ OR ('Section' IN labels(n) AND EXISTS {
52
+ MATCH (parent:KnowledgeDocument)-[:HAS_SECTION]->(n)
53
+ WHERE parent.conversationIdentity IS NOT NULL
54
+ })
55
+ SET n.authorshipMode = $mode,
56
+ n.authorshipTaggedAt = $now
57
+ RETURN elementId(n) AS id`, {
58
+ ids: batch,
59
+ accountId,
60
+ mode,
61
+ now,
62
+ primaryLabels: [...TAGGABLE_PRIMARY_LABELS],
63
+ });
64
+ const matched = new Set(result.records.map((r) => r.get("id")));
65
+ updated += matched.size;
66
+ for (const id of batch) {
67
+ if (matched.has(id))
68
+ continue;
69
+ const reason = "not-found-or-not-content-label";
70
+ skippedReasons[reason] = (skippedReasons[reason] ?? 0) + 1;
71
+ }
72
+ }
73
+ }
74
+ finally {
75
+ await session.close();
76
+ }
77
+ process.stderr.write(`[voice-tag] mode=${mode} accountId=${accountId} updated=${updated} skipped=${nodeIds.length - updated}\n`);
78
+ return {
79
+ updated,
80
+ skipped: nodeIds.length - updated,
81
+ skippedReasons,
82
+ };
83
+ }
84
+ //# sourceMappingURL=voice-tag-content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-tag-content.js","sourceRoot":"","sources":["../../src/tools/voice-tag-content.ts"],"names":[],"mappings":"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"}