@howlil/ez-agents 3.5.0 → 4.0.0
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/README.md +735 -537
- package/agents/ez-architect-agent.md +267 -0
- package/agents/ez-backend-agent.md +303 -0
- package/agents/ez-chief-strategist.md +271 -0
- package/agents/ez-codebase-mapper.md +770 -770
- package/agents/ez-context-manager.md +319 -0
- package/agents/ez-debugger.md +1255 -1255
- package/agents/ez-design-expert.md +347 -0
- package/agents/ez-devops-agent.md +331 -0
- package/agents/ez-executor.md +487 -487
- package/agents/ez-frontend-agent.md +322 -0
- package/agents/ez-phase-researcher.md +553 -553
- package/agents/ez-planner.md +1307 -1307
- package/agents/ez-product-engineer.md +435 -0
- package/agents/ez-project-researcher.md +629 -629
- package/agents/ez-qa-agent.md +320 -0
- package/agents/ez-release-agent.md +333 -333
- package/agents/ez-requirements-agent.md +377 -377
- package/agents/ez-roadmapper.md +650 -650
- package/agents/ez-technical-writer.md +551 -0
- package/agents/ez-ux-expert.md +393 -0
- package/agents/ez-verifier.md +579 -579
- package/bin/guards/autonomy-guard.cjs +346 -0
- package/bin/guards/context-budget-guard.cjs +278 -0
- package/bin/guards/hallucination-guard.cjs +380 -0
- package/bin/guards/hidden-state-guard.cjs +182 -0
- package/bin/guards/team-overhead-guard.cjs +266 -0
- package/bin/guards/tool-sprawl-guard.cjs +271 -0
- package/bin/lib/analytics/analytics-collector.cjs +86 -0
- package/bin/lib/analytics/analytics-reporter.cjs +130 -0
- package/bin/lib/analytics/cohort-analyzer.cjs +138 -0
- package/bin/lib/analytics/funnel-analyzer.cjs +147 -0
- package/bin/lib/analytics/nps-tracker.cjs +147 -0
- package/bin/lib/archetype-detector.cjs +289 -0
- package/bin/lib/assistant-adapter.cjs +361 -0
- package/bin/lib/audit-exec.cjs +175 -0
- package/bin/lib/auth.cjs +176 -0
- package/bin/lib/backup-service.cjs +422 -0
- package/bin/lib/bdd-validator.cjs +622 -0
- package/bin/lib/business-flow-mapper.cjs +429 -0
- package/bin/lib/circuit-breaker.cjs +276 -0
- package/bin/lib/code-complexity-analyzer.cjs +360 -0
- package/bin/lib/codebase-analyzer.cjs +241 -0
- package/bin/lib/commands.cjs +691 -0
- package/bin/lib/config.cjs +236 -0
- package/bin/lib/constraint-extractor.cjs +526 -0
- package/bin/lib/content-scanner.cjs +238 -0
- package/bin/lib/context-cache.cjs +154 -0
- package/bin/lib/context-compressor.cjs +102 -0
- package/bin/lib/context-deduplicator.cjs +105 -0
- package/bin/lib/context-errors.cjs +78 -0
- package/bin/lib/context-manager.cjs +338 -0
- package/bin/lib/context-metadata-tracker.cjs +140 -0
- package/bin/lib/context-relevance-scorer.cjs +99 -0
- package/bin/lib/core.cjs +507 -0
- package/bin/lib/cost-alerts.cjs +174 -0
- package/bin/lib/cost-tracker.cjs +275 -0
- package/bin/lib/crash-recovery.cjs +220 -0
- package/bin/lib/dependency-graph.cjs +319 -0
- package/bin/lib/deploy/deploy-audit-log.cjs +76 -0
- package/bin/lib/deploy/deploy-detector.cjs +69 -0
- package/bin/lib/deploy/deploy-env-manager.cjs +109 -0
- package/bin/lib/deploy/deploy-health-check.cjs +88 -0
- package/bin/lib/deploy/deploy-pre-flight.cjs +57 -0
- package/bin/lib/deploy/deploy-rollback.cjs +72 -0
- package/bin/lib/deploy/deploy-runner.cjs +97 -0
- package/bin/lib/deploy/deploy-status.cjs +74 -0
- package/bin/lib/discussion-synthesizer.cjs +439 -0
- package/bin/lib/error-cache.cjs +114 -0
- package/bin/lib/error-registry.cjs +177 -0
- package/bin/lib/file-access.cjs +207 -0
- package/bin/lib/file-lock.cjs +236 -0
- package/bin/lib/finops/budget-enforcer.cjs +126 -0
- package/bin/lib/finops/cost-reporter.cjs +132 -0
- package/bin/lib/finops/finops-analyzer.cjs +112 -0
- package/bin/lib/finops/spot-manager.cjs +118 -0
- package/bin/lib/framework-detector.cjs +396 -0
- package/bin/lib/frontmatter.cjs +313 -0
- package/bin/lib/fs-utils.cjs +153 -0
- package/bin/lib/gate-executor.cjs +272 -0
- package/bin/lib/gates/README.md +374 -0
- package/bin/lib/gates/gate-01-requirement.cjs +303 -0
- package/bin/lib/gates/gate-02-architecture.cjs +555 -0
- package/bin/lib/gates/gate-03-code.cjs +635 -0
- package/bin/lib/gates/gate-04-security.cjs +829 -0
- package/bin/lib/git-errors.cjs +83 -0
- package/bin/lib/git-utils.cjs +321 -0
- package/bin/lib/git-workflow-engine.cjs +1157 -0
- package/bin/lib/health-check.cjs +227 -0
- package/bin/lib/index.cjs +279 -0
- package/bin/lib/init.cjs +725 -0
- package/bin/lib/lock-logger.cjs +194 -0
- package/bin/lib/lock-state.cjs +263 -0
- package/bin/lib/lockfile-validator.cjs +227 -0
- package/bin/lib/log-rotation.cjs +71 -0
- package/bin/lib/logger.cjs +125 -0
- package/bin/lib/memory-compression.cjs +256 -0
- package/bin/lib/milestone.cjs +247 -0
- package/bin/lib/model-provider.cjs +241 -0
- package/bin/lib/package-manager-detector.cjs +203 -0
- package/bin/lib/package-manager-executor.cjs +385 -0
- package/bin/lib/package-manager-service.cjs +216 -0
- package/bin/lib/perf/api-monitor.cjs +88 -0
- package/bin/lib/perf/db-optimizer.cjs +78 -0
- package/bin/lib/perf/frontend-performance.cjs +56 -0
- package/bin/lib/perf/perf-analyzer.cjs +77 -0
- package/bin/lib/perf/perf-baseline.cjs +102 -0
- package/bin/lib/perf/perf-reporter.cjs +117 -0
- package/bin/lib/perf/regression-detector.cjs +92 -0
- package/bin/lib/phase.cjs +963 -0
- package/bin/lib/planning-write.cjs +123 -0
- package/bin/lib/project-reporter.cjs +565 -0
- package/bin/lib/quality-gate.cjs +332 -0
- package/bin/lib/quality-metrics.cjs +324 -0
- package/bin/lib/recovery-manager.cjs +98 -0
- package/bin/lib/release-validator.cjs +617 -0
- package/bin/lib/retry.cjs +119 -0
- package/bin/lib/roadmap.cjs +309 -0
- package/bin/lib/safe-exec.cjs +173 -0
- package/bin/lib/safe-path.cjs +130 -0
- package/bin/lib/security-errors.cjs +62 -0
- package/bin/lib/session-chain.cjs +304 -0
- package/bin/lib/session-errors.cjs +81 -0
- package/bin/lib/session-export.cjs +251 -0
- package/bin/lib/session-import.cjs +262 -0
- package/bin/lib/session-manager.cjs +280 -0
- package/bin/lib/skill-context.cjs +148 -0
- package/bin/lib/skill-matcher.cjs +236 -0
- package/bin/lib/skill-registry.cjs +360 -0
- package/bin/lib/skill-resolver.cjs +449 -0
- package/bin/lib/skill-triggers.cjs +90 -0
- package/bin/lib/skill-validator.cjs +270 -0
- package/bin/lib/skill-versioning.cjs +355 -0
- package/bin/lib/stack-detector.cjs +399 -0
- package/bin/lib/state.cjs +736 -0
- package/bin/lib/tech-debt-analyzer.cjs +309 -0
- package/bin/lib/temp-file.cjs +239 -0
- package/bin/lib/template.cjs +223 -0
- package/bin/lib/test-file-lock.cjs +112 -0
- package/bin/lib/test-graceful.cjs +93 -0
- package/bin/lib/test-logger.cjs +60 -0
- package/bin/lib/test-safe-exec.cjs +38 -0
- package/bin/lib/test-safe-path.cjs +33 -0
- package/bin/lib/test-temp-file.cjs +125 -0
- package/bin/lib/tier-manager.cjs +428 -0
- package/bin/lib/timeout-exec.cjs +63 -0
- package/bin/lib/tradeoff-analyzer.cjs +284 -0
- package/bin/lib/url-fetch.cjs +170 -0
- package/bin/lib/verify.cjs +863 -0
- package/bin/update.js +217 -214
- package/commands/deploy.cjs +53 -0
- package/commands/ez/add-tests.md +41 -41
- package/commands/ez/audit-milestone.md +36 -36
- package/commands/ez/complete-milestone.md +136 -136
- package/commands/ez/discuss-phase.md +90 -90
- package/commands/ez/execute-phase.md +52 -52
- package/commands/ez/help.md +22 -22
- package/commands/ez/map-codebase.md +71 -71
- package/commands/ez/new-milestone.md +44 -44
- package/commands/ez/new-project.md +51 -42
- package/commands/ez/plan-phase.md +53 -53
- package/commands/ez/progress.md +36 -36
- package/commands/ez/quick.md +45 -45
- package/commands/ez/resume-work.md +40 -40
- package/commands/ez/run-phase.md +580 -0
- package/commands/ez/settings.md +36 -36
- package/commands/ez/update.md +37 -37
- package/commands/ez/verify-work.md +402 -38
- package/commands/health-check.cjs +44 -0
- package/commands/rollback.cjs +47 -0
- package/ez-agents/bin/ez-tools.cjs +599 -2
- package/ez-agents/bin/guards/autonomy-guard.cjs +346 -0
- package/ez-agents/bin/guards/context-budget-guard.cjs +247 -0
- package/ez-agents/bin/guards/hallucination-guard.cjs +271 -0
- package/ez-agents/bin/guards/hidden-state-guard.cjs +182 -0
- package/ez-agents/bin/guards/team-overhead-guard.cjs +266 -0
- package/ez-agents/bin/guards/tool-sprawl-guard.cjs +271 -0
- package/ez-agents/bin/lib/analytics/analytics-collector.cjs +86 -0
- package/ez-agents/bin/lib/analytics/analytics-reporter.cjs +130 -0
- package/ez-agents/bin/lib/analytics/cohort-analyzer.cjs +138 -0
- package/ez-agents/bin/lib/analytics/funnel-analyzer.cjs +147 -0
- package/ez-agents/bin/lib/analytics/nps-tracker.cjs +147 -0
- package/ez-agents/bin/lib/archetype-detector.cjs +289 -0
- package/ez-agents/bin/lib/audit-exec.cjs +166 -167
- package/ez-agents/bin/lib/auth.cjs +176 -176
- package/ez-agents/bin/lib/backup-service.cjs +422 -0
- package/ez-agents/bin/lib/bdd-validator.cjs +622 -622
- package/ez-agents/bin/lib/business-flow-mapper.cjs +429 -0
- package/ez-agents/bin/lib/code-complexity-analyzer.cjs +360 -0
- package/ez-agents/bin/lib/codebase-analyzer.cjs +241 -0
- package/ez-agents/bin/lib/commands.cjs +685 -685
- package/ez-agents/bin/lib/config.cjs +41 -1
- package/ez-agents/bin/lib/constraint-extractor.cjs +526 -0
- package/ez-agents/bin/lib/content-scanner.cjs +238 -238
- package/ez-agents/bin/lib/context-cache.cjs +154 -154
- package/ez-agents/bin/lib/context-errors.cjs +71 -71
- package/ez-agents/bin/lib/context-manager.cjs +220 -220
- package/ez-agents/bin/lib/core.cjs +507 -512
- package/ez-agents/bin/lib/cost-tracker.cjs +243 -0
- package/ez-agents/bin/lib/crash-recovery.cjs +172 -0
- package/ez-agents/bin/lib/dependency-graph.cjs +319 -0
- package/ez-agents/bin/lib/deploy/deploy-audit-log.cjs +76 -0
- package/ez-agents/bin/lib/deploy/deploy-detector.cjs +69 -0
- package/ez-agents/bin/lib/deploy/deploy-env-manager.cjs +109 -0
- package/ez-agents/bin/lib/deploy/deploy-health-check.cjs +88 -0
- package/ez-agents/bin/lib/deploy/deploy-pre-flight.cjs +57 -0
- package/ez-agents/bin/lib/deploy/deploy-rollback.cjs +72 -0
- package/ez-agents/bin/lib/deploy/deploy-runner.cjs +97 -0
- package/ez-agents/bin/lib/deploy/deploy-status.cjs +74 -0
- package/ez-agents/bin/lib/file-access.cjs +207 -207
- package/ez-agents/bin/lib/finops/budget-enforcer.cjs +126 -0
- package/ez-agents/bin/lib/finops/cost-reporter.cjs +132 -0
- package/ez-agents/bin/lib/finops/finops-analyzer.cjs +112 -0
- package/ez-agents/bin/lib/finops/spot-manager.cjs +118 -0
- package/ez-agents/bin/lib/framework-detector.cjs +396 -0
- package/ez-agents/bin/lib/frontmatter.cjs +3 -1
- package/ez-agents/bin/lib/gates/README.md +374 -0
- package/ez-agents/bin/lib/gates/gate-01-requirement.cjs +303 -0
- package/ez-agents/bin/lib/gates/gate-02-architecture.cjs +555 -0
- package/ez-agents/bin/lib/gates/gate-03-code.cjs +635 -0
- package/ez-agents/bin/lib/gates/gate-04-security.cjs +829 -0
- package/ez-agents/bin/lib/git-errors.cjs +83 -83
- package/ez-agents/bin/lib/git-utils.cjs +321 -321
- package/ez-agents/bin/lib/git-workflow-engine.cjs +1157 -1157
- package/ez-agents/bin/lib/health-check.cjs +162 -162
- package/ez-agents/bin/lib/index.cjs +2 -8
- package/ez-agents/bin/lib/init.cjs +0 -2
- package/ez-agents/bin/lib/lockfile-validator.cjs +227 -227
- package/ez-agents/bin/lib/log-rotation.cjs +71 -0
- package/ez-agents/bin/lib/logger.cjs +22 -47
- package/ez-agents/bin/lib/memory-compression.cjs +256 -256
- package/ez-agents/bin/lib/package-manager-detector.cjs +203 -203
- package/ez-agents/bin/lib/package-manager-executor.cjs +385 -385
- package/ez-agents/bin/lib/package-manager-service.cjs +216 -216
- package/ez-agents/bin/lib/perf/api-monitor.cjs +88 -0
- package/ez-agents/bin/lib/perf/db-optimizer.cjs +78 -0
- package/ez-agents/bin/lib/perf/frontend-performance.cjs +56 -0
- package/ez-agents/bin/lib/perf/perf-analyzer.cjs +77 -0
- package/ez-agents/bin/lib/perf/perf-baseline.cjs +102 -0
- package/ez-agents/bin/lib/perf/perf-reporter.cjs +117 -0
- package/ez-agents/bin/lib/perf/regression-detector.cjs +92 -0
- package/ez-agents/bin/lib/project-reporter.cjs +502 -0
- package/ez-agents/bin/lib/quality-gate.cjs +332 -0
- package/ez-agents/bin/lib/recovery-manager.cjs +98 -0
- package/ez-agents/bin/lib/release-validator.cjs +617 -614
- package/ez-agents/bin/lib/security-errors.cjs +62 -0
- package/ez-agents/bin/lib/session-chain.cjs +304 -304
- package/ez-agents/bin/lib/session-errors.cjs +81 -81
- package/ez-agents/bin/lib/session-export.cjs +251 -251
- package/ez-agents/bin/lib/session-import.cjs +262 -262
- package/ez-agents/bin/lib/session-manager.cjs +280 -280
- package/ez-agents/bin/lib/skill-context.cjs +148 -0
- package/ez-agents/bin/lib/skill-matcher.cjs +236 -0
- package/ez-agents/bin/lib/skill-registry.cjs +341 -0
- package/ez-agents/bin/lib/skill-resolver.cjs +449 -0
- package/ez-agents/bin/lib/skill-triggers.cjs +90 -0
- package/ez-agents/bin/lib/skill-validator.cjs +270 -0
- package/ez-agents/bin/lib/skill-versioning.cjs +355 -0
- package/ez-agents/bin/lib/stack-detector.cjs +399 -0
- package/ez-agents/bin/lib/tech-debt-analyzer.cjs +309 -0
- package/ez-agents/bin/lib/tier-manager.cjs +428 -428
- package/ez-agents/bin/lib/tradeoff-analyzer.cjs +284 -0
- package/ez-agents/bin/lib/url-fetch.cjs +170 -170
- package/ez-agents/bin/lib/verify.cjs +863 -863
- package/ez-agents/references/decimal-phase-calculation.md +65 -65
- package/ez-agents/references/git-integration.md +248 -248
- package/ez-agents/references/git-planning-commit.md +38 -38
- package/ez-agents/references/metrics-schema.md +118 -118
- package/ez-agents/references/model-profile-resolution.md +34 -34
- package/ez-agents/references/model-profiles.md +93 -93
- package/ez-agents/references/phase-argument-parsing.md +61 -61
- package/ez-agents/references/planning-config.md +340 -340
- package/ez-agents/references/tier-strategy.md +103 -103
- package/ez-agents/references/ui-brand.md +160 -160
- package/ez-agents/references/verification-patterns.md +612 -612
- package/ez-agents/templates/DEBUG.md +164 -164
- package/ez-agents/templates/UAT.md +247 -247
- package/ez-agents/templates/agent-output-format.md +404 -0
- package/ez-agents/templates/bdd-feature.md +173 -173
- package/ez-agents/templates/codebase/architecture.md +255 -255
- package/ez-agents/templates/codebase/structure.md +285 -285
- package/ez-agents/templates/copilot-instructions.md +7 -7
- package/ez-agents/templates/debug-subagent-prompt.md +91 -91
- package/ez-agents/templates/discovery.md +146 -146
- package/ez-agents/templates/discussion.md +68 -68
- package/ez-agents/templates/handoff-protocol.md +294 -0
- package/ez-agents/templates/incident-runbook.md +205 -205
- package/ez-agents/templates/mode-workflow-templates.md +301 -0
- package/ez-agents/templates/phase-prompt.md +610 -610
- package/ez-agents/templates/planner-subagent-prompt.md +117 -117
- package/ez-agents/templates/project.md +184 -184
- package/ez-agents/templates/release-checklist.md +136 -133
- package/ez-agents/templates/research.md +552 -552
- package/ez-agents/templates/rollback-plan.md +201 -201
- package/ez-agents/templates/security-user-setup.md +244 -0
- package/ez-agents/templates/skill-validation-rules.md +476 -0
- package/ez-agents/templates/state.md +180 -176
- package/ez-agents/templates/summary-complex.md +59 -59
- package/ez-agents/tests/gates/gate-01-02.test.cjs +812 -0
- package/ez-agents/tests/gates/gate-03-04.test.cjs +762 -0
- package/ez-agents/tests/gates/gate-05-validator.test.cjs +145 -0
- package/ez-agents/tests/gates/gate-06-docs-validator.test.cjs +244 -0
- package/ez-agents/tests/gates/gate-07-release-validator.test.cjs +219 -0
- package/ez-agents/tests/guards/context-budget-guard.test.cjs +145 -0
- package/ez-agents/tests/guards/edge-case-guards.test.cjs +238 -0
- package/ez-agents/tests/guards/hallucination-guard.test.cjs +124 -0
- package/ez-agents/workflows/audit-milestone.md +1 -1
- package/ez-agents/workflows/autonomous.md +844 -844
- package/ez-agents/workflows/complete-milestone.md +1 -1
- package/ez-agents/workflows/discuss-phase.md +1 -1
- package/ez-agents/workflows/execute-phase.md +124 -3
- package/ez-agents/workflows/help.md +42 -181
- package/ez-agents/workflows/hotfix.md +291 -291
- package/ez-agents/workflows/new-milestone.md +713 -713
- package/ez-agents/workflows/new-project.md +1089 -1107
- package/ez-agents/workflows/plan-phase.md +0 -40
- package/ez-agents/workflows/release.md +253 -253
- package/ez-agents/workflows/resume-session.md +215 -215
- package/ez-agents/workflows/run-phase.md +531 -0
- package/ez-agents/workflows/settings.md +2 -35
- package/hooks/dist/ez-check-update.js +81 -81
- package/hooks/dist/ez-context-monitor.js +148 -141
- package/hooks/dist/ez-statusline.js +115 -115
- package/package.json +78 -71
- package/scripts/fix-qwen-installation.js +144 -144
- package/agents/ez-integration-checker.md +0 -443
- package/agents/ez-nyquist-auditor.md +0 -176
- package/agents/ez-observer-agent.md +0 -260
- package/agents/ez-plan-checker.md +0 -706
- package/agents/ez-research-synthesizer.md +0 -247
- package/agents/ez-scrum-master-agent.md +0 -242
- package/agents/ez-tech-lead-agent.md +0 -267
- package/agents/ez-ui-auditor.md +0 -439
- package/agents/ez-ui-checker.md +0 -300
- package/agents/ez-ui-researcher.md +0 -353
- package/commands/ez/add-phase.md +0 -43
- package/commands/ez/add-todo.md +0 -47
- package/commands/ez/arch-review.md +0 -102
- package/commands/ez/auth.md +0 -87
- package/commands/ez/autonomous.md +0 -41
- package/commands/ez/check-todos.md +0 -45
- package/commands/ez/cleanup.md +0 -18
- package/commands/ez/debug.md +0 -168
- package/commands/ez/export-session.md +0 -79
- package/commands/ez/gather-requirements.md +0 -117
- package/commands/ez/git-workflow.md +0 -72
- package/commands/ez/health.md +0 -22
- package/commands/ez/hotfix.md +0 -120
- package/commands/ez/import-session.md +0 -82
- package/commands/ez/insert-phase.md +0 -32
- package/commands/ez/join-discord.md +0 -18
- package/commands/ez/list-phase-assumptions.md +0 -46
- package/commands/ez/list-sessions.md +0 -96
- package/commands/ez/package-manager.md +0 -316
- package/commands/ez/pause-work.md +0 -38
- package/commands/ez/plan-milestone-gaps.md +0 -34
- package/commands/ez/preflight.md +0 -79
- package/commands/ez/reapply-patches.md +0 -124
- package/commands/ez/release.md +0 -153
- package/commands/ez/remove-phase.md +0 -31
- package/commands/ez/research-phase.md +0 -190
- package/commands/ez/resume.md +0 -107
- package/commands/ez/set-profile.md +0 -34
- package/commands/ez/standup.md +0 -85
- package/commands/ez/stats.md +0 -18
- package/commands/ez/ui-phase.md +0 -34
- package/commands/ez/ui-review.md +0 -32
- package/commands/ez/validate-phase.md +0 -35
- package/ez-agents/bin/lib/metrics-tracker.cjs +0 -406
- package/ez-agents/templates/UI-SPEC.md +0 -100
- package/ez-agents/templates/VALIDATION.md +0 -76
- package/ez-agents/templates/context.md +0 -352
- package/ez-agents/templates/verification-report.md +0 -322
- package/ez-agents/workflows/arch-review.md +0 -54
- package/ez-agents/workflows/export-session.md +0 -255
- package/ez-agents/workflows/gather-requirements.md +0 -206
- package/ez-agents/workflows/import-session.md +0 -303
- package/ez-agents/workflows/research-phase.md +0 -74
- package/ez-agents/workflows/standup.md +0 -64
- package/ez-agents/workflows/ui-phase.md +0 -290
- package/ez-agents/workflows/ui-review.md +0 -157
- package/ez-agents/workflows/validate-phase.md +0 -167
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Context Manager
|
|
5
|
+
*
|
|
6
|
+
* Orchestrates context gathering from files and URLs.
|
|
7
|
+
* Aggregates content, tracks sources, and updates STATE.md with context metadata.
|
|
8
|
+
* Enhanced with context optimization: scoring, compression, deduplication, and metadata tracking.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const FileAccessService = require('./file-access.cjs');
|
|
14
|
+
const URLFetchService = require('./url-fetch.cjs');
|
|
15
|
+
const ContentSecurityScanner = require('./content-scanner.cjs');
|
|
16
|
+
const ContextCache = require('./context-cache.cjs');
|
|
17
|
+
const { SecurityScanError, FileAccessError, URLFetchError } = require('./context-errors.cjs');
|
|
18
|
+
const ContextRelevanceScorer = require('./context-relevance-scorer.cjs');
|
|
19
|
+
const ContextCompressor = require('./context-compressor.cjs');
|
|
20
|
+
const ContextDeduplicator = require('./context-deduplicator.cjs');
|
|
21
|
+
const ContextMetadataTracker = require('./context-metadata-tracker.cjs');
|
|
22
|
+
|
|
23
|
+
class ContextManager {
|
|
24
|
+
/**
|
|
25
|
+
* Create a new ContextManager instance
|
|
26
|
+
* @param {string} cwd - Current working directory
|
|
27
|
+
*/
|
|
28
|
+
constructor(cwd) {
|
|
29
|
+
this.cwd = cwd || process.cwd();
|
|
30
|
+
this.sources = [];
|
|
31
|
+
this.cache = new ContextCache();
|
|
32
|
+
this.fileAccess = new FileAccessService(this.cwd);
|
|
33
|
+
this.urlFetch = new URLFetchService();
|
|
34
|
+
this.scanner = new ContentSecurityScanner();
|
|
35
|
+
this.scorer = null;
|
|
36
|
+
this.compressor = new ContextCompressor();
|
|
37
|
+
this.deduplicator = new ContextDeduplicator({ enableFuzzyMatch: true });
|
|
38
|
+
this.metadataTracker = new ContextMetadataTracker(this.cwd);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Request context from files and URLs
|
|
43
|
+
* @param {{files?: string[], urls?: string[], task?: string, enableScoring?: boolean, minScore?: number, maxFiles?: number, enableCompression?: boolean, enableDeduplication?: boolean, taskId?: string}} options - Context options
|
|
44
|
+
* @returns {{context: string, sources: Array, errors: Array, scoringStats?: Object, compressionStats?: Object, dedupStats?: Object, metadata?: Object}} - Aggregated context with optimization stats
|
|
45
|
+
*/
|
|
46
|
+
async requestContext(options = {}) {
|
|
47
|
+
const {
|
|
48
|
+
files = [],
|
|
49
|
+
urls = [],
|
|
50
|
+
task,
|
|
51
|
+
enableScoring = false,
|
|
52
|
+
minScore = 0.1,
|
|
53
|
+
maxFiles = 20,
|
|
54
|
+
enableCompression = false,
|
|
55
|
+
enableDeduplication = false,
|
|
56
|
+
taskId
|
|
57
|
+
} = options;
|
|
58
|
+
|
|
59
|
+
const contextParts = [];
|
|
60
|
+
const sources = [];
|
|
61
|
+
const errors = [];
|
|
62
|
+
let scoringStats = null;
|
|
63
|
+
let compressionStats = null;
|
|
64
|
+
let dedupStats = null;
|
|
65
|
+
|
|
66
|
+
// Gather all files from patterns
|
|
67
|
+
let allFiles = [];
|
|
68
|
+
for (const pattern of files) {
|
|
69
|
+
try {
|
|
70
|
+
const fileResults = this.fileAccess.readFiles(pattern);
|
|
71
|
+
for (const file of fileResults) {
|
|
72
|
+
allFiles.push({
|
|
73
|
+
path: file.path,
|
|
74
|
+
content: file.content
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
} catch (err) {
|
|
78
|
+
errors.push({
|
|
79
|
+
source: pattern,
|
|
80
|
+
type: 'file',
|
|
81
|
+
message: err.message
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Step 1: Score files if task provided and scoring enabled
|
|
87
|
+
let filesToProcess = allFiles;
|
|
88
|
+
if (task && enableScoring && allFiles.length > 0) {
|
|
89
|
+
this.scorer = new ContextRelevanceScorer(task, { minScore, maxFiles });
|
|
90
|
+
const scoredFiles = this.scorer.scoreFiles(allFiles.map(f => f.path));
|
|
91
|
+
const scoredPaths = new Set(scoredFiles.map(f => f.path));
|
|
92
|
+
|
|
93
|
+
// Filter to scored files and attach scores
|
|
94
|
+
filesToProcess = allFiles
|
|
95
|
+
.filter(f => scoredPaths.has(f.path))
|
|
96
|
+
.map(f => {
|
|
97
|
+
const scored = scoredFiles.find(s => s.path === f.path);
|
|
98
|
+
return {
|
|
99
|
+
path: f.path,
|
|
100
|
+
content: f.content,
|
|
101
|
+
score: scored ? scored.score : 0,
|
|
102
|
+
breakdown: scored ? scored.breakdown : null
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Calculate scoring stats
|
|
107
|
+
const avgScore = filesToProcess.length > 0
|
|
108
|
+
? filesToProcess.reduce((sum, f) => sum + f.score, 0) / filesToProcess.length
|
|
109
|
+
: 0;
|
|
110
|
+
|
|
111
|
+
scoringStats = {
|
|
112
|
+
enabled: true,
|
|
113
|
+
minScore,
|
|
114
|
+
avgScore: Math.round(avgScore * 100) / 100,
|
|
115
|
+
filteredCount: allFiles.length - filesToProcess.length
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Step 2: Deduplicate files if enabled
|
|
120
|
+
let uniqueFiles = filesToProcess;
|
|
121
|
+
if (enableDeduplication && filesToProcess.length > 0) {
|
|
122
|
+
const result = this.deduplicator.deduplicateFiles(filesToProcess);
|
|
123
|
+
uniqueFiles = result.unique;
|
|
124
|
+
dedupStats = this.deduplicator.getStats();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Step 3: Compress files if enabled
|
|
128
|
+
const processedFiles = [];
|
|
129
|
+
for (const file of uniqueFiles) {
|
|
130
|
+
let content = file.content;
|
|
131
|
+
let compressionInfo = null;
|
|
132
|
+
|
|
133
|
+
if (enableCompression) {
|
|
134
|
+
const result = this.compressor.compressFile(file.path, content);
|
|
135
|
+
if (result.compressed) {
|
|
136
|
+
content = result.content;
|
|
137
|
+
compressionInfo = {
|
|
138
|
+
method: result.method,
|
|
139
|
+
originalSize: result.originalSize,
|
|
140
|
+
compressedSize: result.compressedSize,
|
|
141
|
+
reduction: result.reduction
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
processedFiles.push({
|
|
147
|
+
...file,
|
|
148
|
+
content,
|
|
149
|
+
compression: compressionInfo
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (enableCompression) {
|
|
154
|
+
compressionStats = this.compressor.getStats();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Build context from processed files
|
|
158
|
+
for (const file of processedFiles) {
|
|
159
|
+
contextParts.push(`## File: ${file.path}\n\n${file.content}`);
|
|
160
|
+
const source = {
|
|
161
|
+
type: 'file',
|
|
162
|
+
source: file.path,
|
|
163
|
+
timestamp: new Date().toISOString(),
|
|
164
|
+
size: file.content.length,
|
|
165
|
+
score: file.score,
|
|
166
|
+
compression: file.compression
|
|
167
|
+
};
|
|
168
|
+
sources.push(source);
|
|
169
|
+
this.trackSources([source]);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Process URLs (unchanged)
|
|
173
|
+
for (const url of urls) {
|
|
174
|
+
try {
|
|
175
|
+
const confirmed = await URLFetchService.confirmUrlFetch(url);
|
|
176
|
+
if (!confirmed) {
|
|
177
|
+
errors.push({
|
|
178
|
+
source: url,
|
|
179
|
+
type: 'url',
|
|
180
|
+
message: 'User declined to fetch URL'
|
|
181
|
+
});
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const result = await this.urlFetch.fetchUrl(url);
|
|
186
|
+
const scanResult = this.scanner.scan(result.content, result.contentType);
|
|
187
|
+
if (!scanResult.safe) {
|
|
188
|
+
throw new SecurityScanError(scanResult.findings);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
contextParts.push(`## URL: ${url}\n\n${result.content}`);
|
|
192
|
+
|
|
193
|
+
const source = {
|
|
194
|
+
type: 'url',
|
|
195
|
+
source: url,
|
|
196
|
+
timestamp: new Date().toISOString(),
|
|
197
|
+
contentType: result.contentType,
|
|
198
|
+
size: result.content.length
|
|
199
|
+
};
|
|
200
|
+
sources.push(source);
|
|
201
|
+
this.trackSources([source]);
|
|
202
|
+
this.cache.set(url, result.content, {
|
|
203
|
+
type: 'url',
|
|
204
|
+
contentType: result.contentType
|
|
205
|
+
});
|
|
206
|
+
} catch (err) {
|
|
207
|
+
errors.push({
|
|
208
|
+
source: url,
|
|
209
|
+
type: 'url',
|
|
210
|
+
message: err.message
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Build metadata if taskId provided
|
|
216
|
+
let metadata = null;
|
|
217
|
+
if (taskId) {
|
|
218
|
+
metadata = this.metadataTracker.createMetadata(
|
|
219
|
+
{
|
|
220
|
+
context: contextParts.join('\n\n---\n\n'),
|
|
221
|
+
sources,
|
|
222
|
+
scoringStats,
|
|
223
|
+
compressionStats,
|
|
224
|
+
dedupStats
|
|
225
|
+
},
|
|
226
|
+
{ taskId, task: task || '' }
|
|
227
|
+
);
|
|
228
|
+
this.metadataTracker.saveMetadata(metadata);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return {
|
|
232
|
+
context: contextParts.join('\n\n---\n\n'),
|
|
233
|
+
sources,
|
|
234
|
+
errors,
|
|
235
|
+
scoringStats,
|
|
236
|
+
compressionStats,
|
|
237
|
+
dedupStats,
|
|
238
|
+
metadata
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Track source metadata (with deduplication)
|
|
244
|
+
* @param {Array} sources - Array of source objects
|
|
245
|
+
*/
|
|
246
|
+
trackSources(sources) {
|
|
247
|
+
for (const source of sources) {
|
|
248
|
+
// Check for duplicates (same type and source)
|
|
249
|
+
const isDuplicate = this.sources.some(
|
|
250
|
+
s => s.type === source.type && s.source === source.source
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
if (!isDuplicate) {
|
|
254
|
+
this.sources.push(source);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Update STATE.md with context sources
|
|
261
|
+
* Creates or appends to the Context Sources section
|
|
262
|
+
*/
|
|
263
|
+
updateStateMd() {
|
|
264
|
+
const statePath = path.join(this.cwd, '.planning', 'STATE.md');
|
|
265
|
+
|
|
266
|
+
// Ensure .planning directory exists
|
|
267
|
+
const planningDir = path.join(this.cwd, '.planning');
|
|
268
|
+
if (!fs.existsSync(planningDir)) {
|
|
269
|
+
fs.mkdirSync(planningDir, { recursive: true });
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
let content = '';
|
|
273
|
+
|
|
274
|
+
// Read existing content or start fresh
|
|
275
|
+
if (fs.existsSync(statePath)) {
|
|
276
|
+
content = fs.readFileSync(statePath, 'utf-8');
|
|
277
|
+
} else {
|
|
278
|
+
content = '# Project State\n\n';
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Build the context sources table
|
|
282
|
+
const tableHeader = '| Source | Type | Timestamp |\n|--------|------|-----------|';
|
|
283
|
+
const tableRows = this.sources.map(s =>
|
|
284
|
+
`| ${s.source} | ${s.type.toUpperCase()} | ${s.timestamp} |`
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
const contextSection = `\n## Context Sources\n\n${tableHeader}\n${tableRows.join('\n')}\n`;
|
|
288
|
+
|
|
289
|
+
// Check if Context Sources section already exists
|
|
290
|
+
const sectionRegex = /## Context Sources\n[\s\S]*?(?=\n## |\n$|$)/i;
|
|
291
|
+
const existingSection = content.match(sectionRegex);
|
|
292
|
+
|
|
293
|
+
if (existingSection) {
|
|
294
|
+
// Replace existing section
|
|
295
|
+
content = content.replace(sectionRegex, contextSection);
|
|
296
|
+
} else {
|
|
297
|
+
// Append new section
|
|
298
|
+
content = content.trimEnd() + '\n' + contextSection;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Write back to STATE.md
|
|
302
|
+
fs.writeFileSync(statePath, content, 'utf-8');
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Get all tracked sources
|
|
307
|
+
* @returns {Array} - Array of source objects
|
|
308
|
+
*/
|
|
309
|
+
getSources() {
|
|
310
|
+
return [...this.sources];
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Get cached content for a URL
|
|
315
|
+
* @param {string} key - Cache key (URL)
|
|
316
|
+
* @returns {{content: string, timestamp: number, type: string}|undefined}
|
|
317
|
+
*/
|
|
318
|
+
getCached(key) {
|
|
319
|
+
return this.cache.get(key);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Clear the cache
|
|
324
|
+
*/
|
|
325
|
+
clearCache() {
|
|
326
|
+
this.cache.clear();
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Get cache statistics
|
|
331
|
+
* @returns {{size: number, keys: Array<string>}}
|
|
332
|
+
*/
|
|
333
|
+
getCacheStats() {
|
|
334
|
+
return this.cache.stats();
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
module.exports = ContextManager;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Context Metadata Tracker — Track metadata for context items
|
|
5
|
+
*
|
|
6
|
+
* Tracks:
|
|
7
|
+
- Creation time
|
|
8
|
+
- Last access time
|
|
9
|
+
- Access count
|
|
10
|
+
- Source/origin
|
|
11
|
+
- Tags/categories
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
class ContextMetadataTracker {
|
|
15
|
+
/**
|
|
16
|
+
* Create a ContextMetadataTracker instance
|
|
17
|
+
*/
|
|
18
|
+
constructor() {
|
|
19
|
+
this.metadata = new Map();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Track metadata for a context item
|
|
24
|
+
* @param {string} id - Item identifier
|
|
25
|
+
* @param {Object} data - Metadata to track
|
|
26
|
+
*/
|
|
27
|
+
track(id, data = {}) {
|
|
28
|
+
const existing = this.metadata.get(id) || {};
|
|
29
|
+
|
|
30
|
+
this.metadata.set(id, {
|
|
31
|
+
createdAt: existing.createdAt || Date.now(),
|
|
32
|
+
updatedAt: Date.now(),
|
|
33
|
+
lastAccessed: existing.lastAccessed || Date.now(),
|
|
34
|
+
accessCount: existing.accessCount || 0,
|
|
35
|
+
...data
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Record an access to a context item
|
|
41
|
+
* @param {string} id - Item identifier
|
|
42
|
+
*/
|
|
43
|
+
recordAccess(id) {
|
|
44
|
+
const data = this.metadata.get(id);
|
|
45
|
+
if (data) {
|
|
46
|
+
data.lastAccessed = Date.now();
|
|
47
|
+
data.accessCount = (data.accessCount || 0) + 1;
|
|
48
|
+
this.metadata.set(id, data);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Get metadata for an item
|
|
54
|
+
* @param {string} id - Item identifier
|
|
55
|
+
* @returns {Object|undefined} Metadata
|
|
56
|
+
*/
|
|
57
|
+
get(id) {
|
|
58
|
+
return this.metadata.get(id);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Remove metadata for an item
|
|
63
|
+
* @param {string} id - Item identifier
|
|
64
|
+
* @returns {boolean} True if removed
|
|
65
|
+
*/
|
|
66
|
+
remove(id) {
|
|
67
|
+
return this.metadata.delete(id);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get all tracked metadata
|
|
72
|
+
* @returns {Object} All metadata
|
|
73
|
+
*/
|
|
74
|
+
getAll() {
|
|
75
|
+
const result = {};
|
|
76
|
+
this.metadata.forEach((value, key) => {
|
|
77
|
+
result[key] = value;
|
|
78
|
+
});
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Clear all metadata
|
|
84
|
+
*/
|
|
85
|
+
clear() {
|
|
86
|
+
this.metadata.clear();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Get statistics about tracked items
|
|
91
|
+
* @returns {Object} Statistics
|
|
92
|
+
*/
|
|
93
|
+
stats() {
|
|
94
|
+
let totalAccesses = 0;
|
|
95
|
+
let oldest = Infinity;
|
|
96
|
+
let newest = 0;
|
|
97
|
+
|
|
98
|
+
this.metadata.forEach(data => {
|
|
99
|
+
totalAccesses += data.accessCount || 0;
|
|
100
|
+
if (data.createdAt < oldest) oldest = data.createdAt;
|
|
101
|
+
if (data.createdAt > newest) newest = data.createdAt;
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
total: this.metadata.size,
|
|
106
|
+
totalAccesses,
|
|
107
|
+
avgAccesses: this.metadata.size > 0 ? Math.round(totalAccesses / this.metadata.size) : 0,
|
|
108
|
+
oldest: oldest === Infinity ? null : new Date(oldest).toISOString(),
|
|
109
|
+
newest: new Date(newest).toISOString()
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Find items by metadata criteria
|
|
115
|
+
* @param {Object} criteria - Search criteria
|
|
116
|
+
* @returns {Array} Matching item IDs
|
|
117
|
+
*/
|
|
118
|
+
findBy(criteria) {
|
|
119
|
+
const results = [];
|
|
120
|
+
|
|
121
|
+
this.metadata.forEach((data, id) => {
|
|
122
|
+
let matches = true;
|
|
123
|
+
|
|
124
|
+
for (const [key, value] of Object.entries(criteria)) {
|
|
125
|
+
if (data[key] !== value) {
|
|
126
|
+
matches = false;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (matches) {
|
|
132
|
+
results.push(id);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
return results;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
module.exports = ContextMetadataTracker;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Context Relevance Scorer — Score context items by relevance
|
|
5
|
+
*
|
|
6
|
+
* Analyzes context items and assigns relevance scores based on:
|
|
7
|
+
* - Recency
|
|
8
|
+
* - Frequency of access
|
|
9
|
+
* - Relationship to current task
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
class ContextRelevanceScorer {
|
|
13
|
+
/**
|
|
14
|
+
* Create a ContextRelevanceScorer instance
|
|
15
|
+
*/
|
|
16
|
+
constructor() {
|
|
17
|
+
this.defaultWeights = {
|
|
18
|
+
recency: 0.4,
|
|
19
|
+
frequency: 0.3,
|
|
20
|
+
relevance: 0.3
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Score a context item
|
|
26
|
+
* @param {Object} item - Context item to score
|
|
27
|
+
* @param {Object} options - Scoring options
|
|
28
|
+
* @returns {number} Relevance score (0-100)
|
|
29
|
+
*/
|
|
30
|
+
score(item, options = {}) {
|
|
31
|
+
const { recency = 0, frequency = 0, relevance = 0 } = item;
|
|
32
|
+
const weights = { ...this.defaultWeights, ...options.weights };
|
|
33
|
+
|
|
34
|
+
const recencyScore = this._scoreRecency(recency, options);
|
|
35
|
+
const frequencyScore = this._scoreFrequency(frequency, options);
|
|
36
|
+
const relevanceScore = this._scoreRelevance(relevance, options);
|
|
37
|
+
|
|
38
|
+
return Math.round(
|
|
39
|
+
recencyScore * weights.recency +
|
|
40
|
+
frequencyScore * weights.frequency +
|
|
41
|
+
relevanceScore * weights.relevance
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Score based on recency
|
|
47
|
+
* @param {number} lastAccessed - Timestamp of last access
|
|
48
|
+
* @param {Object} options - Options
|
|
49
|
+
* @returns {number} Score (0-100)
|
|
50
|
+
*/
|
|
51
|
+
_scoreRecency(lastAccessed, options = {}) {
|
|
52
|
+
if (!lastAccessed) return 50;
|
|
53
|
+
const now = Date.now();
|
|
54
|
+
const age = now - lastAccessed;
|
|
55
|
+
const maxAge = options.maxAge || 3600000; // 1 hour default
|
|
56
|
+
|
|
57
|
+
return Math.max(0, Math.min(100, 100 - (age / maxAge) * 100));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Score based on access frequency
|
|
62
|
+
* @param {number} accessCount - Number of accesses
|
|
63
|
+
* @param {Object} options - Options
|
|
64
|
+
* @returns {number} Score (0-100)
|
|
65
|
+
*/
|
|
66
|
+
_scoreFrequency(accessCount, options = {}) {
|
|
67
|
+
if (!accessCount) return 0;
|
|
68
|
+
const maxCount = options.maxCount || 100;
|
|
69
|
+
return Math.min(100, (accessCount / maxCount) * 100);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Score based on content relevance
|
|
74
|
+
* @param {number} relevance - Pre-computed relevance value
|
|
75
|
+
* @param {Object} options - Options
|
|
76
|
+
* @returns {number} Score (0-100)
|
|
77
|
+
*/
|
|
78
|
+
_scoreRelevance(relevance, options = {}) {
|
|
79
|
+
if (relevance === undefined || relevance === null) return 50;
|
|
80
|
+
return Math.max(0, Math.min(100, relevance));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Score multiple items and sort by relevance
|
|
85
|
+
* @param {Array} items - Context items to score
|
|
86
|
+
* @param {Object} options - Scoring options
|
|
87
|
+
* @returns {Array} Items with scores, sorted by relevance
|
|
88
|
+
*/
|
|
89
|
+
scoreAll(items, options = {}) {
|
|
90
|
+
return items
|
|
91
|
+
.map(item => ({
|
|
92
|
+
...item,
|
|
93
|
+
relevanceScore: this.score(item, options)
|
|
94
|
+
}))
|
|
95
|
+
.sort((a, b) => b.relevanceScore - a.relevanceScore);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
module.exports = ContextRelevanceScorer;
|