@rubytech/create-maxy-code 0.1.254 → 0.1.256
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.
- package/dist/__tests__/plugin-install.test.js +58 -40
- package/dist/index.js +77 -26
- package/dist/lib/plugin-install.js +31 -29
- package/package.json +1 -1
- package/payload/platform/.docs/search-surface-contract.md +58 -0
- package/payload/platform/config/brand-registry.json +8 -0
- package/payload/platform/config/brand.json +3 -3
- package/payload/platform/lib/embed-client/dist/index.d.ts +4 -0
- package/payload/platform/lib/embed-client/dist/index.d.ts.map +1 -0
- package/payload/platform/lib/embed-client/dist/index.js +53 -0
- package/payload/platform/lib/embed-client/dist/index.js.map +1 -0
- package/payload/platform/lib/embed-client/src/index.ts +53 -0
- package/payload/platform/lib/embed-client/tsconfig.json +8 -0
- package/payload/platform/lib/graph-search/dist/index.d.ts +27 -6
- package/payload/platform/lib/graph-search/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/graph-search/dist/index.js +19 -1
- package/payload/platform/lib/graph-search/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-search/src/__tests__/fulltext-coverage.test.ts +12 -0
- package/payload/platform/lib/graph-search/src/index.ts +28 -6
- package/payload/platform/lib/graph-write/dist/index.d.ts +25 -0
- package/payload/platform/lib/graph-write/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/graph-write/dist/index.js +80 -2
- package/payload/platform/lib/graph-write/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-write/src/index.ts +98 -1
- package/payload/platform/neo4j/schema.cypher +126 -0
- package/payload/platform/package.json +2 -2
- package/payload/platform/plugins/.claude-plugin/marketplace.json +5 -0
- package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/admin/PLUGIN.md +3 -6
- package/payload/platform/plugins/admin/mcp/dist/index.js +14 -60
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/skills/insight/SKILL.md +24 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +84 -31
- package/payload/platform/plugins/docs/PLUGIN.md +1 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +1 -1
- package/payload/platform/plugins/docs/references/deployment.md +18 -5
- package/payload/platform/plugins/docs/references/graph.md +2 -0
- package/payload/platform/plugins/docs/references/internals.md +12 -1
- package/payload/platform/plugins/docs/references/memory-guide.md +4 -0
- package/payload/platform/plugins/docs/references/neo4j.md +2 -2
- package/payload/platform/plugins/docs/references/platform.md +1 -1
- package/payload/platform/plugins/docs/references/plugins-guide.md +1 -1
- package/payload/platform/plugins/docs/references/session-retrospective.md +5 -18
- package/payload/platform/plugins/docs/references/slides.md +31 -0
- package/payload/platform/plugins/docs/references/voice-mirror-guide.md +1 -1
- package/payload/platform/plugins/email/PLUGIN.md +2 -2
- package/payload/platform/plugins/email/mcp/dist/index.js +8 -0
- package/payload/platform/plugins/email/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/attachment-resolve.d.ts +19 -0
- package/payload/platform/plugins/email/mcp/dist/lib/attachment-resolve.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/attachment-resolve.js +64 -0
- package/payload/platform/plugins/email/mcp/dist/lib/attachment-resolve.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/smtp.d.ts +4 -0
- package/payload/platform/plugins/email/mcp/dist/lib/smtp.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/smtp.js +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/smtp.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-reply.d.ts +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-reply.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-reply.js +6 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-reply.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-send.d.ts +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-send.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-send.js +7 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-send.js.map +1 -1
- package/payload/platform/plugins/email/references/email-reference.md +4 -0
- package/payload/platform/plugins/memory/PLUGIN.md +1 -2
- package/payload/platform/plugins/memory/mcp/dist/index.js +6 -44
- package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/document-sectioniser.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/document-sectioniser.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/document-sectioniser.test.js +41 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/document-sectioniser.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/graph-write-embed-net.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/graph-write-embed-net.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/graph-write-embed-net.test.js +90 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/graph-write-embed-net.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/vector-indexed-labels-drift.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/vector-indexed-labels-drift.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/vector-indexed-labels-drift.test.js +27 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/vector-indexed-labels-drift.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/document-sectioniser.d.ts +10 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/document-sectioniser.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/document-sectioniser.js +47 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/document-sectioniser.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/embeddings.d.ts +1 -2
- package/payload/platform/plugins/memory/mcp/dist/lib/embeddings.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/embeddings.js +5 -28
- package/payload/platform/plugins/memory/mcp/dist/lib/embeddings.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/build-text-representation-bound.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/build-text-representation-bound.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/build-text-representation-bound.test.js +20 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/build-text-representation-bound.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-preference-embed.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-preference-embed.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-preference-embed.test.js +67 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-preference-embed.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embeddings-cap.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embeddings-cap.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embeddings-cap.test.js +34 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embeddings-cap.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-section-writer.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-section-writer.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-section-writer.test.js +61 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-section-writer.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-write.test.js +23 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-write.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-reindex.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-reindex.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-reindex.test.js +87 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-reindex.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-fields.test.js +3 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-fields.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-threshold.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-threshold.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-threshold.test.js +34 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-threshold.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js +19 -4
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.d.ts +33 -6
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js +280 -10
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.js +76 -37
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.js +11 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-typed-edge-pass.d.ts +4 -4
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-typed-edge-pass.js +3 -3
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js +20 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +6 -3
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/vitest.config.ts +5 -0
- package/payload/platform/plugins/memory/references/schema-base.md +1 -1
- package/payload/platform/plugins/memory/references/schema-construction.md +72 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/ics-graph-ingest.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/ics-graph-ingest.js +15 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/ics-graph-ingest.js.map +1 -1
- package/payload/platform/plugins/slides/.claude-plugin/plugin.json +8 -0
- package/payload/platform/plugins/slides/LICENSE +21 -0
- package/payload/platform/plugins/slides/PLUGIN.md +18 -0
- package/payload/platform/plugins/slides/PROVENANCE.md +40 -0
- package/payload/platform/plugins/slides/commands/add-slide.md +29 -0
- package/payload/platform/plugins/slides/commands/slides-claus.md +39 -0
- package/payload/platform/plugins/slides/commands/slides-new-component.md +39 -0
- package/payload/platform/plugins/slides/commands/slides-outline.md +43 -0
- package/payload/platform/plugins/slides/commands/slides-review.md +52 -0
- package/payload/platform/plugins/slides/commands/slides-theme.md +64 -0
- package/payload/platform/plugins/slides/commands/slides.md +59 -0
- package/payload/platform/plugins/slides/skills/deck-system/REFERENCE.md +581 -0
- package/payload/platform/plugins/slides/skills/deck-system/SKILL.md +607 -0
- package/payload/platform/plugins/slides/skills/deck-system/STORYTELLING-board.md +426 -0
- package/payload/platform/plugins/slides/skills/deck-system/STORYTELLING-claus.md +185 -0
- package/payload/platform/plugins/slides/skills/deck-system/STORYTELLING-mbb.md +450 -0
- package/payload/platform/plugins/slides/skills/deck-system/STORYTELLING-product-launch.md +579 -0
- package/payload/platform/plugins/slides/skills/deck-system/STORYTELLING-sales.md +464 -0
- package/payload/platform/plugins/slides/skills/deck-system/STORYTELLING-sequoia.md +489 -0
- package/payload/platform/plugins/slides/skills/deck-system/STORYTELLING.md +273 -0
- package/payload/platform/plugins/slides/skills/deck-system/deck-craft.html +1371 -0
- package/payload/platform/plugins/slides/skills/deck-system/deck-solid.html +1667 -0
- package/payload/platform/plugins/slides/skills/deck-system/deck.html +1359 -0
- package/payload/platform/plugins/url-get/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/url-get/PLUGIN.md +26 -21
- package/payload/platform/plugins/url-get/mcp/dist/index.js +3 -3
- package/payload/platform/plugins/url-get/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/url-get/mcp/dist/tools/url-get.d.ts +1 -2
- package/payload/platform/plugins/url-get/mcp/dist/tools/url-get.d.ts.map +1 -1
- package/payload/platform/plugins/url-get/mcp/dist/tools/url-get.js +20 -40
- package/payload/platform/plugins/url-get/mcp/dist/tools/url-get.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js +4 -0
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js.map +1 -1
- package/payload/platform/scripts/identity-forbidden-token-check.mjs +0 -1
- package/payload/platform/scripts/setup-account.sh +0 -15
- package/payload/platform/services/claude-session-manager/dist/agent-identity-locator.d.ts +23 -0
- package/payload/platform/services/claude-session-manager/dist/agent-identity-locator.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/agent-identity-locator.js +29 -0
- package/payload/platform/services/claude-session-manager/dist/agent-identity-locator.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +0 -2
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +5 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +32 -2
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +8 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.d.ts +13 -1
- package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.js +26 -2
- package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +2 -2
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts +12 -3
- package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/system-prompt.js +3 -2
- package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -1
- package/payload/platform/templates/agents/admin/IDENTITY.md +2 -2
- package/payload/platform/templates/specialists/agents/database-operator.md +3 -7
- package/payload/platform/templates/specialists/agents/typed-edge-classifier.md +1 -1
- package/payload/premium-plugins/writer-craft/PLUGIN.md +2 -2
- package/payload/premium-plugins/writer-craft/mcp/dist/index.js +5 -5
- package/payload/premium-plugins/writer-craft/mcp/dist/index.js.map +1 -1
- package/payload/premium-plugins/writer-craft/mcp/dist/lib/voice-corpus.d.ts +1 -1
- package/payload/premium-plugins/writer-craft/mcp/dist/lib/voice-corpus.js +1 -1
- package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-ingest-session-text.d.ts +4 -8
- package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-ingest-session-text.d.ts.map +1 -1
- package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-ingest-session-text.js +30 -98
- package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-ingest-session-text.js.map +1 -1
- package/payload/premium-plugins/writer-craft/mcp/scripts/smoke.mjs +37 -114
- package/payload/premium-plugins/writer-craft/mcp/src/index.ts +5 -5
- package/payload/premium-plugins/writer-craft/mcp/src/lib/voice-corpus.ts +1 -1
- package/payload/premium-plugins/writer-craft/mcp/src/tools/voice-ingest-session-text.ts +29 -106
- package/payload/premium-plugins/writer-craft/skills/voice-mirror/SKILL.md +15 -17
- package/payload/server/{chunk-M6A6EZD4.js → chunk-76HRO7NX.js} +16 -2
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/public/assets/AdminShell-T-YknnBn.js +1 -0
- package/payload/server/public/assets/Checkbox-DmDxpqVv.js +1 -0
- package/payload/server/public/assets/admin-COUV-jgt.js +1 -0
- package/payload/server/public/assets/{arc-aUiRP9AS.js → arc-B2CweJq3.js} +1 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-Dnn6Hc65.js +1 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-c09loTER.js → architectureDiagram-Q4EWVU46-DP2o-MFV.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-Cjdeyoq1.js → blockDiagram-DXYQGD6D-DO4mcYDJ.js} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-NY6Wlzo2.js → c4Diagram-AHTNJAMY-Sy1giHbj.js} +1 -1
- package/payload/server/public/assets/channel-CEpR_0rE.js +1 -0
- package/payload/server/public/assets/{chunk-2KRD3SAO-BK3470lx.js → chunk-2KRD3SAO-CKsCYCsN.js} +1 -1
- package/payload/server/public/assets/chunk-336JU56O-C0-P-aUF.js +2 -0
- package/payload/server/public/assets/chunk-426QAEUC-DFjEt3Zb.js +1 -0
- package/payload/server/public/assets/{chunk-4BX2VUAB-BOvVdJLf.js → chunk-4BX2VUAB-B8bqAmBa.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-BXpto3yW.js → chunk-4TB4RGXK-D1k0VSlW.js} +1 -1
- package/payload/server/public/assets/{chunk-55IACEB6-BwZyF7vR.js → chunk-55IACEB6-B-p_QNqz.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-C403gCUk.js → chunk-5FUZZQ4R-D6U6tV_j.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-CjVzXQEp.js → chunk-5PVQY5BW-CYK76xfs.js} +1 -1
- package/payload/server/public/assets/{chunk-67CJDMHE-D5bhMrtY.js → chunk-67CJDMHE-BC9js-lf.js} +1 -1
- package/payload/server/public/assets/{chunk-7N4EOEYR-Si7Lgrwc.js → chunk-7N4EOEYR-4j2OqKkv.js} +1 -1
- package/payload/server/public/assets/{chunk-AA7GKIK3-DMuHtDqO.js → chunk-AA7GKIK3-Coen-fXN.js} +1 -1
- package/payload/server/public/assets/{chunk-BSJP7CBP-L79XKVcb.js → chunk-BSJP7CBP-CAiOBvec.js} +1 -1
- package/payload/server/public/assets/{chunk-CIAEETIT-C0O7Upmg.js → chunk-CIAEETIT-AJzzpZVb.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-DJcJAsAg.js → chunk-EDXVE4YY-BL4BKozX.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-CFDNvYu1.js → chunk-ENJZ2VHE-mhAFG8UD.js} +1 -1
- package/payload/server/public/assets/{chunk-FMBD7UC4-C_E43NFJ.js → chunk-FMBD7UC4-H231gZA_.js} +1 -1
- package/payload/server/public/assets/{chunk-FOC6F5B3-D9lWWHAu.js → chunk-FOC6F5B3-Cl3ZZjYG.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-ecLOxGhL.js → chunk-ICPOFSXX-DOEzvzJa.js} +2 -2
- package/payload/server/public/assets/{chunk-K5T4RW27-DuhsNH4c.js → chunk-K5T4RW27-C_ipbUDD.js} +1 -1
- package/payload/server/public/assets/{chunk-KGLVRYIC-B4-A1Abi.js → chunk-KGLVRYIC-CTsDNSCU.js} +1 -1
- package/payload/server/public/assets/{chunk-LIHQZDEY-BxqgHRgT.js → chunk-LIHQZDEY-DvSXhkGf.js} +1 -1
- package/payload/server/public/assets/{chunk-ORNJ4GCN-DEYQ5WaJ.js → chunk-ORNJ4GCN-p574NOI7.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-B7MW66KB.js → chunk-OYMX7WX6-BlEgFM6U.js} +1 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-DpF06ZZQ.js +1 -0
- package/payload/server/public/assets/{chunk-U2HBQHQK-BMawmsyk.js → chunk-U2HBQHQK-B2bDK0jv.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-CT6g7pno.js → chunk-X2U36JSP-D69BxKFw.js} +1 -1
- package/payload/server/public/assets/{chunk-XPW4576I-CBfZXZDB.js → chunk-XPW4576I-Dm-PcyUi.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-xeAluiAH.js → chunk-YZCP3GAM-Be8RnXgx.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-BRN9qUC5.js → chunk-ZZ45TVLE-Ck8PCTa4.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-CYbXvKLI.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DEyHzRhq.js +1 -0
- package/payload/server/public/assets/clone-y8gexbBy.js +1 -0
- package/payload/server/public/assets/{cose-bilkent-S5V4N54A-Br2gjtEO.js → cose-bilkent-S5V4N54A-CmkW2Eaj.js} +1 -1
- package/payload/server/public/assets/{dagre-DTjePoco.js → dagre-Dqp-ns8F.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-DHBkRke4.js → dagre-KV5264BT-ZgWWXPLc.js} +1 -1
- package/payload/server/public/assets/data-gy6QH9c1.js +1 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-BIq1-idL.js → diagram-5BDNPKRD-CTX5-ScM.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-BsIUDzV6.js → diagram-G4DWMVQ6-BovIsO6H.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-CgHSri2i.js → diagram-MMDJMWI5-DcETsQy-.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-Ce2Wh9ZX.js → diagram-TYMM5635-yyq6peoZ.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-BU0Kh6OQ.js → erDiagram-SMLLAGMA-CiNToftB.js} +1 -1
- package/payload/server/public/assets/{flatten-Bo6YRmWl.js → flatten-BtFI066E.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-B0N06MF7.js → flowDiagram-DWJPFMVM-Xnl3SpIM.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-BVbx4ARZ.js → ganttDiagram-T4ZO3ILL-C1iyWe0f.js} +1 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-CNs-LD5i.js +1 -0
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-C-xRJ94t.js → gitGraphDiagram-UUTBAWPF-D97pbMQb.js} +1 -1
- package/payload/server/public/assets/graph-labels-cZu4pK16.js +1 -0
- package/payload/server/public/assets/{graph-g48ZcA5M.js → graph-qz5tFKqU.js} +3 -3
- package/payload/server/public/assets/{graphlib-YmNcoMjY.js → graphlib-Lq8ijgON.js} +1 -1
- package/payload/server/public/assets/info-OMHHGYJF-DsTNigSS.js +1 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-C_OarRTA.js +2 -0
- package/payload/server/public/assets/{isEmpty-D6Kr-M1M.js → isEmpty-D6QovjYR.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-DTrq54yC.js → ishikawaDiagram-UXIWVN3A-B8XBdjJn.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-OZZZMrFX.js → journeyDiagram-VCZTEJTY-CZYbiOaQ.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY--w-IP9pN.js → kanban-definition-6JOO6SKY-B1PybFoh.js} +1 -1
- package/payload/server/public/assets/{line-Ckeulv5T.js → line-D-tw3hHp.js} +1 -1
- package/payload/server/public/assets/{linear-DOh_6k2k.js → linear-BHhXD3cd.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-CVRAxYRD.js → mermaid-parser.core-C9RAnysF.js} +2 -2
- package/payload/server/public/assets/{mermaid.core-B-mE18I1.js → mermaid.core-B532LT1r.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-Bm8mDicL.js → mindmap-definition-QFDTVHPH-DGlgeeTV.js} +1 -1
- package/payload/server/public/assets/{ordinal-BDi6f4xk.js → ordinal-Bl-aM5b9.js} +1 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-DGES22b-.js +1 -0
- package/payload/server/public/assets/pie-ZZUOXDRM-ChKeDbzt.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-BCmRLgGO.js → pieDiagram-DEJITSTG-DV9FIWko.js} +1 -1
- package/payload/server/public/assets/{public-DknO-g9S.js → public-Bu2_Xi0a.js} +5 -5
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-CniTIUTm.js → quadrantDiagram-34T5L4WZ-Betwya4l.js} +1 -1
- package/payload/server/public/assets/radar-PYXPWWZC-FGG5Fs7N.js +1 -0
- package/payload/server/public/assets/{reduce-CGi9ik8i.js → reduce-BD4xUd2c.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-CoxBSj9M.js → requirementDiagram-MS252O5E-Cq3vODdg.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-BjS-4jzq.js → sankeyDiagram-XADWPNL6-x8krXWcS.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-B9jVOnPR.js → sequenceDiagram-FGHM5R23-i-_uH-Yl.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-BvOQPzP8.js → stateDiagram-FHFEXIEX-il4KqSgI.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-B6zNJ6Tv.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-CdfgWLo1.js → timeline-definition-GMOUNBTQ-DATdZkA5.js} +1 -1
- package/payload/server/public/assets/treeView-SZITEDCU-VAQQdbtf.js +1 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-DKchO3zI.js +1 -0
- package/payload/server/public/assets/useSelectionMode-A5KItZ2T.js +13 -0
- package/payload/server/public/assets/{brand-D0gNihp7.css → useSelectionMode-C-Ojh7W9.css} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-JCgpIbj-.js → vennDiagram-DHZGUBPP-BJh9tJTt.js} +1 -1
- package/payload/server/public/assets/wardley-RL74JXVD-CBGtx0bS.js +1 -0
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-Dei3VqHo.js → wardleyDiagram-NUSXRM2D-EMN1Hdfg.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-DUtIyoIb.js → xychartDiagram-5P7HB3ND-DbUWXa7T.js} +1 -1
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +5 -6
- package/payload/server/public/public.html +4 -5
- package/payload/server/server.js +525 -39
- package/payload/platform/plugins/admin/hooks/__tests__/session-end-retrospective.test.sh +0 -396
- package/payload/platform/plugins/admin/hooks/lib/admin-graph-pass-common.sh +0 -239
- package/payload/platform/plugins/admin/hooks/session-end-retrospective.sh +0 -214
- package/payload/premium-plugins/writer-craft/hooks/__tests__/voice-session-end-text.test.sh +0 -284
- package/payload/premium-plugins/writer-craft/hooks/voice-session-end-text.sh +0 -75
- package/payload/premium-plugins/writer-craft/mcp/src/cli/ingest-session-text.ts +0 -65
- package/payload/server/public/assets/AdminShell-892Jy_rs.js +0 -1
- package/payload/server/public/assets/Checkbox-Bc2QzX9b.js +0 -1
- package/payload/server/public/assets/admin-D3K13ndi.js +0 -1
- package/payload/server/public/assets/architecture-YZFGNWBL--v-pJPNp.js +0 -1
- package/payload/server/public/assets/brand-CcN3dELF.js +0 -9
- package/payload/server/public/assets/channel-B1IT7to2.js +0 -1
- package/payload/server/public/assets/chunk-336JU56O-CdKRCIeE.js +0 -2
- package/payload/server/public/assets/chunk-426QAEUC-BybuQ3Ve.js +0 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-Bd-GrQM6.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-rjCize6i.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BORWOUt0.js +0 -1
- package/payload/server/public/assets/clone-Csqv5U6T.js +0 -1
- package/payload/server/public/assets/data-Br-pdljK.js +0 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-CI0s_tqn.js +0 -1
- package/payload/server/public/assets/graph-labels-BYH-IPCb.js +0 -1
- package/payload/server/public/assets/info-OMHHGYJF-g3gYW7Qm.js +0 -1
- package/payload/server/public/assets/infoDiagram-42DDH7IO-Di6oPQ_-.js +0 -2
- package/payload/server/public/assets/packet-4T2RLAQJ-CT0TB9HI.js +0 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-CXLe7TFF.js +0 -1
- package/payload/server/public/assets/radar-PYXPWWZC-DnPLBl-D.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-v4ND10uR.js +0 -1
- package/payload/server/public/assets/treeView-SZITEDCU-C3cb7Xwe.js +0 -1
- package/payload/server/public/assets/treemap-W4RFUUIX-Dc7G3Bgm.js +0 -1
- package/payload/server/public/assets/useSelectionMode-DwsyptOw.js +0 -5
- package/payload/server/public/assets/wardley-RL74JXVD-DtgibWAt.js +0 -1
- /package/payload/server/public/assets/{_baseFor-Cam2PbSt.js → _baseFor-Cs8Y-rGh.js} +0 -0
- /package/payload/server/public/assets/{array-DYRGGQae.js → array-iHZP4KWJ.js} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-nWsJMTNI.js → cytoscape.esm-BR2GOQ8_.js} +0 -0
- /package/payload/server/public/assets/{defaultLocale-Du1XY3Dp.js → defaultLocale-B9aLeOTg.js} +0 -0
- /package/payload/server/public/assets/{dist-BzAsli7o.js → dist-DB-VPj_8.js} +0 -0
- /package/payload/server/public/assets/{init-B5BXBRcm.js → init-BNFRgqHM.js} +0 -0
- /package/payload/server/public/assets/{katex-HOUACuRw.js → katex-B-EfS3nw.js} +0 -0
- /package/payload/server/public/assets/{path-CNO468J-.js → path-DmWWdwp7.js} +0 -0
- /package/payload/server/public/assets/{rough.esm-DRO6hWPh.js → rough.esm-Ci7Kjt46.js} +0 -0
- /package/payload/server/public/assets/{src-CWiyyVfn.js → src-C1jfwBq0.js} +0 -0
|
@@ -16,14 +16,13 @@
|
|
|
16
16
|
* collapsing a failed lookup into the no-data payload.
|
|
17
17
|
* 9. voice-tag-content validates mode and format enums, requires format,
|
|
18
18
|
* and returns zero counts on empty nodeIds (with format supplied).
|
|
19
|
-
* 11. voice-ingest-session-text:
|
|
19
|
+
* 11. voice-ingest-session-text: filterOperatorText() keeps real turns
|
|
20
20
|
* and excludes slash commands, paste blocks, and system reminders.
|
|
21
21
|
*
|
|
22
22
|
* Exit code: 0 on pass, 1 on any assertion failure.
|
|
23
23
|
*/
|
|
24
24
|
import { strict as assert } from "node:assert";
|
|
25
|
-
import { readFileSync
|
|
26
|
-
import { tmpdir } from "node:os";
|
|
25
|
+
import { readFileSync } from "node:fs";
|
|
27
26
|
import { join, dirname } from "node:path";
|
|
28
27
|
import { fileURLToPath } from "node:url";
|
|
29
28
|
import { readdirSync } from "node:fs";
|
|
@@ -132,8 +131,7 @@ await check("voice-record-feedback exports voiceRecordFeedback function", () =>
|
|
|
132
131
|
});
|
|
133
132
|
await check("voice-ingest-session-text exports required functions", () => {
|
|
134
133
|
assert.equal(typeof ingestMod.voiceIngestSessionText, "function");
|
|
135
|
-
assert.equal(typeof ingestMod.
|
|
136
|
-
assert.equal(typeof ingestMod.extractOperatorText, "function");
|
|
134
|
+
assert.equal(typeof ingestMod.filterOperatorText, "function");
|
|
137
135
|
});
|
|
138
136
|
|
|
139
137
|
// ---------------------------------------------------------------------------
|
|
@@ -294,127 +292,52 @@ await check("voice-tag-content returns zero counts on empty nodeIds (no DB hit)"
|
|
|
294
292
|
});
|
|
295
293
|
|
|
296
294
|
// ---------------------------------------------------------------------------
|
|
297
|
-
// 7. voice-ingest-session-text:
|
|
295
|
+
// 7. voice-ingest-session-text: operator-turn filter (no DB required).
|
|
298
296
|
// ---------------------------------------------------------------------------
|
|
299
|
-
console.log("\n--
|
|
297
|
+
console.log("\n-- operator-turn filter --");
|
|
300
298
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
await check("extractOperatorText: real user turn is extracted", () => {
|
|
306
|
-
const record = { type: "user", message: { role: "user", content: "Hello world" } };
|
|
307
|
-
const result = ingestMod.extractOperatorText(record);
|
|
308
|
-
assert.equal(result, "Hello world");
|
|
309
|
-
});
|
|
310
|
-
await check("extractOperatorText: slash command is excluded", () => {
|
|
311
|
-
const record = { type: "user", message: { role: "user", content: "/end" } };
|
|
312
|
-
assert.equal(ingestMod.extractOperatorText(record), null);
|
|
299
|
+
await check("filterOperatorText: real turn is kept (and trimmed)", () => {
|
|
300
|
+
assert.equal(ingestMod.filterOperatorText(" Hello world "), "Hello world");
|
|
313
301
|
});
|
|
314
|
-
await check("
|
|
315
|
-
|
|
316
|
-
type: "user",
|
|
317
|
-
message: { role: "user", content: "<system-reminder>some injected text</system-reminder>" },
|
|
318
|
-
};
|
|
319
|
-
assert.equal(ingestMod.extractOperatorText(record), null);
|
|
302
|
+
await check("filterOperatorText: slash command is excluded", () => {
|
|
303
|
+
assert.equal(ingestMod.filterOperatorText("/end"), null);
|
|
320
304
|
});
|
|
321
|
-
await check("
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
assert.equal(ingestMod.extractOperatorText(record), null);
|
|
305
|
+
await check("filterOperatorText: system-reminder is excluded", () => {
|
|
306
|
+
assert.equal(
|
|
307
|
+
ingestMod.filterOperatorText("<system-reminder>some injected text</system-reminder>"),
|
|
308
|
+
null,
|
|
309
|
+
);
|
|
327
310
|
});
|
|
328
|
-
await check("
|
|
329
|
-
|
|
330
|
-
type: "user",
|
|
331
|
-
message: { role: "user", content: "x".repeat(4096) },
|
|
332
|
-
};
|
|
333
|
-
assert.equal(ingestMod.extractOperatorText(record), null);
|
|
311
|
+
await check("filterOperatorText: empty / whitespace-only is excluded", () => {
|
|
312
|
+
assert.equal(ingestMod.filterOperatorText(" "), null);
|
|
334
313
|
});
|
|
335
|
-
await check("
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
assert.equal(ingestMod.extractOperatorText(record), body);
|
|
314
|
+
await check("filterOperatorText: non-string is excluded", () => {
|
|
315
|
+
assert.equal(ingestMod.filterOperatorText(undefined), null);
|
|
316
|
+
assert.equal(ingestMod.filterOperatorText(42), null);
|
|
339
317
|
});
|
|
340
|
-
await check("
|
|
341
|
-
|
|
342
|
-
assert.equal(ingestMod.
|
|
318
|
+
await check("filterOperatorText: paste block >= 4096 chars is excluded", () => {
|
|
319
|
+
assert.equal(ingestMod.filterOperatorText("x".repeat(4096)), null);
|
|
320
|
+
assert.equal(ingestMod.filterOperatorText("x".repeat(4097)), null);
|
|
343
321
|
});
|
|
344
|
-
await check("
|
|
345
|
-
const
|
|
346
|
-
|
|
347
|
-
message: {
|
|
348
|
-
role: "user",
|
|
349
|
-
content: [{ type: "tool_result", tool_use_id: "x", content: "ok" }],
|
|
350
|
-
},
|
|
351
|
-
};
|
|
352
|
-
assert.equal(ingestMod.extractOperatorText(record), null);
|
|
353
|
-
});
|
|
354
|
-
await check("extractOperatorText: content array with text block is extracted", () => {
|
|
355
|
-
const record = {
|
|
356
|
-
type: "user",
|
|
357
|
-
message: {
|
|
358
|
-
role: "user",
|
|
359
|
-
content: [{ type: "text", text: "Hello from array" }],
|
|
360
|
-
},
|
|
361
|
-
};
|
|
362
|
-
assert.equal(ingestMod.extractOperatorText(record), "Hello from array");
|
|
322
|
+
await check("filterOperatorText: 4095 chars is included", () => {
|
|
323
|
+
const body = "x".repeat(4095);
|
|
324
|
+
assert.equal(ingestMod.filterOperatorText(body), body);
|
|
363
325
|
});
|
|
364
326
|
|
|
365
|
-
//
|
|
366
|
-
// Expected: extractOperatorTurns returns 3 strings.
|
|
327
|
+
// turns-array semantics: a mixed array filters down to the real turns.
|
|
367
328
|
await check(
|
|
368
|
-
"
|
|
369
|
-
|
|
370
|
-
const
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
//
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
// 2 assistant turns
|
|
378
|
-
makeJsonlLine("assistant", "assistant", "Agent reply 1"),
|
|
379
|
-
makeJsonlLine("assistant", "assistant", "Agent reply 2"),
|
|
380
|
-
// 1 slash command
|
|
381
|
-
makeJsonlLine("user", "user", "/end"),
|
|
382
|
-
// 1 system reminder
|
|
383
|
-
makeJsonlLine("user", "user", "<system-reminder>injected</system-reminder>"),
|
|
329
|
+
"turns array: 3 real turns + 3 excluded → filterOperatorText keeps 3",
|
|
330
|
+
() => {
|
|
331
|
+
const turns = [
|
|
332
|
+
"First real turn",
|
|
333
|
+
"Second real turn",
|
|
334
|
+
"/end", // slash command
|
|
335
|
+
"<system-reminder>injected</system-reminder>", // harness injection
|
|
336
|
+
"Third real turn",
|
|
337
|
+
" ", // whitespace only
|
|
384
338
|
];
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
const turns = await ingestMod.extractOperatorTurns(jsonlPath);
|
|
388
|
-
assert.equal(turns.length, 3, `expected 3 turns, got ${turns.length}`);
|
|
389
|
-
assert.equal(turns[0], "First real turn");
|
|
390
|
-
assert.equal(turns[1], "Second real turn");
|
|
391
|
-
assert.equal(turns[2], "Third real turn");
|
|
392
|
-
} finally {
|
|
393
|
-
rmSync(tmp, { recursive: true, force: true });
|
|
394
|
-
}
|
|
395
|
-
},
|
|
396
|
-
);
|
|
397
|
-
|
|
398
|
-
// Second-run fixture: same lines written to same path → same 3 turns extracted.
|
|
399
|
-
// (Actual dedup happens in the DB via contentHash MERGE; extraction is idempotent.)
|
|
400
|
-
await check(
|
|
401
|
-
"extractOperatorTurns: re-running same JSONL extracts same turns (dedup is in DB)",
|
|
402
|
-
async () => {
|
|
403
|
-
const tmp = mkdtempSync(join(tmpdir(), "smoke-ingest-dedup-"));
|
|
404
|
-
const jsonlPath = join(tmp, "session.jsonl");
|
|
405
|
-
const lines = [
|
|
406
|
-
makeJsonlLine("user", "user", "Dedupe turn"),
|
|
407
|
-
makeJsonlLine("user", "user", "/skip-cmd"),
|
|
408
|
-
];
|
|
409
|
-
writeFileSync(jsonlPath, lines.join("\n") + "\n");
|
|
410
|
-
try {
|
|
411
|
-
const turns1 = await ingestMod.extractOperatorTurns(jsonlPath);
|
|
412
|
-
const turns2 = await ingestMod.extractOperatorTurns(jsonlPath);
|
|
413
|
-
assert.deepEqual(turns1, turns2, "idempotent: same JSONL gives same turns");
|
|
414
|
-
assert.equal(turns1.length, 1);
|
|
415
|
-
} finally {
|
|
416
|
-
rmSync(tmp, { recursive: true, force: true });
|
|
417
|
-
}
|
|
339
|
+
const kept = turns.map((t) => ingestMod.filterOperatorText(t)).filter((t) => t !== null);
|
|
340
|
+
assert.deepEqual(kept, ["First real turn", "Second real turn", "Third real turn"]);
|
|
418
341
|
},
|
|
419
342
|
);
|
|
420
343
|
|
|
@@ -348,13 +348,13 @@ server.tool(
|
|
|
348
348
|
|
|
349
349
|
server.tool(
|
|
350
350
|
"voice-ingest-session-text",
|
|
351
|
-
"
|
|
351
|
+
"Write operator turns from the current session as :Message {format:'text', source:'admin-pty', authorshipMode:'human-only'} corpus nodes. The admin agent reads its own operator turns from the live conversation context and passes them as `turns`. Deduplication via SHA256 contentHash — re-running with the same turns is a no-op. Triggers voice-distil-profile {format:'text'} after ingest (cadence guard decides whether distillation runs). Invoked on demand by the voice-mirror skill when the operator asks to capture this session's voice.",
|
|
352
352
|
{
|
|
353
|
-
|
|
354
|
-
sessionId: z.string().optional().describe("Session ID for provenance
|
|
353
|
+
turns: z.array(z.string()).describe("Operator turns the agent read from its own session context (one string per operator message). Slash commands, harness injections, and large paste blocks are filtered out by the tool."),
|
|
354
|
+
sessionId: z.string().optional().describe("Session ID for provenance."),
|
|
355
355
|
userId: z.string().optional().describe("Operator AdminUser identifier. Defaults to ADMIN_USER_ID env."),
|
|
356
356
|
},
|
|
357
|
-
async ({
|
|
357
|
+
async ({ turns, sessionId, userId }) => {
|
|
358
358
|
if (!accountId) return refuseNoAccount("voice-ingest-session-text");
|
|
359
359
|
const resolvedUserId = userId ?? resolveUserId();
|
|
360
360
|
if (!resolvedUserId) {
|
|
@@ -370,7 +370,7 @@ server.tool(
|
|
|
370
370
|
}
|
|
371
371
|
try {
|
|
372
372
|
const result = await voiceIngestSessionText({
|
|
373
|
-
|
|
373
|
+
turns,
|
|
374
374
|
accountId,
|
|
375
375
|
userId: resolvedUserId,
|
|
376
376
|
sessionId,
|
|
@@ -19,7 +19,7 @@ export function notTrashed(alias: string): string {
|
|
|
19
19
|
*
|
|
20
20
|
* Imported by `voice-distil-profile` (count + sample walks),
|
|
21
21
|
* `voice-retrieve-conditioning` (exemplar walk), `voice-tag-content` (tag
|
|
22
|
-
* writes), and `voice-ingest-session-text` (
|
|
22
|
+
* writes), and `voice-ingest-session-text` (on-demand session-text ingest). The single
|
|
23
23
|
* load-bearing filter — when the corpus rules change, this is the only place
|
|
24
24
|
* to edit.
|
|
25
25
|
*
|
|
@@ -1,34 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* voice-ingest-session-text —
|
|
3
|
-
* session
|
|
4
|
-
*
|
|
2
|
+
* voice-ingest-session-text — write operator turns the agent read from its
|
|
3
|
+
* own session context as :Message {format:'text', source:'admin-pty'} corpus
|
|
4
|
+
* nodes.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* session
|
|
8
|
-
*
|
|
6
|
+
* Invoked on demand by the voice-mirror skill (Task 644): the operator asks to
|
|
7
|
+
* capture this session's voice, the admin agent extracts its own operator
|
|
8
|
+
* turns from the live conversation context, and passes them here as `turns`.
|
|
9
|
+
* Re-running with the same turns is a no-op — MERGE on (contentHash, accountId)
|
|
10
|
+
* is the deduplication primitive.
|
|
9
11
|
*
|
|
10
12
|
* After ingest, triggers voice-distil-profile {format:'text'} so the cadence
|
|
11
13
|
* guard decides whether distillation runs.
|
|
12
14
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* "Real operator text" extraction rules (excludes):
|
|
17
|
-
* - type != "user" or message.role != "user" → not the operator
|
|
18
|
-
* - content is tool_result-only → tool reply, not turn
|
|
15
|
+
* "Real operator text" filter (each supplied turn is excluded when):
|
|
16
|
+
* - text is empty after trimming → nothing to ingest
|
|
19
17
|
* - text starts with "/" → slash command
|
|
20
18
|
* - text contains "<system-reminder>" → harness injection
|
|
21
19
|
* - text.length >= 4096 → likely pasted content
|
|
22
|
-
* - text is empty after trimming → nothing to ingest
|
|
23
20
|
*/
|
|
24
21
|
import { createHash } from "node:crypto";
|
|
25
|
-
import { createReadStream } from "node:fs";
|
|
26
|
-
import { createInterface } from "node:readline";
|
|
27
22
|
import { getSession } from "../lib/neo4j.js";
|
|
28
23
|
import { voiceDistilProfile } from "./voice-distil-profile.js";
|
|
29
24
|
|
|
30
25
|
export interface VoiceIngestSessionTextParams {
|
|
31
|
-
|
|
26
|
+
turns: string[];
|
|
32
27
|
accountId: string;
|
|
33
28
|
userId: string;
|
|
34
29
|
sessionId?: string;
|
|
@@ -41,109 +36,37 @@ export interface VoiceIngestSessionTextResult {
|
|
|
41
36
|
}
|
|
42
37
|
|
|
43
38
|
/**
|
|
44
|
-
*
|
|
45
|
-
* Returns null when the
|
|
46
|
-
*/
|
|
47
|
-
export function extractOperatorText(record: unknown): string | null {
|
|
48
|
-
if (!record || typeof record !== "object") return null;
|
|
49
|
-
const rec = record as Record<string, unknown>;
|
|
50
|
-
|
|
51
|
-
if (rec["type"] !== "user") return null;
|
|
52
|
-
|
|
53
|
-
const msg = rec["message"];
|
|
54
|
-
if (!msg || typeof msg !== "object") return null;
|
|
55
|
-
const message = msg as Record<string, unknown>;
|
|
56
|
-
if (message["role"] !== "user") return null;
|
|
57
|
-
|
|
58
|
-
const content = message["content"];
|
|
59
|
-
let text = "";
|
|
60
|
-
|
|
61
|
-
if (typeof content === "string") {
|
|
62
|
-
text = content;
|
|
63
|
-
} else if (Array.isArray(content)) {
|
|
64
|
-
// Must have at least one non-tool_result block to be a real turn.
|
|
65
|
-
const nonToolResult = content.filter(
|
|
66
|
-
(b) => typeof b === "object" && b !== null && (b as Record<string, unknown>)["type"] !== "tool_result",
|
|
67
|
-
);
|
|
68
|
-
if (nonToolResult.length === 0) return null;
|
|
69
|
-
|
|
70
|
-
// Collect text from all text-type content blocks.
|
|
71
|
-
const parts: string[] = [];
|
|
72
|
-
for (const block of content) {
|
|
73
|
-
if (typeof block !== "object" || block === null) continue;
|
|
74
|
-
const b = block as Record<string, unknown>;
|
|
75
|
-
if (b["type"] === "text" && typeof b["text"] === "string") {
|
|
76
|
-
parts.push(b["text"]);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
text = parts.join("");
|
|
80
|
-
} else {
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
text = text.trim();
|
|
85
|
-
if (text.length === 0) return null;
|
|
86
|
-
|
|
87
|
-
// Exclusions.
|
|
88
|
-
if (text.startsWith("/")) return null; // slash command
|
|
89
|
-
if (text.includes("<system-reminder>")) return null; // harness injection
|
|
90
|
-
if (text.length >= 4096) return null; // paste block
|
|
91
|
-
|
|
92
|
-
return text;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Parse a session JSONL file and return all real operator turn texts.
|
|
39
|
+
* Applies the "real operator text" exclusions to a single supplied turn.
|
|
40
|
+
* Returns the trimmed text to ingest, or null when the turn should be skipped.
|
|
97
41
|
* Exported for testability (no DB required).
|
|
98
42
|
*/
|
|
99
|
-
export
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
for await (const line of rl) {
|
|
108
|
-
const trimmed = line.trim();
|
|
109
|
-
if (!trimmed) continue;
|
|
110
|
-
let record: unknown;
|
|
111
|
-
try {
|
|
112
|
-
record = JSON.parse(trimmed);
|
|
113
|
-
} catch {
|
|
114
|
-
continue;
|
|
115
|
-
}
|
|
116
|
-
const text = extractOperatorText(record);
|
|
117
|
-
if (text !== null) {
|
|
118
|
-
turns.push(text);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return turns;
|
|
43
|
+
export function filterOperatorText(text: unknown): string | null {
|
|
44
|
+
if (typeof text !== "string") return null;
|
|
45
|
+
const trimmed = text.trim();
|
|
46
|
+
if (trimmed.length === 0) return null;
|
|
47
|
+
if (trimmed.startsWith("/")) return null; // slash command
|
|
48
|
+
if (trimmed.includes("<system-reminder>")) return null; // harness injection
|
|
49
|
+
if (trimmed.length >= 4096) return null; // paste block
|
|
50
|
+
return trimmed;
|
|
123
51
|
}
|
|
124
52
|
|
|
125
53
|
export async function voiceIngestSessionText(
|
|
126
54
|
params: VoiceIngestSessionTextParams,
|
|
127
55
|
): Promise<VoiceIngestSessionTextResult> {
|
|
128
|
-
const {
|
|
56
|
+
const { turns, accountId, userId, sessionId = null } = params;
|
|
129
57
|
|
|
130
58
|
if (!accountId || !userId) {
|
|
131
59
|
throw new Error("voice-ingest-session-text: accountId and userId required");
|
|
132
60
|
}
|
|
133
|
-
if (!
|
|
134
|
-
throw new Error("voice-ingest-session-text:
|
|
61
|
+
if (!Array.isArray(turns)) {
|
|
62
|
+
throw new Error("voice-ingest-session-text: turns array required");
|
|
135
63
|
}
|
|
136
64
|
|
|
137
|
-
// 1.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
throw new Error(
|
|
143
|
-
`voice-ingest-session-text: failed to read JSONL at '${sessionJsonlPath}': ${
|
|
144
|
-
err instanceof Error ? err.message : String(err)
|
|
145
|
-
}`,
|
|
146
|
-
);
|
|
65
|
+
// 1. Apply the operator-text filter to each supplied turn.
|
|
66
|
+
const allTurns: string[] = [];
|
|
67
|
+
for (const turn of turns) {
|
|
68
|
+
const text = filterOperatorText(turn);
|
|
69
|
+
if (text !== null) allTurns.push(text);
|
|
147
70
|
}
|
|
148
71
|
|
|
149
72
|
if (allTurns.length === 0) {
|
|
@@ -15,7 +15,7 @@ The skill is built on five deterministic MCP tools served by the `writer-craft`
|
|
|
15
15
|
| `voice-distil-profile` | Walk the operator's `human-only` corpus for a given `format` and produce a `:VoiceProfile {styleCard, generatedAt, corpusSize, feedbackEntries, format}` node. Without a `format`, enumerates all formats present in the corpus and distils each. |
|
|
16
16
|
| `voice-retrieve-conditioning` | Return `{styleCard, exemplars[]}` for a drafting brief. Requires `brief.format` (one of the six corpus formats). K=5 for short-form, K=15 for long-form. Token-budget bounded. |
|
|
17
17
|
| `voice-record-feedback` | When the operator edits an agent draft, write a `:VoiceEdit {originalText, editedText, intent, occurredAt, format}-[:FEEDBACK_FOR]->(:VoiceProfile {format})` node. The `intent` field is a Haiku-summarised diff. |
|
|
18
|
-
| `voice-ingest-session-text` |
|
|
18
|
+
| `voice-ingest-session-text` | Write operator turns from the current session as `:Message {format:'text', authorshipMode:'human-only'}` corpus nodes. The agent reads its own operator turns from context and passes them as `turns`. Deduplicates via `contentHash`. Invoked on demand when the operator asks to capture this session's voice. |
|
|
19
19
|
|
|
20
20
|
## Surface — admin only, never delegated
|
|
21
21
|
|
|
@@ -32,6 +32,7 @@ Activate when the operator says any of:
|
|
|
32
32
|
- **"Read my writing first" / "draft this in my voice" — when the operator is asking for a hand-written-quality draft, not a generic AI reply.** Drives `voice-retrieve-conditioning`; the calling drafting skill is the actual surface, this skill is the conditioning input.
|
|
33
33
|
- **"Use my edit as a teaching example" / "remember how I changed that".** Drives `voice-record-feedback`.
|
|
34
34
|
- **"Review my historical writing and tag it" / "start the backfill".** Drives the interactive backfill flow described below.
|
|
35
|
+
- **"Capture my voice from this chat" / "ingest this session" / "learn how I write from this conversation".** Drives the on-demand session-text capture flow described below.
|
|
35
36
|
|
|
36
37
|
Do **not** activate for:
|
|
37
38
|
|
|
@@ -45,7 +46,7 @@ Voice profiles are segmented by content format. The closed enum is:
|
|
|
45
46
|
|
|
46
47
|
| Format | Operator picks for |
|
|
47
48
|
|--------|--------------------|
|
|
48
|
-
| `text` | `:Message` nodes; the
|
|
49
|
+
| `text` | `:Message` nodes; the operator's session turns, captured on demand via `voice-ingest-session-text` when the operator asks to capture this session's voice |
|
|
49
50
|
| `email` | Email threads stored as `:KnowledgeDocument {source:'email'}` or `:ConversationArchive {source:'email'}` |
|
|
50
51
|
| `social-post` | `:SocialPost` nodes |
|
|
51
52
|
| `article` | Long-form `:KnowledgeDocument` the operator considers an article |
|
|
@@ -97,18 +98,17 @@ Authorship at conversation granularity is a deliberate UX trade-off: chunks with
|
|
|
97
98
|
|
|
98
99
|
After each backfill batch, check whether the qualifying corpus (`authorshipMode IN ['human-only', 'human-led-agent-assisted']`) for any format has grown ≥20% since the last `:VoiceProfile.corpusSize` for that format (or ≥1 entry if no profile exists for that format). If yes, offer to run `voice-distil-profile` immediately. The operator can defer; the next scheduled distillation will pick it up.
|
|
99
100
|
|
|
100
|
-
##
|
|
101
|
+
## On-demand text-format capture (session turns)
|
|
101
102
|
|
|
102
|
-
Operator
|
|
103
|
+
Operator turns are captured into the `text` corpus on demand — when the operator asks to capture this session's voice, never automatically. There is no SessionEnd hook; the operator is in the loop.
|
|
103
104
|
|
|
104
|
-
|
|
105
|
+
When the operator says "capture my voice from this chat" (or similar):
|
|
105
106
|
|
|
106
|
-
|
|
107
|
+
1. Read the operator's own turns from the live conversation context — the user messages already in this session.
|
|
108
|
+
2. Call `voice-ingest-session-text` with those turns as the `turns` array. The tool filters out slash commands, harness injections (`<system-reminder>`), and large paste blocks, deduplicates via SHA256 content hash, and writes each new turn as a `:Message {format:'text', authorshipMode:'human-only'}` node.
|
|
109
|
+
3. The tool triggers an incremental `text`-format distillation if the corpus grew ≥20% since the last profile.
|
|
107
110
|
|
|
108
|
-
|
|
109
|
-
```
|
|
110
|
-
journalctl -u maxy-code | grep '\[voice-session-end-hook\]'
|
|
111
|
-
```
|
|
111
|
+
This runs only on the admin seat (the tool is admin-allowlisted). Accounts without a voice profile degrade gracefully — capture simply populates the corpus for the first distillation.
|
|
112
112
|
|
|
113
113
|
## Flow — drafting-time conditioning
|
|
114
114
|
|
|
@@ -182,7 +182,7 @@ The tool returns `{existingStyleCard, exemplars[], feedbackIntents[], eligible,
|
|
|
182
182
|
|
|
183
183
|
When `eligible=0` (every named document failed the predicate) surface the `ineligible[]` payload to the operator naming the per-id reason (`node-not-found`, `wrong-account`, `ineligible-authorship-mode`, `trashed`, `ineligible-label`) rather than silently no-op. Most commonly this means the documents are tagged as `agent-only` and need re-tagging via `voice-tag-content` before they can amend a profile.
|
|
184
184
|
|
|
185
|
-
Amend mode does not apply to the
|
|
185
|
+
Amend mode does not apply to the on-demand session-text capture path. Session-text ingest stays on the full-corpus path; amend is operator-initiated only.
|
|
186
186
|
|
|
187
187
|
## Per-operator scope
|
|
188
188
|
|
|
@@ -199,18 +199,16 @@ One `:VoiceProfile` per `(accountId, userId, format)`. Multi-author accounts (an
|
|
|
199
199
|
| `[voice-distil] mode=write userId=<id> format=<format> amended=true amendedFromNodeIds=<count> ...` | Amend-write fired (operator-initiated update persisted). |
|
|
200
200
|
| `[voice-retrieve] task=<topic> format=<format> styleCardBytes=<n> exemplarCount=<k> tokenBudget=<n>` | Each retrieval. |
|
|
201
201
|
| `[voice-record-feedback] userId=<id> format=<format> intent="<haiku-summary>" diffBytes=<n>` | Each feedback write. |
|
|
202
|
-
| `[voice-session-
|
|
203
|
-
| `[voice-session-end-hook] result=ok sessionId=<id> turns=<n> skipped=<m>` | Successful ingest. |
|
|
204
|
-
| `[voice-session-end-hook] trigger-skipped sessionId=<id> reason=<reason>` | Hook guard fired. |
|
|
202
|
+
| `[voice-ingest-session-text] sessionId=<id> adminUser=<id> turns=<n> bytes=<n> skipped=<m>` | On-demand session-text capture. |
|
|
205
203
|
|
|
206
|
-
**Confirms working:** `[voice-retrieve] exemplarCount≥1` precedes every drafting-skill prompt assembly when the calling skill has not opted out. `[voice-distil]` appears at least once per 30-day window per active format per operator. `[voice-session-
|
|
204
|
+
**Confirms working:** `[voice-retrieve] exemplarCount≥1` precedes every drafting-skill prompt assembly when the calling skill has not opted out. `[voice-distil]` appears at least once per 30-day window per active format per operator. `[voice-ingest-session-text] turns≥1` appears when the operator asks to capture a session's voice.
|
|
207
205
|
|
|
208
|
-
**Indicates failure:** `[voice-retrieve] exemplarCount=0` with non-empty corpus → similarity index broken; `[voice-distil] error …` → corpus walk or LLM call failed; absence of `[voice-record-feedback]` after an operator-edit-then-send flow → feedback loop is dead
|
|
206
|
+
**Indicates failure:** `[voice-retrieve] exemplarCount=0` with non-empty corpus → similarity index broken; `[voice-distil] error …` → corpus walk or LLM call failed; absence of `[voice-record-feedback]` after an operator-edit-then-send flow → feedback loop is dead.
|
|
209
207
|
|
|
210
208
|
**Diagnostic path:**
|
|
211
209
|
|
|
212
210
|
```
|
|
213
|
-
journalctl -u maxy-code | grep -E '\[voice-(tag|distil|retrieve|record-feedback|session-
|
|
211
|
+
journalctl -u maxy-code | grep -E '\[voice-(tag|distil|retrieve|record-feedback|ingest-session-text)\]'
|
|
214
212
|
```
|
|
215
213
|
|
|
216
214
|
Filter by `userId=<id>` for per-operator drill-down.
|
|
@@ -4107,11 +4107,13 @@ process.on("SIGINT", async () => {
|
|
|
4107
4107
|
});
|
|
4108
4108
|
var OLLAMA_URL = process.env.OLLAMA_URL ?? "http://localhost:11434";
|
|
4109
4109
|
var EMBED_MODEL = process.env.EMBED_MODEL ?? "nomic-embed-text";
|
|
4110
|
+
var EMBED_INPUT_MAX_CHARS = 8e3;
|
|
4110
4111
|
async function embed(text) {
|
|
4112
|
+
const input = text.length > EMBED_INPUT_MAX_CHARS ? text.slice(0, EMBED_INPUT_MAX_CHARS) : text;
|
|
4111
4113
|
const res = await fetch(`${OLLAMA_URL}/api/embed`, {
|
|
4112
4114
|
method: "POST",
|
|
4113
4115
|
headers: { "Content-Type": "application/json" },
|
|
4114
|
-
body: JSON.stringify({ model: EMBED_MODEL, input
|
|
4116
|
+
body: JSON.stringify({ model: EMBED_MODEL, input }),
|
|
4115
4117
|
signal: AbortSignal.timeout(5e3)
|
|
4116
4118
|
});
|
|
4117
4119
|
if (!res.ok) {
|
|
@@ -4898,6 +4900,17 @@ async function writeAdminUserAndPerson(params) {
|
|
|
4898
4900
|
const givenName = firstSpace === -1 ? trimmed : trimmed.slice(0, firstSpace).trim();
|
|
4899
4901
|
const familyName = firstSpace === -1 ? null : trimmed.slice(firstSpace + 1).trim() || null;
|
|
4900
4902
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4903
|
+
let personEmbedding = null;
|
|
4904
|
+
try {
|
|
4905
|
+
personEmbedding = await embed(
|
|
4906
|
+
`[Person] ${[givenName, familyName].filter(Boolean).join(" ")} role: admin-personal`
|
|
4907
|
+
);
|
|
4908
|
+
} catch (err) {
|
|
4909
|
+
process.stderr.write(
|
|
4910
|
+
`[graph-write] warn reason=embed-failed labels=Person agent=admin-bootstrap detail=${err instanceof Error ? err.message : String(err)}
|
|
4911
|
+
`
|
|
4912
|
+
);
|
|
4913
|
+
}
|
|
4901
4914
|
const session = getSession();
|
|
4902
4915
|
try {
|
|
4903
4916
|
const result = await session.run(
|
|
@@ -4927,6 +4940,7 @@ async function writeAdminUserAndPerson(params) {
|
|
|
4927
4940
|
familyName: $familyName,
|
|
4928
4941
|
role: 'admin-personal',
|
|
4929
4942
|
scope: 'admin',
|
|
4943
|
+
embedding: $personEmbedding,
|
|
4930
4944
|
createdAt: $now
|
|
4931
4945
|
})
|
|
4932
4946
|
MERGE (au)-[:OWNS]->(newPerson)
|
|
@@ -4934,7 +4948,7 @@ async function writeAdminUserAndPerson(params) {
|
|
|
4934
4948
|
}
|
|
4935
4949
|
RETURN reused, elementId(p) AS personElementId,
|
|
4936
4950
|
p.givenName AS givenName, p.familyName AS familyName`,
|
|
4937
|
-
{ userId, fullName: trimmed, accountId, givenName, familyName, now }
|
|
4951
|
+
{ userId, fullName: trimmed, accountId, givenName, familyName, now, personEmbedding }
|
|
4938
4952
|
);
|
|
4939
4953
|
if (result.records.length === 0) {
|
|
4940
4954
|
throw new Error("writeAdminUserAndPerson: no record returned");
|