@rubytech/create-maxy-code 0.1.158 → 0.1.161
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/package.json +1 -1
- package/payload/platform/lib/admin-conversation-purge/dist/index.d.ts +1 -1
- package/payload/platform/lib/admin-conversation-purge/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/admin-conversation-purge/dist/index.js +4 -4
- package/payload/platform/lib/admin-conversation-purge/dist/index.js.map +1 -1
- package/payload/platform/lib/admin-conversation-purge/src/index.ts +5 -5
- package/payload/platform/lib/graph-search/src/__tests__/fulltext-coverage.test.ts +48 -17
- package/payload/platform/lib/graph-style/dist/index.js +2 -2
- package/payload/platform/lib/graph-style/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-style/src/__tests__/parity.test.ts +1 -1
- package/payload/platform/lib/graph-style/src/index.ts +2 -2
- package/payload/platform/lib/graph-trash/dist/index.js +1 -1
- package/payload/platform/lib/graph-trash/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-trash/src/index.ts +1 -1
- package/payload/platform/lib/graph-write/dist/__tests__/action-provenance-gate.test.js +1 -1
- package/payload/platform/lib/graph-write/dist/__tests__/action-provenance-gate.test.js.map +1 -1
- package/payload/platform/lib/graph-write/dist/conversation-provenance.d.ts +3 -3
- package/payload/platform/lib/graph-write/dist/conversation-provenance.js +5 -5
- package/payload/platform/lib/graph-write/dist/conversation-provenance.js.map +1 -1
- package/payload/platform/lib/graph-write/dist/index.js +1 -1
- package/payload/platform/lib/graph-write/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-write/src/__tests__/action-provenance-gate.test.ts +1 -1
- package/payload/platform/lib/graph-write/src/conversation-provenance.ts +8 -8
- package/payload/platform/lib/graph-write/src/index.ts +1 -1
- package/payload/platform/neo4j/schema.cypher +86 -46
- 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 +8 -4
- package/payload/platform/plugins/admin/hooks/__tests__/archive-ingest-surface-gate.test.sh +1 -1
- package/payload/platform/plugins/admin/hooks/__tests__/per-turn-graph-pass-gate.test.sh +361 -0
- package/payload/platform/plugins/admin/hooks/__tests__/pre-turn-graph-pass.test.sh +13 -13
- package/payload/platform/plugins/admin/hooks/__tests__/turn-completed-graph-write.test.sh +1 -1
- package/payload/platform/plugins/admin/hooks/archive-ingest-surface-gate.sh +2 -2
- package/payload/platform/plugins/admin/hooks/lib/admin-graph-pass-common.sh +102 -0
- package/payload/platform/plugins/admin/hooks/per-turn-graph-pass-gate.sh +106 -0
- package/payload/platform/plugins/admin/hooks/pre-turn-graph-pass.sh +15 -8
- package/payload/platform/plugins/admin/hooks/turn-completed-graph-write.sh +4 -4
- package/payload/platform/plugins/admin/mcp/dist/index.js +65 -24
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/skills/business-profile/SKILL.md +1 -1
- package/payload/platform/plugins/admin/skills/session-management/SKILL.md +2 -2
- package/payload/platform/plugins/admin/skills/stream-log-review/SKILL.md +5 -5
- package/payload/platform/plugins/admin/skills/stream-log-review/references/analysis-patterns.md +6 -6
- package/payload/platform/plugins/business-assistant/references/profiling.md +1 -1
- package/payload/platform/plugins/contacts/PLUGIN.md +1 -1
- package/payload/platform/plugins/contacts/mcp/dist/tools/contact-create.js +2 -2
- package/payload/platform/plugins/contacts/mcp/dist/tools/contact-create.js.map +1 -1
- package/payload/platform/plugins/contacts/mcp/dist/tools/contact-erase.js +3 -3
- package/payload/platform/plugins/contacts/mcp/dist/tools/contact-export.d.ts +1 -1
- package/payload/platform/plugins/contacts/mcp/dist/tools/contact-export.js +2 -2
- package/payload/platform/plugins/contacts/mcp/dist/tools/group-create.d.ts +1 -1
- package/payload/platform/plugins/contacts/mcp/dist/tools/group-create.d.ts.map +1 -1
- package/payload/platform/plugins/contacts/mcp/dist/tools/group-create.js +4 -4
- package/payload/platform/plugins/contacts/mcp/dist/tools/group-create.js.map +1 -1
- package/payload/platform/plugins/contacts/mcp/dist/tools/group-manage.js +10 -10
- package/payload/platform/plugins/contacts/mcp/dist/tools/group-manage.js.map +1 -1
- package/payload/platform/plugins/docs/references/admin-session.md +6 -6
- package/payload/platform/plugins/docs/references/admin-ui.md +1 -1
- package/payload/platform/plugins/docs/references/internals.md +5 -5
- package/payload/platform/plugins/docs/references/plugins-guide.md +6 -5
- package/payload/platform/plugins/docs/references/troubleshooting.md +1 -1
- package/payload/platform/plugins/email/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/email/PLUGIN.md +19 -2
- package/payload/platform/plugins/email/mcp/dist/index.js +78 -0
- package/payload/platform/plugins/email/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/conversation-archive-dispatch.d.ts +8 -0
- package/payload/platform/plugins/email/mcp/dist/lib/conversation-archive-dispatch.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/conversation-archive-dispatch.js +177 -0
- package/payload/platform/plugins/email/mcp/dist/lib/conversation-archive-dispatch.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/embedding.js +2 -2
- package/payload/platform/plugins/email/mcp/dist/lib/embedding.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/graph.d.ts +6 -54
- package/payload/platform/plugins/email/mcp/dist/lib/graph.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/graph.js +12 -300
- package/payload/platform/plugins/email/mcp/dist/lib/graph.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/ingest-batch.d.ts +23 -0
- package/payload/platform/plugins/email/mcp/dist/lib/ingest-batch.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/ingest-batch.js +15 -0
- package/payload/platform/plugins/email/mcp/dist/lib/ingest-batch.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-classify.d.ts +6 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-classify.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-classify.js +89 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-classify.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-fetch.d.ts +15 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-fetch.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-fetch.js +49 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-fetch.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-ingest.d.ts +20 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-ingest.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-ingest.js +91 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-ingest.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-setup.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-setup.js +32 -52
- package/payload/platform/plugins/email/mcp/dist/tools/email-setup.js.map +1 -1
- package/payload/platform/plugins/email/references/email-reference.md +19 -83
- package/payload/platform/plugins/email/skills/email-ingest/SKILL.md +87 -0
- package/payload/platform/plugins/linkedin-import/skills/linkedin-import/SKILL.md +10 -37
- package/payload/platform/plugins/linkedin-import/skills/linkedin-import/references/connections.md +1 -0
- package/payload/platform/plugins/memory/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/memory/PLUGIN.md +11 -2
- package/payload/platform/plugins/memory/bin/conversation-archive-ingest.mjs +139 -439
- package/payload/platform/plugins/memory/bin/conversation-archive-ingest.sh +15 -47
- package/payload/platform/plugins/memory/mcp/dist/index.js +197 -58
- package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.js +43 -27
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/label-delete-gate.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/label-delete-gate.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/label-delete-gate.test.js +62 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/label-delete-gate.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-cypher-drift.test.js +5 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-cypher-drift.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/typed-edge-schema.test.js +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/typed-edge-schema.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-revision.d.ts +42 -25
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-revision.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-revision.js +23 -17
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-revision.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/email.d.ts +3 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/email.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/email.js +61 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/email.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/index.d.ts +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/index.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/index.js +3 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/index.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.d.ts +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.js +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/x-dm.js +2 -2
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/x-dm.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/derive-keys.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/derive-keys.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/derive-keys.js +9 -3
- package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/derive-keys.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/graph-prune.d.ts +3 -3
- package/payload/platform/plugins/memory/mcp/dist/lib/graph-prune.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/graph-prune.js +6 -6
- package/payload/platform/plugins/memory/mcp/dist/lib/graph-prune.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/kd-classify-gate.d.ts +41 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/kd-classify-gate.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/kd-classify-gate.js +71 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/kd-classify-gate.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/label-delete-gate.d.ts +18 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/label-delete-gate.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/label-delete-gate.js +31 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/label-delete-gate.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/neo4j.d.ts +2 -2
- package/payload/platform/plugins/memory/mcp/dist/lib/neo4j.js +2 -2
- package/payload/platform/plugins/memory/mcp/dist/lib/typed-edge-pass.d.ts +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/typed-edge-pass.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-derive-insights.test.d.ts +5 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-derive-insights.test.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-derive-insights.test.js +162 -78
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-derive-insights.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-enrich-rejection.test.js +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-enrich-rejection.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-memory-expunge-emit.test.js +3 -3
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-memory-expunge-emit.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-normalisers-source-agnosticism.test.js +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-normalisers-source-agnosticism.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.js +2 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-compiled-truth-history.test.js +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-compiled-truth-history.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-delete-emit.test.js +6 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-delete-emit.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-delete-reserved-label.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-delete-reserved-label.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-delete-reserved-label.test.js +141 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-delete-reserved-label.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-empty-trash-admin-conversation.test.js +8 -8
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-empty-trash-admin-conversation.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-empty-trash-reserved-label.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-empty-trash-reserved-label.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-empty-trash-reserved-label.test.js +86 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-empty-trash-reserved-label.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-report-tools.test.js +2 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-report-tools.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.d.ts +33 -34
- 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 +94 -273
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-list-chunks.d.ts +43 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-list-chunks.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-list-chunks.js +96 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-list-chunks.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-memory-expunge.d.ts +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-memory-expunge.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-memory-expunge.js +2 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-memory-expunge.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/kd-classify.d.ts +6 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/kd-classify.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/kd-classify.js +73 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/kd-classify.js.map +1 -0
- 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 +0 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-brain-capture-recent.d.ts +2 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-brain-capture-recent.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-brain-capture-recent.js +4 -4
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-brain-capture-recent.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-compiled-truth-history.d.ts +6 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-compiled-truth-history.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-compiled-truth-history.js +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-compiled-truth-history.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.d.ts +8 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.js +40 -5
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.d.ts +8 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.js +25 -9
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-find-candidates.d.ts +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-find-candidates.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-find-candidates.js +2 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-find-candidates.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js +11 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-node-exists.d.ts +28 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-node-exists.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-node-exists.js +46 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-node-exists.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-write.d.ts +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-write.js +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-typed-edge-pass.d.ts +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-typed-edge-pass.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-typed-edge-pass.js +2 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-typed-edge-pass.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js +26 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js +2 -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.d.ts +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +11 -11
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/scripts/backfill-typed-edges.ts +1 -1
- package/payload/platform/plugins/memory/mcp/scripts/graph/fixture.cypher +1 -1
- package/payload/platform/plugins/memory/mcp/vitest.config.ts +5 -4
- package/payload/platform/plugins/memory/references/graph-primitives.md +1 -1
- package/payload/platform/plugins/memory/references/schema-base.md +8 -10
- package/payload/platform/plugins/memory/skills/conversation-archive/SKILL.md +100 -116
- package/payload/platform/plugins/memory/skills/conversation-archive-enrich/SKILL.md +74 -24
- package/payload/platform/plugins/memory/skills/conversational-memory/SKILL.md +1 -1
- package/payload/platform/plugins/notion-import/skills/notion-import/SKILL.md +1 -1
- package/payload/platform/plugins/obsidian-import/skills/obsidian-import/SKILL.md +1 -1
- package/payload/platform/plugins/substack-import/.claude-plugin/plugin.json +8 -0
- package/payload/platform/plugins/substack-import/PLUGIN.md +34 -0
- package/payload/platform/plugins/substack-import/skills/substack-import/SKILL.md +182 -0
- package/payload/platform/plugins/substack-import/skills/substack-import/references/archive-shape.md +68 -0
- package/payload/platform/plugins/substack-import/skills/substack-import/references/attachments.md +72 -0
- package/payload/platform/plugins/substack-import/skills/substack-import/references/engagement.md +61 -0
- package/payload/platform/plugins/substack-import/skills/substack-import/references/posts.md +80 -0
- package/payload/platform/plugins/substack-import/skills/substack-import/references/subscribers.md +74 -0
- package/payload/platform/plugins/whatsapp/PLUGIN.md +1 -1
- package/payload/platform/plugins/whatsapp/mcp/dist/index.js +2 -2
- package/payload/platform/plugins/whatsapp/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/work/mcp/dist/index.js +2 -2
- package/payload/platform/plugins/work/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/work/mcp/dist/tools/project-create.js +6 -6
- package/payload/platform/plugins/work/mcp/dist/tools/project-create.js.map +1 -1
- package/payload/platform/plugins/work/mcp/dist/tools/session-list.d.ts +1 -1
- package/payload/platform/plugins/work/mcp/dist/tools/session-list.d.ts.map +1 -1
- package/payload/platform/plugins/work/mcp/dist/tools/session-list.js +1 -1
- package/payload/platform/plugins/work/mcp/dist/tools/session-list.js.map +1 -1
- package/payload/platform/plugins/x-import/references/archive-shape.md +2 -2
- package/payload/platform/plugins/x-import/skills/x-import/SKILL.md +4 -4
- package/payload/platform/scripts/admin-persist-audit.ts +18 -18
- package/payload/platform/scripts/identity-forbidden-token-check.mjs +2 -0
- package/payload/platform/scripts/seed-neo4j.sh +1 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.js +3 -3
- 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 +3 -3
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +4 -4
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- 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 +2 -0
- package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -1
- package/payload/platform/templates/specialists/agents/archive-ingest-operator.md +45 -0
- package/payload/platform/templates/specialists/agents/database-operator.md +5 -17
- package/payload/platform/templates/specialists/agents/librarian.md +1 -1
- package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
- package/payload/server/{chunk-AXOL2PPG.js → chunk-3TRIXQSJ.js} +101 -101
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/public/assets/{admin-3fLFD5h_.js → admin-Dal5FWaD.js} +2 -2
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-Breg9-99.js → architectureDiagram-Q4EWVU46-Do2zYONG.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DXf1_673.js → blockDiagram-DXYQGD6D-DpIX_bRu.js} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-CSZ36W4-.js → c4Diagram-AHTNJAMY-Cz335ZSY.js} +1 -1
- package/payload/server/public/assets/channel-PC4_IjI1.js +1 -0
- package/payload/server/public/assets/{chunk-336JU56O-DsrLk2eK.js → chunk-336JU56O-Dmknn3Wo.js} +2 -2
- package/payload/server/public/assets/{chunk-426QAEUC-JpNfNf81.js → chunk-426QAEUC-ClfGjizN.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-DmClEAD0.js → chunk-4TB4RGXK-BPKctJ5c.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-BI9blW3N.js → chunk-5FUZZQ4R-BWDCO9zw.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-BbgttEFO.js → chunk-5PVQY5BW-BE34_Db0.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-BX_LCFOx.js → chunk-EDXVE4YY-BysA-_6v.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-Bb7EoD0w.js → chunk-ENJZ2VHE-BMVyMsqA.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-DH8uQk-s.js → chunk-ICPOFSXX-C5KRdLV4.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-FH5kgXsw.js → chunk-OYMX7WX6-DVZD-AVc.js} +1 -1
- package/payload/server/public/assets/{chunk-U2HBQHQK-D_ljlkHr.js → chunk-U2HBQHQK-DYmQdx8x.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-BX3EmZvm.js → chunk-X2U36JSP-DrZenIl3.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-Vu7-E93h.js → chunk-YZCP3GAM-CDuGbvMq.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-CwjhNPX5.js → chunk-ZZ45TVLE-COztbiu5.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-B_pMa-SX.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BdBAgF20.js +1 -0
- package/payload/server/public/assets/clone-CkNt9L9r.js +1 -0
- package/payload/server/public/assets/{dagre-Ce6gsj0C.js → dagre-Cv9Ib2OM.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-BaMGpsoy.js → dagre-KV5264BT-CoEd61KZ.js} +1 -1
- package/payload/server/public/assets/{data-BHASh0_Y.js → data-DbSORCl4.js} +1 -1
- package/payload/server/public/assets/{diagram-5BDNPKRD-CHEE9rjq.js → diagram-5BDNPKRD-WXNzw3uW.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-C98sZLW1.js → diagram-G4DWMVQ6-C6IuQ2VV.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-DNvMGsTZ.js → diagram-MMDJMWI5-CdJdir5A.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-Cdte4IBa.js → diagram-TYMM5635-DxWKQH5T.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-C9VZsWXK.js → erDiagram-SMLLAGMA-C9fvs33K.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-tuP5fzzR.js → flowDiagram-DWJPFMVM-BO7Yrbqv.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-SJgRPUwx.js → ganttDiagram-T4ZO3ILL-CQJyWBZq.js} +1 -1
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-DU_cI_50.js → gitGraphDiagram-UUTBAWPF-DZfQHrYw.js} +1 -1
- package/payload/server/public/assets/{graph-labels-DXlmm1og.js → graph-labels-BBB5jsZk.js} +1 -1
- package/payload/server/public/assets/{graph-BhEI09tF.js → graph-ys_joP2o.js} +1 -1
- package/payload/server/public/assets/{graphlib-D_nAsvmx.js → graphlib-C40H-Q5E.js} +1 -1
- package/payload/server/public/assets/{infoDiagram-42DDH7IO-Cj2Y19m6.js → infoDiagram-42DDH7IO-CakfV5f9.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-DMc1xq1y.js → ishikawaDiagram-UXIWVN3A-CPuBPyfa.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-C4CRAQma.js → journeyDiagram-VCZTEJTY-zpZm2Mmo.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-CTr4AldU.js → kanban-definition-6JOO6SKY-DfJduQCo.js} +1 -1
- package/payload/server/public/assets/{line-Btlm_IAl.js → line-BpYQqO5R.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-DXFdj_y1.js → mermaid-parser.core-C5Mwi14D.js} +1 -1
- package/payload/server/public/assets/{mermaid.core-DFBhoCr5.js → mermaid.core-D8qBtvvT.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-r9gVQybo.js → mindmap-definition-QFDTVHPH-Bli9JhIN.js} +1 -1
- package/payload/server/public/assets/{page-CDWu1Aft.js → page--bl5Y7ZI.js} +2 -2
- package/payload/server/public/assets/page-CwmZ76U7.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-CHKZjSaH.js → pieDiagram-DEJITSTG-MsLXTSLg.js} +1 -1
- package/payload/server/public/assets/{public-DyGWgfaZ.js → public-DltgEfA9.js} +2 -2
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-CSGR1HJr.js → quadrantDiagram-34T5L4WZ-De1sh2K0.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-DZ6hX9D6.js → requirementDiagram-MS252O5E-D5Sfg1t_.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-DbZBKh0m.js → sankeyDiagram-XADWPNL6-DHA3LIbv.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-BHHpb8dt.js → sequenceDiagram-FGHM5R23-BE_QlG1B.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DQ1jiLB4.js → stateDiagram-FHFEXIEX-NIwp3F4u.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-pfk2F6st.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-BlGiEU7p.js → timeline-definition-GMOUNBTQ-CPE9jyDF.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-DmEH-hsB.js → vennDiagram-DHZGUBPP-CKfoyYmH.js} +1 -1
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-C7KJJ40d.js → wardleyDiagram-NUSXRM2D-B9yJek-o.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-JDnusCaa.js → xychartDiagram-5P7HB3ND-DuCcSLqX.js} +1 -1
- package/payload/server/public/data.html +3 -3
- package/payload/server/public/graph.html +3 -3
- package/payload/server/public/index.html +4 -4
- package/payload/server/public/public.html +1 -1
- package/payload/server/server.js +133 -133
- package/payload/server/public/assets/channel-BmZnt3PP.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-kmMLFUpV.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BV7Ae8ct.js +0 -1
- package/payload/server/public/assets/clone-B5eqoN9I.js +0 -1
- package/payload/server/public/assets/page-cyvshX4Z.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CByT2RzF.js +0 -1
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { updatePollState } from "../lib/credentials.js";
|
|
2
|
+
import { stripAngleBrackets } from "../lib/graph.js";
|
|
3
|
+
import { dispatchEmailMessagesToConversationArchive } from "../lib/conversation-archive-dispatch.js";
|
|
4
|
+
import { takeBatch, peekBatch } from "../lib/ingest-batch.js";
|
|
5
|
+
function normaliseId(id) {
|
|
6
|
+
return stripAngleBrackets(id)?.toLowerCase() ?? null;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Apply operator decisions to the most recent email-fetch batch.
|
|
10
|
+
*
|
|
11
|
+
* - Every pending message must have a decision; missing IDs cause refusal
|
|
12
|
+
* so messages never silently fall through the high-water mark.
|
|
13
|
+
* - Only "ingest" entries are written to the graph; "discard" entries
|
|
14
|
+
* advance the high-water mark without persisting anything.
|
|
15
|
+
* - The cached batch is consumed (taken, not peeked) only on success.
|
|
16
|
+
*/
|
|
17
|
+
export async function emailIngest(params) {
|
|
18
|
+
const batch = peekBatch(params.accountId);
|
|
19
|
+
if (!batch) {
|
|
20
|
+
throw new Error("No pending email batch. Call email-fetch first to list new messages, then email-ingest to apply the operator's decisions.");
|
|
21
|
+
}
|
|
22
|
+
// Build a normalised disposition map. The agent may pass IDs with or
|
|
23
|
+
// without RFC 2822 angle brackets — normalise both sides.
|
|
24
|
+
const decisionMap = new Map();
|
|
25
|
+
for (const d of params.decisions) {
|
|
26
|
+
const key = normaliseId(d.messageId);
|
|
27
|
+
if (!key) {
|
|
28
|
+
throw new Error(`Decision had a blank messageId: ${JSON.stringify(d)}`);
|
|
29
|
+
}
|
|
30
|
+
decisionMap.set(key, d.disposition);
|
|
31
|
+
}
|
|
32
|
+
// Every pending message must have a decision. List missing ones so the
|
|
33
|
+
// operator can re-decide rather than silently dropping them.
|
|
34
|
+
const missing = [];
|
|
35
|
+
for (const m of batch.messages) {
|
|
36
|
+
const key = normaliseId(m.messageId);
|
|
37
|
+
if (!key)
|
|
38
|
+
continue; // messages with no Message-ID can't be addressed individually
|
|
39
|
+
if (!decisionMap.has(key))
|
|
40
|
+
missing.push(m.messageId ?? `UID ${m.uid}`);
|
|
41
|
+
}
|
|
42
|
+
if (missing.length > 0) {
|
|
43
|
+
throw new Error(`Refusing to ingest — missing decisions for ${missing.length} message(s): ${missing.join(", ")}. Pass a disposition ("ingest" or "discard") for every Message-ID returned by email-fetch.`);
|
|
44
|
+
}
|
|
45
|
+
const toIngest = [];
|
|
46
|
+
let discarded = 0;
|
|
47
|
+
for (const m of batch.messages) {
|
|
48
|
+
const key = normaliseId(m.messageId);
|
|
49
|
+
const disposition = key ? decisionMap.get(key) : undefined;
|
|
50
|
+
if (disposition === "ingest") {
|
|
51
|
+
toIngest.push({
|
|
52
|
+
messageId: m.messageId,
|
|
53
|
+
inReplyTo: m.inReplyTo,
|
|
54
|
+
toAddresses: m.toAddresses,
|
|
55
|
+
ccAddresses: m.ccAddresses,
|
|
56
|
+
uid: m.uid,
|
|
57
|
+
uidValidity: batch.uidValidity,
|
|
58
|
+
mailbox: "INBOX",
|
|
59
|
+
recipientAddress: batch.recipientAddress,
|
|
60
|
+
fromAddress: m.fromAddress,
|
|
61
|
+
fromName: m.fromName,
|
|
62
|
+
subject: m.subject,
|
|
63
|
+
bodyPreview: m.bodyPreview,
|
|
64
|
+
receivedAt: m.date,
|
|
65
|
+
accountId: params.accountId,
|
|
66
|
+
screening: "clean",
|
|
67
|
+
screeningReason: "operator-approved",
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
discarded++;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
toIngest.sort((a, b) => a.receivedAt.localeCompare(b.receivedAt));
|
|
75
|
+
const { threadsDispatched, threadsSkipped, unresolvedAddresses } = await dispatchEmailMessagesToConversationArchive(toIngest);
|
|
76
|
+
// Advance the high-water mark so the next email-fetch starts after this batch.
|
|
77
|
+
await updatePollState(params.accountId, batch.maxUid, batch.uidValidity);
|
|
78
|
+
// Consume the cached batch only after a successful write + state advance.
|
|
79
|
+
takeBatch(params.accountId);
|
|
80
|
+
console.error(`[email-ingest] tag=email-ingest ingested=${toIngest.length} discarded=${discarded} threadsDispatched=${threadsDispatched} threadsSkipped=${threadsSkipped} unresolved=${unresolvedAddresses.length}`);
|
|
81
|
+
const lines = [
|
|
82
|
+
`Ingested ${toIngest.length} message(s); discarded ${discarded}.`,
|
|
83
|
+
`Graph: ${threadsDispatched} thread(s) dispatched to conversation-archive, ${threadsSkipped} skipped.`,
|
|
84
|
+
`Inbox high-water mark advanced to UID ${batch.maxUid}.`,
|
|
85
|
+
];
|
|
86
|
+
if (unresolvedAddresses.length > 0) {
|
|
87
|
+
lines.push(`Unresolved sender/recipient addresses (no :Person or :AdminUser carries these emails — add them to the graph and re-run email-ingest to land their threads): ${unresolvedAddresses.join(", ")}`);
|
|
88
|
+
}
|
|
89
|
+
return lines.join("\n");
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=email-ingest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-ingest.js","sourceRoot":"","sources":["../../src/tools/email-ingest.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email-setup.d.ts","sourceRoot":"","sources":["../../src/tools/email-setup.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"email-setup.d.ts","sourceRoot":"","sources":["../../src/tools/email-setup.ts"],"names":[],"mappings":"AA0CA,UAAU,WAAW;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;IAC7D,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC,CAkID"}
|
|
@@ -1,62 +1,38 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
import { resolve } from "node:path";
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
4
2
|
import { writeConfig, writePassword, removeConfig, checkAddressBinding, writeBindingConfig, } from "../lib/credentials.js";
|
|
5
3
|
import { inferProvider, getProviderNotes } from "../lib/providers.js";
|
|
6
4
|
import * as imap from "../lib/imap.js";
|
|
7
5
|
import * as smtp from "../lib/smtp.js";
|
|
8
6
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* If the installer already registered the crons (via the brand crons block),
|
|
14
|
-
* this is a no-op. Handles the case where email is configured on a device
|
|
15
|
-
* that predates the installer cron registration fix.
|
|
7
|
+
* Task 432 — operator-initiated ingestion replaces the background poll.
|
|
8
|
+
* Strips any pre-existing email-fetch crontab line written by an older
|
|
9
|
+
* setup so previously-configured installs stop auto-polling on next
|
|
10
|
+
* email-setup. Returns true when a stale line was removed.
|
|
16
11
|
*/
|
|
17
|
-
function
|
|
12
|
+
function stripStaleEmailFetchCron() {
|
|
18
13
|
try {
|
|
19
14
|
const listResult = spawnSync("crontab", ["-l"], {
|
|
20
15
|
encoding: "utf-8",
|
|
21
16
|
stdio: ["pipe", "pipe", "pipe"],
|
|
22
17
|
});
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return execFileSync("which", ["node"], { encoding: "utf-8" }).trim();
|
|
33
|
-
}
|
|
34
|
-
catch {
|
|
35
|
-
return "/usr/bin/node";
|
|
36
|
-
}
|
|
37
|
-
})();
|
|
38
|
-
const logDir = resolve(homedir(), ".maxy/logs");
|
|
39
|
-
const cronEntries = [
|
|
40
|
-
`* * * * * mkdir -p ${logDir} && PLATFORM_ROOT=${platformRoot} ACCOUNT_ID=${accountId} ${nodeBin} ${platformRoot}/plugins/email/mcp/dist/scripts/email-fetch.js >> ${logDir}/email-fetch.log 2>&1`,
|
|
41
|
-
];
|
|
42
|
-
const newCrontab = existing.trimEnd()
|
|
43
|
-
? `${existing.trimEnd()}\n${cronEntries.join("\n")}\n`
|
|
44
|
-
: `${cronEntries.join("\n")}\n`;
|
|
18
|
+
if (listResult.status !== 0)
|
|
19
|
+
return false;
|
|
20
|
+
const existing = listResult.stdout ?? "";
|
|
21
|
+
if (!existing.includes("email-fetch"))
|
|
22
|
+
return false;
|
|
23
|
+
const cleaned = existing
|
|
24
|
+
.split("\n")
|
|
25
|
+
.filter((line) => !line.includes("email-fetch"))
|
|
26
|
+
.join("\n");
|
|
45
27
|
const writeResult = spawnSync("crontab", ["-"], {
|
|
46
|
-
input:
|
|
28
|
+
input: cleaned.endsWith("\n") ? cleaned : `${cleaned}\n`,
|
|
47
29
|
encoding: "utf-8",
|
|
48
30
|
stdio: ["pipe", "pipe", "pipe"],
|
|
49
31
|
});
|
|
50
|
-
|
|
51
|
-
return { registered: false, error: (writeResult.stderr || "").trim() };
|
|
52
|
-
}
|
|
53
|
-
return { registered: true };
|
|
32
|
+
return writeResult.status === 0;
|
|
54
33
|
}
|
|
55
|
-
catch
|
|
56
|
-
return
|
|
57
|
-
registered: false,
|
|
58
|
-
error: err instanceof Error ? err.message : String(err),
|
|
59
|
-
};
|
|
34
|
+
catch {
|
|
35
|
+
return false;
|
|
60
36
|
}
|
|
61
37
|
}
|
|
62
38
|
export async function emailSetup(params) {
|
|
@@ -155,8 +131,11 @@ export async function emailSetup(params) {
|
|
|
155
131
|
catch {
|
|
156
132
|
bindingOk = false;
|
|
157
133
|
}
|
|
158
|
-
//
|
|
159
|
-
|
|
134
|
+
// Task 432 — background polling retired. Strip any stale email-fetch
|
|
135
|
+
// crontab line from an earlier setup so previously-configured installs
|
|
136
|
+
// stop auto-polling. Operator now drives ingestion via the email-ingest
|
|
137
|
+
// skill (email-fetch + email-ingest tools).
|
|
138
|
+
const cronStripped = stripStaleEmailFetchCron();
|
|
160
139
|
// Get inbox count as a confirmation signal
|
|
161
140
|
let inboxCount;
|
|
162
141
|
try {
|
|
@@ -166,15 +145,16 @@ export async function emailSetup(params) {
|
|
|
166
145
|
// Non-fatal — setup still succeeded
|
|
167
146
|
}
|
|
168
147
|
const aliasNote = agentAddress !== email ? ` Agent address: ${agentAddress} (auth: ${email}).` : "";
|
|
169
|
-
const
|
|
170
|
-
? `
|
|
171
|
-
: ` Email configured but
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
148
|
+
const bindingNote = bindingOk
|
|
149
|
+
? ` Bound to agent ${agentSlug}.`
|
|
150
|
+
: ` Email configured but agent binding could not be set — run email-setup again.`;
|
|
151
|
+
const ingestNote = ` Ingestion is operator-initiated: ask the agent to "check my emails" to review and decide on new messages.`;
|
|
152
|
+
const cronNote = cronStripped
|
|
153
|
+
? ` Removed a stale background-fetch crontab line from an earlier setup.`
|
|
154
|
+
: "";
|
|
175
155
|
return {
|
|
176
156
|
success: true,
|
|
177
|
-
message: `Email configured successfully for ${email}.${aliasNote} IMAP and SMTP connections verified.${inboxCount !== undefined ? ` Inbox has ${inboxCount} messages.` : ""}${
|
|
157
|
+
message: `Email configured successfully for ${email}.${aliasNote} IMAP and SMTP connections verified.${inboxCount !== undefined ? ` Inbox has ${inboxCount} messages.` : ""}${bindingNote}${ingestNote}${cronNote}`,
|
|
178
158
|
inboxCount,
|
|
179
159
|
providerNotes,
|
|
180
160
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email-setup.js","sourceRoot":"","sources":["../../src/tools/email-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"email-setup.js","sourceRoot":"","sources":["../../src/tools/email-setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -54,7 +54,7 @@ The tool accepts the `messageId` of the email being replied to (visible in `emai
|
|
|
54
54
|
- **Reply to sender:** Default behaviour — replies to the original sender only.
|
|
55
55
|
- **Reply all:** Set `replyAll: true` to include all original recipients (TO + CC). The agent's own address is automatically excluded from the recipient list.
|
|
56
56
|
- **Threading:** The reply appears in the same conversation thread in Gmail, Apple Mail, Outlook, and other RFC 2822-compliant clients.
|
|
57
|
-
- **Prerequisite:** The original email must exist in the graph (
|
|
57
|
+
- **Prerequisite:** The original email must exist in the graph (ingested via the operator-initiated `email-ingest` flow). If the message hasn't been ingested yet, the tool returns a clear error.
|
|
58
58
|
|
|
59
59
|
Use `email-reply` when responding to a received email. Use `email-send` for new outbound messages.
|
|
60
60
|
|
|
@@ -71,26 +71,28 @@ When `agentAddress` is not set or matches the auth email, all tools behave as be
|
|
|
71
71
|
|
|
72
72
|
## Email Persistence
|
|
73
73
|
|
|
74
|
-
Emails
|
|
74
|
+
Emails enter the graph as `:KnowledgeDocument {source:'email'}` thread documents via the **operator-initiated ingestion flow** (see `skills/email-ingest/SKILL.md`). There is no background poll, cron, or auto-classifier — new messages are written only when the operator says "check my emails" and approves each one.
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
- **Deduplication:** Each email is identified by its Message-ID header. Re-polling the same messages does not create duplicates, even if the agent's email address changes between poll cycles. A composite unique constraint on `(messageId, accountId)` provides database-level enforcement.
|
|
78
|
-
- **Semantic search:** Stored emails are vector-indexed (subject + body preview), enabling natural-language search over email history via `email-graph-query`.
|
|
79
|
-
- **Isolation:** Each agent sees only emails addressed to its own bound email address, even when sharing a catchall mailbox.
|
|
76
|
+
The two ingestion tools:
|
|
80
77
|
|
|
81
|
-
|
|
78
|
+
- **`email-fetch`** — lists new IMAP messages since the stored high-water mark (`lastFetchedUid` on the `:EmailAccount` node). Returns sender, subject, date, Message-ID, UID, and a body preview. Writes nothing to the graph; stages the batch in-memory for the follow-up `email-ingest` call.
|
|
79
|
+
- **`email-ingest`** — takes a `decisions` array (`messageId` + `ingest` or `discard` per message). Writes only the `ingest` subset to the graph, advances `lastFetchedUid` to the batch's max UID, and consumes the staged batch. Refuses if any pending Message-ID lacks a decision.
|
|
82
80
|
|
|
83
|
-
|
|
81
|
+
Properties of the persistence layer:
|
|
84
82
|
|
|
85
|
-
- **
|
|
86
|
-
- **
|
|
87
|
-
- **
|
|
83
|
+
- **Operator-initiated only.** No `setInterval`, cron, or systemd timer ever invokes `email-fetch`. The operator drives every cycle.
|
|
84
|
+
- **Deduplication:** Each message is identified by Message-ID. Re-ingesting the same message MERGEs without duplicating; a composite unique constraint on `(messageId, accountId)` provides database-level enforcement.
|
|
85
|
+
- **Alias filtering:** Only emails addressed TO the agent's `agentAddress` are listed and ingested.
|
|
86
|
+
- **Semantic search:** Ingested threads are vector-indexed (subject + body preview), enabling natural-language search via `email-graph-query`.
|
|
87
|
+
- **Isolation:** Each agent sees only emails addressed to its own bound email address, even when sharing a catchall mailbox.
|
|
88
88
|
|
|
89
|
-
##
|
|
89
|
+
## Email Threading
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
Ingested messages are linked into conversation threads as one `:KnowledgeDocument {source:'email'}` per thread, with `:Person` `FROM`/`TO`/`CC` edges. Threading is resolved by `In-Reply-To`/`References` headers at ingest time.
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
- **Out-of-order arrival:** If a reply is ingested before its parent, the reply lives in its own thread until the parent is ingested, at which point future ingests fold them together via the shared root.
|
|
94
|
+
- **Thread context:** `email-read` and `email-search` include `Thread-Depth` (number of hops to the thread root) and `Thread-ID` (emailId of the root message) for any message already in the graph. Root emails (no parent) have no thread fields.
|
|
95
|
+
- **Scope:** Thread linkage never crosses account boundaries — parent lookups are always scoped to the same `accountId`.
|
|
94
96
|
|
|
95
97
|
### Agent-Email Binding
|
|
96
98
|
|
|
@@ -112,31 +114,9 @@ When the user asks about stored emails, email history, or email recall — use `
|
|
|
112
114
|
|
|
113
115
|
## Inbound Email Screening
|
|
114
116
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
### Verdicts
|
|
118
|
-
|
|
119
|
-
| Verdict | Stored? | Embedding? | Auto-respond? | Graph query? |
|
|
120
|
-
|---------|---------|------------|---------------|--------------|
|
|
121
|
-
| `clean` | Yes | Yes | Yes | Yes |
|
|
122
|
-
| `suspicious` | Yes (with `screeningReason`) | Yes | No | Yes |
|
|
123
|
-
| `discarded` | Yes (with `screeningReason`) | No | No | No (list mode) |
|
|
124
|
-
|
|
125
|
-
- **clean** — legitimate personal or business correspondence
|
|
126
|
-
- **suspicious** — phishing indicators (urgency + credential requests, mismatched sender), prompt injection patterns, or classification failure (safe default)
|
|
127
|
-
- **discarded** — obvious spam, marketing bulk mail, auto-generated notifications with no actionable content
|
|
128
|
-
|
|
129
|
-
### Prompt injection flag
|
|
117
|
+
There is no automated screener. The operator screens by eye during the `email-ingest` skill flow: `email-fetch` lists the new messages with sender, subject, and a body preview; the operator picks which ones to ingest and which to discard. A `screening` property of `clean` is stamped on every operator-approved row as a provenance marker (operator-approved), and discarded messages never enter the graph.
|
|
130
118
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
### Failure handling
|
|
134
|
-
|
|
135
|
-
If the Haiku API is unavailable (network, rate limit, auth failure), the email defaults to `suspicious`. The entire fetch batch is never blocked — each email is classified independently. API key absence causes all emails in the batch to default to `suspicious`.
|
|
136
|
-
|
|
137
|
-
### Logs
|
|
138
|
-
|
|
139
|
-
Classification verdicts are logged to `{accountDir}/logs/email-fetch.log` with per-email detail (fromAddress, verdict, reason, promptInjectionRisk) and batch summaries.
|
|
119
|
+
The previous Haiku classifier was removed in Task 424; the auto-respond binary that depended on it was removed alongside the screener. Both are intentionally absent — the doctrine is that every LLM-bearing pipeline is operator-initiated.
|
|
140
120
|
|
|
141
121
|
## Security
|
|
142
122
|
|
|
@@ -144,51 +124,7 @@ Classification verdicts are logged to `{accountDir}/logs/email-fetch.log` with p
|
|
|
144
124
|
- IMAP and SMTP connections require TLS or STARTTLS — plaintext is rejected
|
|
145
125
|
- Only the agent's own dedicated account is accessed — never the user's personal email
|
|
146
126
|
- Email nodes have `scope: "admin"` — never visible to public agents
|
|
147
|
-
- Inbound
|
|
148
|
-
|
|
149
|
-
## Auto-Respond
|
|
150
|
-
|
|
151
|
-
When enabled, a public agent replies to incoming emails. The auto-respond binary lives at `email/mcp/dist/scripts/email-auto-respond.js` and, like the fetcher, is **not currently scheduled on any install** — see `maxy-code-prd.md` §Scheduled tasks for the canonical dispatch destination. Until that landing, auto-respond only runs when an operator invokes the script manually.
|
|
152
|
-
|
|
153
|
-
### Setup
|
|
154
|
-
|
|
155
|
-
To enable auto-respond, call `email-auto-respond-config` with `enabled: true`. The tool requires an `agentSlug`. When called without a slug, the tool returns available public agents — present these as a numbered list in plain chat so the admin can choose which agent handles responses, then call the tool again with the selected slug.
|
|
156
|
-
|
|
157
|
-
### Configuration
|
|
158
|
-
|
|
159
|
-
- `enabled` — `true` to enable, `false` to disable
|
|
160
|
-
- `agentSlug` — slug of the public agent that responds (required when enabling)
|
|
161
|
-
- `pollIntervalMinutes` — how often to check for new emails (default: 5, range: 1–60)
|
|
162
|
-
- `hourlyLimit` — maximum auto-replies per clock hour UTC (default: 20, range: 1–1000)
|
|
163
|
-
- `dailyLimit` — maximum auto-replies per calendar day UTC (default: 100, range: 1–10000)
|
|
164
|
-
|
|
165
|
-
### Behaviour
|
|
166
|
-
|
|
167
|
-
- Once the dispatcher is wired (see above), each account's poll is skipped if the configured interval hasn't elapsed since the last poll. The interval gate is enforced inside `email-auto-respond.js`, so the same skip logic applies whether the script is fired by the dispatcher or manually by an operator.
|
|
168
|
-
- Only emails addressed TO the agent's email address are processed (alias filtering applies).
|
|
169
|
-
- Auto-replies, mailing list messages, and emails from the agent's own address are automatically skipped (RFC 3834 loop prevention).
|
|
170
|
-
- Outgoing replies include `In-Reply-To` and `References` headers for correct threading, and `Auto-Submitted: auto-replied` to prevent loops with other auto-responders.
|
|
171
|
-
- Every reply includes a deterministic AI disclosure footer ("This reply was generated by an AI assistant.") appended after the agent's response. This is a regulatory requirement (EU AI Act Article 50) and is not dependent on the LLM including disclosure in its generated text.
|
|
172
|
-
- The subject line carries a single `Re:` prefix (no doubling).
|
|
173
|
-
|
|
174
|
-
### Rate Limiting
|
|
175
|
-
|
|
176
|
-
Per-account send caps prevent runaway auto-replies from spam waves, mailing list explosions, or deliberate attacks. Two independent limits:
|
|
177
|
-
|
|
178
|
-
- **Hourly limit** (default 20) — resets at each UTC clock-hour boundary
|
|
179
|
-
- **Daily limit** (default 100) — resets at midnight UTC
|
|
180
|
-
|
|
181
|
-
When either limit is reached, remaining emails in the poll cycle are skipped (not replied to). Auto-respond is **not** disabled — counters reset naturally at the next boundary. A medium-priority admin Task is created to notify the admin.
|
|
182
|
-
|
|
183
|
-
Within a single poll cycle, only one auto-reply is sent per unique sender address. This prevents reply storms when an automated sender delivers multiple messages. Sender deduplication is case-insensitive.
|
|
184
|
-
|
|
185
|
-
### Circuit Breaker
|
|
186
|
-
|
|
187
|
-
After 3 consecutive failures (IMAP errors, API failures, SMTP rejections), auto-respond is automatically disabled and a high-priority Task is created for the admin. The admin sees this task at the start of their next session and can re-enable auto-respond after resolving the issue.
|
|
188
|
-
|
|
189
|
-
### Disabling
|
|
190
|
-
|
|
191
|
-
Call `email-auto-respond-config` with `enabled: false`. This clears the agent assignment and resets the failure counter.
|
|
127
|
+
- Inbound messages enter the graph only when the operator approves them by eye via `email-ingest`
|
|
192
128
|
|
|
193
129
|
## OTP Integration
|
|
194
130
|
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: email-ingest
|
|
3
|
+
description: "Operator-initiated email ingestion. Activate when the operator asks to check, triage, or pull in new email ('check my emails', 'any new mail?', 'pull in the latest emails', 'what came in overnight'). Drives a list → summarise → ask → ingest loop using the email-fetch and email-ingest tools. Human-in-the-loop: nothing enters the graph without an explicit operator decision per message."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Email ingestion
|
|
7
|
+
|
|
8
|
+
Operator-initiated, human-in-the-loop ingestion of the agent's IMAP inbox into the graph. New messages enter the knowledge graph **only** when the operator says so, and only the ones they pick. There is no background poll, no automatic classifier, no silent writes.
|
|
9
|
+
|
|
10
|
+
## When to activate
|
|
11
|
+
|
|
12
|
+
Activate when the operator wants to bring new email into the agent's memory. Typical phrasings:
|
|
13
|
+
|
|
14
|
+
- "Check my emails."
|
|
15
|
+
- "Any new mail?"
|
|
16
|
+
- "Pull in the latest emails."
|
|
17
|
+
- "What came in overnight?"
|
|
18
|
+
|
|
19
|
+
Do **not** activate for:
|
|
20
|
+
|
|
21
|
+
- Searching, reading, or recalling email already in the inbox or the graph — those are `email-search`, `email-read`, `email-graph-query`.
|
|
22
|
+
- Drafting or sending — that's `email-composition`.
|
|
23
|
+
- Setup, status, or OTP extraction — those are direct tool calls.
|
|
24
|
+
|
|
25
|
+
## Flow
|
|
26
|
+
|
|
27
|
+
### 1. List
|
|
28
|
+
|
|
29
|
+
Call `email-fetch`. It pulls new messages since the stored high-water mark (or a `since_uid` if the operator asked for a wider window) and stages them in-memory for the follow-up ingest. **It writes nothing to the graph.**
|
|
30
|
+
|
|
31
|
+
If `email-fetch` returns "No new messages", say that and stop. There is nothing to ingest.
|
|
32
|
+
|
|
33
|
+
### 2. Summarise
|
|
34
|
+
|
|
35
|
+
Present the listed messages to the operator as a numbered or per-`Message-ID` summary. For each, surface:
|
|
36
|
+
|
|
37
|
+
- Sender (name + address).
|
|
38
|
+
- Subject.
|
|
39
|
+
- A one-line gist drawn from the body preview (not the full preview — keep it tight).
|
|
40
|
+
- A suggested disposition where the message is obviously one or the other (e.g., "newsletter — looks like discard", "thread reply from a known correspondent — looks like ingest"). The suggestion is a hint, never an action; the operator decides.
|
|
41
|
+
|
|
42
|
+
Do not classify suspicious vs clean — there is no screener. If a message looks like phishing, surface that observation in plain English so the operator can discard it by eye.
|
|
43
|
+
|
|
44
|
+
### 3. Ask
|
|
45
|
+
|
|
46
|
+
Ask the operator to confirm a disposition for **every** message in the list. Either:
|
|
47
|
+
|
|
48
|
+
- A blanket call ("ingest all", "discard everything"), which you turn into the per-message map.
|
|
49
|
+
- An explicit per-message choice ("ingest 1, 2, 4; discard 3").
|
|
50
|
+
|
|
51
|
+
If the operator answers ambiguously ("the work ones"), restate the messages you think they mean and confirm before proceeding. Never guess.
|
|
52
|
+
|
|
53
|
+
### 4. Ingest
|
|
54
|
+
|
|
55
|
+
Call `email-ingest` with a `decisions` array containing one entry per Message-ID returned by `email-fetch`. The tool refuses if any pending Message-ID is missing a decision — that's the safeguard against silent drops, not an error to retry around. If it refuses, go back to the operator and ask about the missing ones.
|
|
56
|
+
|
|
57
|
+
On success the tool returns a one-line summary (ingested / discarded / thread counts) and advances the inbox high-water mark.
|
|
58
|
+
|
|
59
|
+
### 5. Confirm
|
|
60
|
+
|
|
61
|
+
Echo the tool's summary back to the operator in one sentence. If they want to draft a reply to anything that was just ingested, hand off to `email-composition`.
|
|
62
|
+
|
|
63
|
+
## Edge cases
|
|
64
|
+
|
|
65
|
+
| Situation | Behaviour |
|
|
66
|
+
|-----------|-----------|
|
|
67
|
+
| `email-fetch` returns zero new messages | Tell the operator and stop. Do not call `email-ingest`. |
|
|
68
|
+
| A listed message has no `Message-ID` header | Surface it by UID and ask the operator how to handle it. `email-ingest` cannot apply a per-message decision to it, so either widen the search or skip it explicitly. |
|
|
69
|
+
| Operator wants to ingest some now and review the rest later | Refuse cleanly. The high-water mark advances on every successful ingest, so a partial decision would silently drop the rest. Ask them to commit one way or the other on every message, or to wait. |
|
|
70
|
+
| Operator abandons mid-flow | Do not call `email-ingest`. The staged batch stays in memory until the next `email-fetch` overwrites it; the high-water mark does not move. |
|
|
71
|
+
| `email-fetch` errors (IMAP down, auth failure) | Surface the error verbatim. Do not retry silently. |
|
|
72
|
+
|
|
73
|
+
## Out of scope
|
|
74
|
+
|
|
75
|
+
- **Automatic re-screening or LLM classification.** The screener was removed; the operator is the screener now.
|
|
76
|
+
- **Scheduled or recurring ingestion.** There is no cron, no interval, no background trigger. The operator initiates every cycle.
|
|
77
|
+
- **Per-thread or per-sender allowlists.** Each message gets a fresh decision.
|
|
78
|
+
- **Other channels.** WhatsApp and the public web have their own ingestion paths.
|
|
79
|
+
|
|
80
|
+
## Observability
|
|
81
|
+
|
|
82
|
+
Each tool emits a single tagged log line:
|
|
83
|
+
|
|
84
|
+
- `[email-fetch] tag=email-fetch listed=<n> sinceUid=<uid>` — one per list call.
|
|
85
|
+
- `[email-ingest] tag=email-ingest ingested=<n> discarded=<m>` — one per ingest call.
|
|
86
|
+
|
|
87
|
+
A complete cycle is greppable as the pair `email-fetch` → `email-ingest` for the same session.
|
|
@@ -72,7 +72,7 @@ When the owner is an external Person (non-operator archive), the anchor is the c
|
|
|
72
72
|
|
|
73
73
|
**Doctrine:** raw Cypher and `cypher-shell` invocations are forbidden in this skill and its references. Writes route through `mcp__plugin_memory_memory__memory-archive-write` (bulk archives) or `mcp__plugin_memory_memory__memory-write` / `mcp__plugin_memory_memory__memory-update` (single-node enrichments like `profile.md`). If a CSV needs a write shape no current MCP tool supports, file a task to extend `memory-archive-write` with a new `archiveType` handler — never improvise via Bash. See [librarian's LOUD-FAIL prerogative](../../../../templates/specialists/agents/librarian.md#prerogatives).
|
|
74
74
|
|
|
75
|
-
**LOUD-FAIL on parse errors (structurally enforced).** When LinkedIn parser tools land that follow the `mcp__*__*-import-parse` naming convention, the harness-level `platform/plugins/admin/hooks/archive-ingest-gate.sh` will record an `isError: true` response and block every subsequent tool call this turn until the operator submits the next prompt. The hook also denies edits to `platform/plugins/*/lib/*` and JavaScript test runners (`vitest`, `bun test`, `npm test`, `npx jest`) unconditionally. The skill's "no Bash improvisation" doctrine above is the contract; the hook is the enforcement. See [.docs/hooks.md](../../../../../.docs/hooks.md) for the full gate surface.
|
|
75
|
+
**LOUD-FAIL on parse errors (structurally enforced).** When LinkedIn parser tools land that follow the `mcp__*__*-import-parse` naming convention, the harness-level `platform/plugins/admin/hooks/archive-ingest-surface-gate.sh` will record an `isError: true` response and block every subsequent tool call this turn until the operator submits the next prompt. The hook also denies edits to `platform/plugins/*/lib/*` and JavaScript test runners (`vitest`, `bun test`, `npm test`, `npx jest`) unconditionally. The skill's "no Bash improvisation" doctrine above is the contract; the hook is the enforcement. See [.docs/hooks.md](../../../../../.docs/hooks.md) for the full gate surface.
|
|
76
76
|
|
|
77
77
|
## Selective-ingest threshold (bulk archives)
|
|
78
78
|
|
|
@@ -94,42 +94,15 @@ The operator picks one axis or a combination. The agent applies the filter to `r
|
|
|
94
94
|
|
|
95
95
|
## File roster
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
|
100
|
-
|
|
101
|
-
|
|
|
102
|
-
|
|
|
103
|
-
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
| 3 | `Education.csv` | _pending_ | `(:UserProfile)-[:ATTENDED {degree,startDate,endDate}]->(:Organization {organizationCategory:'educational'})` |
|
|
107
|
-
| 3 | `Certifications.csv` | _pending_ | `(:UserProfile)-[:HOLDS]->(:Credential)` |
|
|
108
|
-
| 3 | `Languages.csv` | _pending_ | `(:UserProfile)-[:SPEAKS {proficiency}]->(:DefinedTerm {category:'language'})` |
|
|
109
|
-
| 3 | `Skills.csv` | _pending_ | `(:UserProfile)-[:HAS_SKILL]->(:DefinedTerm {category:'linkedin-skill'})` |
|
|
110
|
-
| 4 | `Connections.csv` | [connections.md](references/connections.md) | `(:AdminUser)-[:CONNECTED_ON_LINKEDIN {connectedOn}]->(:Person)` + `(:Person)-[:WORKS_FOR {title}]->(:Organization)` |
|
|
111
|
-
| 5 | `Invitations.csv` | _pending_ | `(:AdminUser)-[:INVITED / :INVITED_BY]->(:Person)` |
|
|
112
|
-
| 5 | `Endorsement_Given_Info.csv` | _pending_ | `(:AdminUser)-[:ENDORSED {date}]->(:Person)-[:FOR_SKILL]->(:DefinedTerm)` |
|
|
113
|
-
| 5 | `Endorsement_Received_Info.csv` | _pending_ | `(:Person)-[:ENDORSED {date}]->(:AdminUser)-[:FOR_SKILL]->(:DefinedTerm)` |
|
|
114
|
-
| 5 | `Recommendations_Given.csv` | _pending_ | `(:Review)-[:ABOUT]->(:Person)`, `(:AdminUser)-[:AUTHORED]->(:Review)` |
|
|
115
|
-
| 5 | `Recommendations_Received.csv` | _pending_ | `(:Review)-[:ABOUT]->(:AdminUser)`, `(:Person)-[:AUTHORED]->(:Review)` |
|
|
116
|
-
| 6 | `Company Follows.csv` | _pending_ | `(:AdminUser)-[:FOLLOWS {since}]->(:Organization)` |
|
|
117
|
-
| 6 | `Causes You Care About.csv` | _pending_ | `(:UserProfile)-[:SUPPORTS]->(:DefinedTerm {category:'cause'})` |
|
|
118
|
-
| 6 | `Events.csv` | _pending_ | `(:AdminUser)-[:ATTENDED_EVENT]->(:Event)` |
|
|
119
|
-
| 7 | `messages.csv` | conversation-archive (Task 397) | dispatched to `conversation-archive` skill with `--source linkedin-messages`; one `:ConversationArchive` per DM thread + `:Section` chunks + `(:Person)-[:PARTICIPANT_IN]->(archive)` |
|
|
120
|
-
| 7 | `guide_messages.csv` | same | same dispatch (likely empty) |
|
|
121
|
-
| 7 | `learning_coach_messages.csv` | same | same dispatch (likely empty) |
|
|
122
|
-
| 7 | `learning_role_play_messages.csv` | same | same dispatch (likely empty) |
|
|
123
|
-
| 8 | `Articles/` | _pending_ | `(:AdminUser)-[:AUTHORED]->(:CreativeWork {category:'linkedin-article'})` |
|
|
124
|
-
| 8 | `Learning.csv` | _pending_ | `(:UserProfile)-[:COMPLETED]->(:Credential)` (LinkedIn Learning courses) |
|
|
125
|
-
| 9 | `Jobs/Job Applications.csv` | _pending_ | `(:AdminUser)-[:APPLIED_TO {date}]->(:Organization)` via job-posting text on the edge |
|
|
126
|
-
| 9 | `Jobs/Saved Jobs.csv` | _pending_ | `(:AdminUser)-[:SAVED_JOB]->(:Organization)` |
|
|
127
|
-
| 9 | `Jobs/Job Seeker Preferences.csv` | _pending_ | `:UserProfile.jobSeekerPreferences` property blob |
|
|
128
|
-
| 9 | `Jobs/Online Job Postings.csv` | _pending_ | `(:AdminUser)-[:POSTED]->(:JobPosting)` (only rows where the operator authored the posting) |
|
|
129
|
-
| 9 | `SavedJobAlerts.csv` | _pending_ | `:UserProfile.savedJobAlerts` property blob |
|
|
130
|
-
| 10 | `Services Marketplace/Providers.csv` | _pending_ | `:UserProfile.servicesOffered` property blob |
|
|
131
|
-
| 10 | `Receipts_v2.csv` | _pending_ | `(:AdminUser)-[:PAID]->(:Invoice)` (LinkedIn subscriptions) |
|
|
132
|
-
| 10 | `Registration.csv` | _pending_ | `:UserProfile.linkedinRegisteredAt` property enrichment |
|
|
97
|
+
What's shipped today:
|
|
98
|
+
|
|
99
|
+
| File | Reference | Edges produced |
|
|
100
|
+
|------|-----------|----------------|
|
|
101
|
+
| `Profile.csv` | [profile.md](references/profile.md) | enrichment on `:UserProfile` (no new nodes) |
|
|
102
|
+
| `Connections.csv` | [connections.md](references/connections.md) | `(:AdminUser)-[:CONNECTED_ON_LINKEDIN {connectedOn}]->(:Person)` + `(:Person)-[:WORKS_FOR {title}]->(:Organization)` |
|
|
103
|
+
| `messages.csv` (and the three other DM CSVs) | conversation-archive (Task 397) | dispatched to `conversation-archive` skill with `--source linkedin-messages`; one `:ConversationArchive` per DM thread + `:Section` chunks + `(:Person)-[:PARTICIPANT_IN]->(archive)` |
|
|
104
|
+
|
|
105
|
+
Additional CSVs in the export (Positions, Education, Skills, Endorsements, Recommendations, Company Follows, Articles, Jobs, etc.) land as new references when the operator asks for them — each is its own follow-up.
|
|
133
106
|
|
|
134
107
|
## Explicitly out of scope
|
|
135
108
|
|
package/payload/platform/plugins/linkedin-import/skills/linkedin-import/references/connections.md
CHANGED
|
@@ -130,5 +130,6 @@ These are **read queries**, not writes. Cypher writes from the agent are forbidd
|
|
|
130
130
|
| Every row parsed as "Notes:,NaN,…" | Header preamble not skipped | Skip first 3 lines before the CSV parser |
|
|
131
131
|
| Tool error "row connectedOn is not ISO 8601" | Parser left `Connected On` in `"23 Apr 2026"` form | Convert to `YYYY-MM-DD` before passing to the tool |
|
|
132
132
|
| Tool error "ownerNodeId not found" | Owner-confirmation flow not run, or operator typed the wrong id | Re-run owner confirmation; pass the resulting `elementId` as `ownerNodeId` |
|
|
133
|
+
| Tool error `ownerNodeId <id> belongs to account <X>, not <Y>. Cross-account archive ingest refused.` | The confirmed owner lives in a different account than the calling session — typically the operator confirmed a Person/AdminUser from a different brand, or `accountId` was passed wrong | Re-run owner confirmation inside the correct account, or pass the calling session's `accountId` |
|
|
133
134
|
| `WORKS_FOR` count « connection count | Many rows have blank company | Expected — LinkedIn doesn't force connections to list a current employer |
|
|
134
135
|
| Tool not present in `init` frame | `specialists:librarian` spawned without the `mcp__plugin_memory_memory__memory-archive-write` token | Loud-fail per librarian's prerogatives. Do not improvise via Bash. Operator must remediate (re-seed specialist templates) |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memory",
|
|
3
|
-
"description": "Graph memory plugin. Provides memory-search (with optional `fields` projection for known-shape lookups), memory-write, memory-update, and the :Report surface (memory-report-write / memory-report-read-latest / memory-report-list) for reading from, writing to, and updating the Neo4j knowledge graph. Includes conversational memory — organic preference learning, evidence-backed recall, and transparent 'what do you know about me?' responses. Document ingestion goes through memory-ingest; the dispatched specialist produces typed-section JSON in-turn from the loaded ontology. Two modes: `document` (default) for unstructured PDF/web content → :KnowledgeDocument (keyed on `attachmentId`) + :Section, and `chat` for conversation transcripts → :ConversationArchive (keyed on `conversationIdentity`) + :Section chunks; two parent labels, two writer paths chosen by which identity property is set. Conversation-archive Phase 2 (`conversation-archive-
|
|
3
|
+
"description": "Graph memory plugin. Provides memory-search (with optional `fields` projection for known-shape lookups), memory-write, memory-update, and the :Report surface (memory-report-write / memory-report-read-latest / memory-report-list) for reading from, writing to, and updating the Neo4j knowledge graph. Includes conversational memory — organic preference learning, evidence-backed recall, and transparent 'what do you know about me?' responses. Document ingestion goes through memory-ingest; the dispatched specialist produces typed-section JSON in-turn from the loaded ontology. Operator-solicited reclassify of an already-stored thread-shaped KD (today: email-thread KDs) is exposed as `kd-classify <attachmentId>` — runs a body-growth gate (proceed iff body grew ≥25% since the last classify, or first-ever classify), stages the body to a temp file under `$ACCOUNT_DIR/tmp/`, and returns a dispatch envelope for the `librarian`; on success `memory-ingest` replaces the prior :Section children and stamps `lastClassifiedAt` + `lastClassifiedBodyLength` on the parent KD. Two modes: `document` (default) for unstructured PDF/web content → :KnowledgeDocument (keyed on `attachmentId`) + :Section, and `chat` for conversation transcripts → :ConversationArchive (keyed on `conversationIdentity`) + :Section chunks; two parent labels, two writer paths chosen by which identity property is set. Conversation-archive Phase 2 splits across two read-only tools (Task 433): `conversation-archive-list-chunks` pages chunk bodies for the dispatched specialist to read in-turn; `conversation-archive-derive-insights` converts the specialist's per-chunk claims into operator-facing proposals with per-kind cypher. `conversation-archive-enrich-rejection` records (or undoes) durable per-row rejections so already-triaged claims do not re-surface on re-runs. Ships four skills: `conversational-memory`, `document-ingest`, `conversation-archive` (source-agnostic transcript ingest for WhatsApp, Telegram, Signal, LinkedIn DMs, Zoom, meeting minutes, iMessage, Slack), and `conversation-archive-enrich` (per-row operator-gated insight derivation over a named archive's chunks).",
|
|
4
4
|
"version": "0.1.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Rubytech LLC"
|