fraim 2.0.362-next.4 → 2.0.362
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/registry/scripts/domains/folders.js +55 -0
- package/dist/registry/scripts/learning/entry-authoring.js +13 -24
- package/dist/registry/scripts/learning/run-publication.js +5 -30
- package/dist/registry/stubs/jobs/ai-employee/ai-engineering/aeo-optimization.md +43 -0
- package/dist/registry/stubs/jobs/ai-employee/ai-engineering/author-ai-evals.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/ai-engineering/create-ai-agent.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/ai-engineering/create-hub-configured-agent.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/ai-engineering/enable-web-mcp.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/ai-engineering/evaluate-ai-agent.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/ai-engineering/mcp-server-creation.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/ai-engineering/publish-mcp-app.md +28 -0
- package/dist/registry/stubs/jobs/ai-employee/bank-compliance/banking-evidence-audit.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/bank-operations/kyc-case-review.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/career/career-networking.md +46 -0
- package/dist/registry/stubs/jobs/ai-employee/career/career-spec.md +41 -0
- package/dist/registry/stubs/jobs/ai-employee/career/career-trajectory-planning.md +41 -0
- package/dist/registry/stubs/jobs/ai-employee/career/job-applications-and-networking.md +40 -0
- package/dist/registry/stubs/jobs/ai-employee/career/job-search-strategy-and-application-plan.md +41 -0
- package/dist/registry/stubs/jobs/ai-employee/career/offer-negotiation.md +42 -0
- package/dist/registry/stubs/jobs/ai-employee/career/pitch-and-interview-prep.md +43 -0
- package/dist/registry/stubs/jobs/ai-employee/career/public-profile-updates.md +41 -0
- package/dist/registry/stubs/jobs/ai-employee/career/resilience-planning.md +38 -0
- package/dist/registry/stubs/jobs/ai-employee/career/resume-creation.md +40 -0
- package/dist/registry/stubs/jobs/ai-employee/customer/crm-case-resolution.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/customer/customer-health-review.md +36 -0
- package/dist/registry/stubs/jobs/ai-employee/customer/loyalty-program-management.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/customer/support-case-resolution.md +39 -0
- package/dist/registry/stubs/jobs/ai-employee/customer/support-playbook-evaluation.md +37 -0
- package/dist/registry/stubs/jobs/ai-employee/customer/support-queue-management.md +36 -0
- package/dist/registry/stubs/jobs/ai-employee/customer/support-sop-operationalization.md +36 -0
- package/dist/registry/stubs/jobs/ai-employee/customer/support-system-operationalization.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/customer/survey-campaign-management.md +36 -0
- package/dist/registry/stubs/jobs/ai-employee/customer/update-crm.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/customer/user-survey-management.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/design/brand-creation.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/design/branding-quality-audit.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/design/design-system-creation.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/design/ui-quality-assessment.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/design/user-facing-prototyping.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/design/user-journey-mapping.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/design/ux-research-synthesis.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/design/website-creation.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/dev-ops/cloud-application-deployment.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/dev-ops/cloud-cost-optimization.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/dev-ops/cloud-performance-diagnosis.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/dev-ops/cross-cloud-migration.md +42 -0
- package/dist/registry/stubs/jobs/ai-employee/dev-ops/incident-response.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/dev-ops/production-readiness-review.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/dev-ops/reliability-review.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/dev-ops/route-llm-spend-to-cloud-credits.md +36 -0
- package/dist/registry/stubs/jobs/ai-employee/dev-ops/run-on-remote-hub.md +30 -0
- package/dist/registry/stubs/jobs/ai-employee/dev-ops/set-up-cloud-cost-alerts.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/dev-ops/setup-remote-hub.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/dev-ops/slo-design-and-implementation.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/application-replication-workflow.md +42 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/code-refactoring.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/codebase-analysis-and-ideation.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/create-architecture.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/data-pipeline-design.md +30 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/data-platform-architecture.md +29 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/data-quality-monitoring.md +29 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/database-schema-design.md +30 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/feature-implementation.md +39 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/github-org-setup.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/gitlabs-to-github.md +44 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/google-workspace-setup.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/issue-preparation.md +28 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/large-refactor-plan.md +36 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/mobile-app-development.md +43 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/mobile-app-rejection-response.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/mobile-app-submission.md +37 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/project-scaffolding.md +39 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/system-migration.md +41 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/technical-design.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/work-completion.md +29 -0
- package/dist/registry/stubs/jobs/ai-employee/engineering/write-dev-docs.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/executive-assistance/analyze-transcript.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/executive-assistance/calendar-triage.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/executive-assistance/chief-of-staff-briefing.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/executive-assistance/executive-assistant.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/executive-assistance/meeting-preparation.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/finance/business-banking-setup.md +29 -0
- package/dist/registry/stubs/jobs/ai-employee/finance/cloud-credits-application.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/finance/community-funding-preparation.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/finance/financial-analysis.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/finance/fpa-and-forecasting.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/finance/fundraising-prospect-discovery.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/finance/investor-pitch-preparation.md +40 -0
- package/dist/registry/stubs/jobs/ai-employee/finance/invoice-generation.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/finance/monthly-close-review.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/finance/review-funding-preparation.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/finance/tax-strategy-planning.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/fraim/adhoc-prompt.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/fraim/contribute-to-fraim.md +30 -0
- package/dist/registry/stubs/jobs/ai-employee/fraim/file-fraim-issue.md +29 -0
- package/dist/registry/stubs/jobs/ai-employee/fraim/organizational-learning-synthesis.md +40 -0
- package/dist/registry/stubs/jobs/ai-employee/fraim/praise-fraim.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/fraim/share-with-others.md +30 -0
- package/dist/registry/stubs/jobs/ai-employee/fraim/sleep-on-learnings.md +41 -0
- package/dist/registry/stubs/jobs/ai-employee/fraim/troubleshoot-fraim.md +29 -0
- package/dist/registry/stubs/jobs/ai-employee/fraim/video-demo-to-sop.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/ad-performance-analysis.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/aeo-strategy.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/analyze-revenue-system.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/build-gtm-motion.md +37 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/build-gtm-stack.md +36 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/design-gtm-system.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/developer-advocacy.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/domain-registration-research.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/evangelist-content-development.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/funnel-analysis.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/growth-loop-design.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/linkedin-carousel-from-deck.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/linkedin-company-page-setup.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/marketing-analytics-review.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/marketing-content-creation.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/marketing-strategy-definition.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/notebooklm-content-generation.md +39 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/paid-social-strategy.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/plan-gtm-team.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/ppc-campaign-management.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/product-launch-management.md +29 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/promo-video-creation.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/seo-strategy.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/social-engagement-campaign.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/thought-leadership-engagement.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/tracking-and-attribution-setup.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/go-to-market/x-account-setup.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/inclusion/ai-fluency-program-design.md +30 -0
- package/dist/registry/stubs/jobs/ai-employee/inclusion/ai-governance-for-inclusion.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/inclusion/dei-toolkit-creation.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/inclusion/equity-pattern-analysis.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/inclusion/erg-sop-modernization.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/inclusion/executive-order-dei-impact-analysis.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/inclusion/inclusion-ai-readiness-audit.md +37 -0
- package/dist/registry/stubs/jobs/ai-employee/legal/business-annual-report-filing.md +37 -0
- package/dist/registry/stubs/jobs/ai-employee/legal/business-tax-registration.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/legal/cap-table-construction.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/legal/contract-review-analysis.md +36 -0
- package/dist/registry/stubs/jobs/ai-employee/legal/ein-application.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/legal/employment-structure-decision.md +29 -0
- package/dist/registry/stubs/jobs/ai-employee/legal/entity-type-selection.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/legal/founder-and-equity-agreements.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/legal/ip-assignment-agreement-creation.md +29 -0
- package/dist/registry/stubs/jobs/ai-employee/legal/nda-creation.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/legal/provisional-patent-application-creation.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/legal/saas-contract-package-creation.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/legal/state-incorporation-filing.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/legal/trademark-registration-management.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/legal/w9-creation.md +37 -0
- package/dist/registry/stubs/jobs/ai-employee/management/evolve-employee.md +44 -0
- package/dist/registry/stubs/jobs/ai-employee/management/fully-delegate.md +37 -0
- package/dist/registry/stubs/jobs/ai-employee/management/generate-productivity-report.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/management/graduate-job.md +24 -0
- package/dist/registry/stubs/jobs/ai-employee/management/issue-retrospective.md +30 -0
- package/dist/registry/stubs/jobs/ai-employee/management/manager-agreements.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/management/organization-onboarding.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/management/project-onboarding.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/management/send-stakeholder-update.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/people-ops/benefits-analysis-and-enrollment.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/people-ops/hr-business-partner-advisory.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/people-ops/new-hire-onboarding.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/people-ops/payroll-coordination.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/people-ops/performance-review-preparation.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/procurement/equipment-acceptance-and-supplier-retrospective.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/procurement/procurement-intake-and-strategy.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/procurement/procurement-negotiation-prep.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/procurement/proposal-response-evaluation.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/procurement/purchase-approval-and-po-package.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/procurement/rfp-response-preparation.md +30 -0
- package/dist/registry/stubs/jobs/ai-employee/procurement/rfx-package-authoring.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/procurement/supplier-discovery-and-qualification.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/procurement/supplier-performance-review.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/product/customer-prospect-discovery.md +42 -0
- package/dist/registry/stubs/jobs/ai-employee/product/experiment-tracking.md +30 -0
- package/dist/registry/stubs/jobs/ai-employee/product/feature-specification.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/product/independent-implementation-review.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/product/interview-preparation.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/product/mvp-validation-plan.md +30 -0
- package/dist/registry/stubs/jobs/ai-employee/product/participant-recruitment.md +38 -0
- package/dist/registry/stubs/jobs/ai-employee/product/process-interview-notes.md +42 -0
- package/dist/registry/stubs/jobs/ai-employee/product/review-customer-development.md +38 -0
- package/dist/registry/stubs/jobs/ai-employee/product/send-newsletter.md +30 -0
- package/dist/registry/stubs/jobs/ai-employee/product/send-thank-you-notes.md +30 -0
- package/dist/registry/stubs/jobs/ai-employee/product/triage-customer-needs.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/project-management/cross-functional-dependency-management.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/project-management/delivery-governance-review.md +30 -0
- package/dist/registry/stubs/jobs/ai-employee/project-management/operational-reporting.md +37 -0
- package/dist/registry/stubs/jobs/ai-employee/project-management/project-plan-creation.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/project-management/scrum-sprint-planning.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/project-management/sprint-planning.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/quality-assurance/accessibility-audit.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/quality-assurance/api-testing.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/quality-assurance/codebase-quality-assessment.md +37 -0
- package/dist/registry/stubs/jobs/ai-employee/quality-assurance/iterative-quality-improvement.md +37 -0
- package/dist/registry/stubs/jobs/ai-employee/quality-assurance/mutation-testing.md +30 -0
- package/dist/registry/stubs/jobs/ai-employee/quality-assurance/performance-quality-assessment.md +38 -0
- package/dist/registry/stubs/jobs/ai-employee/quality-assurance/stress-test-app-under-load.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/quality-assurance/test-authoring.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/quality-assurance/test-quality-assessment.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/quality-assurance/ui-polish-validation.md +45 -0
- package/dist/registry/stubs/jobs/ai-employee/quality-assurance/user-testing-and-bug-bash.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/recruiting/candidate-pipeline-management.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/recruiting/candidate-sourcing-and-ranking.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/recruiting/interview-coordination.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/recruiting/job-posting-and-sourcing.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/recruiting/offer-and-close-management.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/recruiting/role-intake-and-scorecard.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/recruiting/sourcing-funnel-recap.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/sales/account-strategy.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/sales/crm-pipeline-review.md +30 -0
- package/dist/registry/stubs/jobs/ai-employee/sales/deal-strategy.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/sales/outbound-sales-strategy.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/sales/proposal-development.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/sales/sales-coaching.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/sales/sales-discovery-preparation.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/salesforce/sf-build-automation.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/salesforce/sf-build-dashboard.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/salesforce/sf-config-deployment.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/salesforce/sf-data-management.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/salesforce/sf-org-health-check.md +38 -0
- package/dist/registry/stubs/jobs/ai-employee/salesforce/sf-user-and-access-management.md +35 -0
- package/dist/registry/stubs/jobs/ai-employee/security/compliance-continuous-monitoring.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/security/compliance-policy-authoring.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/security/compliance-questionnaire-response.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/security/compliance-requirements-detection.md +30 -0
- package/dist/registry/stubs/jobs/ai-employee/security/compliance-review.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/security/generate-audit-evidence.md +34 -0
- package/dist/registry/stubs/jobs/ai-employee/security/regulation-evidence-management.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/security/security-baseline-setup.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/security/security-review.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/security/soc2-evidence-management.md +32 -0
- package/dist/registry/stubs/jobs/ai-employee/security/vulnerability-triage-and-remediation.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/strategy/advisor-interview.md +29 -0
- package/dist/registry/stubs/jobs/ai-employee/strategy/advisory-board-development.md +31 -0
- package/dist/registry/stubs/jobs/ai-employee/strategy/advisory-board-selection.md +29 -0
- package/dist/registry/stubs/jobs/ai-employee/strategy/blue-sky-brainstorming.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/strategy/business-idea-validation-and-scoping.md +44 -0
- package/dist/registry/stubs/jobs/ai-employee/strategy/business-plan-creation.md +38 -0
- package/dist/registry/stubs/jobs/ai-employee/strategy/competitive-analysis.md +36 -0
- package/dist/registry/stubs/jobs/ai-employee/strategy/founder-market-fit-analysis.md +40 -0
- package/dist/registry/stubs/jobs/ai-employee/strategy/pricing-strategy-definition.md +40 -0
- package/dist/registry/stubs/jobs/ai-employee/strategy/problem-statement-crystallization.md +37 -0
- package/dist/registry/stubs/jobs/ai-employee/strategy/review-business-strategy.md +37 -0
- package/dist/registry/stubs/jobs/ai-employee/travel/travel-disruption-rebooking.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/travel/travel-fare-watch.md +33 -0
- package/dist/registry/stubs/jobs/ai-employee/travel/travel-planning.md +32 -0
- package/dist/registry/stubs/jobs/ai-manager/fraim/instruction-hygiene-review.md +34 -0
- package/dist/registry/stubs/jobs/ai-manager/management/analyze-why-you-messed-up.md +29 -0
- package/dist/registry/stubs/jobs/ai-manager/management/author-project-rules.md +31 -0
- package/dist/registry/stubs/jobs/ai-manager/management/create-clarity.md +30 -0
- package/dist/registry/stubs/jobs/ai-manager/management/explain-it.md +30 -0
- package/dist/registry/stubs/jobs/ai-manager/management/follow-your-mentor.md +29 -0
- package/dist/registry/stubs/jobs/ai-manager/management/hire-right-ai-for-the-job.md +29 -0
- package/dist/registry/stubs/jobs/ai-manager/management/hire-the-right-human-ai-manager.md +29 -0
- package/dist/registry/stubs/jobs/ai-manager/management/how-should-i-verify.md +32 -0
- package/dist/registry/stubs/jobs/ai-manager/management/need-pov.md +30 -0
- package/dist/registry/stubs/jobs/ai-manager/management/recognize-good-work.md +29 -0
- package/dist/registry/stubs/jobs/ai-manager/management/refine-core-values.md +29 -0
- package/dist/registry/stubs/jobs/ai-manager/management/shape-team.md +30 -0
- package/dist/registry/stubs/jobs/ai-manager/management/strong-pov.md +30 -0
- package/dist/registry/stubs/jobs/ai-manager/management/weak-pov.md +30 -0
- package/dist/registry/stubs/jobs/ai-manager/management/what-should-i-review.md +34 -0
- package/dist/src/cli/utils/remote-sync.js +0 -7
- package/dist/src/cli/utils/script-sync-utils.js +0 -4
- package/dist/src/config/learning-domains.js +12 -19
- package/dist/src/core/ai-mentor.js +2 -2
- package/dist/src/core/utils/domain-rule-assembler.js +78 -153
- package/dist/src/core/utils/include-resolver.js +25 -47
- package/dist/src/core/utils/local-registry-resolver.js +0 -51
- package/dist/src/local-mcp-server/learning-context-builder.js +36 -33
- package/dist/src/local-mcp-server/stdio-server.js +27 -59
- package/dist/src/services/mcp-service.js +15 -15
- package/dist/src/services/registry-service.js +0 -4
- package/package.json +3 -3
- package/dist/registry/domains.json +0 -159
- package/dist/registry/scripts/domains/catalog.js +0 -112
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CATEGORY_TO_FILETYPE = exports.BRAIN_LEARNING_FILETYPE_TO_REGION = exports.TEAM_CONTEXT_RELATIVE_PATHS = exports.generateLearningEntryId = exports.learningEntryIdLineRegex = exports.learningEntryHeadingRegex = exports.LEARNING_ENTRY_ID_REGEX = exports.LEARNING_PRIORITIES = exports.DEFAULT_THRESHOLD = void 0;
|
|
4
4
|
exports.storedLearningDomains = storedLearningDomains;
|
|
5
|
+
exports.learningDomainsForWorkspace = learningDomainsForWorkspace;
|
|
5
6
|
exports.getScoreThreshold = getScoreThreshold;
|
|
6
7
|
exports.computeEffectiveScore = computeEffectiveScore;
|
|
7
8
|
exports.getLearningInputHomes = getLearningInputHomes;
|
|
@@ -42,12 +43,14 @@ const brand_store_1 = require("../core/brand-store");
|
|
|
42
43
|
// cache, which silently returned nothing once that cache stopped existing.
|
|
43
44
|
const pack_home_2 = require("../cli/utils/pack-home");
|
|
44
45
|
const learning_domains_1 = require("../config/learning-domains");
|
|
46
|
+
const folders_1 = require("../../registry/scripts/domains/folders");
|
|
45
47
|
const entry_authoring_1 = require("../../registry/scripts/learning/entry-authoring");
|
|
46
|
-
/**
|
|
47
|
-
function storedLearningDomains(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
/** Stored names stay readable; local job folders extend current domains. */
|
|
49
|
+
function storedLearningDomains(effectiveDomains = []) {
|
|
50
|
+
return [...new Set([...learning_domains_1.STORED_LEARNING_DOMAINS, ...effectiveDomains.filter(folders_1.isSafeDomainId)])];
|
|
51
|
+
}
|
|
52
|
+
function learningDomainsForWorkspace(workspaceRoot) {
|
|
53
|
+
return [...new Set([...learning_domains_1.LEARNING_DOMAINS, ...(0, folders_1.discoverJobDomains)((0, path_1.join)(workspaceRoot, 'registry'), (0, project_fraim_paths_1.getUserFraimDirPath)(), (0, path_1.join)((0, project_fraim_paths_1.getWorkspaceFraimDir)(workspaceRoot), 'personalized-employee'), (0, pack_home_2.resolvePackHome)('manager', { migrateLegacy: false }).contentRoot, (0, pack_home_2.resolvePackHome)('org', { migrateLegacy: false }).contentRoot)])];
|
|
51
54
|
}
|
|
52
55
|
const REPO_LEARNINGS_REL = (0, project_fraim_paths_1.getWorkspaceFraimDisplayPath)('personalized-employee/learnings').replace(/\/$/, '');
|
|
53
56
|
/**
|
|
@@ -546,7 +549,7 @@ const CONTEXT_CATEGORIES = {
|
|
|
546
549
|
validated: { ft: 'validated-patterns', label: '(all entries)' },
|
|
547
550
|
};
|
|
548
551
|
/** Resolve the files listed in injected context, in delivery order. */
|
|
549
|
-
function resolveContextLearningFiles(workspaceRoot, resolvedUserId, roots, forJob, domain,
|
|
552
|
+
function resolveContextLearningFiles(workspaceRoot, resolvedUserId, roots, forJob, domain, effectiveDomains) {
|
|
550
553
|
// Domain axis (issue #806) plus the connect/job single-injection contract (issue
|
|
551
554
|
// #860). Session startup stays broad enough for stable preferences plus L0, while
|
|
552
555
|
// job contexts add the remaining global categories and may append the current job's
|
|
@@ -590,7 +593,7 @@ function resolveContextLearningFiles(workspaceRoot, resolvedUserId, roots, forJo
|
|
|
590
593
|
const content = (0, fs_1.readFileSync)(tier.path, 'utf8');
|
|
591
594
|
const explicitProvenance = /^\*\*(?:Domain|Originating job)\*\*:/m.test(content);
|
|
592
595
|
if (storageDomain !== 'global' || explicitProvenance)
|
|
593
|
-
selected = (0, entry_authoring_1.selectStoredLearningEntries)(content, storageDomain, activeDomain ?? 'global', includeGlobal,
|
|
596
|
+
selected = (0, entry_authoring_1.selectStoredLearningEntries)(content, storageDomain, activeDomain ?? 'global', includeGlobal, effectiveDomains);
|
|
594
597
|
else if (!includeGlobal)
|
|
595
598
|
continue;
|
|
596
599
|
}
|
|
@@ -619,7 +622,7 @@ function resolveContextLearningFiles(workspaceRoot, resolvedUserId, roots, forJo
|
|
|
619
622
|
for (const key of cats.domain) {
|
|
620
623
|
if (sessionCats.includes(key))
|
|
621
624
|
push(domainFiles, key, tiersFor(CONTEXT_CATEGORIES[key].ft), 'global', false);
|
|
622
|
-
for (const storageDomain of storedLearningDomains(
|
|
625
|
+
for (const storageDomain of storedLearningDomains(effectiveDomains)) {
|
|
623
626
|
push(domainFiles, key, tiersFor(CONTEXT_CATEGORIES[key].ft, storageDomain), storageDomain);
|
|
624
627
|
}
|
|
625
628
|
}
|
|
@@ -630,10 +633,10 @@ function resolveContextLearningFiles(workspaceRoot, resolvedUserId, roots, forJo
|
|
|
630
633
|
const l1 = collect({ global: l1GlobalCats, domain: l1DomainCats }, (ft, dom) => resolvePersonalLearningFileTiers(roots.repoLearningsBase, roots.managerCacheBase, roots.managerCacheDisplayBase, roots.globalPersonalBase, roots.globalPersonalDisplayBase, dom ? `${resolvedUserId}-${dom}-${ft}.md` : `${resolvedUserId}-${ft}.md`), 'manager');
|
|
631
634
|
return { l2, l1, multiTier, coachPresent };
|
|
632
635
|
}
|
|
633
|
-
function buildLearningContextSection(workspaceRoot, userId, forJob, domain,
|
|
636
|
+
function buildLearningContextSection(workspaceRoot, userId, forJob, domain, effectiveDomains) {
|
|
634
637
|
const roots = getLearningRoots(workspaceRoot);
|
|
635
638
|
const resolvedUserId = resolveLearningUserId(workspaceRoot, userId, roots);
|
|
636
|
-
const resolved = resolveContextLearningFiles(workspaceRoot, resolvedUserId, roots, forJob, domain,
|
|
639
|
+
const resolved = resolveContextLearningFiles(workspaceRoot, resolvedUserId, roots, forJob, domain, effectiveDomains);
|
|
637
640
|
const multiTier = resolved.multiTier;
|
|
638
641
|
const toListed = (f) => ({
|
|
639
642
|
displayPath: f.displayPath,
|
|
@@ -1068,7 +1071,7 @@ function readLearningEntryTitles(filePath) {
|
|
|
1068
1071
|
* manager-coaching entries that field used to hold, so the tile labelled
|
|
1069
1072
|
* "Manager" reports the level rather than a category.
|
|
1070
1073
|
*/
|
|
1071
|
-
function countPreservedLearnings(workspaceRoot, userId,
|
|
1074
|
+
function countPreservedLearnings(workspaceRoot, userId, effectiveDomains) {
|
|
1072
1075
|
const roots = getLearningRoots(workspaceRoot);
|
|
1073
1076
|
const resolvedUserId = resolveLearningUserId(workspaceRoot, userId, roots);
|
|
1074
1077
|
// Distinct entry titles across every level holding this company family, so a
|
|
@@ -1120,7 +1123,7 @@ function countPreservedLearnings(workspaceRoot, userId, effectiveCatalog) {
|
|
|
1120
1123
|
let reverseMentoring = coachByLevel.manager + coachByLevel.project;
|
|
1121
1124
|
// #806: domain-scoped files fold into the same per-level counts so the Brain
|
|
1122
1125
|
// reconciles with what the loader injects for a job.
|
|
1123
|
-
for (const domain of storedLearningDomains(
|
|
1126
|
+
for (const domain of storedLearningDomains(effectiveDomains)) {
|
|
1124
1127
|
for (const ft of ORG_TYPES)
|
|
1125
1128
|
organization += countOrgFamily(`org-${domain}-${ft}.md`);
|
|
1126
1129
|
for (const ft of PERSONAL_WORK_TYPES) {
|
|
@@ -1331,11 +1334,11 @@ const FILETYPE_TO_CATEGORY = {
|
|
|
1331
1334
|
* #806) present in a directory, in a deterministic domain order. Used by the Hub
|
|
1332
1335
|
* read/count paths so domain learnings appear alongside the flat global files.
|
|
1333
1336
|
*/
|
|
1334
|
-
function listDomainLearningFiles(dir, prefix, fileType,
|
|
1337
|
+
function listDomainLearningFiles(dir, prefix, fileType, effectiveDomains) {
|
|
1335
1338
|
if (!(0, fs_1.existsSync)(dir))
|
|
1336
1339
|
return [];
|
|
1337
1340
|
const out = [];
|
|
1338
|
-
for (const domain of storedLearningDomains(
|
|
1341
|
+
for (const domain of storedLearningDomains(effectiveDomains)) {
|
|
1339
1342
|
const fileName = `${prefix}-${domain}-${fileType}.md`;
|
|
1340
1343
|
if ((0, fs_1.existsSync)((0, path_1.join)(dir, fileName)))
|
|
1341
1344
|
out.push({ fileName, domain });
|
|
@@ -1550,7 +1553,7 @@ function readRejectedProposals(workspaceRoot, userId) {
|
|
|
1550
1553
|
// Newest first: the manager is most often checking what they just said no to.
|
|
1551
1554
|
return out.sort((a, b) => String(b.rejectedAt).localeCompare(String(a.rejectedAt)));
|
|
1552
1555
|
}
|
|
1553
|
-
function readPreservedLearnings(workspaceRoot, userId, scope, level = 'machine',
|
|
1556
|
+
function readPreservedLearnings(workspaceRoot, userId, scope, level = 'machine', effectiveDomains) {
|
|
1554
1557
|
const roots = getLearningRoots(workspaceRoot);
|
|
1555
1558
|
const usageStats = resolveUsageStats();
|
|
1556
1559
|
// Only the human library reads these observations. An unavailable store must
|
|
@@ -1599,8 +1602,8 @@ function readPreservedLearnings(workspaceRoot, userId, scope, level = 'machine',
|
|
|
1599
1602
|
out.push(...parseTiers(resolveOrgLearningFileTiers(roots.repoLearningsBase, f), cat));
|
|
1600
1603
|
// #806: domain-scoped org learnings — union from both locations.
|
|
1601
1604
|
const allDomainFiles = [
|
|
1602
|
-
...listDomainLearningFiles(roots.repoLearningsBase, 'org', fileType,
|
|
1603
|
-
...listDomainLearningFiles((0, path_1.join)((0, pack_home_2.resolvePackHome)('org', { migrateLegacy: false }).contentRoot, 'learnings'), 'org', fileType,
|
|
1605
|
+
...listDomainLearningFiles(roots.repoLearningsBase, 'org', fileType, effectiveDomains).map((d) => ({ ...d, base: roots.repoLearningsBase })),
|
|
1606
|
+
...listDomainLearningFiles((0, path_1.join)((0, pack_home_2.resolvePackHome)('org', { migrateLegacy: false }).contentRoot, 'learnings'), 'org', fileType, effectiveDomains)
|
|
1604
1607
|
.map((d) => ({ ...d, base: (0, path_1.join)((0, pack_home_2.resolvePackHome)('org', { migrateLegacy: false }).contentRoot, 'learnings') })),
|
|
1605
1608
|
];
|
|
1606
1609
|
const seenDomainFile = new Set();
|
|
@@ -1624,7 +1627,7 @@ function readPreservedLearnings(workspaceRoot, userId, scope, level = 'machine',
|
|
|
1624
1627
|
const cats = scope === 'reverse' ? ['coaching'] : ['avoid', 'preference', 'repeat'];
|
|
1625
1628
|
for (const cat of cats) {
|
|
1626
1629
|
const fileType = exports.CATEGORY_TO_FILETYPE[cat];
|
|
1627
|
-
for (const domain of ['global', ...storedLearningDomains(
|
|
1630
|
+
for (const domain of ['global', ...storedLearningDomains(effectiveDomains)]) {
|
|
1628
1631
|
const domainPart = domain === 'global' ? '' : `-${domain}`;
|
|
1629
1632
|
for (const storageTier of ['hot', 'cold']) {
|
|
1630
1633
|
const suffix = storageTier === 'cold' ? COLD_FILE_SUFFIX : '';
|
|
@@ -1641,39 +1644,39 @@ function isGlobalDomain(domain) {
|
|
|
1641
1644
|
return !domain || domain === 'global';
|
|
1642
1645
|
}
|
|
1643
1646
|
/** Normalize a caller-supplied domain to one of the known domains, or 'global'. */
|
|
1644
|
-
function normalizeLearningDomain(domain,
|
|
1647
|
+
function normalizeLearningDomain(domain, effectiveDomains) {
|
|
1645
1648
|
if (isGlobalDomain(domain))
|
|
1646
1649
|
return 'global';
|
|
1647
|
-
const found = storedLearningDomains(
|
|
1650
|
+
const found = storedLearningDomains(effectiveDomains).find((d) => d === domain);
|
|
1648
1651
|
return found ?? 'global';
|
|
1649
1652
|
}
|
|
1650
|
-
function learningFileName(userId, fileType, domain,
|
|
1653
|
+
function learningFileName(userId, fileType, domain, effectiveDomains) {
|
|
1651
1654
|
// Issue #1755 / #754: normalize here rather than trusting the caller. The HTTP
|
|
1652
1655
|
// layer already allowlists the domain, but this function builds a path and a
|
|
1653
1656
|
// direct caller passing `../../escape` would otherwise write outside the
|
|
1654
1657
|
// learnings root. Anything not in the known set resolves to the global file.
|
|
1655
|
-
const safe = normalizeLearningDomain(domain,
|
|
1658
|
+
const safe = normalizeLearningDomain(domain, effectiveDomains);
|
|
1656
1659
|
return safe === 'global' ? `${userId}-${fileType}.md` : `${userId}-${safe}-${fileType}.md`;
|
|
1657
1660
|
}
|
|
1658
|
-
function resolveLearningFilePath(workspaceRoot, userId, ref,
|
|
1661
|
+
function resolveLearningFilePath(workspaceRoot, userId, ref, effectiveDomains) {
|
|
1659
1662
|
const roots = getLearningRoots(workspaceRoot);
|
|
1660
1663
|
const fileType = exports.CATEGORY_TO_FILETYPE[ref.category];
|
|
1661
1664
|
if (ref.scope === 'org') {
|
|
1662
1665
|
// Write org entries to the org pack home — same location share-with-others uses.
|
|
1663
1666
|
// The Hub read path already merges pack home + repo-local, so edits land where
|
|
1664
1667
|
// the agent reads them without needing a repo commit.
|
|
1665
|
-
return (0, path_1.join)((0, pack_home_2.resolvePackHome)('org', { migrateLegacy: false }).contentRoot, 'learnings', learningFileName('org', fileType, ref.domain,
|
|
1668
|
+
return (0, path_1.join)((0, pack_home_2.resolvePackHome)('org', { migrateLegacy: false }).contentRoot, 'learnings', learningFileName('org', fileType, ref.domain, effectiveDomains));
|
|
1666
1669
|
}
|
|
1667
1670
|
const resolvedUserId = resolveLearningUserId(workspaceRoot, userId, roots);
|
|
1668
1671
|
// Issue #1070: for the 'machine' level use the configured manager home.
|
|
1669
1672
|
const base = ref.level === 'project' ? roots.repoLearningsBase : roots.managerHomeBase;
|
|
1670
|
-
return (0, path_1.join)(base, learningFileName(resolvedUserId, fileType, ref.domain,
|
|
1673
|
+
return (0, path_1.join)(base, learningFileName(resolvedUserId, fileType, ref.domain, effectiveDomains));
|
|
1671
1674
|
}
|
|
1672
1675
|
function titleCaseFromFileType(fileType) {
|
|
1673
1676
|
return fileType.split('-').map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
|
|
1674
1677
|
}
|
|
1675
|
-
function applyLearningEntryChange(workspaceRoot, userId, ref, action, payload,
|
|
1676
|
-
const filePath = resolveLearningFilePath(workspaceRoot, userId, ref,
|
|
1678
|
+
function applyLearningEntryChange(workspaceRoot, userId, ref, action, payload, effectiveDomains) {
|
|
1679
|
+
const filePath = resolveLearningFilePath(workspaceRoot, userId, ref, effectiveDomains);
|
|
1677
1680
|
const existing = (0, fs_1.existsSync)(filePath) ? (0, fs_1.readFileSync)(filePath, 'utf8') : '';
|
|
1678
1681
|
const nl = existing.includes('\r\n') ? '\r\n' : '\n';
|
|
1679
1682
|
const lines = existing.length ? existing.split(/\r?\n/) : [];
|
|
@@ -1687,9 +1690,9 @@ function applyLearningEntryChange(workspaceRoot, userId, ref, action, payload, e
|
|
|
1687
1690
|
};
|
|
1688
1691
|
const metadataLine = /^\*\*(Id|Score|Last seen|Recurrences|Technical trace|Users|First recorded|First synthesized|Originating job|Sources|Domain|Domain basis|Domain history)\*\*:/i;
|
|
1689
1692
|
const setManagerDomain = (metadata, domain) => {
|
|
1690
|
-
const version =
|
|
1693
|
+
const version = learning_domains_1.LEARNING_DOMAIN_MAP_VERSION;
|
|
1691
1694
|
if (!Number.isInteger(version) || version < 1)
|
|
1692
|
-
throw new Error('Cannot record a learning domain decision:
|
|
1695
|
+
throw new Error('Cannot record a learning domain decision: check the stored provenance version.');
|
|
1693
1696
|
const oldDomain = metadata.find(line => /^\*\*Domain\*\*:/i.test(line.trim()))?.trim().replace(/^\*\*Domain\*\*:\s*/i, '');
|
|
1694
1697
|
const oldBasis = metadata.find(line => /^\*\*Domain basis\*\*:/i.test(line.trim()))?.trim().replace(/^\*\*Domain basis\*\*:\s*/i, '');
|
|
1695
1698
|
const retained = metadata.filter(line => !/^\*\*(Domain|Domain basis)\*\*:/i.test(line.trim()));
|
|
@@ -1702,7 +1705,7 @@ function applyLearningEntryChange(workspaceRoot, userId, ref, action, payload, e
|
|
|
1702
1705
|
const sev = (payload.severity || 'P-MED');
|
|
1703
1706
|
const title = (payload.title || '').trim() || 'Untitled learning';
|
|
1704
1707
|
const suppliedLines = String(payload.body || '').trim().split(/\r?\n/);
|
|
1705
|
-
const addDomain = normalizeLearningDomain(ref.domain,
|
|
1708
|
+
const addDomain = normalizeLearningDomain(ref.domain, effectiveDomains);
|
|
1706
1709
|
const metadata = setManagerDomain(suppliedLines.filter(line => metadataLine.test(line.trim())), addDomain);
|
|
1707
1710
|
const body = suppliedLines.filter(line => !metadataLine.test(line.trim())).join(nl).trim();
|
|
1708
1711
|
const block = [`#### [${sev}] ${title}`, '', ...metadata, '', body, '', '---'].join(nl);
|
|
@@ -1755,7 +1758,7 @@ function applyLearningEntryChange(workspaceRoot, userId, ref, action, payload, e
|
|
|
1755
1758
|
}
|
|
1756
1759
|
const originalBody = lines.slice(start + 1, end).filter(line => line.trim() !== '---' && !metadataLine.test(line.trim()) && !/^(First|Last) synthesized:/i.test(line.trim())).join(nl).trim();
|
|
1757
1760
|
const body = payload.body === undefined ? originalBody : String(payload.body).split(/\r?\n/).filter(line => !metadataLine.test(line.trim())).join(nl).trim();
|
|
1758
|
-
const targetDomain = payload.targetDomain === undefined ? undefined : normalizeLearningDomain(payload.targetDomain,
|
|
1761
|
+
const targetDomain = payload.targetDomain === undefined ? undefined : normalizeLearningDomain(payload.targetDomain, effectiveDomains);
|
|
1759
1762
|
// A normal prose edit is not authority to reclassify an ambiguous legacy entry.
|
|
1760
1763
|
// An explicit choice records a manager decision even when its filename is unchanged.
|
|
1761
1764
|
const updatedMeta = targetDomain !== undefined && targetDomain === payload.targetDomain ? setManagerDomain(meta, targetDomain) : meta;
|
|
@@ -1764,8 +1767,8 @@ function applyLearningEntryChange(workspaceRoot, userId, ref, action, payload, e
|
|
|
1764
1767
|
// IS the filename. Cut the rebuilt block from the source file and append it to the
|
|
1765
1768
|
// destination, so the entry keeps its id, score and history rather than being
|
|
1766
1769
|
// re-created as a new entry with no past.
|
|
1767
|
-
if (targetDomain !== undefined && targetDomain !== normalizeLearningDomain(ref.domain,
|
|
1768
|
-
const destPath = resolveLearningFilePath(workspaceRoot, userId, { ...ref, domain: targetDomain },
|
|
1770
|
+
if (targetDomain !== undefined && targetDomain !== normalizeLearningDomain(ref.domain, effectiveDomains)) {
|
|
1771
|
+
const destPath = resolveLearningFilePath(workspaceRoot, userId, { ...ref, domain: targetDomain }, effectiveDomains);
|
|
1769
1772
|
const destExisting = (0, fs_1.existsSync)(destPath) ? (0, fs_1.readFileSync)(destPath, 'utf8') : '';
|
|
1770
1773
|
const destNl = destExisting.includes('\r\n') ? '\r\n' : nl;
|
|
1771
1774
|
const fileTypeForHeader = exports.CATEGORY_TO_FILETYPE[ref.category];
|
|
@@ -81,7 +81,7 @@ const usage_collector_js_1 = require("./usage-collector.js");
|
|
|
81
81
|
const otlp_metrics_receiver_js_1 = require("./otlp-metrics-receiver.js");
|
|
82
82
|
const token_adapter_registry_js_1 = require("./token-adapter-registry.js");
|
|
83
83
|
const learning_context_builder_js_1 = require("./learning-context-builder.js");
|
|
84
|
-
const
|
|
84
|
+
const folders_1 = require("../../registry/scripts/domains/folders");
|
|
85
85
|
const skill_include_dedup_js_1 = require("./skill-include-dedup.js");
|
|
86
86
|
const git_utils_1 = require("../core/utils/git-utils");
|
|
87
87
|
/**
|
|
@@ -1820,7 +1820,7 @@ class FraimLocalMCPServer {
|
|
|
1820
1820
|
// request, authorizes dependent catalog, include and rule reads. Keep it
|
|
1821
1821
|
// request-local so a later rejected reconnect cannot change another call.
|
|
1822
1822
|
if (toolName === 'fraim_connect') {
|
|
1823
|
-
const connectedSessionId = response.result?.
|
|
1823
|
+
const connectedSessionId = response.result?._meta?.sessionId ?? response.result?.sessionId;
|
|
1824
1824
|
if (typeof connectedSessionId === 'string' && connectedSessionId.trim())
|
|
1825
1825
|
requestSessionId = connectedSessionId;
|
|
1826
1826
|
}
|
|
@@ -1903,13 +1903,11 @@ class FraimLocalMCPServer {
|
|
|
1903
1903
|
finalizedResponse.result.content[0].text = responseText;
|
|
1904
1904
|
}
|
|
1905
1905
|
}
|
|
1906
|
-
let catalogRead;
|
|
1907
1906
|
// 4. After get_fraim_job succeeds, inject learning context with job-focus frame.
|
|
1908
1907
|
if (toolName === 'get_fraim_job' && !finalizedResponse.error) {
|
|
1909
1908
|
const text = finalizedResponse.result?.content?.[0]?.text;
|
|
1910
1909
|
if (typeof text === 'string') {
|
|
1911
|
-
|
|
1912
|
-
finalizedResponse.result.content[0].text = await this.appendJobContext(text, args.job, requestSessionId, requestId, catalogRead);
|
|
1910
|
+
finalizedResponse.result.content[0].text = await this.appendJobContext(text, args.job, requestSessionId, requestId);
|
|
1913
1911
|
}
|
|
1914
1912
|
// Issue #1345: forward executionMode from get_fraim_job response to Hub so
|
|
1915
1913
|
// the chip reads from run data (no local file read, no separate endpoint needed).
|
|
@@ -1925,23 +1923,17 @@ class FraimLocalMCPServer {
|
|
|
1925
1923
|
}
|
|
1926
1924
|
}
|
|
1927
1925
|
}
|
|
1928
|
-
finalizedResponse = await this.addRuleDelivery(request, finalizedResponse, requestSessionId
|
|
1926
|
+
finalizedResponse = await this.addRuleDelivery(request, finalizedResponse, requestSessionId);
|
|
1929
1927
|
return this.processResponseWithHydration(finalizedResponse, requestSessionId);
|
|
1930
1928
|
}
|
|
1931
1929
|
/** Keep context delivery and offer attribution together for local and remote jobs. */
|
|
1932
|
-
async appendJobContext(text, jobName, requestSessionId, requestId
|
|
1930
|
+
async appendJobContext(text, jobName, requestSessionId, requestId) {
|
|
1933
1931
|
const userEmail = this.ensureEngine().getUserEmail();
|
|
1934
1932
|
const workspaceRoot = this.findProjectRoot() || process.cwd();
|
|
1935
|
-
let effectiveCatalog;
|
|
1936
|
-
try {
|
|
1937
|
-
const source = await (catalogRead ?? (0, domain_rule_assembler_1.withRuleDeliveryTimeout)(this.getRegistryResolver(requestSessionId).resolveFile('domains.json', { includeMetadata: false })));
|
|
1938
|
-
effectiveCatalog = JSON.parse(source.content);
|
|
1939
|
-
}
|
|
1940
|
-
catch { /* Rule delivery returns the source warning; retain available global learning. */ }
|
|
1941
1933
|
if (!userEmail)
|
|
1942
1934
|
return text;
|
|
1943
|
-
const jobDomain =
|
|
1944
|
-
const learningSection = (0, learning_context_builder_js_1.buildLearningContextSection)(workspaceRoot, userEmail, true, jobDomain,
|
|
1935
|
+
const jobDomain = await this.resolveJobDomainForJob(jobName, requestSessionId);
|
|
1936
|
+
const learningSection = (0, learning_context_builder_js_1.buildLearningContextSection)(workspaceRoot, userEmail, true, jobDomain, (0, learning_context_builder_js_1.learningDomainsForWorkspace)(workspaceRoot));
|
|
1945
1937
|
const teamContextSection = (0, learning_context_builder_js_1.buildTeamContextSection)(workspaceRoot, true);
|
|
1946
1938
|
if (learningSection || teamContextSection) {
|
|
1947
1939
|
text += `\n\n---` + learningSection + teamContextSection;
|
|
@@ -1956,7 +1948,7 @@ class FraimLocalMCPServer {
|
|
|
1956
1948
|
* context must never break a job response, and an unknown job never guesses a
|
|
1957
1949
|
* wrong domain.
|
|
1958
1950
|
*/
|
|
1959
|
-
async resolveJobDomainForJob(jobName, requestSessionId
|
|
1951
|
+
async resolveJobDomainForJob(jobName, requestSessionId) {
|
|
1960
1952
|
try {
|
|
1961
1953
|
const resolver = this.getRegistryResolver(requestSessionId);
|
|
1962
1954
|
if (!resolver)
|
|
@@ -1964,9 +1956,7 @@ class FraimLocalMCPServer {
|
|
|
1964
1956
|
const registryPath = await resolver.findRegistryPath('jobs', jobName);
|
|
1965
1957
|
if (!registryPath)
|
|
1966
1958
|
return null;
|
|
1967
|
-
|
|
1968
|
-
const selected = (0, catalog_1.selectCatalogDomain)(catalog, registryPath);
|
|
1969
|
-
return selected.selection === 'mapped' && selected.domain !== 'global' ? selected.domain : null;
|
|
1959
|
+
return (0, folders_1.jobDomainFromRegistryPath)(registryPath);
|
|
1970
1960
|
}
|
|
1971
1961
|
catch {
|
|
1972
1962
|
return null;
|
|
@@ -2003,51 +1993,32 @@ class FraimLocalMCPServer {
|
|
|
2003
1993
|
}
|
|
2004
1994
|
return errors;
|
|
2005
1995
|
}
|
|
2006
|
-
async addRuleDelivery(request, response, sessionId
|
|
1996
|
+
async addRuleDelivery(request, response, sessionId) {
|
|
2007
1997
|
if (response.error || response.result?.isError || response.result?.personaLock || !response.result)
|
|
2008
1998
|
return response;
|
|
2009
1999
|
const tool = request.params?.name;
|
|
2010
2000
|
const args = request.params?.arguments || {};
|
|
2011
2001
|
let jobPath = null;
|
|
2012
2002
|
if (tool === 'get_fraim_job' || tool === 'seekMentoring') {
|
|
2003
|
+
if (tool === 'seekMentoring' && !(args.status === 'starting' && args.requestInstructions === true))
|
|
2004
|
+
return response;
|
|
2013
2005
|
const context = await this.getMentor(sessionId).getRuleDeliveryContext(args.job || args.jobName);
|
|
2014
2006
|
if (!context)
|
|
2015
2007
|
return response;
|
|
2016
2008
|
jobPath = context.jobPath;
|
|
2017
|
-
if (tool === 'seekMentoring' && !(args.status === 'starting' &&
|
|
2018
|
-
(args.currentPhase === 'starting' || args.currentPhase === context.initialPhase || args.requestInstructions === true)))
|
|
2019
|
-
return response;
|
|
2020
2009
|
}
|
|
2021
2010
|
else if (tool !== 'fraim_connect')
|
|
2022
2011
|
return response;
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
const block = Number.isInteger(prior?.contentBlockIndex) && prior.contentBlockIndex >= 0
|
|
2029
|
-
? response.result.content?.[prior.contentBlockIndex] : undefined;
|
|
2030
|
-
const artifact = Array.isArray(prior?.artifacts) && prior.artifacts.length === 1 ? prior.artifacts[0] : undefined;
|
|
2031
|
-
const prefix = '## Applicable rules\n\n### rules/constitution.md\n\n';
|
|
2032
|
-
if (prior?.complete === true && prior.selection === 'connect' && prior.domain === 'global'
|
|
2033
|
-
&& Array.isArray(prior.warnings) && prior.warnings.length === 0
|
|
2034
|
-
&& artifact?.path === 'rules/constitution.md' && block?.type === 'text'
|
|
2035
|
-
&& typeof block.text === 'string' && block.text.startsWith(prefix)) {
|
|
2036
|
-
const body = block.text.slice(prefix.length);
|
|
2037
|
-
if ((0, crypto_1.createHash)('sha256').update(body).digest('hex') === artifact?.hash)
|
|
2038
|
-
remoteFiles.set(artifact.path, body);
|
|
2039
|
-
}
|
|
2040
|
-
}
|
|
2041
|
-
const resolver = this.getRegistryResolver(sessionId, remoteFiles);
|
|
2042
|
-
const result = (0, domain_rule_assembler_1.attachRuleAssembly)(response.result, await (0, domain_rule_assembler_1.assembleDomainRules)({ jobPath,
|
|
2043
|
-
resolveFile: path => path === 'domains.json' && catalogRead ? catalogRead : resolver.resolveFile(path, { includeMetadata: false, stripMcpHeader: true }) }));
|
|
2044
|
-
const metadata = result.structuredContent?.ruleAssembly;
|
|
2045
|
-
for (const warning of metadata?.warnings ?? []) {
|
|
2012
|
+
const resolver = this.getRegistryResolver(sessionId);
|
|
2013
|
+
const assembly = await (0, domain_rule_assembler_1.assembleDomainRules)({ jobPath,
|
|
2014
|
+
resolveFile: path => resolver.resolveFile(path, { includeMetadata: false, stripMcpHeader: true }) });
|
|
2015
|
+
const result = (0, domain_rule_assembler_1.appendRuleInstructions)(response.result, assembly);
|
|
2016
|
+
for (const warning of assembly.metadata.warnings) {
|
|
2046
2017
|
this.logError('Rule delivery warning: ' + JSON.stringify(warning));
|
|
2047
2018
|
}
|
|
2048
2019
|
return { ...response, result };
|
|
2049
2020
|
}
|
|
2050
|
-
async finalizeLocalToolTextResponse(request, requestSessionId, requestId, text
|
|
2021
|
+
async finalizeLocalToolTextResponse(request, requestSessionId, requestId, text) {
|
|
2051
2022
|
const response = {
|
|
2052
2023
|
jsonrpc: '2.0',
|
|
2053
2024
|
id: request.id,
|
|
@@ -2055,7 +2026,7 @@ class FraimLocalMCPServer {
|
|
|
2055
2026
|
content: [{ type: 'text', text }]
|
|
2056
2027
|
}
|
|
2057
2028
|
};
|
|
2058
|
-
const withRules = await this.addRuleDelivery(request, response, requestSessionId
|
|
2029
|
+
const withRules = await this.addRuleDelivery(request, response, requestSessionId);
|
|
2059
2030
|
const withResolvedIncludes = await this.resolveIncludesInResponse(withRules, requestSessionId, requestId);
|
|
2060
2031
|
return this.processResponseWithHydration(withResolvedIncludes, requestSessionId);
|
|
2061
2032
|
}
|
|
@@ -2201,7 +2172,7 @@ class FraimLocalMCPServer {
|
|
|
2201
2172
|
/**
|
|
2202
2173
|
* Initialize the LocalRegistryResolver for override resolution
|
|
2203
2174
|
*/
|
|
2204
|
-
getRegistryResolver(requestSessionId
|
|
2175
|
+
getRegistryResolver(requestSessionId) {
|
|
2205
2176
|
const projectRoot = this.findProjectRoot();
|
|
2206
2177
|
this.log(`🔍 getRegistryResolver: projectRoot = ${projectRoot}`);
|
|
2207
2178
|
// Determine effective FRAIM dir using shadow semantics
|
|
@@ -2228,8 +2199,6 @@ class FraimLocalMCPServer {
|
|
|
2228
2199
|
orgCacheRoot: (0, pack_home_1.resolvePackHome)('org', { migrateLegacy: false }).contentRoot,
|
|
2229
2200
|
shouldFilter: (content) => this.isStub(content),
|
|
2230
2201
|
remoteContentResolver: async (path) => {
|
|
2231
|
-
if (remoteFiles?.has(path))
|
|
2232
|
-
return remoteFiles.get(path);
|
|
2233
2202
|
// Fetch parent content from remote for inheritance
|
|
2234
2203
|
this.log(`🔄 Remote content resolver: fetching ${path}`);
|
|
2235
2204
|
this.log(`🔄 Fetching raw file content: ${path}`);
|
|
@@ -2988,7 +2957,7 @@ class FraimLocalMCPServer {
|
|
|
2988
2957
|
return acceptedResponse;
|
|
2989
2958
|
const acceptedReceipt = this.persistAcceptedReceipt(args, requestSessionId, tutoringResponse, request.id);
|
|
2990
2959
|
const phaseStartWarning = this.acceptPhaseTracking(args, requestSessionId, tutoringResponse.nextPhase, !!acceptedReceipt);
|
|
2991
|
-
acceptedResponse.result.
|
|
2960
|
+
acceptedResponse.result._meta = { ...acceptedResponse.result._meta,
|
|
2992
2961
|
phaseAccepted: true, nextPhase: tutoringResponse.nextPhase, outcome: tutoringResponse.outcome,
|
|
2993
2962
|
workflowDigest: tutoringResponse.workflowDigest, ...(acceptedReceipt ? { acceptedReceipt } : {}) };
|
|
2994
2963
|
if (phaseStartWarning && acceptedResponse.result?.content?.[0]) {
|
|
@@ -3026,9 +2995,8 @@ class FraimLocalMCPServer {
|
|
|
3026
2995
|
responseText = `${mentor.getCompactPhaseAuthority()}\n\n${responseText}`;
|
|
3027
2996
|
responseText += `\n\n---\n\n**Job ID:** \`${jobId}\`\n\n**This job has phases.** Use \`seekMentoring\` with the jobId above to get phase-specific instructions.`;
|
|
3028
2997
|
}
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
return await this.finalizeLocalToolTextResponse(request, requestSessionId, requestId, responseText, catalogRead);
|
|
2998
|
+
responseText = await this.appendJobContext(responseText, name, requestSessionId, requestId);
|
|
2999
|
+
return await this.finalizeLocalToolTextResponse(request, requestSessionId, requestId, responseText);
|
|
3032
3000
|
}
|
|
3033
3001
|
}
|
|
3034
3002
|
catch (error) {
|
|
@@ -3126,8 +3094,8 @@ class FraimLocalMCPServer {
|
|
|
3126
3094
|
// Reconcile remote fallback against the same persisted local instance.
|
|
3127
3095
|
// Only the remote's explicit accepted result can consume a start.
|
|
3128
3096
|
if (toolName === 'seekMentoring' && !processedResponse.error && !processedResponse.result?.isError
|
|
3129
|
-
&& response.result?.
|
|
3130
|
-
const metadata = response.result.
|
|
3097
|
+
&& response.result?._meta?.phaseAccepted === true) {
|
|
3098
|
+
const metadata = response.result._meta;
|
|
3131
3099
|
let acceptedReceipt;
|
|
3132
3100
|
if (metadata.acceptedReceipt) {
|
|
3133
3101
|
const remote = metadata.acceptedReceipt;
|
|
@@ -3146,7 +3114,7 @@ class FraimLocalMCPServer {
|
|
|
3146
3114
|
catch (error) {
|
|
3147
3115
|
return { jsonrpc: '2.0', id: request.id, result: { isError: true, content: [{ type: 'text', text: `Phase acceptance failed: ${error.message}` }] } };
|
|
3148
3116
|
}
|
|
3149
|
-
processedResponse.result.
|
|
3117
|
+
processedResponse.result._meta = { ...processedResponse.result._meta, ...(acceptedReceipt ? { acceptedReceipt } : {}) };
|
|
3150
3118
|
}
|
|
3151
3119
|
const textBlock = processedResponse.result?.content?.find((item) => item.type === 'text');
|
|
3152
3120
|
if (textBlock) {
|
|
@@ -3385,7 +3353,7 @@ class FraimLocalMCPServer {
|
|
|
3385
3353
|
const requestSessionId = this.extractSessionIdFromRequest(request);
|
|
3386
3354
|
if (toolName && requestSessionId) {
|
|
3387
3355
|
const success = !response.error && !response.result?.isError;
|
|
3388
|
-
let acceptedPhaseResponse = success && response.result?.
|
|
3356
|
+
let acceptedPhaseResponse = success && response.result?._meta?.phaseAccepted === true;
|
|
3389
3357
|
this.log(`📊 Collecting usage: ${toolName} (session: ${requestSessionId}, success: ${success})`);
|
|
3390
3358
|
if (!this.repoInfo) {
|
|
3391
3359
|
this.detectRepoInfo();
|
|
@@ -238,12 +238,12 @@ class McpService {
|
|
|
238
238
|
case 'get_fraim_job':
|
|
239
239
|
if (!args.job)
|
|
240
240
|
throw new Error('Argument "job" is required for get_fraim_job');
|
|
241
|
-
return await this.handleGetJob(args.job, context.apiKey, context.userId);
|
|
241
|
+
return await this.handleGetJob(args.job, context.apiKey, context.userId, !!context.localMcpVersion && context.localMcpVersion !== 'unknown');
|
|
242
242
|
case 'seekMentoring':
|
|
243
243
|
if (!args.jobName || !args.issueNumber || !args.currentPhase || !args.status) {
|
|
244
244
|
throw new Error('Arguments "jobName", "issueNumber", "currentPhase", and "status" are required for seekMentoring');
|
|
245
245
|
}
|
|
246
|
-
return await this.handleSeekMentoring(args, context.userId);
|
|
246
|
+
return await this.handleSeekMentoring(args, context.userId, !!context.localMcpVersion && context.localMcpVersion !== 'unknown');
|
|
247
247
|
case 'list_fraim_jobs':
|
|
248
248
|
return await this.handleListJobs();
|
|
249
249
|
case 'file_fraim_github_issue':
|
|
@@ -327,7 +327,7 @@ class McpService {
|
|
|
327
327
|
throw new Error(`Failed to read file: ${error.message}`);
|
|
328
328
|
}
|
|
329
329
|
}
|
|
330
|
-
async handleGetJob(jobName, apiKey, userId) {
|
|
330
|
+
async handleGetJob(jobName, apiKey, userId, localProxy = false) {
|
|
331
331
|
let effectiveUserId = userId;
|
|
332
332
|
if (!effectiveUserId && apiKey) {
|
|
333
333
|
try {
|
|
@@ -424,7 +424,7 @@ class McpService {
|
|
|
424
424
|
}
|
|
425
425
|
return this.addRuleDelivery({
|
|
426
426
|
content: [{ type: 'text', text: response }]
|
|
427
|
-
}, jobName);
|
|
427
|
+
}, jobName, undefined, localProxy);
|
|
428
428
|
}
|
|
429
429
|
async handleListJobs() {
|
|
430
430
|
const jobs = Array.from(this.registryService.getFileIndex().values()).filter((f) => f.type === 'job' && !f.isStub);
|
|
@@ -577,7 +577,7 @@ class McpService {
|
|
|
577
577
|
type: 'text',
|
|
578
578
|
text: lines.join('\n')
|
|
579
579
|
}],
|
|
580
|
-
|
|
580
|
+
_meta: {
|
|
581
581
|
sessionId,
|
|
582
582
|
userId: session.userId,
|
|
583
583
|
agent: session.agent,
|
|
@@ -585,7 +585,7 @@ class McpService {
|
|
|
585
585
|
repo: session.repo
|
|
586
586
|
},
|
|
587
587
|
sessionId: sessionId
|
|
588
|
-
});
|
|
588
|
+
}, undefined, undefined, isLocalProxyCall);
|
|
589
589
|
}
|
|
590
590
|
validateIssueTrackingConfig(issueTracking) {
|
|
591
591
|
if (!issueTracking.provider) {
|
|
@@ -705,7 +705,7 @@ class McpService {
|
|
|
705
705
|
}
|
|
706
706
|
};
|
|
707
707
|
}
|
|
708
|
-
async handleSeekMentoring(args, userId) {
|
|
708
|
+
async handleSeekMentoring(args, userId, localProxy = false) {
|
|
709
709
|
const restoringInstructions = args.status === 'starting' && args.requestInstructions === true;
|
|
710
710
|
const personaLock = await this.maybeBuildPersonaLockResponse(args.jobName, userId, undefined, args.status === 'starting' && !restoringInstructions);
|
|
711
711
|
if (personaLock) {
|
|
@@ -900,8 +900,8 @@ class McpService {
|
|
|
900
900
|
type: 'text',
|
|
901
901
|
text: trackingWarning + phaseStartWarning + result.message
|
|
902
902
|
}],
|
|
903
|
-
|
|
904
|
-
}, args.jobName, args);
|
|
903
|
+
_meta: { phaseAccepted: true, nextPhase: result.nextPhase, phaseStartWarning }
|
|
904
|
+
}, args.jobName, args, localProxy);
|
|
905
905
|
if (!finalized.isError && !restoringInstructions && result.outcome && result.workflowDigest && sessionId) {
|
|
906
906
|
// Remote-only execution has no trusted Hub binding. The executing local
|
|
907
907
|
// proxy verifies this envelope and supplies its own launch binding.
|
|
@@ -912,25 +912,25 @@ class McpService {
|
|
|
912
912
|
executionEpoch: sessionId, phaseId: args.currentPhase, requestedStatus: args.status,
|
|
913
913
|
outcome: result.outcome.kind, ...(result.nextPhase ? { nextPhase: result.nextPhase } : {}), verifiedEvidenceRefs: [],
|
|
914
914
|
};
|
|
915
|
-
finalized.
|
|
915
|
+
finalized._meta = { ...finalized._meta, acceptedReceipt, outcome: result.outcome, workflowDigest: result.workflowDigest };
|
|
916
916
|
}
|
|
917
917
|
return finalized;
|
|
918
918
|
}
|
|
919
|
-
async addRuleDelivery(response, jobName, phaseArgs) {
|
|
920
|
-
if (response.isError || response.personaLock)
|
|
919
|
+
async addRuleDelivery(response, jobName, phaseArgs, localProxy = false) {
|
|
920
|
+
if (localProxy || response.isError || response.personaLock)
|
|
921
|
+
return response;
|
|
922
|
+
if (phaseArgs && !(phaseArgs.status === 'starting' && phaseArgs.requestInstructions === true))
|
|
921
923
|
return response;
|
|
922
924
|
const context = jobName ? await this.aiMentor.getRuleDeliveryContext(jobName) : null;
|
|
923
925
|
if (jobName && !context)
|
|
924
926
|
return response;
|
|
925
|
-
if (phaseArgs && !(phaseArgs.status === 'starting' && (phaseArgs.currentPhase === 'starting' || phaseArgs.currentPhase === context?.initialPhase || phaseArgs.requestInstructions === true)))
|
|
926
|
-
return response;
|
|
927
927
|
const assembly = await (0, domain_rule_assembler_1.assembleDomainRules)({ jobPath: context?.jobPath, resolveFile: async (path) => {
|
|
928
928
|
const content = await this.registryService.getFile(path);
|
|
929
929
|
if (content === null)
|
|
930
930
|
throw new Error(`Rule source unavailable: ${path}`);
|
|
931
931
|
return { content, source: 'remote', personalized: false, inherited: false };
|
|
932
932
|
} });
|
|
933
|
-
const result = (0, domain_rule_assembler_1.
|
|
933
|
+
const result = (0, domain_rule_assembler_1.appendRuleInstructions)(response, assembly);
|
|
934
934
|
for (const warning of assembly.metadata.warnings) {
|
|
935
935
|
console.warn('Rule delivery warning:', JSON.stringify(warning));
|
|
936
936
|
}
|
|
@@ -308,10 +308,6 @@ class RegistryService {
|
|
|
308
308
|
}
|
|
309
309
|
getSyncBundle() {
|
|
310
310
|
const files = [];
|
|
311
|
-
const domainCatalog = (0, path_1.join)(this.registryPath, 'domains.json');
|
|
312
|
-
if ((0, fs_1.existsSync)(domainCatalog)) {
|
|
313
|
-
files.push({ path: 'domains.json', content: (0, fs_1.readFileSync)(domainCatalog, 'utf8'), type: 'config' });
|
|
314
|
-
}
|
|
315
311
|
const allFiles = Array.from(this.fileIndex.values());
|
|
316
312
|
// 1. Add job STUBS (not full jobs) from registry/stubs/jobs
|
|
317
313
|
const jobStubs = allFiles.filter(f => f.type === 'job' && f.path.includes('stubs/jobs/'));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fraim",
|
|
3
|
-
"version": "2.0.362
|
|
3
|
+
"version": "2.0.362",
|
|
4
4
|
"description": "FRAIM core CLI and MCP package.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"dist/registry/scripts/artifact-paths.js",
|
|
11
11
|
"dist/registry/scripts/learning-usage/local-runtime.js",
|
|
12
|
-
"dist/registry/
|
|
13
|
-
"dist/registry/scripts/domains/
|
|
12
|
+
"dist/registry/stubs/jobs/",
|
|
13
|
+
"dist/registry/scripts/domains/folders.js",
|
|
14
14
|
"dist/registry/scripts/learning/entry-format.js",
|
|
15
15
|
"dist/registry/scripts/learning/completion-state.js",
|
|
16
16
|
"dist/registry/scripts/learning/corpus-audit.js",
|