@rubytech/create-realagent 1.0.406 → 1.0.423
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/index.js +12 -7
- package/package.json +2 -2
- package/payload/maxy/public/assets/ChatInput-BcuvuN5M.css +1 -0
- package/payload/maxy/public/assets/ChatInput-Bkvp46jn.js +42 -0
- package/payload/maxy/public/assets/{admin-k0izNYS1.js → admin-h_MCGiva.js} +2 -2
- package/payload/maxy/public/assets/{public-3Y1Xk7cO.js → public-CJdTPrH1.js} +1 -1
- package/payload/maxy/public/brand/demo-9pm-enquiry.svg +95 -0
- package/payload/maxy/public/brand/demo-create-agent.svg +110 -0
- package/payload/maxy/public/brand/demo-morning-briefing.svg +83 -0
- package/payload/maxy/public/brand/demo-post-viewing.svg +107 -0
- package/payload/maxy/public/brand/how-it-works.svg +152 -0
- package/payload/maxy/public/brand/realagent-favicon-dark-32.png +0 -0
- package/payload/maxy/public/brand/realagent-icon-dark-round-web.png +0 -0
- package/payload/maxy/public/brand/realagent-icon-dark-web.png +0 -0
- package/payload/maxy/public/brand/realagent-icon-web.png +0 -0
- package/payload/maxy/public/brand-constants.json +3 -3
- package/payload/maxy/public/brand-defaults.css +4 -4
- package/payload/maxy/public/index.html +3 -3
- package/payload/maxy/public/public.html +3 -3
- package/payload/maxy/server.js +618 -115
- package/payload/platform/config/brand.json +9 -7
- package/payload/platform/knowledge/maxy.md +4 -0
- package/payload/platform/plugins/admin/PLUGIN.md +7 -6
- package/payload/platform/plugins/admin/hooks/agent-creation-approval.sh +9 -1
- package/payload/platform/plugins/admin/hooks/agent-creation-gate.sh +9 -1
- package/payload/platform/plugins/admin/hooks/agent-creation-post.sh +9 -1
- package/payload/platform/plugins/admin/hooks/test-agent-creation-gate.sh +15 -0
- package/payload/platform/plugins/admin/mcp/dist/index.js +1 -1
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/skills/plugin-management/skill.md +56 -7
- package/payload/platform/plugins/admin/skills/public-agent-manager/skill.md +21 -2
- package/payload/platform/plugins/anthropic/PLUGIN.md +0 -1
- package/payload/platform/plugins/business-assistant/PLUGIN.md +1 -1
- package/payload/platform/plugins/cloudflare/PLUGIN.md +0 -1
- package/payload/platform/plugins/contacts/PLUGIN.md +0 -1
- package/payload/platform/plugins/deep-research/PLUGIN.md +0 -1
- package/payload/platform/plugins/docs/PLUGIN.md +1 -1
- package/payload/platform/plugins/docs/references/plugins-guide.md +11 -5
- package/payload/platform/plugins/email/PLUGIN.md +1 -2
- package/payload/platform/plugins/email/mcp/dist/scripts/email-auto-respond.d.ts +1 -1
- package/payload/platform/plugins/email/mcp/dist/scripts/email-auto-respond.js +1 -1
- package/payload/platform/plugins/memory/PLUGIN.md +24 -4
- package/payload/platform/plugins/memory/mcp/dist/index.js +1 -1
- package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.js +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.js +2 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-edit-attachment.js +2 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-extract.js +2 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-read-attachment.js +2 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.js +5 -5
- 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 +31 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js.map +1 -1
- package/payload/platform/plugins/memory/skills/{conversational-memory.md → conversational-memory/SKILL.md} +10 -1
- package/payload/platform/plugins/projects/PLUGIN.md +1 -1
- package/payload/platform/plugins/sales/PLUGIN.md +1 -1
- package/payload/platform/plugins/scheduling/PLUGIN.md +15 -1
- package/payload/platform/plugins/scheduling/mcp/dist/index.js +36 -9
- package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.d.ts +6 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.js +23 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/time-format.d.ts +48 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/time-format.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/time-format.js +140 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/time-format.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +24 -14
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.js +24 -6
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-list.js.map +1 -1
- package/payload/platform/plugins/tasks/.claude-plugin/plugin.json +0 -1
- package/payload/platform/plugins/tasks/PLUGIN.md +11 -1
- package/payload/platform/plugins/waitlist/PLUGIN.md +2 -2
- package/payload/platform/plugins/waitlist/mcp/dist/index.js +44 -0
- package/payload/platform/plugins/waitlist/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-heal.d.ts +33 -0
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-heal.d.ts.map +1 -0
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-heal.js +124 -0
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-heal.js.map +1 -0
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-list.d.ts +1 -0
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-list.d.ts.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-list.js +1 -0
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-list.js.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-persist.d.ts +6 -3
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-persist.d.ts.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-persist.js +20 -9
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-persist.js.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-review.d.ts +1 -0
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-review.d.ts.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-review.js +1 -0
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-review.js.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-scan.d.ts +3 -2
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-scan.d.ts.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-scan.js +3 -2
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-scan.js.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-setup.d.ts.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-setup.js +4 -35
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-setup.js.map +1 -1
- package/payload/platform/plugins/workflows/.claude-plugin/plugin.json +0 -1
- package/payload/platform/plugins/workflows/PLUGIN.md +12 -3
- package/payload/platform/plugins/workflows/mcp/dist/lib/llm-call.d.ts +15 -23
- package/payload/platform/plugins/workflows/mcp/dist/lib/llm-call.d.ts.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/lib/llm-call.js +64 -233
- package/payload/platform/plugins/workflows/mcp/dist/lib/llm-call.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.d.ts +4 -4
- package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.js +4 -4
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.d.ts +6 -6
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js +7 -7
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js.map +1 -1
- package/payload/platform/templates/agents/admin/IDENTITY.md +23 -6
- package/payload/platform/templates/specialists/agents/scheduler.md +1 -1
- package/payload/premium-plugins/real-agency/BUNDLE.md +32 -0
- package/payload/premium-plugins/real-agency/agents/buyer-enquiry/IDENTITY.md +13 -0
- package/payload/premium-plugins/real-agency/agents/buyer-enquiry/SOUL.md +9 -0
- package/payload/premium-plugins/real-agency/agents/buyer-enquiry/template.json +9 -0
- package/payload/premium-plugins/real-agency/plugins/real-agency-business/PLUGIN.md +34 -0
- package/payload/premium-plugins/real-agency/{skills/business-growth.md → plugins/real-agency-business/skills/business-growth/SKILL.md} +20 -25
- package/payload/premium-plugins/real-agency/{skills/business-operations.md → plugins/real-agency-business/skills/business-operations/SKILL.md} +5 -5
- package/payload/premium-plugins/real-agency/{skills/exp-partnership.md → plugins/real-agency-business/skills/exp-partnership/SKILL.md} +7 -7
- package/payload/premium-plugins/real-agency/{skills/personal-branding.md → plugins/real-agency-business/skills/personal-branding/SKILL.md} +17 -17
- package/payload/premium-plugins/real-agency/plugins/real-agency-buyers/PLUGIN.md +35 -0
- package/payload/premium-plugins/real-agency/{skills/buyer-feedback.md → plugins/real-agency-buyers/skills/buyer-feedback/SKILL.md} +2 -2
- package/payload/premium-plugins/real-agency/{skills/buyer-management.md → plugins/real-agency-buyers/skills/buyer-management/SKILL.md} +8 -8
- package/payload/premium-plugins/real-agency/{skills/buyer-seller-guides.md → plugins/real-agency-buyers/skills/buyer-seller-guides/SKILL.md} +7 -7
- package/payload/premium-plugins/real-agency/plugins/real-agency-coaching/PLUGIN.md +55 -0
- package/payload/premium-plugins/real-agency/{skills/agent-performance.md → plugins/real-agency-coaching/skills/agent-performance/SKILL.md} +5 -1
- package/payload/premium-plugins/real-agency/{skills/bespoke-coaching.md → plugins/real-agency-coaching/skills/bespoke-coaching/SKILL.md} +10 -2
- package/payload/premium-plugins/real-agency/{skills/coaching-toolkit.md → plugins/real-agency-coaching/skills/coaching-toolkit/SKILL.md} +3 -1
- package/payload/premium-plugins/real-agency/{skills/serhant-training.md → plugins/real-agency-coaching/skills/serhant-training/SKILL.md} +1 -1
- package/payload/premium-plugins/real-agency/plugins/real-agency-leads/PLUGIN.md +32 -0
- package/payload/premium-plugins/real-agency/{skills/lead-nurturing.md → plugins/real-agency-leads/skills/lead-nurturing/SKILL.md} +20 -26
- package/payload/premium-plugins/real-agency/{references/lead-nurturing-database-reactivation.md → plugins/real-agency-leads/skills/lead-nurturing/references/database-reactivation.md} +1 -1
- package/payload/premium-plugins/real-agency/{skills/prospecting.md → plugins/real-agency-leads/skills/prospecting/SKILL.md} +4 -4
- package/payload/premium-plugins/real-agency/plugins/real-agency-listings/PLUGIN.md +33 -0
- package/payload/premium-plugins/real-agency/{skills/home-preparation.md → plugins/real-agency-listings/skills/home-preparation/SKILL.md} +4 -4
- package/payload/premium-plugins/real-agency/{skills/listing-presentation.md → plugins/real-agency-listings/skills/listing-presentation/SKILL.md} +4 -4
- package/payload/premium-plugins/real-agency/{skills/property-marketing.md → plugins/real-agency-listings/skills/property-marketing/SKILL.md} +8 -8
- package/payload/premium-plugins/real-agency/plugins/real-agency-onboarding/PLUGIN.md +31 -0
- package/payload/premium-plugins/real-agency/{skills/bootstrap.md → plugins/real-agency-onboarding/skills/bootstrap/SKILL.md} +3 -3
- package/payload/premium-plugins/real-agency/{references/bootstrap-onboarding-flow.md → plugins/real-agency-onboarding/skills/bootstrap/references/onboarding-flow.md} +1 -1
- package/payload/premium-plugins/real-agency/plugins/real-agency-sales/PLUGIN.md +34 -0
- package/payload/premium-plugins/real-agency/{skills/sales-closer.md → plugins/real-agency-sales/skills/sales-closer/SKILL.md} +1 -4
- package/payload/premium-plugins/real-agency/{skills/sales-discovery.md → plugins/real-agency-sales/skills/sales-discovery/SKILL.md} +7 -11
- package/payload/premium-plugins/real-agency/{skills/sales-negotiation.md → plugins/real-agency-sales/skills/sales-negotiation/SKILL.md} +5 -8
- package/payload/premium-plugins/real-agency/{skills/sales-progression.md → plugins/real-agency-sales/skills/sales-progression/SKILL.md} +2 -2
- package/payload/premium-plugins/real-agency/plugins/real-agency-teaching/PLUGIN.md +32 -0
- package/payload/premium-plugins/real-agency/{skills/content-directory.md → plugins/real-agency-teaching/skills/content-directory/SKILL.md} +2 -2
- package/payload/premium-plugins/real-agency/plugins/real-agency-vendors/PLUGIN.md +34 -0
- package/payload/premium-plugins/real-agency/{skills/negotiation.md → plugins/real-agency-vendors/skills/negotiation/SKILL.md} +5 -5
- package/payload/premium-plugins/real-agency/{skills/vendor-communication.md → plugins/real-agency-vendors/skills/vendor-communication/SKILL.md} +10 -10
- package/payload/premium-plugins/real-agency/{skills/vendor-updates.md → plugins/real-agency-vendors/skills/vendor-updates/SKILL.md} +3 -3
- package/payload/premium-plugins/teaching/PLUGIN.md +1 -2
- package/payload/premium-plugins/writer-craft/PLUGIN.md +1 -2
- package/payload/maxy/public/assets/ChatInput-7sHhJaNJ.js +0 -42
- package/payload/maxy/public/assets/ChatInput-oLFewltq.css +0 -1
- package/payload/premium-plugins/real-agency/PLUGIN.md +0 -101
- /package/payload/platform/plugins/anthropic/skills/{get-api-key.md → get-api-key/SKILL.md} +0 -0
- /package/payload/platform/plugins/cloudflare/skills/{setup-tunnel.md → setup-tunnel/SKILL.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/business-growth-buy-back-your-time.md → plugins/real-agency-business/skills/business-growth/references/buy-back-your-time.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/business-growth-firewave-gost-scorecards.md → plugins/real-agency-business/skills/business-growth/references/firewave-gost-scorecards.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/business-growth-keller-org-model.md → plugins/real-agency-business/skills/business-growth/references/keller-org-model.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/business-growth-lencioni-team-models.md → plugins/real-agency-business/skills/business-growth/references/lencioni-team-models.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/business-growth-listing-management-system.md → plugins/real-agency-business/skills/business-growth/references/listing-management-system.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/business-growth-net-figure-form.md → plugins/real-agency-business/skills/business-growth/references/net-figure-form.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/business-growth-serhant-bizinbox-notes.md → plugins/real-agency-business/skills/business-growth/references/serhant-bizinbox-notes.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/business-growth-team-roles-commission.md → plugins/real-agency-business/skills/business-growth/references/team-roles-commission.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/business-growth-va-2026-ops.md → plugins/real-agency-business/skills/business-growth/references/va-2026-ops.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/business-growth-wingman-structure.md → plugins/real-agency-business/skills/business-growth/references/wingman-structure.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/business-operations-crm-systems.md → plugins/real-agency-business/skills/business-operations/references/crm-systems.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/business-operations-hiring-guide.md → plugins/real-agency-business/skills/business-operations/references/hiring-guide.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/business-operations-impact-framework.md → plugins/real-agency-business/skills/business-operations/references/impact-framework.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/business-operations-minutes-equal-money.md → plugins/real-agency-business/skills/business-operations/references/minutes-equal-money.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/business-operations-team-management.md → plugins/real-agency-business/skills/business-operations/references/team-management.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/exp-partnership-12-reasons.md → plugins/real-agency-business/skills/exp-partnership/references/12-reasons.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/exp-partnership-95-5-system.md → plugins/real-agency-business/skills/exp-partnership/references/95-5-system.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/exp-partnership-agent-attraction-scripts.md → plugins/real-agency-business/skills/exp-partnership/references/agent-attraction-scripts.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/exp-partnership-business-partnership.md → plugins/real-agency-business/skills/exp-partnership/references/business-partnership.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/exp-partnership-exp-model-overview.md → plugins/real-agency-business/skills/exp-partnership/references/exp-model-overview.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/exp-partnership-model-comparison.md → plugins/real-agency-business/skills/exp-partnership/references/model-comparison.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/exp-partnership-revenue-share-explained.md → plugins/real-agency-business/skills/exp-partnership/references/revenue-share-explained.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/personal-branding-attraction-agent-notes.md → plugins/real-agency-business/skills/personal-branding/references/attraction-agent-notes.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/personal-branding-attraction-agent.md → plugins/real-agency-business/skills/personal-branding/references/attraction-agent.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/personal-branding-authenticity-boundaries.md → plugins/real-agency-business/skills/personal-branding/references/authenticity-boundaries.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/personal-branding-become-a-brand-leader-notes.md → plugins/real-agency-business/skills/personal-branding/references/become-a-brand-leader-notes.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/personal-branding-blast-formula.md → plugins/real-agency-business/skills/personal-branding/references/blast-formula.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/personal-branding-brand-leader.md → plugins/real-agency-business/skills/personal-branding/references/brand-leader.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/personal-branding-brand-strategy-system.md → plugins/real-agency-business/skills/personal-branding/references/brand-strategy-system.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/personal-branding-content-engine.md → plugins/real-agency-business/skills/personal-branding/references/content-engine.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/personal-branding-firewave-blast-and-blogging.md → plugins/real-agency-business/skills/personal-branding/references/firewave-blast-and-blogging.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/personal-branding-gary-v-content.md → plugins/real-agency-business/skills/personal-branding/references/gary-v-content.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/personal-branding-gary-v-principles.md → plugins/real-agency-business/skills/personal-branding/references/gary-v-principles.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/personal-branding-oversubscribed-positioning.md → plugins/real-agency-business/skills/personal-branding/references/oversubscribed-positioning.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/personal-branding-platforms.md → plugins/real-agency-business/skills/personal-branding/references/platforms.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/personal-branding-priestley-oversubscribed.md → plugins/real-agency-business/skills/personal-branding/references/priestley-oversubscribed.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/personal-branding-storeys-style-examples.md → plugins/real-agency-business/skills/personal-branding/references/storeys-style-examples.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/personal-branding-visual-identity.md → plugins/real-agency-business/skills/personal-branding/references/visual-identity.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/buyer-management-buyer-qualification-questions.md → plugins/real-agency-buyers/skills/buyer-management/references/buyer-qualification-questions.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/buyer-management-buyer-qualification.md → plugins/real-agency-buyers/skills/buyer-management/references/buyer-qualification.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/buyer-management-buyer-scripts.md → plugins/real-agency-buyers/skills/buyer-management/references/buyer-scripts.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/buyer-management-buyer-working-scripts.md → plugins/real-agency-buyers/skills/buyer-management/references/buyer-working-scripts.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/buyer-management-feedback-collection.md → plugins/real-agency-buyers/skills/buyer-management/references/feedback-collection.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/buyer-management-offer-capture.md → plugins/real-agency-buyers/skills/buyer-management/references/offer-capture.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/buyer-management-viewing-booking.md → plugins/real-agency-buyers/skills/buyer-management/references/viewing-booking.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/buyer-management-viewing-management.md → plugins/real-agency-buyers/skills/buyer-management/references/viewing-management.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/buyer-seller-guides-care-fees-guide.md → plugins/real-agency-buyers/skills/buyer-seller-guides/references/care-fees-guide.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/buyer-seller-guides-divorce-sales-guide.md → plugins/real-agency-buyers/skills/buyer-seller-guides/references/divorce-sales-guide.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/buyer-seller-guides-downsizing-guide.md → plugins/real-agency-buyers/skills/buyer-seller-guides/references/downsizing-guide.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/buyer-seller-guides-first-time-buyers.md → plugins/real-agency-buyers/skills/buyer-seller-guides/references/first-time-buyers.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/buyer-seller-guides-first-time-sellers.md → plugins/real-agency-buyers/skills/buyer-seller-guides/references/first-time-sellers.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/buyer-seller-guides-probate-guide.md → plugins/real-agency-buyers/skills/buyer-seller-guides/references/probate-guide.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/buyer-seller-guides-upsizing-guide.md → plugins/real-agency-buyers/skills/buyer-seller-guides/references/upsizing-guide.md} +0 -0
- /package/payload/premium-plugins/real-agency/{skills/property-enquiry.md → plugins/real-agency-buyers/skills/property-enquiry/SKILL.md} +0 -0
- /package/payload/premium-plugins/real-agency/{skills/viewing-management.md → plugins/real-agency-buyers/skills/viewing-management/SKILL.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/agent-performance-atomic-habits.md → plugins/real-agency-coaching/skills/agent-performance/references/atomic-habits.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/agent-performance-daily-routine-scorecard.md → plugins/real-agency-coaching/skills/agent-performance/references/daily-routine-scorecard.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/agent-performance-hp6-model.md → plugins/real-agency-coaching/skills/agent-performance/references/hp6-model.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/agent-performance-twelve-week-year.md → plugins/real-agency-coaching/skills/agent-performance/references/twelve-week-year.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/bespoke-coaching-coaching-boundaries.md → plugins/real-agency-coaching/skills/bespoke-coaching/references/coaching-boundaries.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/bespoke-coaching-feedback-framework.md → plugins/real-agency-coaching/skills/bespoke-coaching/references/feedback-framework.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/bespoke-coaching-performance-framework.md → plugins/real-agency-coaching/skills/bespoke-coaching/references/performance-framework.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/coaching-toolkit-coaching-exercises.md → plugins/real-agency-coaching/skills/coaching-toolkit/references/coaching-exercises.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/coaching-toolkit-goal-setting.md → plugins/real-agency-coaching/skills/coaching-toolkit/references/goal-setting.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/coaching-toolkit-one-to-one-framework.md → plugins/real-agency-coaching/skills/coaching-toolkit/references/one-to-one-framework.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/coaching-toolkit-soi-workbook.md → plugins/real-agency-coaching/skills/coaching-toolkit/references/soi-workbook.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/serhant-training-agent-training-guide.md → plugins/real-agency-coaching/skills/serhant-training/references/agent-training-guide.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/serhant-training-business-in-a-box.md → plugins/real-agency-coaching/skills/serhant-training/references/business-in-a-box.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/serhant-training-buyers-guide.md → plugins/real-agency-coaching/skills/serhant-training/references/buyers-guide.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/serhant-training-codo-method.md → plugins/real-agency-coaching/skills/serhant-training/references/codo-method.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/serhant-training-website-planning-guide.md → plugins/real-agency-coaching/skills/serhant-training/references/website-planning-guide.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/lead-nurturing-buyer-search-letter.md → plugins/real-agency-leads/skills/lead-nurturing/references/buyer-search-letter.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/lead-nurturing-buyer-search-letters.md → plugins/real-agency-leads/skills/lead-nurturing/references/buyer-search-letters.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/lead-nurturing-email-nurture-sequences.md → plugins/real-agency-leads/skills/lead-nurturing/references/email-nurture-sequences.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/lead-nurturing-facebook-referrals.md → plugins/real-agency-leads/skills/lead-nurturing/references/facebook-referrals.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/lead-nurturing-firewave-email-nurture-sequences.md → plugins/real-agency-leads/skills/lead-nurturing/references/firewave-email-nurture-sequences.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/lead-nurturing-keller-33-touch.md → plugins/real-agency-leads/skills/lead-nurturing/references/keller-33-touch.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/lead-nurturing-neighbour-letters.md → plugins/real-agency-leads/skills/lead-nurturing/references/neighbour-letters.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/lead-nurturing-neighbour-notification-letter.md → plugins/real-agency-leads/skills/lead-nurturing/references/neighbour-notification-letter.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/lead-nurturing-ofi-follow-up-dialogue.md → plugins/real-agency-leads/skills/lead-nurturing/references/ofi-follow-up-dialogue.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/lead-nurturing-ofi-follow-up.md → plugins/real-agency-leads/skills/lead-nurturing/references/ofi-follow-up.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/lead-nurturing-serhant-three-fs-plus.md → plugins/real-agency-leads/skills/lead-nurturing/references/serhant-three-fs-plus.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/lead-nurturing-sharran-10x10x10.md → plugins/real-agency-leads/skills/lead-nurturing/references/sharran-10x10x10.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/lead-nurturing-sms-templates.md → plugins/real-agency-leads/skills/lead-nurturing/references/sms-templates.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/lead-nurturing-sphere-of-influence-notes.md → plugins/real-agency-leads/skills/lead-nurturing/references/sphere-of-influence-notes.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/lead-nurturing-sphere-of-influence.md → plugins/real-agency-leads/skills/lead-nurturing/references/sphere-of-influence.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/lead-nurturing-tom-panos-sms-templates.md → plugins/real-agency-leads/skills/lead-nurturing/references/tom-panos-sms-templates.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/prospecting-database-matching.md → plugins/real-agency-leads/skills/prospecting/references/database-matching.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/prospecting-database-value.md → plugins/real-agency-leads/skills/prospecting/references/database-value.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/prospecting-prospecting-dialogues.md → plugins/real-agency-leads/skills/prospecting/references/prospecting-dialogues.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/prospecting-reactivation.md → plugins/real-agency-leads/skills/prospecting/references/reactivation.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/home-preparation-kerb-appeal.md → plugins/real-agency-listings/skills/home-preparation/references/kerb-appeal.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/home-preparation-photo-day.md → plugins/real-agency-listings/skills/home-preparation/references/photo-day.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/home-preparation-situational-tips.md → plugins/real-agency-listings/skills/home-preparation/references/situational-tips.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/home-preparation-staging-guide.md → plugins/real-agency-listings/skills/home-preparation/references/staging-guide.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/listing-presentation-booking-script.md → plugins/real-agency-listings/skills/listing-presentation/references/booking-script.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/listing-presentation-objection-scripts.md → plugins/real-agency-listings/skills/listing-presentation/references/objection-scripts.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/listing-presentation-penhaul-presentation.md → plugins/real-agency-listings/skills/listing-presentation/references/penhaul-presentation.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/listing-presentation-pre-listing-kit.md → plugins/real-agency-listings/skills/listing-presentation/references/pre-listing-kit.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/listing-presentation-set-to-sell.md → plugins/real-agency-listings/skills/listing-presentation/references/set-to-sell.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/listing-presentation-sharran-frameworks.md → plugins/real-agency-listings/skills/listing-presentation/references/sharran-frameworks.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/property-marketing-auction-report-template.md → plugins/real-agency-listings/skills/property-marketing/references/auction-report-template.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/property-marketing-coming-soon-campaign.md → plugins/real-agency-listings/skills/property-marketing/references/coming-soon-campaign.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/property-marketing-direct-mail-templates.md → plugins/real-agency-listings/skills/property-marketing/references/direct-mail-templates.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/property-marketing-eoi-form-template.md → plugins/real-agency-listings/skills/property-marketing/references/eoi-form-template.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/property-marketing-monthly-scorecard.md → plugins/real-agency-listings/skills/property-marketing/references/monthly-scorecard.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/sales-closer-serhant-emotion-stages.md → plugins/real-agency-sales/skills/sales-closer/references/serhant-emotion-stages.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/sales-discovery-chris-voss-discovery.md → plugins/real-agency-sales/skills/sales-discovery/references/chris-voss-discovery.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/sales-discovery-firewave-gost-journey.md → plugins/real-agency-sales/skills/sales-discovery/references/firewave-gost-journey.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/sales-discovery-phil-jones-openers.md → plugins/real-agency-sales/skills/sales-discovery/references/phil-jones-openers.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/sales-discovery-pre-listing-checklist.md → plugins/real-agency-sales/skills/sales-discovery/references/pre-listing-checklist.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/sales-discovery-serhant-improv.md → plugins/real-agency-sales/skills/sales-discovery/references/serhant-improv.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/sales-discovery-tom-ferry-discovery.md → plugins/real-agency-sales/skills/sales-discovery/references/tom-ferry-discovery.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/sales-discovery-vendor-motivation-competitor.md → plugins/real-agency-sales/skills/sales-discovery/references/vendor-motivation-competitor.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/sales-negotiation-chris-voss-negotiation.md → plugins/real-agency-sales/skills/sales-negotiation/references/chris-voss-negotiation.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/sales-negotiation-phil-jones-price-words.md → plugins/real-agency-sales/skills/sales-negotiation/references/phil-jones-price-words.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/sales-negotiation-serhant-negotiation-plus.md → plugins/real-agency-sales/skills/sales-negotiation/references/serhant-negotiation-plus.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/sales-negotiation-tom-panos-commission-pricing.md → plugins/real-agency-sales/skills/sales-negotiation/references/tom-panos-commission-pricing.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/sales-negotiation-tony-morris-questioning.md → plugins/real-agency-sales/skills/sales-negotiation/references/tony-morris-questioning.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/sales-progression-conveyancing-guide.md → plugins/real-agency-sales/skills/sales-progression/references/conveyancing-guide.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/sales-progression-transaction-tracking.md → plugins/real-agency-sales/skills/sales-progression/references/transaction-tracking.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/content-directory-module-delivery.md → plugins/real-agency-teaching/skills/content-directory/references/module-delivery.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/content-directory-progress-tracking.md → plugins/real-agency-teaching/skills/content-directory/references/progress-tracking.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/negotiation-deal-saving.md → plugins/real-agency-vendors/skills/negotiation/references/deal-saving.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/negotiation-negotiation-deep-guide.md → plugins/real-agency-vendors/skills/negotiation/references/negotiation-deep-guide.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/negotiation-negotiation-prep-principles.md → plugins/real-agency-vendors/skills/negotiation/references/negotiation-prep-principles.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/negotiation-negotiation-techniques.md → plugins/real-agency-vendors/skills/negotiation/references/negotiation-techniques.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/negotiation-offer-presentation.md → plugins/real-agency-vendors/skills/negotiation/references/offer-presentation.md} +0 -0
- /package/payload/premium-plugins/real-agency/{skills/valuation-booking.md → plugins/real-agency-vendors/skills/valuation-booking/SKILL.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/vendor-communication-fee-protection-and-agenda.md → plugins/real-agency-vendors/skills/vendor-communication/references/fee-protection-and-agenda.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/vendor-communication-listing-scripts.md → plugins/real-agency-vendors/skills/vendor-communication/references/listing-scripts.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/vendor-communication-negotiation-deep-guide.md → plugins/real-agency-vendors/skills/vendor-communication/references/negotiation-deep-guide.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/vendor-communication-price-alignment-scripts.md → plugins/real-agency-vendors/skills/vendor-communication/references/price-alignment-scripts.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/vendor-communication-price-alignment.md → plugins/real-agency-vendors/skills/vendor-communication/references/price-alignment.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/vendor-communication-scenario-scripts.md → plugins/real-agency-vendors/skills/vendor-communication/references/scenario-scripts.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/vendor-communication-seller-engagement.md → plugins/real-agency-vendors/skills/vendor-communication/references/seller-engagement.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/vendor-communication-valuation-booking.md → plugins/real-agency-vendors/skills/vendor-communication/references/valuation-booking.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/vendor-communication-vendor-scripts.md → plugins/real-agency-vendors/skills/vendor-communication/references/vendor-scripts.md} +0 -0
- /package/payload/premium-plugins/real-agency/{references/vendor-communication-vendor-updates.md → plugins/real-agency-vendors/skills/vendor-communication/references/vendor-updates.md} +0 -0
- /package/payload/premium-plugins/teaching/skills/{interactive-tutor.md → interactive-tutor/SKILL.md} +0 -0
- /package/payload/premium-plugins/teaching/{references → skills/interactive-tutor/references}/assessment.md +0 -0
- /package/payload/premium-plugins/teaching/{references → skills/interactive-tutor/references}/classroom-conduct.md +0 -0
- /package/payload/premium-plugins/teaching/{references → skills/interactive-tutor/references}/teaching-modes.md +0 -0
- /package/payload/premium-plugins/teaching/skills/{lesson-planner.md → lesson-planner/SKILL.md} +0 -0
- /package/payload/premium-plugins/teaching/{references → skills/lesson-planner/references}/context-gathering.md +0 -0
- /package/payload/premium-plugins/teaching/{references → skills/lesson-planner/references}/plan-structure.md +0 -0
- /package/payload/premium-plugins/teaching/skills/{study-pack-builder.md → study-pack-builder/SKILL.md} +0 -0
- /package/payload/premium-plugins/teaching/{references → skills/study-pack-builder/references}/disaggregation.md +0 -0
- /package/payload/premium-plugins/teaching/{references → skills/study-pack-builder/references}/materials.md +0 -0
- /package/payload/premium-plugins/writer-craft/skills/{citation-style.md → citation-style/SKILL.md} +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/citation-style/references}/book-and-chapter-models.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/citation-style/references}/citation-rules.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/citation-style/references}/journal-article-models.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/citation-style/references}/other-source-models.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/citation-style/references}/reference-list-rules.md +0 -0
- /package/payload/premium-plugins/writer-craft/skills/{editorial-practice.md → editorial-practice/SKILL.md} +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/editorial-practice/references}/copyediting.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/editorial-practice/references}/developmental-editing.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/editorial-practice/references}/genre-specific-editing.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/editorial-practice/references}/line-editing.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/editorial-practice/references}/self-editing.md +0 -0
- /package/payload/premium-plugins/writer-craft/skills/{persuasive-storytelling.md → persuasive-storytelling/SKILL.md} +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/persuasive-storytelling/references}/audience-analysis.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/persuasive-storytelling/references}/crafting-persuasive-story.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/persuasive-storytelling/references}/persuasion-case-studies.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/persuasive-storytelling/references}/transformation-framework.md +0 -0
- /package/payload/premium-plugins/writer-craft/skills/{point-of-view.md → point-of-view/SKILL.md} +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/point-of-view/references}/indirect-narration.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/point-of-view/references}/pov-types-and-voice.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/point-of-view/references}/protagonist-filter.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/point-of-view/references}/tense-and-person.md +0 -0
- /package/payload/premium-plugins/writer-craft/skills/{prose-craft.md → prose-craft/SKILL.md} +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/prose-craft/references}/punctuation-and-grammar.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/prose-craft/references}/repetition.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/prose-craft/references}/sound-and-rhythm.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/prose-craft/references}/word-economy.md +0 -0
- /package/payload/premium-plugins/writer-craft/skills/{reader-engagement.md → reader-engagement/SKILL.md} +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/reader-engagement/references}/cause-effect-setup-payoff.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/reader-engagement/references}/conflict-escalation.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/reader-engagement/references}/hooking-readers.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/reader-engagement/references}/neurochemistry-of-engagement.md +0 -0
- /package/payload/premium-plugins/writer-craft/skills/{review-manuscript.md → review-manuscript/SKILL.md} +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/review-manuscript/references}/review-manuscript-checklist.md +0 -0
- /package/payload/premium-plugins/writer-craft/skills/{review-prose.md → review-prose/SKILL.md} +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/review-prose/references}/prose-review-checklist.md +0 -0
- /package/payload/premium-plugins/writer-craft/skills/{review-scene.md → review-scene/SKILL.md} +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/review-scene/references}/scene-analysis-framework.md +0 -0
- /package/payload/premium-plugins/writer-craft/skills/{story-architecture.md → story-architecture/SKILL.md} +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/story-architecture/references}/blueprinting-and-scene-cards.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/story-architecture/references}/inner-issue-and-protagonist-goal.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/story-architecture/references}/misbelief-desire-worldview.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/story-architecture/references}/origin-scenes-and-escalation.md +0 -0
- /package/payload/premium-plugins/writer-craft/skills/{story-blueprint.md → story-blueprint/SKILL.md} +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/story-blueprint/references}/blueprinting-exercises.md +0 -0
- /package/payload/premium-plugins/writer-craft/{references → skills/story-blueprint/references}/blueprinting-process.md +0 -0
package/payload/maxy/server.js
CHANGED
|
@@ -2845,7 +2845,7 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
2845
2845
|
};
|
|
2846
2846
|
|
|
2847
2847
|
// server/index.ts
|
|
2848
|
-
import { readFileSync as readFileSync17, existsSync as
|
|
2848
|
+
import { readFileSync as readFileSync17, existsSync as existsSync17, watchFile } from "fs";
|
|
2849
2849
|
import { resolve as resolve15, join as join5 } from "path";
|
|
2850
2850
|
import { homedir as homedir2 } from "os";
|
|
2851
2851
|
|
|
@@ -3666,6 +3666,24 @@ var VALID_CATEGORIES = /* @__PURE__ */ new Set([
|
|
|
3666
3666
|
"content",
|
|
3667
3667
|
"interaction"
|
|
3668
3668
|
]);
|
|
3669
|
+
async function getUserTimezone(accountId) {
|
|
3670
|
+
const session = getSession();
|
|
3671
|
+
try {
|
|
3672
|
+
const result = await session.run(
|
|
3673
|
+
`MATCH (up:UserProfile {accountId: $accountId})
|
|
3674
|
+
RETURN up.timezone AS timezone`,
|
|
3675
|
+
{ accountId }
|
|
3676
|
+
);
|
|
3677
|
+
if (result.records.length === 0) return null;
|
|
3678
|
+
const tz = result.records[0].get("timezone");
|
|
3679
|
+
return tz && tz.trim().length > 0 ? tz : null;
|
|
3680
|
+
} catch (err) {
|
|
3681
|
+
console.error(`[datetime] getUserTimezone failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
3682
|
+
return null;
|
|
3683
|
+
} finally {
|
|
3684
|
+
await session.close();
|
|
3685
|
+
}
|
|
3686
|
+
}
|
|
3669
3687
|
async function loadUserProfile(accountId) {
|
|
3670
3688
|
const session = getSession();
|
|
3671
3689
|
try {
|
|
@@ -3804,7 +3822,7 @@ async function loadSessionContext(accountId) {
|
|
|
3804
3822
|
try {
|
|
3805
3823
|
const summaryResult = await session.run(
|
|
3806
3824
|
`MATCH (n:CreativeWork {accountId: $accountId})
|
|
3807
|
-
WHERE n.title STARTS WITH 'Session Summary'
|
|
3825
|
+
WHERE n.title STARTS WITH 'Session Summary' OR n.title = 'Session Snapshot'
|
|
3808
3826
|
RETURN n.title AS title, n.createdAt AS createdAt, n.abstract AS abstract
|
|
3809
3827
|
ORDER BY n.createdAt DESC LIMIT 1`,
|
|
3810
3828
|
{ accountId }
|
|
@@ -3831,17 +3849,27 @@ async function loadSessionContext(accountId) {
|
|
|
3831
3849
|
END,
|
|
3832
3850
|
t.createdAt DESC
|
|
3833
3851
|
LIMIT $limit`,
|
|
3834
|
-
{ accountId, limit: MAX_SESSION_TASKS }
|
|
3852
|
+
{ accountId, limit: neo4j.int(MAX_SESSION_TASKS) }
|
|
3835
3853
|
);
|
|
3836
3854
|
const sections = [];
|
|
3855
|
+
const STALENESS_LIMIT_MS = 48 * 60 * 60 * 1e3;
|
|
3837
3856
|
if (summaryResult.records.length > 0) {
|
|
3838
3857
|
const rec = summaryResult.records[0];
|
|
3839
3858
|
const title = rec.get("title");
|
|
3840
3859
|
const createdAt = rec.get("createdAt");
|
|
3841
3860
|
const abstract = rec.get("abstract");
|
|
3842
|
-
|
|
3843
|
-
|
|
3861
|
+
let isStale = false;
|
|
3862
|
+
if (createdAt) {
|
|
3863
|
+
const ageMs = Date.now() - new Date(createdAt).getTime();
|
|
3864
|
+
isStale = !isNaN(ageMs) && ageMs > STALENESS_LIMIT_MS;
|
|
3865
|
+
}
|
|
3866
|
+
if (isStale) {
|
|
3867
|
+
console.error(`[session-context] Skipped stale summary for ${accountId.slice(0, 8)}\u2026: title="${title}" createdAt=${createdAt}`);
|
|
3868
|
+
} else {
|
|
3869
|
+
const dateSuffix = createdAt ? ` (${createdAt.slice(0, 10)})` : "";
|
|
3870
|
+
sections.push(`## Last Session${dateSuffix}
|
|
3844
3871
|
${abstract}`);
|
|
3872
|
+
}
|
|
3845
3873
|
}
|
|
3846
3874
|
if (digestResult.records.length > 0) {
|
|
3847
3875
|
const rec = digestResult.records[0];
|
|
@@ -3867,8 +3895,9 @@ ${abstract}`);
|
|
|
3867
3895
|
${taskLines.join("\n")}`);
|
|
3868
3896
|
}
|
|
3869
3897
|
if (sections.length === 0) return null;
|
|
3898
|
+
const summaryCreatedAt = summaryResult.records.length > 0 ? summaryResult.records[0].get("createdAt") ?? "unknown" : "n/a";
|
|
3870
3899
|
console.error(
|
|
3871
|
-
`[session-context] Loaded for ${accountId.slice(0, 8)}\u2026: summary=${summaryResult.records.length > 0 ? "yes" : "no"}, digest=${digestResult.records.length > 0 ? "yes" : "no"}, tasks=${tasksResult.records.length}`
|
|
3900
|
+
`[session-context] Loaded for ${accountId.slice(0, 8)}\u2026: summary=${summaryResult.records.length > 0 ? "yes" : "no"}, summaryDate=${summaryCreatedAt}, digest=${digestResult.records.length > 0 ? "yes" : "no"}, tasks=${tasksResult.records.length}`
|
|
3872
3901
|
);
|
|
3873
3902
|
return `<previous-context>
|
|
3874
3903
|
${sections.join("\n\n")}
|
|
@@ -3880,6 +3909,22 @@ ${sections.join("\n\n")}
|
|
|
3880
3909
|
await session.close();
|
|
3881
3910
|
}
|
|
3882
3911
|
}
|
|
3912
|
+
async function writeSessionSummary(accountId, summary) {
|
|
3913
|
+
const session = getSession();
|
|
3914
|
+
try {
|
|
3915
|
+
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3916
|
+
await session.run(
|
|
3917
|
+
`MERGE (n:CreativeWork {accountId: $accountId, title: 'Session Snapshot'})
|
|
3918
|
+
SET n.abstract = $summary, n.createdAt = $createdAt, n.scope = 'admin'`,
|
|
3919
|
+
{ accountId, summary, createdAt }
|
|
3920
|
+
);
|
|
3921
|
+
console.error(`[session-summary] Written for ${accountId.slice(0, 8)}\u2026`);
|
|
3922
|
+
} catch (err) {
|
|
3923
|
+
console.error(`[session-summary] Failed for ${accountId.slice(0, 8)}\u2026: ${err instanceof Error ? err.message : String(err)}`);
|
|
3924
|
+
} finally {
|
|
3925
|
+
await session.close();
|
|
3926
|
+
}
|
|
3927
|
+
}
|
|
3883
3928
|
async function loadOnboardingStep(accountId) {
|
|
3884
3929
|
const session = getSession();
|
|
3885
3930
|
try {
|
|
@@ -4076,19 +4121,20 @@ async function writeReflectionPreferences(accountId, conversationId, updates) {
|
|
|
4076
4121
|
|
|
4077
4122
|
// app/lib/claude-agent.ts
|
|
4078
4123
|
var LOG_RETENTION_DAYS = 7;
|
|
4079
|
-
function agentLogStream(name) {
|
|
4080
|
-
|
|
4124
|
+
function agentLogStream(name, accountDir) {
|
|
4125
|
+
const logDir = resolve4(accountDir, "logs");
|
|
4126
|
+
mkdirSync2(logDir, { recursive: true });
|
|
4081
4127
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
4082
4128
|
const cutoff = Date.now() - LOG_RETENTION_DAYS * 24 * 60 * 60 * 1e3;
|
|
4083
4129
|
try {
|
|
4084
|
-
for (const file of readdirSync(
|
|
4130
|
+
for (const file of readdirSync(logDir)) {
|
|
4085
4131
|
if (!file.startsWith(`${name}-`)) continue;
|
|
4086
|
-
const filePath = resolve4(
|
|
4132
|
+
const filePath = resolve4(logDir, file);
|
|
4087
4133
|
if (statSync2(filePath).mtimeMs < cutoff) unlinkSync(filePath);
|
|
4088
4134
|
}
|
|
4089
4135
|
} catch {
|
|
4090
4136
|
}
|
|
4091
|
-
return createWriteStream(resolve4(
|
|
4137
|
+
return createWriteStream(resolve4(logDir, `${name}-${date}.log`), { flags: "a" });
|
|
4092
4138
|
}
|
|
4093
4139
|
var PLATFORM_ROOT3 = process.env.MAXY_PLATFORM_ROOT ?? resolve4(process.cwd(), "..");
|
|
4094
4140
|
var ACCOUNTS_DIR = resolve4(PLATFORM_ROOT3, "config/accounts");
|
|
@@ -4299,6 +4345,7 @@ function parsePluginFrontmatter(pluginDir) {
|
|
|
4299
4345
|
return items;
|
|
4300
4346
|
}
|
|
4301
4347
|
const tools = parseYamlList("tools");
|
|
4348
|
+
const hidden = parseYamlList("hidden");
|
|
4302
4349
|
const requires = parseYamlList("requires");
|
|
4303
4350
|
let taskmaster = {};
|
|
4304
4351
|
const metaMatch = fm.match(/^metadata:\s*(.+)$/m);
|
|
@@ -4316,10 +4363,105 @@ function parsePluginFrontmatter(pluginDir) {
|
|
|
4316
4363
|
name: nameMatch?.[1]?.trim() ?? pluginDir,
|
|
4317
4364
|
description,
|
|
4318
4365
|
tools,
|
|
4366
|
+
hidden,
|
|
4319
4367
|
requires,
|
|
4320
4368
|
taskmaster
|
|
4321
4369
|
};
|
|
4322
4370
|
}
|
|
4371
|
+
function assemblePublicPluginContent(pluginDir) {
|
|
4372
|
+
const pluginRoot = resolve4(PLATFORM_ROOT3, "plugins", pluginDir);
|
|
4373
|
+
const pluginPath = resolve4(pluginRoot, "PLUGIN.md");
|
|
4374
|
+
let raw2;
|
|
4375
|
+
try {
|
|
4376
|
+
raw2 = readFileSync5(pluginPath, "utf-8");
|
|
4377
|
+
} catch {
|
|
4378
|
+
return null;
|
|
4379
|
+
}
|
|
4380
|
+
const pluginBody = raw2.replace(/^---\n[\s\S]*?\n---\n*/, "").trim();
|
|
4381
|
+
if (!pluginBody) return null;
|
|
4382
|
+
const parts = [pluginBody];
|
|
4383
|
+
let skillCount = 0;
|
|
4384
|
+
let refCount = 0;
|
|
4385
|
+
const skillsDir = resolve4(pluginRoot, "skills");
|
|
4386
|
+
let skillDirs;
|
|
4387
|
+
try {
|
|
4388
|
+
skillDirs = readdirSync(skillsDir).sort();
|
|
4389
|
+
} catch {
|
|
4390
|
+
return { body: pluginBody, skillCount: 0, refCount: 0 };
|
|
4391
|
+
}
|
|
4392
|
+
for (const skillName of skillDirs) {
|
|
4393
|
+
const skillDir = resolve4(skillsDir, skillName);
|
|
4394
|
+
const skillMdPath = resolve4(skillDir, "SKILL.md");
|
|
4395
|
+
let skillRaw;
|
|
4396
|
+
try {
|
|
4397
|
+
skillRaw = readFileSync5(skillMdPath, "utf-8");
|
|
4398
|
+
} catch {
|
|
4399
|
+
continue;
|
|
4400
|
+
}
|
|
4401
|
+
const fmMatch = skillRaw.match(/^---\n([\s\S]*?)\n---/);
|
|
4402
|
+
let publicEmbed = true;
|
|
4403
|
+
const publicExcludeReferences = [];
|
|
4404
|
+
if (fmMatch) {
|
|
4405
|
+
const fm = fmMatch[1];
|
|
4406
|
+
const embedMatch = fm.match(/^publicEmbed:\s*(.+)$/m);
|
|
4407
|
+
if (embedMatch && embedMatch[1].trim() === "false") {
|
|
4408
|
+
publicEmbed = false;
|
|
4409
|
+
}
|
|
4410
|
+
const fmLines = fm.split("\n");
|
|
4411
|
+
let insideExclude = false;
|
|
4412
|
+
for (const line of fmLines) {
|
|
4413
|
+
if (/^publicExcludeReferences:/.test(line)) {
|
|
4414
|
+
if (/^publicExcludeReferences:\s*\[]/.test(line)) break;
|
|
4415
|
+
insideExclude = true;
|
|
4416
|
+
continue;
|
|
4417
|
+
}
|
|
4418
|
+
if (insideExclude) {
|
|
4419
|
+
const m = line.match(/^ - (.+)/);
|
|
4420
|
+
if (m) {
|
|
4421
|
+
publicExcludeReferences.push(m[1].trim());
|
|
4422
|
+
} else {
|
|
4423
|
+
break;
|
|
4424
|
+
}
|
|
4425
|
+
}
|
|
4426
|
+
}
|
|
4427
|
+
}
|
|
4428
|
+
if (!publicEmbed) {
|
|
4429
|
+
console.log(`[plugins] ${pluginDir}/skills/${skillName}: publicEmbed=false \u2014 skipping for public`);
|
|
4430
|
+
continue;
|
|
4431
|
+
}
|
|
4432
|
+
const skillBody = skillRaw.replace(/^---\n[\s\S]*?\n---\n*/, "").trim();
|
|
4433
|
+
if (!skillBody) continue;
|
|
4434
|
+
parts.push(`
|
|
4435
|
+
<!-- skill: ${skillName} -->`);
|
|
4436
|
+
parts.push(skillBody);
|
|
4437
|
+
const refsDir = resolve4(skillDir, "references");
|
|
4438
|
+
let refFiles;
|
|
4439
|
+
try {
|
|
4440
|
+
refFiles = readdirSync(refsDir).filter((f) => f.endsWith(".md")).filter((f) => !publicExcludeReferences.includes(f)).sort();
|
|
4441
|
+
} catch {
|
|
4442
|
+
parts.push(`<!-- /skill: ${skillName} -->`);
|
|
4443
|
+
skillCount++;
|
|
4444
|
+
continue;
|
|
4445
|
+
}
|
|
4446
|
+
for (const refFile of refFiles) {
|
|
4447
|
+
try {
|
|
4448
|
+
const refContent = readFileSync5(resolve4(refsDir, refFile), "utf-8").trim();
|
|
4449
|
+
if (refContent) {
|
|
4450
|
+
parts.push(`
|
|
4451
|
+
<!-- reference: ${refFile} -->`);
|
|
4452
|
+
parts.push(refContent);
|
|
4453
|
+
parts.push(`<!-- /reference: ${refFile} -->`);
|
|
4454
|
+
refCount++;
|
|
4455
|
+
}
|
|
4456
|
+
} catch {
|
|
4457
|
+
console.warn(`[plugins] ${pluginDir}/skills/${skillName}/references/${refFile}: unreadable \u2014 skipping`);
|
|
4458
|
+
}
|
|
4459
|
+
}
|
|
4460
|
+
parts.push(`<!-- /skill: ${skillName} -->`);
|
|
4461
|
+
skillCount++;
|
|
4462
|
+
}
|
|
4463
|
+
return { body: parts.join("\n"), skillCount, refCount };
|
|
4464
|
+
}
|
|
4323
4465
|
function loadEmbeddedPlugins(agentType, selectedPlugins, enabledPlugins) {
|
|
4324
4466
|
const pluginsDir = resolve4(PLATFORM_ROOT3, "plugins");
|
|
4325
4467
|
let dirs;
|
|
@@ -4362,25 +4504,129 @@ function loadEmbeddedPlugins(agentType, selectedPlugins, enabledPlugins) {
|
|
|
4362
4504
|
}
|
|
4363
4505
|
}
|
|
4364
4506
|
if (selectedPlugins && !selectedPlugins.includes(dir)) continue;
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
}
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4507
|
+
if (agentType === "public") {
|
|
4508
|
+
const assembled = assemblePublicPluginContent(dir);
|
|
4509
|
+
if (assembled) {
|
|
4510
|
+
results.push({ name: dir, chars: assembled.body.length, body: assembled.body });
|
|
4511
|
+
console.log(`[plugins] loaded ${dir} for public (${assembled.body.length} chars, ${assembled.skillCount} skills, ${assembled.refCount} refs)`);
|
|
4512
|
+
}
|
|
4513
|
+
} else {
|
|
4514
|
+
const pluginPath = resolve4(pluginsDir, dir, "PLUGIN.md");
|
|
4515
|
+
let raw2;
|
|
4516
|
+
try {
|
|
4517
|
+
raw2 = readFileSync5(pluginPath, "utf-8");
|
|
4518
|
+
} catch {
|
|
4519
|
+
continue;
|
|
4520
|
+
}
|
|
4521
|
+
const body = raw2.replace(/^---\n[\s\S]*?\n---\n*/, "").trim();
|
|
4522
|
+
if (body) {
|
|
4523
|
+
results.push({ name: dir, chars: body.length, body });
|
|
4524
|
+
console.log(`[plugins] loaded ${dir} for ${agentType} (${body.length} chars)`);
|
|
4525
|
+
}
|
|
4376
4526
|
}
|
|
4377
4527
|
}
|
|
4378
4528
|
if (results.length === 0) {
|
|
4379
4529
|
console.log(`[plugins] no embedded plugins for agentType=${agentType}`);
|
|
4530
|
+
} else if (agentType === "public") {
|
|
4531
|
+
const totalChars = results.reduce((sum, r) => sum + r.chars, 0);
|
|
4532
|
+
console.log(`[plugins] total embedded for public: ${totalChars} chars across ${results.length} plugins`);
|
|
4380
4533
|
}
|
|
4381
4534
|
return results;
|
|
4382
4535
|
}
|
|
4383
|
-
|
|
4536
|
+
var mcpToolsCache = /* @__PURE__ */ new Map();
|
|
4537
|
+
function fetchMcpToolsList(pluginDir) {
|
|
4538
|
+
const cached = mcpToolsCache.get(pluginDir);
|
|
4539
|
+
if (cached) return Promise.resolve(cached);
|
|
4540
|
+
const serverPath = resolve4(PLATFORM_ROOT3, "plugins", pluginDir, "mcp/dist/index.js");
|
|
4541
|
+
if (!existsSync5(serverPath)) return Promise.resolve([]);
|
|
4542
|
+
const startMs = Date.now();
|
|
4543
|
+
return new Promise((resolvePromise) => {
|
|
4544
|
+
const proc = spawn(process.execPath, [serverPath], {
|
|
4545
|
+
env: {
|
|
4546
|
+
...process.env,
|
|
4547
|
+
PLATFORM_ROOT: PLATFORM_ROOT3,
|
|
4548
|
+
ACCOUNT_ID: "__toolslist__"
|
|
4549
|
+
}
|
|
4550
|
+
});
|
|
4551
|
+
let buffer = "";
|
|
4552
|
+
let stderrBuf = "";
|
|
4553
|
+
let settled = false;
|
|
4554
|
+
const TOOLS_LIST_ID = 2;
|
|
4555
|
+
const settle = (tools, reason) => {
|
|
4556
|
+
if (settled) return;
|
|
4557
|
+
settled = true;
|
|
4558
|
+
proc.kill();
|
|
4559
|
+
const elapsed = Date.now() - startMs;
|
|
4560
|
+
if (tools.length > 0) {
|
|
4561
|
+
mcpToolsCache.set(pluginDir, tools);
|
|
4562
|
+
console.error(`[plugin-manifest] ${pluginDir}: ${tools.length} tools via MCP (${elapsed}ms)`);
|
|
4563
|
+
} else {
|
|
4564
|
+
console.error(`[plugin-manifest] ${pluginDir}: tools/list failed (${reason}) (${elapsed}ms)${stderrBuf ? ` stderr: ${stderrBuf.slice(0, 300)}` : ""}`);
|
|
4565
|
+
}
|
|
4566
|
+
resolvePromise(tools);
|
|
4567
|
+
};
|
|
4568
|
+
proc.stdout.on("data", (chunk) => {
|
|
4569
|
+
buffer += chunk.toString();
|
|
4570
|
+
const lines = buffer.split("\n");
|
|
4571
|
+
buffer = lines.pop() ?? "";
|
|
4572
|
+
for (const line of lines) {
|
|
4573
|
+
if (!line.trim()) continue;
|
|
4574
|
+
let msg;
|
|
4575
|
+
try {
|
|
4576
|
+
msg = JSON.parse(line);
|
|
4577
|
+
} catch {
|
|
4578
|
+
continue;
|
|
4579
|
+
}
|
|
4580
|
+
if (msg.id === 1) {
|
|
4581
|
+
proc.stdin.write(
|
|
4582
|
+
JSON.stringify({ jsonrpc: "2.0", method: "notifications/initialized" }) + "\n"
|
|
4583
|
+
);
|
|
4584
|
+
proc.stdin.write(
|
|
4585
|
+
JSON.stringify({
|
|
4586
|
+
jsonrpc: "2.0",
|
|
4587
|
+
id: TOOLS_LIST_ID,
|
|
4588
|
+
method: "tools/list",
|
|
4589
|
+
params: {}
|
|
4590
|
+
}) + "\n"
|
|
4591
|
+
);
|
|
4592
|
+
} else if (msg.id === TOOLS_LIST_ID) {
|
|
4593
|
+
const result = msg.result;
|
|
4594
|
+
const rawTools = result?.tools;
|
|
4595
|
+
if (Array.isArray(rawTools)) {
|
|
4596
|
+
const tools = rawTools.filter((t) => typeof t.name === "string" && t.name.length > 0).map((t) => ({
|
|
4597
|
+
name: t.name,
|
|
4598
|
+
description: typeof t.description === "string" ? t.description : ""
|
|
4599
|
+
}));
|
|
4600
|
+
settle(tools, "success");
|
|
4601
|
+
} else {
|
|
4602
|
+
settle([], "no tools array in response");
|
|
4603
|
+
}
|
|
4604
|
+
}
|
|
4605
|
+
}
|
|
4606
|
+
});
|
|
4607
|
+
proc.stderr.on("data", (chunk) => {
|
|
4608
|
+
stderrBuf += chunk.toString();
|
|
4609
|
+
});
|
|
4610
|
+
proc.on("error", (err) => settle([], `spawn error: ${err.message}`));
|
|
4611
|
+
proc.on("close", (code) => {
|
|
4612
|
+
if (!settled) settle([], `process exited with code ${code}`);
|
|
4613
|
+
});
|
|
4614
|
+
proc.stdin.write(
|
|
4615
|
+
JSON.stringify({
|
|
4616
|
+
jsonrpc: "2.0",
|
|
4617
|
+
id: 1,
|
|
4618
|
+
method: "initialize",
|
|
4619
|
+
params: {
|
|
4620
|
+
protocolVersion: "2024-11-05",
|
|
4621
|
+
capabilities: {},
|
|
4622
|
+
clientInfo: { name: "maxy-manifest", version: "1.0" }
|
|
4623
|
+
}
|
|
4624
|
+
}) + "\n"
|
|
4625
|
+
);
|
|
4626
|
+
setTimeout(() => settle([], "timeout (5s)"), 5e3);
|
|
4627
|
+
});
|
|
4628
|
+
}
|
|
4629
|
+
async function buildPluginManifest(enabledPlugins) {
|
|
4384
4630
|
const pluginsDir = resolve4(PLATFORM_ROOT3, "plugins");
|
|
4385
4631
|
let dirs;
|
|
4386
4632
|
try {
|
|
@@ -4389,7 +4635,7 @@ function buildPluginManifest(enabledPlugins) {
|
|
|
4389
4635
|
return "";
|
|
4390
4636
|
}
|
|
4391
4637
|
const enabled = Array.isArray(enabledPlugins) ? enabledPlugins : [];
|
|
4392
|
-
const
|
|
4638
|
+
const activePlugins = [];
|
|
4393
4639
|
for (const dir of dirs.sort()) {
|
|
4394
4640
|
const parsed = parsePluginFrontmatter(dir);
|
|
4395
4641
|
if (!parsed) continue;
|
|
@@ -4402,6 +4648,19 @@ function buildPluginManifest(enabledPlugins) {
|
|
|
4402
4648
|
});
|
|
4403
4649
|
if (missing.length > 0) continue;
|
|
4404
4650
|
}
|
|
4651
|
+
activePlugins.push({ dir, parsed });
|
|
4652
|
+
}
|
|
4653
|
+
const mcpResults = await Promise.all(
|
|
4654
|
+
activePlugins.map(({ dir }) => fetchMcpToolsList(dir))
|
|
4655
|
+
);
|
|
4656
|
+
const lines = ["<plugin-manifest>"];
|
|
4657
|
+
let totalTools = 0;
|
|
4658
|
+
let mcpSourced = 0;
|
|
4659
|
+
let fallbackSourced = 0;
|
|
4660
|
+
let noServer = 0;
|
|
4661
|
+
for (let i = 0; i < activePlugins.length; i++) {
|
|
4662
|
+
const { dir, parsed } = activePlugins[i];
|
|
4663
|
+
const mcpTools = mcpResults[i];
|
|
4405
4664
|
const pluginRoot = resolve4(pluginsDir, dir);
|
|
4406
4665
|
const skills = [];
|
|
4407
4666
|
const references = [];
|
|
@@ -4429,14 +4688,39 @@ function buildPluginManifest(enabledPlugins) {
|
|
|
4429
4688
|
};
|
|
4430
4689
|
scanDir("skills", "skills/", skills);
|
|
4431
4690
|
scanDir("references", "references/", references);
|
|
4691
|
+
const hiddenSet = new Set(parsed.hidden);
|
|
4692
|
+
let toolLines = [];
|
|
4693
|
+
if (mcpTools.length > 0) {
|
|
4694
|
+
mcpSourced++;
|
|
4695
|
+
for (const tool of mcpTools) {
|
|
4696
|
+
if (hiddenSet.has(tool.name)) continue;
|
|
4697
|
+
const desc = tool.description ? tool.description.split(/\.\s/)[0].replace(/\.$/, "") : "";
|
|
4698
|
+
toolLines.push(desc ? ` ${tool.name} \u2014 ${desc}` : ` ${tool.name}`);
|
|
4699
|
+
}
|
|
4700
|
+
} else if (parsed.tools.length > 0) {
|
|
4701
|
+
const serverPath = resolve4(PLATFORM_ROOT3, "plugins", dir, "mcp/dist/index.js");
|
|
4702
|
+
if (existsSync5(serverPath)) {
|
|
4703
|
+
fallbackSourced++;
|
|
4704
|
+
console.error(`[plugin-manifest] ${dir}: tools/list empty \u2014 fallback to frontmatter (${parsed.tools.length} tools)`);
|
|
4705
|
+
}
|
|
4706
|
+
for (const name of parsed.tools) {
|
|
4707
|
+
if (hiddenSet.has(name)) continue;
|
|
4708
|
+
toolLines.push(` ${name}`);
|
|
4709
|
+
}
|
|
4710
|
+
} else {
|
|
4711
|
+
noServer++;
|
|
4712
|
+
}
|
|
4713
|
+
totalTools += toolLines.length;
|
|
4432
4714
|
lines.push(`
|
|
4433
4715
|
## ${dir}`);
|
|
4434
4716
|
if (parsed.description) lines.push(parsed.description);
|
|
4435
|
-
if (
|
|
4717
|
+
if (toolLines.length > 0) lines.push(`Tools:
|
|
4718
|
+
${toolLines.join("\n")}`);
|
|
4436
4719
|
if (skills.length > 0) lines.push(`Skills: ${skills.join(", ")}`);
|
|
4437
4720
|
if (references.length > 0) lines.push(`References: ${references.join(", ")}`);
|
|
4438
4721
|
}
|
|
4439
4722
|
lines.push("\n</plugin-manifest>");
|
|
4723
|
+
console.error(`[plugin-manifest] plugins=${activePlugins.length} tools=${totalTools} (mcp=${mcpSourced} fallback=${fallbackSourced} no-server=${noServer})`);
|
|
4440
4724
|
const dormantLines = [];
|
|
4441
4725
|
for (const dir of dirs.sort()) {
|
|
4442
4726
|
const parsed = parsePluginFrontmatter(dir);
|
|
@@ -4520,7 +4804,16 @@ function validateSession(sessionKey, agentType) {
|
|
|
4520
4804
|
if (!session) return false;
|
|
4521
4805
|
if (session.agentType !== agentType) return false;
|
|
4522
4806
|
if (Date.now() - session.createdAt > 24 * 60 * 60 * 1e3) {
|
|
4807
|
+
const history = session.messageHistory;
|
|
4808
|
+
const expiredAccountId = session.accountId;
|
|
4523
4809
|
sessionStore.delete(sessionKey);
|
|
4810
|
+
if (history && history.length >= 2) {
|
|
4811
|
+
writeEndOfTurnSummary(expiredAccountId, history).catch(
|
|
4812
|
+
(err) => console.error(`[session-summary] expiry write failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
4813
|
+
);
|
|
4814
|
+
} else {
|
|
4815
|
+
console.error(`[session-summary] Session ${sessionKey.slice(0, 8)}\u2026 expired without summary \u2014 ${history?.length ?? 0} messages`);
|
|
4816
|
+
}
|
|
4524
4817
|
return false;
|
|
4525
4818
|
}
|
|
4526
4819
|
if (session.grantExpiresAt && Date.now() > session.grantExpiresAt) {
|
|
@@ -4804,6 +5097,80 @@ function getAdminAllowedTools(enabledPlugins) {
|
|
|
4804
5097
|
}
|
|
4805
5098
|
return tools;
|
|
4806
5099
|
}
|
|
5100
|
+
var QUERY_CLASSIFIER_MODEL = "claude-haiku-4-5-20251001";
|
|
5101
|
+
var QUERY_CLASSIFIER_TIMEOUT_MS = 3e3;
|
|
5102
|
+
var QUERY_CLASSIFIER_MSG_CAP = 500;
|
|
5103
|
+
var QUERY_CLASSIFIER_HISTORY_TURNS = 4;
|
|
5104
|
+
var QUERY_CLASSIFIER_FALLBACK = {
|
|
5105
|
+
search: true,
|
|
5106
|
+
query: null,
|
|
5107
|
+
// null means "use raw message"
|
|
5108
|
+
reason: "classifier-fallback"
|
|
5109
|
+
};
|
|
5110
|
+
var QUERY_CLASSIFIER_SYSTEM = `You decide whether a user message to a business assistant requires a knowledge base search.
|
|
5111
|
+
|
|
5112
|
+
The knowledge base contains the business's products, services, pricing, policies, and domain expertise. It does NOT contain conversation history \u2014 the assistant already has that.
|
|
5113
|
+
|
|
5114
|
+
Respond with ONLY a JSON object: {"search": boolean, "query": string | null, "reason": string}
|
|
5115
|
+
|
|
5116
|
+
Set search to false when:
|
|
5117
|
+
- The message is a greeting, farewell, acknowledgement, or filler ("hello", "thanks", "ok", "bye")
|
|
5118
|
+
- The message is about session state ("continue where we left off", "what were we discussing")
|
|
5119
|
+
- The conversation history already contains sufficient information to answer the question
|
|
5120
|
+
- The message is a conversational response that doesn't require new factual knowledge
|
|
5121
|
+
|
|
5122
|
+
Set search to true when:
|
|
5123
|
+
- The message asks about products, services, pricing, capabilities, or business information
|
|
5124
|
+
- The message introduces a new topic not already covered in the conversation
|
|
5125
|
+
- The message requires factual knowledge the assistant wouldn't have from conversation alone
|
|
5126
|
+
|
|
5127
|
+
When search is true, set query to a search-optimised phrase that captures the information need. Resolve references from conversation history \u2014 e.g. if the user says "tell me more about the first one" and the history mentions "property valuations", set query to "property valuations details". If the raw message is already a good search query, use it as-is.
|
|
5128
|
+
|
|
5129
|
+
When search is false, set query to null and reason to a brief category (e.g. "greeting", "acknowledgement", "session-reference", "context-sufficient").`;
|
|
5130
|
+
async function classifyMemoryQuery(message, history) {
|
|
5131
|
+
let apiKey = process.env.ANTHROPIC_API_KEY;
|
|
5132
|
+
if (!apiKey) {
|
|
5133
|
+
try {
|
|
5134
|
+
apiKey = readFileSync5(API_KEY_FILE, "utf-8").trim();
|
|
5135
|
+
} catch {
|
|
5136
|
+
}
|
|
5137
|
+
}
|
|
5138
|
+
if (!apiKey) return QUERY_CLASSIFIER_FALLBACK;
|
|
5139
|
+
const recentHistory = history.slice(-QUERY_CLASSIFIER_HISTORY_TURNS);
|
|
5140
|
+
const transcript = recentHistory.length > 0 ? recentHistory.map((m) => `[${m.role}] ${m.content.slice(0, QUERY_CLASSIFIER_MSG_CAP)}`).join("\n") : "(no conversation history \u2014 this is the first message)";
|
|
5141
|
+
const userContent = [
|
|
5142
|
+
`Conversation history:
|
|
5143
|
+
${transcript}`,
|
|
5144
|
+
`
|
|
5145
|
+
Current message:
|
|
5146
|
+
${message.slice(0, QUERY_CLASSIFIER_MSG_CAP)}`
|
|
5147
|
+
].join("\n");
|
|
5148
|
+
const controller = new AbortController();
|
|
5149
|
+
const timer = setTimeout(() => controller.abort(), QUERY_CLASSIFIER_TIMEOUT_MS);
|
|
5150
|
+
try {
|
|
5151
|
+
const client = new Anthropic({ apiKey });
|
|
5152
|
+
const response = await client.messages.create({
|
|
5153
|
+
model: QUERY_CLASSIFIER_MODEL,
|
|
5154
|
+
max_tokens: 150,
|
|
5155
|
+
system: QUERY_CLASSIFIER_SYSTEM,
|
|
5156
|
+
messages: [{ role: "user", content: userContent }]
|
|
5157
|
+
}, { signal: controller.signal });
|
|
5158
|
+
const text = response.content.filter((b) => b.type === "text").map((b) => "text" in b ? b.text : "").join("").trim();
|
|
5159
|
+
if (!text) return QUERY_CLASSIFIER_FALLBACK;
|
|
5160
|
+
const jsonStr = text.replace(/^```json\s*/i, "").replace(/```\s*$/, "").trim();
|
|
5161
|
+
const parsed = JSON.parse(jsonStr);
|
|
5162
|
+
if (typeof parsed.search !== "boolean") return QUERY_CLASSIFIER_FALLBACK;
|
|
5163
|
+
return {
|
|
5164
|
+
search: parsed.search,
|
|
5165
|
+
query: parsed.search && typeof parsed.query === "string" ? parsed.query.slice(0, QUERY_CLASSIFIER_MSG_CAP) : null,
|
|
5166
|
+
reason: typeof parsed.reason === "string" ? parsed.reason.replace(/[\n\r]/g, " ").slice(0, 100) : "unknown"
|
|
5167
|
+
};
|
|
5168
|
+
} catch {
|
|
5169
|
+
return QUERY_CLASSIFIER_FALLBACK;
|
|
5170
|
+
} finally {
|
|
5171
|
+
clearTimeout(timer);
|
|
5172
|
+
}
|
|
5173
|
+
}
|
|
4807
5174
|
async function fetchMemoryContext(accountId, query, sessionKey, options) {
|
|
4808
5175
|
const serverPath = resolve4(PLATFORM_ROOT3, "plugins/memory/mcp/dist/index.js");
|
|
4809
5176
|
if (!existsSync5(serverPath)) {
|
|
@@ -5199,6 +5566,65 @@ Extract preference updates as JSON array.`
|
|
|
5199
5566
|
clearTimeout(timer);
|
|
5200
5567
|
}
|
|
5201
5568
|
}
|
|
5569
|
+
var SESSION_SUMMARY_PROMPT = `You are summarising a conversation between a business assistant and its owner. Write a 3-5 sentence summary covering:
|
|
5570
|
+
- What was discussed and accomplished this session
|
|
5571
|
+
- Any tasks created, decisions made, or state changes
|
|
5572
|
+
- Current state of any ongoing work
|
|
5573
|
+
- What the owner is likely to want to continue next
|
|
5574
|
+
|
|
5575
|
+
Be factual and specific. Use present tense for current state. Do not include greetings or meta-commentary.`;
|
|
5576
|
+
var SESSION_SUMMARY_TIMEOUT_MS = 1e4;
|
|
5577
|
+
var lastSummaryWrite = /* @__PURE__ */ new Map();
|
|
5578
|
+
var SUMMARY_RATE_LIMIT_MS = 5 * 60 * 1e3;
|
|
5579
|
+
async function generateSessionSummary(history) {
|
|
5580
|
+
if (history.length < 2) return null;
|
|
5581
|
+
let apiKey = process.env.ANTHROPIC_API_KEY;
|
|
5582
|
+
if (!apiKey) {
|
|
5583
|
+
try {
|
|
5584
|
+
apiKey = readFileSync5(API_KEY_FILE, "utf-8").trim();
|
|
5585
|
+
} catch {
|
|
5586
|
+
return null;
|
|
5587
|
+
}
|
|
5588
|
+
}
|
|
5589
|
+
if (!apiKey) {
|
|
5590
|
+
console.error("[session-summary] Skipping \u2014 no API key available");
|
|
5591
|
+
return null;
|
|
5592
|
+
}
|
|
5593
|
+
const transcript = history.slice(-20).map((m) => `[${m.role}] ${m.content}`).join("\n\n");
|
|
5594
|
+
const controller = new AbortController();
|
|
5595
|
+
const timer = setTimeout(() => controller.abort(), SESSION_SUMMARY_TIMEOUT_MS);
|
|
5596
|
+
try {
|
|
5597
|
+
const client = new Anthropic({ apiKey });
|
|
5598
|
+
const response = await client.messages.create({
|
|
5599
|
+
model: REFLECTION_MODEL,
|
|
5600
|
+
max_tokens: 500,
|
|
5601
|
+
system: SESSION_SUMMARY_PROMPT,
|
|
5602
|
+
messages: [{ role: "user", content: `Conversation:
|
|
5603
|
+
${transcript}` }]
|
|
5604
|
+
}, { signal: controller.signal });
|
|
5605
|
+
return response.content.filter((b) => b.type === "text").map((b) => "text" in b ? b.text : "").join("");
|
|
5606
|
+
} catch (err) {
|
|
5607
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
5608
|
+
console.error(`[session-summary] Haiku call timed out after ${SESSION_SUMMARY_TIMEOUT_MS}ms`);
|
|
5609
|
+
} else {
|
|
5610
|
+
console.error(`[session-summary] Haiku call failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
5611
|
+
}
|
|
5612
|
+
return null;
|
|
5613
|
+
} finally {
|
|
5614
|
+
clearTimeout(timer);
|
|
5615
|
+
}
|
|
5616
|
+
}
|
|
5617
|
+
async function writeEndOfTurnSummary(accountId, history) {
|
|
5618
|
+
const now = Date.now();
|
|
5619
|
+
const lastWrite = lastSummaryWrite.get(accountId) ?? 0;
|
|
5620
|
+
if (now - lastWrite < SUMMARY_RATE_LIMIT_MS) {
|
|
5621
|
+
return;
|
|
5622
|
+
}
|
|
5623
|
+
const summary = await generateSessionSummary(history);
|
|
5624
|
+
if (!summary) return;
|
|
5625
|
+
await writeSessionSummary(accountId, summary);
|
|
5626
|
+
lastSummaryWrite.set(accountId, Date.now());
|
|
5627
|
+
}
|
|
5202
5628
|
var MANAGED_WORK_BUDGET_RATIO = 0.5;
|
|
5203
5629
|
var TOOL_SCHEMA_OVERHEAD_TOKENS = 15e3;
|
|
5204
5630
|
function estimateTokens(text) {
|
|
@@ -5248,7 +5674,7 @@ var COMPACTION_TIMEOUT_MS = 45e3;
|
|
|
5248
5674
|
async function* runCompactionTurn(accountDir, accountId, systemPrompt, resumeSessionId, adminModel, enabledPlugins) {
|
|
5249
5675
|
const mcpConfig = JSON.stringify({ mcpServers: getMcpServers(accountId, enabledPlugins) });
|
|
5250
5676
|
const specialistsDir = resolve4(accountDir, "specialists");
|
|
5251
|
-
if (!existsSync5(specialistsDir)) agentLogStream("claude-agent-compaction-stream").write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
|
|
5677
|
+
if (!existsSync5(specialistsDir)) agentLogStream("claude-agent-compaction-stream", accountDir).write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
|
|
5252
5678
|
`);
|
|
5253
5679
|
const args = [
|
|
5254
5680
|
"--print",
|
|
@@ -5278,9 +5704,9 @@ async function* runCompactionTurn(accountDir, accountId, systemPrompt, resumeSes
|
|
|
5278
5704
|
stdio: ["ignore", "pipe", "pipe"],
|
|
5279
5705
|
env: { ...process.env, PLATFORM_ROOT: PLATFORM_ROOT3, ACCOUNT_DIR: accountDir }
|
|
5280
5706
|
});
|
|
5281
|
-
const stderrLog = agentLogStream("claude-agent-compaction-stderr");
|
|
5707
|
+
const stderrLog = agentLogStream("claude-agent-compaction-stderr", accountDir);
|
|
5282
5708
|
proc.stderr?.pipe(stderrLog);
|
|
5283
|
-
const streamLog = agentLogStream("claude-agent-compaction-stream");
|
|
5709
|
+
const streamLog = agentLogStream("claude-agent-compaction-stream", accountDir);
|
|
5284
5710
|
streamLog.write(`[${isoTs()}] [compaction-start] resumeSessionId=${resumeSessionId}
|
|
5285
5711
|
`);
|
|
5286
5712
|
proc.on("error", (err) => streamLog.write(`[${isoTs()}] [compaction-spawn-error] ${err.message}
|
|
@@ -5848,7 +6274,7 @@ async function* invokeAdminAgent(message, systemPrompt, accountDir, accountId, a
|
|
|
5848
6274
|
await ensureCdp();
|
|
5849
6275
|
const mcpConfig = JSON.stringify({ mcpServers: getMcpServers(accountId, enabledPlugins) });
|
|
5850
6276
|
const specialistsDir = resolve4(accountDir, "specialists");
|
|
5851
|
-
if (!existsSync5(specialistsDir)) agentLogStream("claude-agent-stream").write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
|
|
6277
|
+
if (!existsSync5(specialistsDir)) agentLogStream("claude-agent-stream", accountDir).write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
|
|
5852
6278
|
`);
|
|
5853
6279
|
const args = [
|
|
5854
6280
|
"--print",
|
|
@@ -5880,9 +6306,9 @@ async function* invokeAdminAgent(message, systemPrompt, accountDir, accountId, a
|
|
|
5880
6306
|
stdio: ["ignore", "pipe", "pipe"],
|
|
5881
6307
|
env: { ...process.env, PLATFORM_ROOT: PLATFORM_ROOT3, ACCOUNT_DIR: accountDir }
|
|
5882
6308
|
});
|
|
5883
|
-
const stderrLog = agentLogStream("claude-agent-stderr");
|
|
6309
|
+
const stderrLog = agentLogStream("claude-agent-stderr", accountDir);
|
|
5884
6310
|
proc.stderr?.pipe(stderrLog);
|
|
5885
|
-
const streamLog = agentLogStream("claude-agent-stream");
|
|
6311
|
+
const streamLog = agentLogStream("claude-agent-stream", accountDir);
|
|
5886
6312
|
streamLog.write(`[${isoTs()}] [spawn] pid=${proc.pid} resume=${resumeSessionId ?? "none"} sessionKey=${sessionKey ?? "none"} pluginDir=${specialistsDir}
|
|
5887
6313
|
`);
|
|
5888
6314
|
streamLog.write(`[${isoTs()}] [stdin] len=${fullMessage.length} preview=${JSON.stringify(fullMessage.slice(0, 80))}
|
|
@@ -6070,7 +6496,7 @@ async function* invokeManagedAdminAgent(message, systemPrompt, accountDir, accou
|
|
|
6070
6496
|
storePendingTrimmedMessages(sessionKey, pendingTrimmed);
|
|
6071
6497
|
}
|
|
6072
6498
|
}
|
|
6073
|
-
const streamLog = agentLogStream("claude-agent-stream");
|
|
6499
|
+
const streamLog = agentLogStream("claude-agent-stream", accountDir);
|
|
6074
6500
|
const systemPromptTokens = estimateTokens(systemPrompt);
|
|
6075
6501
|
let historyBudget = managedHistoryBudget(adminModel, systemPromptTokens);
|
|
6076
6502
|
const session = sessionStore.get(sessionKey);
|
|
@@ -6127,7 +6553,7 @@ async function* invokeManagedAdminAgent(message, systemPrompt, accountDir, accou
|
|
|
6127
6553
|
stdio: ["ignore", "pipe", "pipe"],
|
|
6128
6554
|
env: { ...process.env, PLATFORM_ROOT: PLATFORM_ROOT3, ACCOUNT_DIR: accountDir }
|
|
6129
6555
|
});
|
|
6130
|
-
const stderrLog = agentLogStream("claude-agent-stderr");
|
|
6556
|
+
const stderrLog = agentLogStream("claude-agent-stderr", accountDir);
|
|
6131
6557
|
proc.stderr?.pipe(stderrLog);
|
|
6132
6558
|
streamLog.write(`[${isoTs()}] [managed-spawn] pid=${proc.pid} sessionKey=${sessionKey} historyMessages=${history.length} pluginDir=${specialistsDir}
|
|
6133
6559
|
`);
|
|
@@ -6246,6 +6672,9 @@ async function* invokeManagedAdminAgent(message, systemPrompt, accountDir, accou
|
|
|
6246
6672
|
if (responseText) persistMessage(convId, "assistant", responseText, accountId, capturedTokens, assistantTimestamp).catch(() => {
|
|
6247
6673
|
});
|
|
6248
6674
|
}
|
|
6675
|
+
writeEndOfTurnSummary(accountId, afterHistory).catch(
|
|
6676
|
+
(err) => console.error(`[session-summary] end-of-turn write failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
6677
|
+
);
|
|
6249
6678
|
}
|
|
6250
6679
|
yield event;
|
|
6251
6680
|
}
|
|
@@ -6286,7 +6715,7 @@ ${summary}`;
|
|
|
6286
6715
|
stderrLog.end();
|
|
6287
6716
|
streamLog.end();
|
|
6288
6717
|
}
|
|
6289
|
-
async function* invokePublicAgent(message, systemPrompt, accountId, publicModel, sessionKey, pluginInfo, knowledgeBaked = false, agentSlug, liveMemory = false, knowledgeKeywords) {
|
|
6718
|
+
async function* invokePublicAgent(message, systemPrompt, accountId, accountDir, publicModel, sessionKey, pluginInfo, knowledgeBaked = false, agentSlug, liveMemory = false, knowledgeKeywords) {
|
|
6290
6719
|
const userTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
6291
6720
|
let apiKey = process.env.ANTHROPIC_API_KEY;
|
|
6292
6721
|
if (!apiKey) {
|
|
@@ -6300,7 +6729,7 @@ async function* invokePublicAgent(message, systemPrompt, accountId, publicModel,
|
|
|
6300
6729
|
yield { type: "done" };
|
|
6301
6730
|
return;
|
|
6302
6731
|
}
|
|
6303
|
-
const streamLog = agentLogStream("public-agent-stream");
|
|
6732
|
+
const streamLog = agentLogStream("public-agent-stream", accountDir);
|
|
6304
6733
|
streamLog.write(`[${isoTs()}] [public-user-message] ${JSON.stringify(message)}
|
|
6305
6734
|
`);
|
|
6306
6735
|
if (sessionKey) {
|
|
@@ -6324,18 +6753,32 @@ async function* invokePublicAgent(message, systemPrompt, accountId, publicModel,
|
|
|
6324
6753
|
}
|
|
6325
6754
|
}
|
|
6326
6755
|
}
|
|
6756
|
+
const history = sessionKey ? getMessageHistory(sessionKey) : [];
|
|
6327
6757
|
const fetchOptions = {
|
|
6328
6758
|
...agentSlug ? { agentSlug } : {},
|
|
6329
6759
|
...knowledgeKeywords && knowledgeKeywords.length > 0 ? { knowledgeKeywords } : {}
|
|
6330
6760
|
};
|
|
6761
|
+
const needsClassification = !(knowledgeBaked && !liveMemory);
|
|
6762
|
+
const classifyStartMs = Date.now();
|
|
6763
|
+
const classification = needsClassification ? await classifyMemoryQuery(message, history) : QUERY_CLASSIFIER_FALLBACK;
|
|
6764
|
+
const classifyMs = Date.now() - classifyStartMs;
|
|
6765
|
+
const effectiveQuery = classification.query ?? message;
|
|
6766
|
+
if (needsClassification) {
|
|
6767
|
+
streamLog.write(`[${isoTs()}] [public-query-classifier] search=${classification.search} effectiveQuery=${JSON.stringify(effectiveQuery.slice(0, 200))} reason=${classification.reason} latencyMs=${classifyMs}
|
|
6768
|
+
`);
|
|
6769
|
+
}
|
|
6331
6770
|
let system;
|
|
6332
6771
|
if (knowledgeBaked && !liveMemory) {
|
|
6333
6772
|
streamLog.write(`[${isoTs()}] [public-knowledge-source] baked \u2014 skipping memory-search (liveMemory=false)
|
|
6773
|
+
`);
|
|
6774
|
+
system = systemPrompt;
|
|
6775
|
+
} else if (!classification.search) {
|
|
6776
|
+
streamLog.write(`[${isoTs()}] [public-knowledge-source] skipped \u2014 classifier (reason=${classification.reason})
|
|
6334
6777
|
`);
|
|
6335
6778
|
system = systemPrompt;
|
|
6336
6779
|
} else if (knowledgeBaked && liveMemory) {
|
|
6337
|
-
const memoryContext = await fetchMemoryContext(accountId,
|
|
6338
|
-
streamLog.write(`[${isoTs()}] [public-knowledge-source] baked+live agentSlug=${agentSlug ?? "none"} keywords=${knowledgeKeywords?.length ?? 0} result=${memoryContext ? `ok (${memoryContext.length} chars)` : "null"}
|
|
6780
|
+
const memoryContext = await fetchMemoryContext(accountId, effectiveQuery, sessionKey, fetchOptions);
|
|
6781
|
+
streamLog.write(`[${isoTs()}] [public-knowledge-source] baked+live agentSlug=${agentSlug ?? "none"} keywords=${knowledgeKeywords?.length ?? 0} effectiveQuery=${JSON.stringify(effectiveQuery.slice(0, 200))} result=${memoryContext ? `ok (${memoryContext.length} chars)` : "null"}
|
|
6339
6782
|
`);
|
|
6340
6783
|
system = memoryContext ? `${systemPrompt}
|
|
6341
6784
|
|
|
@@ -6343,8 +6786,8 @@ async function* invokePublicAgent(message, systemPrompt, accountId, publicModel,
|
|
|
6343
6786
|
${memoryContext}
|
|
6344
6787
|
</live-memory>` : systemPrompt;
|
|
6345
6788
|
} else {
|
|
6346
|
-
const memoryContext = await fetchMemoryContext(accountId,
|
|
6347
|
-
streamLog.write(`[${isoTs()}] [public-knowledge-source] memory-search agentSlug=${agentSlug ?? "none"} keywords=${knowledgeKeywords?.length ?? 0} result=${memoryContext ? `ok (${memoryContext.length} chars)` : "null \u2014 agent has no knowledge"}
|
|
6789
|
+
const memoryContext = await fetchMemoryContext(accountId, effectiveQuery, sessionKey, fetchOptions);
|
|
6790
|
+
streamLog.write(`[${isoTs()}] [public-knowledge-source] memory-search agentSlug=${agentSlug ?? "none"} keywords=${knowledgeKeywords?.length ?? 0} effectiveQuery=${JSON.stringify(effectiveQuery.slice(0, 200))} result=${memoryContext ? `ok (${memoryContext.length} chars)` : "null \u2014 agent has no knowledge"}
|
|
6348
6791
|
`);
|
|
6349
6792
|
if (memoryContext) {
|
|
6350
6793
|
streamLog.write(`[${isoTs()}] [public-memory-context] ${JSON.stringify(memoryContext.slice(0, 500))}${memoryContext.length > 500 ? "\u2026" : ""}
|
|
@@ -6356,7 +6799,6 @@ ${memoryContext}
|
|
|
6356
6799
|
${memoryContext}
|
|
6357
6800
|
</memory>` : systemPrompt;
|
|
6358
6801
|
}
|
|
6359
|
-
const history = sessionKey ? getMessageHistory(sessionKey) : [];
|
|
6360
6802
|
const sdkMessages = [
|
|
6361
6803
|
...history.map((m) => ({ role: m.role, content: m.content })),
|
|
6362
6804
|
{ role: "user", content: message }
|
|
@@ -6577,6 +7019,13 @@ async function* invokeAgent(config, message, sessionKey, attachments = []) {
|
|
|
6577
7019
|
${soul}` : identityPrompt;
|
|
6578
7020
|
const now = /* @__PURE__ */ new Date();
|
|
6579
7021
|
const isoTimestamp = now.toISOString();
|
|
7022
|
+
const userTimezone = await getUserTimezone(accountId);
|
|
7023
|
+
const effectiveTimezone = userTimezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
7024
|
+
if (!userTimezone) {
|
|
7025
|
+
console.error(`[datetime] getUserTimezone returned null for ${accountId.slice(0, 8)}\u2026, falling back to server timezone: ${effectiveTimezone}`);
|
|
7026
|
+
} else {
|
|
7027
|
+
console.error(`[datetime] using user timezone: ${effectiveTimezone}`);
|
|
7028
|
+
}
|
|
6580
7029
|
const humanReadable = new Intl.DateTimeFormat("en-GB", {
|
|
6581
7030
|
weekday: "long",
|
|
6582
7031
|
year: "numeric",
|
|
@@ -6584,14 +7033,14 @@ ${soul}` : identityPrompt;
|
|
|
6584
7033
|
day: "numeric",
|
|
6585
7034
|
hour: "2-digit",
|
|
6586
7035
|
minute: "2-digit",
|
|
6587
|
-
timeZoneName: "shortOffset"
|
|
7036
|
+
timeZoneName: "shortOffset",
|
|
7037
|
+
timeZone: effectiveTimezone
|
|
6588
7038
|
}).format(now);
|
|
6589
|
-
const tzName = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
6590
7039
|
baseSystemPrompt += `
|
|
6591
7040
|
|
|
6592
7041
|
<datetime>
|
|
6593
7042
|
${isoTimestamp}
|
|
6594
|
-
${humanReadable} (${
|
|
7043
|
+
${humanReadable} (${effectiveTimezone})
|
|
6595
7044
|
</datetime>`;
|
|
6596
7045
|
if (agentType === "admin") {
|
|
6597
7046
|
const [profileSummary, sessionContext, onboardingStep] = await Promise.all([
|
|
@@ -6636,7 +7085,7 @@ ${agentConfig.knowledge}
|
|
|
6636
7085
|
${body}`;
|
|
6637
7086
|
}
|
|
6638
7087
|
if (agentType === "admin") {
|
|
6639
|
-
const manifest = buildPluginManifest(account.config.enabledPlugins);
|
|
7088
|
+
const manifest = await buildPluginManifest(account.config.enabledPlugins);
|
|
6640
7089
|
if (manifest) {
|
|
6641
7090
|
baseSystemPrompt += `
|
|
6642
7091
|
|
|
@@ -6713,7 +7162,7 @@ Current session key: ${sessionKey}` : systemPromptBase;
|
|
|
6713
7162
|
const knowledgeBaked = agentConfig?.knowledgeBaked ?? false;
|
|
6714
7163
|
const agentLiveMemory = agentConfig?.liveMemory ?? false;
|
|
6715
7164
|
const agentKeywords = agentConfig?.knowledgeKeywords ?? null;
|
|
6716
|
-
yield* invokePublicAgent(message, systemPrompt, accountId, publicModel, sessionKey, pluginInfo, knowledgeBaked, resolvedAgentName, agentLiveMemory, agentKeywords);
|
|
7165
|
+
yield* invokePublicAgent(message, systemPrompt, accountId, account.accountDir, publicModel, sessionKey, pluginInfo, knowledgeBaked, resolvedAgentName, agentLiveMemory, agentKeywords);
|
|
6717
7166
|
} else if (account.config.contextMode !== "claude-code" && sessionKey) {
|
|
6718
7167
|
yield* invokeManagedAdminAgent(message, systemPrompt, account.accountDir, accountId, account.config.adminModel, sessionKey, effortToMaxTurns(effort), attachments, 0, account.config.enabledPlugins);
|
|
6719
7168
|
} else {
|
|
@@ -7084,12 +7533,18 @@ async function POST2(req) {
|
|
|
7084
7533
|
}
|
|
7085
7534
|
const fullMessage = message + uploadNote;
|
|
7086
7535
|
const encoder = new TextEncoder();
|
|
7087
|
-
const
|
|
7536
|
+
const account = resolveAccount();
|
|
7537
|
+
if (!account) {
|
|
7538
|
+
return new Response(
|
|
7539
|
+
JSON.stringify({ error: "No account configured" }),
|
|
7540
|
+
{ status: 500, headers: { "Content-Type": "application/json" } }
|
|
7541
|
+
);
|
|
7542
|
+
}
|
|
7543
|
+
const sseLog = agentLogStream("sse-events", account.accountDir);
|
|
7088
7544
|
const sk = session_key.slice(0, 8);
|
|
7089
7545
|
let agentName = getAgentNameForSession(session_key);
|
|
7090
7546
|
if (!agentName) {
|
|
7091
|
-
|
|
7092
|
-
agentName = (account ? resolveDefaultAgentSlug(account.accountDir) : null) ?? void 0;
|
|
7547
|
+
agentName = resolveDefaultAgentSlug(account.accountDir) ?? void 0;
|
|
7093
7548
|
}
|
|
7094
7549
|
if (!agentName) {
|
|
7095
7550
|
return new Response(
|
|
@@ -7127,21 +7582,35 @@ async function POST2(req) {
|
|
|
7127
7582
|
}
|
|
7128
7583
|
} catch (err) {
|
|
7129
7584
|
const rawMessage = err instanceof Error ? err.message : String(err);
|
|
7130
|
-
const category = classifyAgentError(err);
|
|
7131
7585
|
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
7132
|
-
|
|
7586
|
+
const controllerClosed = err instanceof TypeError && /Controller is already closed/i.test(rawMessage);
|
|
7587
|
+
if (controllerClosed) {
|
|
7588
|
+
sseLog.write(`[${ts}] [${sk}] ${agentName}: DISCONNECT [client_disconnect] ${rawMessage}
|
|
7589
|
+
`);
|
|
7590
|
+
} else {
|
|
7591
|
+
const category = classifyAgentError(err);
|
|
7592
|
+
sseLog.write(`[${ts}] [${sk}] ${agentName}: ERROR [${category}] ${rawMessage}
|
|
7133
7593
|
`);
|
|
7134
|
-
|
|
7594
|
+
sseLog.write(`[${ts}] [${sk}] ${agentName}: ${JSON.stringify({ type: "done", subtype: "error", error: rawMessage, error_category: category })}
|
|
7135
7595
|
`);
|
|
7136
|
-
|
|
7137
|
-
|
|
7596
|
+
try {
|
|
7597
|
+
controller.enqueue(
|
|
7598
|
+
encoder.encode(`data: ${JSON.stringify({ error: friendlyAgentError(err, local ? "admin" : "public") })}
|
|
7138
7599
|
|
|
7139
7600
|
`)
|
|
7140
|
-
|
|
7141
|
-
|
|
7601
|
+
);
|
|
7602
|
+
controller.enqueue(encoder.encode("data: [DONE]\n\n"));
|
|
7603
|
+
} catch {
|
|
7604
|
+
sseLog.write(`[${ts}] [${sk}] ${agentName}: DISCONNECT [client_disconnect] could not deliver error \u2014 client disconnected
|
|
7605
|
+
`);
|
|
7606
|
+
}
|
|
7607
|
+
}
|
|
7142
7608
|
} finally {
|
|
7143
7609
|
sseLog.end();
|
|
7144
|
-
|
|
7610
|
+
try {
|
|
7611
|
+
controller.close();
|
|
7612
|
+
} catch {
|
|
7613
|
+
}
|
|
7145
7614
|
}
|
|
7146
7615
|
}
|
|
7147
7616
|
});
|
|
@@ -8843,10 +9312,17 @@ async function POST12(req) {
|
|
|
8843
9312
|
}
|
|
8844
9313
|
} catch {
|
|
8845
9314
|
}
|
|
9315
|
+
const account = resolveAccount();
|
|
9316
|
+
if (!account) {
|
|
9317
|
+
return new Response(
|
|
9318
|
+
JSON.stringify({ error: "No account configured" }),
|
|
9319
|
+
{ status: 500, headers: { "Content-Type": "application/json" } }
|
|
9320
|
+
);
|
|
9321
|
+
}
|
|
8846
9322
|
try {
|
|
8847
9323
|
const parsed = JSON.parse(message);
|
|
8848
9324
|
if (parsed._lifecycle) {
|
|
8849
|
-
const lifecycleLog = agentLogStream("component-lifecycle");
|
|
9325
|
+
const lifecycleLog = agentLogStream("component-lifecycle", account.accountDir);
|
|
8850
9326
|
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
8851
9327
|
const detail = parsed.filePath ? ` filePath=${parsed.filePath}` : "";
|
|
8852
9328
|
lifecycleLog.write(`[${ts}] [component:${parsed.component ?? "unknown"}] ${parsed.event ?? "unknown"}${detail}
|
|
@@ -8868,7 +9344,7 @@ async function POST12(req) {
|
|
|
8868
9344
|
} catch {
|
|
8869
9345
|
}
|
|
8870
9346
|
const encoder = new TextEncoder();
|
|
8871
|
-
const sseLog = agentLogStream("sse-events");
|
|
9347
|
+
const sseLog = agentLogStream("sse-events", account.accountDir);
|
|
8872
9348
|
const sk = session_key.slice(0, 8);
|
|
8873
9349
|
const readable = new ReadableStream({
|
|
8874
9350
|
async start(controller) {
|
|
@@ -8889,25 +9365,39 @@ async function POST12(req) {
|
|
|
8889
9365
|
}
|
|
8890
9366
|
} catch (err) {
|
|
8891
9367
|
const rawMessage = err instanceof Error ? err.message : String(err);
|
|
8892
|
-
const category = classifyAgentError(err);
|
|
8893
|
-
const errEvent = JSON.stringify({ type: "text", content: friendlyAgentError(err) });
|
|
8894
|
-
const doneEvent = JSON.stringify({ type: "done", subtype: "error", error: rawMessage, error_category: category });
|
|
8895
9368
|
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
8896
|
-
|
|
9369
|
+
const controllerClosed = err instanceof TypeError && /Controller is already closed/i.test(rawMessage);
|
|
9370
|
+
if (controllerClosed) {
|
|
9371
|
+
sseLog.write(`[${ts}] [${sk}] admin: DISCONNECT [client_disconnect] ${rawMessage}
|
|
9372
|
+
`);
|
|
9373
|
+
} else {
|
|
9374
|
+
const category = classifyAgentError(err);
|
|
9375
|
+
const errEvent = JSON.stringify({ type: "text", content: friendlyAgentError(err) });
|
|
9376
|
+
const doneEvent = JSON.stringify({ type: "done", subtype: "error", error: rawMessage, error_category: category });
|
|
9377
|
+
sseLog.write(`[${ts}] [${sk}] admin: ERROR [${category}] ${rawMessage}
|
|
8897
9378
|
`);
|
|
8898
|
-
|
|
9379
|
+
sseLog.write(`[${ts}] [${sk}] admin: ${errEvent}
|
|
8899
9380
|
`);
|
|
8900
|
-
|
|
9381
|
+
sseLog.write(`[${ts}] [${sk}] admin: ${doneEvent}
|
|
8901
9382
|
`);
|
|
8902
|
-
|
|
9383
|
+
try {
|
|
9384
|
+
controller.enqueue(encoder.encode(`data: ${errEvent}
|
|
8903
9385
|
|
|
8904
9386
|
`));
|
|
8905
|
-
|
|
9387
|
+
controller.enqueue(encoder.encode(`data: ${doneEvent}
|
|
8906
9388
|
|
|
8907
9389
|
`));
|
|
9390
|
+
} catch {
|
|
9391
|
+
sseLog.write(`[${ts}] [${sk}] admin: DISCONNECT [client_disconnect] could not deliver error \u2014 client disconnected
|
|
9392
|
+
`);
|
|
9393
|
+
}
|
|
9394
|
+
}
|
|
8908
9395
|
} finally {
|
|
8909
9396
|
sseLog.end();
|
|
8910
|
-
|
|
9397
|
+
try {
|
|
9398
|
+
controller.close();
|
|
9399
|
+
} catch {
|
|
9400
|
+
}
|
|
8911
9401
|
}
|
|
8912
9402
|
}
|
|
8913
9403
|
});
|
|
@@ -8962,7 +9452,7 @@ async function POST13(req) {
|
|
|
8962
9452
|
}
|
|
8963
9453
|
|
|
8964
9454
|
// app/api/admin/logs/route.ts
|
|
8965
|
-
import { readdirSync as readdirSync2, readFileSync as readFileSync12, statSync as statSync3 } from "fs";
|
|
9455
|
+
import { existsSync as existsSync12, readdirSync as readdirSync2, readFileSync as readFileSync12, statSync as statSync3 } from "fs";
|
|
8966
9456
|
import { resolve as resolve9, basename } from "path";
|
|
8967
9457
|
var TAIL_BYTES = 8192;
|
|
8968
9458
|
async function GET3(request) {
|
|
@@ -8970,17 +9460,22 @@ async function GET3(request) {
|
|
|
8970
9460
|
const fileParam = searchParams.get("file");
|
|
8971
9461
|
const typeParam = searchParams.get("type");
|
|
8972
9462
|
const download = searchParams.get("download") === "1";
|
|
9463
|
+
const account = resolveAccount();
|
|
9464
|
+
const accountLogDir = account ? resolve9(account.accountDir, "logs") : null;
|
|
8973
9465
|
if (fileParam) {
|
|
8974
9466
|
const safe = basename(fileParam);
|
|
8975
|
-
const
|
|
8976
|
-
|
|
8977
|
-
const
|
|
8978
|
-
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
|
|
8982
|
-
|
|
9467
|
+
for (const dir of [accountLogDir, LOG_DIR]) {
|
|
9468
|
+
if (!dir) continue;
|
|
9469
|
+
const filePath = resolve9(dir, safe);
|
|
9470
|
+
try {
|
|
9471
|
+
const content = readFileSync12(filePath, "utf-8");
|
|
9472
|
+
const headers = { "Content-Type": "text/plain; charset=utf-8" };
|
|
9473
|
+
if (download) headers["Content-Disposition"] = `attachment; filename="${safe}"`;
|
|
9474
|
+
return new Response(content, { headers });
|
|
9475
|
+
} catch {
|
|
9476
|
+
}
|
|
8983
9477
|
}
|
|
9478
|
+
return Response.json({ error: `File not found: ${safe}` }, { status: 404 });
|
|
8984
9479
|
}
|
|
8985
9480
|
if (typeParam) {
|
|
8986
9481
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -8995,32 +9490,40 @@ async function GET3(request) {
|
|
|
8995
9490
|
if (!fileName) {
|
|
8996
9491
|
return Response.json({ error: `Unknown type: ${typeParam}. Valid: stream, error, session, sse, public` }, { status: 400 });
|
|
8997
9492
|
}
|
|
8998
|
-
const
|
|
8999
|
-
|
|
9000
|
-
const
|
|
9001
|
-
|
|
9002
|
-
|
|
9003
|
-
|
|
9004
|
-
|
|
9005
|
-
|
|
9493
|
+
for (const dir of [accountLogDir, LOG_DIR]) {
|
|
9494
|
+
if (!dir) continue;
|
|
9495
|
+
const filePath = resolve9(dir, fileName);
|
|
9496
|
+
try {
|
|
9497
|
+
const content = readFileSync12(filePath, "utf-8");
|
|
9498
|
+
const headers = { "Content-Type": "text/plain; charset=utf-8" };
|
|
9499
|
+
if (download) headers["Content-Disposition"] = `attachment; filename="${fileName}"`;
|
|
9500
|
+
return new Response(content, { headers });
|
|
9501
|
+
} catch {
|
|
9502
|
+
}
|
|
9006
9503
|
}
|
|
9504
|
+
return Response.json({ error: `Log not found: ${fileName}` }, { status: 404 });
|
|
9007
9505
|
}
|
|
9008
|
-
|
|
9009
|
-
try {
|
|
9010
|
-
files = readdirSync2(LOG_DIR).filter((f) => f.endsWith(".log"));
|
|
9011
|
-
} catch {
|
|
9012
|
-
return Response.json({ logs: {} });
|
|
9013
|
-
}
|
|
9506
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9014
9507
|
const logs = {};
|
|
9015
|
-
|
|
9508
|
+
for (const dir of [accountLogDir, LOG_DIR]) {
|
|
9509
|
+
if (!dir || !existsSync12(dir)) continue;
|
|
9510
|
+
let files;
|
|
9016
9511
|
try {
|
|
9017
|
-
|
|
9018
|
-
const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
|
|
9019
|
-
logs[name] = tail.trim() || "(empty)";
|
|
9512
|
+
files = readdirSync2(dir).filter((f) => f.endsWith(".log"));
|
|
9020
9513
|
} catch {
|
|
9021
|
-
|
|
9514
|
+
continue;
|
|
9022
9515
|
}
|
|
9023
|
-
|
|
9516
|
+
files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync3(resolve9(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
|
|
9517
|
+
seen.add(name);
|
|
9518
|
+
try {
|
|
9519
|
+
const content = readFileSync12(resolve9(dir, name));
|
|
9520
|
+
const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
|
|
9521
|
+
logs[name] = tail.trim() || "(empty)";
|
|
9522
|
+
} catch {
|
|
9523
|
+
logs[name] = "(unreadable)";
|
|
9524
|
+
}
|
|
9525
|
+
});
|
|
9526
|
+
}
|
|
9024
9527
|
return Response.json({ logs });
|
|
9025
9528
|
}
|
|
9026
9529
|
|
|
@@ -9048,7 +9551,7 @@ async function GET4() {
|
|
|
9048
9551
|
|
|
9049
9552
|
// app/api/admin/attachment/[attachmentId]/route.ts
|
|
9050
9553
|
import { readFile, readdir } from "fs/promises";
|
|
9051
|
-
import { existsSync as
|
|
9554
|
+
import { existsSync as existsSync13 } from "fs";
|
|
9052
9555
|
import { resolve as resolve10 } from "path";
|
|
9053
9556
|
async function GET5(req, attachmentId) {
|
|
9054
9557
|
const sessionKey = new URL(req.url).searchParams.get("session_key") ?? "";
|
|
@@ -9063,11 +9566,11 @@ async function GET5(req, attachmentId) {
|
|
|
9063
9566
|
return new Response("Not found", { status: 404 });
|
|
9064
9567
|
}
|
|
9065
9568
|
const dir = resolve10(ATTACHMENTS_ROOT, accountId, attachmentId);
|
|
9066
|
-
if (!
|
|
9569
|
+
if (!existsSync13(dir)) {
|
|
9067
9570
|
return new Response("Not found", { status: 404 });
|
|
9068
9571
|
}
|
|
9069
9572
|
const metaPath = resolve10(dir, `${attachmentId}.meta.json`);
|
|
9070
|
-
if (!
|
|
9573
|
+
if (!existsSync13(metaPath)) {
|
|
9071
9574
|
return new Response("Not found", { status: 404 });
|
|
9072
9575
|
}
|
|
9073
9576
|
let meta;
|
|
@@ -9133,14 +9636,14 @@ async function PATCH(req) {
|
|
|
9133
9636
|
|
|
9134
9637
|
// app/api/admin/agents/route.ts
|
|
9135
9638
|
import { resolve as resolve12 } from "path";
|
|
9136
|
-
import { readdirSync as readdirSync3, readFileSync as readFileSync14, existsSync as
|
|
9639
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync14, existsSync as existsSync14 } from "fs";
|
|
9137
9640
|
async function GET6() {
|
|
9138
9641
|
const account = resolveAccount();
|
|
9139
9642
|
if (!account) {
|
|
9140
9643
|
return Response.json({ agents: [] });
|
|
9141
9644
|
}
|
|
9142
9645
|
const agentsDir = resolve12(account.accountDir, "agents");
|
|
9143
|
-
if (!
|
|
9646
|
+
if (!existsSync14(agentsDir)) {
|
|
9144
9647
|
return Response.json({ agents: [] });
|
|
9145
9648
|
}
|
|
9146
9649
|
const agents = [];
|
|
@@ -9150,7 +9653,7 @@ async function GET6() {
|
|
|
9150
9653
|
if (!entry.isDirectory()) continue;
|
|
9151
9654
|
if (entry.name === "admin") continue;
|
|
9152
9655
|
const configPath = resolve12(agentsDir, entry.name, "config.json");
|
|
9153
|
-
if (!
|
|
9656
|
+
if (!existsSync14(configPath)) continue;
|
|
9154
9657
|
try {
|
|
9155
9658
|
const config = JSON.parse(readFileSync14(configPath, "utf-8"));
|
|
9156
9659
|
agents.push({
|
|
@@ -9170,13 +9673,13 @@ async function GET6() {
|
|
|
9170
9673
|
}
|
|
9171
9674
|
|
|
9172
9675
|
// app/api/admin/version/route.ts
|
|
9173
|
-
import { readFileSync as readFileSync15, existsSync as
|
|
9676
|
+
import { readFileSync as readFileSync15, existsSync as existsSync15 } from "fs";
|
|
9174
9677
|
import { resolve as resolve13, join as join3 } from "path";
|
|
9175
9678
|
var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve13(process.cwd(), "..");
|
|
9176
9679
|
var brandHostname = "maxy";
|
|
9177
9680
|
var brandNpmPackage = "@rubytech/create-maxy";
|
|
9178
9681
|
var brandJsonPath = join3(PLATFORM_ROOT6, "config", "brand.json");
|
|
9179
|
-
if (
|
|
9682
|
+
if (existsSync15(brandJsonPath)) {
|
|
9180
9683
|
try {
|
|
9181
9684
|
const brand = JSON.parse(readFileSync15(brandJsonPath, "utf-8"));
|
|
9182
9685
|
if (brand.hostname) brandHostname = brand.hostname;
|
|
@@ -9191,7 +9694,7 @@ var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
|
9191
9694
|
var FETCH_TIMEOUT_MS = 5e3;
|
|
9192
9695
|
var latestCache = null;
|
|
9193
9696
|
function readInstalled() {
|
|
9194
|
-
if (!
|
|
9697
|
+
if (!existsSync15(VERSION_FILE)) return "unknown";
|
|
9195
9698
|
const content = readFileSync15(VERSION_FILE, "utf-8").trim();
|
|
9196
9699
|
return content || "unknown";
|
|
9197
9700
|
}
|
|
@@ -9246,13 +9749,13 @@ async function GET7() {
|
|
|
9246
9749
|
|
|
9247
9750
|
// app/api/admin/version/upgrade/route.ts
|
|
9248
9751
|
import { spawn as spawn3 } from "child_process";
|
|
9249
|
-
import { existsSync as
|
|
9752
|
+
import { existsSync as existsSync16, statSync as statSync4, writeFileSync as writeFileSync9, readFileSync as readFileSync16, openSync as openSync2, closeSync as closeSync2 } from "fs";
|
|
9250
9753
|
import { resolve as resolve14, join as join4 } from "path";
|
|
9251
9754
|
var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve14(process.cwd(), "..");
|
|
9252
9755
|
var upgradePkg = "@rubytech/create-maxy";
|
|
9253
9756
|
var upgradeHostname = "maxy";
|
|
9254
9757
|
var brandPath = join4(PLATFORM_ROOT7, "config", "brand.json");
|
|
9255
|
-
if (
|
|
9758
|
+
if (existsSync16(brandPath)) {
|
|
9256
9759
|
try {
|
|
9257
9760
|
const brand = JSON.parse(readFileSync16(brandPath, "utf-8"));
|
|
9258
9761
|
if (brand.npm?.packageName) upgradePkg = brand.npm.packageName;
|
|
@@ -9264,7 +9767,7 @@ var LOCK_FILE = `/tmp/${upgradeHostname}-upgrade.lock`;
|
|
|
9264
9767
|
var LOG_FILE = `/tmp/${upgradeHostname}-upgrade.log`;
|
|
9265
9768
|
var LOCK_MAX_AGE_MS = 3 * 60 * 1e3;
|
|
9266
9769
|
function isLockFresh() {
|
|
9267
|
-
if (!
|
|
9770
|
+
if (!existsSync16(LOCK_FILE)) return false;
|
|
9268
9771
|
try {
|
|
9269
9772
|
const stat = statSync4(LOCK_FILE);
|
|
9270
9773
|
return Date.now() - stat.mtimeMs < LOCK_MAX_AGE_MS;
|
|
@@ -9420,10 +9923,10 @@ async function POST15() {
|
|
|
9420
9923
|
var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
9421
9924
|
var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join5(PLATFORM_ROOT8, "config", "brand.json") : "";
|
|
9422
9925
|
var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", domain: "getmaxy.com" };
|
|
9423
|
-
if (BRAND_JSON_PATH && !
|
|
9926
|
+
if (BRAND_JSON_PATH && !existsSync17(BRAND_JSON_PATH)) {
|
|
9424
9927
|
console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
|
|
9425
9928
|
}
|
|
9426
|
-
if (BRAND_JSON_PATH &&
|
|
9929
|
+
if (BRAND_JSON_PATH && existsSync17(BRAND_JSON_PATH)) {
|
|
9427
9930
|
try {
|
|
9428
9931
|
const parsed = JSON.parse(readFileSync17(BRAND_JSON_PATH, "utf-8"));
|
|
9429
9932
|
BRAND = { ...BRAND, ...parsed };
|
|
@@ -9435,7 +9938,7 @@ if (BRAND_JSON_PATH && existsSync16(BRAND_JSON_PATH)) {
|
|
|
9435
9938
|
var ALIAS_DOMAINS_PATH = join5(homedir2(), BRAND.configDir, "alias-domains.json");
|
|
9436
9939
|
function loadAliasDomains() {
|
|
9437
9940
|
try {
|
|
9438
|
-
if (!
|
|
9941
|
+
if (!existsSync17(ALIAS_DOMAINS_PATH)) return null;
|
|
9439
9942
|
const parsed = JSON.parse(readFileSync17(ALIAS_DOMAINS_PATH, "utf-8"));
|
|
9440
9943
|
if (!Array.isArray(parsed)) {
|
|
9441
9944
|
console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
|
|
@@ -9764,7 +10267,7 @@ app.get(
|
|
|
9764
10267
|
);
|
|
9765
10268
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
9766
10269
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
9767
|
-
if (BRAND_JSON_PATH &&
|
|
10270
|
+
if (BRAND_JSON_PATH && existsSync17(BRAND_JSON_PATH)) {
|
|
9768
10271
|
try {
|
|
9769
10272
|
const fullBrand = JSON.parse(readFileSync17(BRAND_JSON_PATH, "utf-8"));
|
|
9770
10273
|
if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
|
|
@@ -9792,12 +10295,12 @@ function loadBrandingCache(agentSlug) {
|
|
|
9792
10295
|
const configDir = join5(homedir2(), BRAND.configDir);
|
|
9793
10296
|
try {
|
|
9794
10297
|
const accountJsonPath = join5(configDir, "account.json");
|
|
9795
|
-
if (!
|
|
10298
|
+
if (!existsSync17(accountJsonPath)) return null;
|
|
9796
10299
|
const account = JSON.parse(readFileSync17(accountJsonPath, "utf-8"));
|
|
9797
10300
|
const accountId = account.accountId;
|
|
9798
10301
|
if (!accountId) return null;
|
|
9799
10302
|
const cachePath = join5(configDir, "branding-cache", accountId, `${agentSlug}.json`);
|
|
9800
|
-
if (!
|
|
10303
|
+
if (!existsSync17(cachePath)) return null;
|
|
9801
10304
|
return JSON.parse(readFileSync17(cachePath, "utf-8"));
|
|
9802
10305
|
} catch {
|
|
9803
10306
|
return null;
|
|
@@ -9807,7 +10310,7 @@ function resolveDefaultSlug() {
|
|
|
9807
10310
|
try {
|
|
9808
10311
|
const configDir = join5(homedir2(), BRAND.configDir);
|
|
9809
10312
|
const accountJsonPath = join5(configDir, "account.json");
|
|
9810
|
-
if (!
|
|
10313
|
+
if (!existsSync17(accountJsonPath)) return null;
|
|
9811
10314
|
const account = JSON.parse(readFileSync17(accountJsonPath, "utf-8"));
|
|
9812
10315
|
return account.defaultAgent || null;
|
|
9813
10316
|
} catch {
|