@howlil/ez-agents 3.4.2 → 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 -462
- 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 -0
- package/agents/ez-requirements-agent.md +377 -0
- 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/install.js +3221 -3272
- 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 -41
- 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 -45
- package/commands/ez/progress.md +36 -24
- 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 +1692 -716
- 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 -0
- 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 -0
- package/ez-agents/bin/lib/context-cache.cjs +154 -0
- package/ez-agents/bin/lib/context-errors.cjs +71 -0
- package/ez-agents/bin/lib/context-manager.cjs +220 -0
- 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/discussion-synthesizer.cjs +458 -0
- package/ez-agents/bin/lib/file-access.cjs +207 -0
- 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 -0
- package/ez-agents/bin/lib/git-utils.cjs +118 -0
- package/ez-agents/bin/lib/git-workflow-engine.cjs +1157 -0
- package/ez-agents/bin/lib/health-check.cjs +162 -162
- package/ez-agents/bin/lib/index.cjs +40 -2
- package/ez-agents/bin/lib/init.cjs +0 -2
- package/ez-agents/bin/lib/lockfile-validator.cjs +227 -0
- package/ez-agents/bin/lib/log-rotation.cjs +71 -0
- package/ez-agents/bin/lib/logger.cjs +99 -154
- package/ez-agents/bin/lib/memory-compression.cjs +256 -0
- package/ez-agents/bin/lib/package-manager-detector.cjs +203 -0
- package/ez-agents/bin/lib/package-manager-executor.cjs +385 -0
- package/ez-agents/bin/lib/package-manager-service.cjs +216 -0
- 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 -0
- package/ez-agents/bin/lib/safe-exec.cjs +128 -214
- package/ez-agents/bin/lib/security-errors.cjs +62 -0
- package/ez-agents/bin/lib/session-chain.cjs +304 -0
- package/ez-agents/bin/lib/session-errors.cjs +81 -0
- package/ez-agents/bin/lib/session-export.cjs +251 -0
- package/ez-agents/bin/lib/session-import.cjs +262 -0
- package/ez-agents/bin/lib/session-manager.cjs +280 -0
- 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 -0
- package/ez-agents/bin/lib/tradeoff-analyzer.cjs +284 -0
- package/ez-agents/bin/lib/url-fetch.cjs +170 -0
- 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 -0
- 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 -200
- package/ez-agents/references/tier-strategy.md +103 -0
- 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 -0
- 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 -0
- package/ez-agents/templates/handoff-protocol.md +294 -0
- package/ez-agents/templates/incident-runbook.md +205 -0
- 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 -0
- package/ez-agents/templates/research.md +552 -552
- package/ez-agents/templates/rollback-plan.md +201 -0
- 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 +131 -30
- 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 +169 -3
- package/ez-agents/workflows/help.md +86 -133
- package/ez-agents/workflows/hotfix.md +291 -0
- package/ez-agents/workflows/new-milestone.md +340 -11
- package/ez-agents/workflows/new-project.md +294 -318
- package/ez-agents/workflows/plan-phase.md +22 -40
- package/ez-agents/workflows/progress.md +15 -25
- package/ez-agents/workflows/release.md +253 -0
- package/ez-agents/workflows/resume-session.md +215 -0
- 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 -64
- 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-plan-checker.md +0 -706
- package/agents/ez-research-synthesizer.md +0 -247
- 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/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/health.md +0 -22
- 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/pause-work.md +0 -38
- package/commands/ez/plan-milestone-gaps.md +0 -34
- package/commands/ez/reapply-patches.md +0 -124
- package/commands/ez/remove-phase.md +0 -31
- package/commands/ez/research-phase.md +0 -190
- package/commands/ez/set-profile.md +0 -34
- 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/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/research-phase.md +0 -74
- 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,449 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Skill Resolver — Conflict resolution for competing skill recommendations
|
|
5
|
+
*
|
|
6
|
+
* Provides systematic conflict resolution with:
|
|
7
|
+
* - Priority rules (security > speed, maintainability > novelty)
|
|
8
|
+
* - Context-weighted scoring
|
|
9
|
+
* - Trade-off analysis generation
|
|
10
|
+
* - Escalation logic for irreconcilable conflicts
|
|
11
|
+
* - Decision audit trail
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* const { SkillResolver, PRIORITY_RULES } = require('./skill-resolver');
|
|
15
|
+
* const resolver = new SkillResolver({ context: { project_phase: 'MVP' } });
|
|
16
|
+
* const result = resolver.resolve(skills, context);
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const Logger = require('./logger.cjs');
|
|
20
|
+
const logger = new Logger();
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Priority rules for conflict resolution
|
|
24
|
+
* Higher priority value wins in conflicts
|
|
25
|
+
*/
|
|
26
|
+
const PRIORITY_RULES = {
|
|
27
|
+
'security > speed': {
|
|
28
|
+
higher: 'security',
|
|
29
|
+
lower: 'speed',
|
|
30
|
+
priority: 100,
|
|
31
|
+
rationale: 'Security vulnerabilities are costly to fix post-release',
|
|
32
|
+
example: "Don't skip input validation to meet deadline",
|
|
33
|
+
absolute: true
|
|
34
|
+
},
|
|
35
|
+
'security > convenience': {
|
|
36
|
+
higher: 'security',
|
|
37
|
+
lower: 'convenience',
|
|
38
|
+
priority: 95,
|
|
39
|
+
rationale: 'User convenience should not compromise security',
|
|
40
|
+
example: 'Require MFA even if adds friction',
|
|
41
|
+
absolute: true
|
|
42
|
+
},
|
|
43
|
+
'maintainability > novelty': {
|
|
44
|
+
higher: 'maintainability',
|
|
45
|
+
lower: 'novelty',
|
|
46
|
+
priority: 90,
|
|
47
|
+
rationale: 'New tech should be proven, not just novel',
|
|
48
|
+
example: 'Use stable Laravel over bleeding-edge framework',
|
|
49
|
+
absolute: true
|
|
50
|
+
},
|
|
51
|
+
'data integrity > performance': {
|
|
52
|
+
higher: 'data-integrity',
|
|
53
|
+
lower: 'performance',
|
|
54
|
+
priority: 95,
|
|
55
|
+
rationale: 'Wrong fast answers are worse than slow correct ones',
|
|
56
|
+
example: 'Use transactions even if slower',
|
|
57
|
+
absolute: true
|
|
58
|
+
},
|
|
59
|
+
'compliance > feature completeness': {
|
|
60
|
+
higher: 'compliance',
|
|
61
|
+
lower: 'feature-completeness',
|
|
62
|
+
priority: 100,
|
|
63
|
+
rationale: 'Regulatory violations can shut down business',
|
|
64
|
+
example: 'Implement GDPR consent before launching feature',
|
|
65
|
+
absolute: true
|
|
66
|
+
},
|
|
67
|
+
'delivery speed > ideal architecture (for POC/MVP)': {
|
|
68
|
+
higher: 'delivery-speed',
|
|
69
|
+
lower: 'ideal-architecture',
|
|
70
|
+
priority: 80,
|
|
71
|
+
context: ['POC', 'MVP'],
|
|
72
|
+
rationale: 'POCs need validation, not perfection',
|
|
73
|
+
example: 'Monolith is fine for MVP validation',
|
|
74
|
+
absolute: false
|
|
75
|
+
},
|
|
76
|
+
'scalability > simplicity (when scale is proven need)': {
|
|
77
|
+
higher: 'scalability',
|
|
78
|
+
lower: 'simplicity',
|
|
79
|
+
priority: 85,
|
|
80
|
+
context: ['scale-up', 'enterprise'],
|
|
81
|
+
rationale: 'If you have 1M users, invest in scaling',
|
|
82
|
+
example: 'Add caching layer when queries slow under load',
|
|
83
|
+
absolute: false
|
|
84
|
+
},
|
|
85
|
+
'user experience > technical purity': {
|
|
86
|
+
higher: 'user-experience',
|
|
87
|
+
lower: 'technical-purity',
|
|
88
|
+
priority: 75,
|
|
89
|
+
rationale: 'Users do not care about clean code',
|
|
90
|
+
example: 'Add denormalization for faster page loads',
|
|
91
|
+
absolute: false
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Conflict types recognized by the resolver
|
|
97
|
+
*/
|
|
98
|
+
const CONFLICT_TYPES = [
|
|
99
|
+
'Security vs Speed',
|
|
100
|
+
'Security vs Convenience',
|
|
101
|
+
'Maintainability vs Delivery',
|
|
102
|
+
'Performance vs Simplicity',
|
|
103
|
+
'Data Integrity vs Performance',
|
|
104
|
+
'Compliance vs Feature Completeness',
|
|
105
|
+
'Ideal Architecture vs Constraints',
|
|
106
|
+
'Feature Completeness vs Deadline',
|
|
107
|
+
'User Experience vs Technical Purity',
|
|
108
|
+
'Unknown'
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Skill Resolver class for conflict resolution
|
|
113
|
+
*/
|
|
114
|
+
class SkillResolver {
|
|
115
|
+
/**
|
|
116
|
+
* Create a SkillResolver instance
|
|
117
|
+
* @param {Object} options - Resolver options
|
|
118
|
+
* @param {Object} options.priorityRules - Override default priority rules
|
|
119
|
+
* @param {Object} options.context - Project context for resolution
|
|
120
|
+
*/
|
|
121
|
+
constructor(options = {}) {
|
|
122
|
+
this.priorityRules = { ...PRIORITY_RULES, ...options.priorityRules };
|
|
123
|
+
this.context = options.context || {};
|
|
124
|
+
this.logger = logger;
|
|
125
|
+
this.decisionLog = [];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Detect conflicts between skill recommendations
|
|
130
|
+
* @param {Array} skills - Array of activated skills
|
|
131
|
+
* @returns {Object} { hasConflict, conflicts: [] }
|
|
132
|
+
*/
|
|
133
|
+
detectConflict(skills) {
|
|
134
|
+
const conflicts = [];
|
|
135
|
+
const recommendations = this._collectRecommendations(skills);
|
|
136
|
+
|
|
137
|
+
// Check for conflicting recommendations on same aspect
|
|
138
|
+
const aspectMap = new Map();
|
|
139
|
+
for (const rec of recommendations) {
|
|
140
|
+
const aspect = rec.aspect;
|
|
141
|
+
if (!aspectMap.has(aspect)) {
|
|
142
|
+
aspectMap.set(aspect, []);
|
|
143
|
+
}
|
|
144
|
+
aspectMap.get(aspect).push(rec);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Find aspects with conflicting recommendations
|
|
148
|
+
for (const [aspect, recs] of aspectMap) {
|
|
149
|
+
if (recs.length > 1) {
|
|
150
|
+
const values = new Set(recs.map(r => r.value));
|
|
151
|
+
if (values.size > 1) {
|
|
152
|
+
conflicts.push({
|
|
153
|
+
aspect,
|
|
154
|
+
type: this._inferConflictType(recs),
|
|
155
|
+
recommendations: recs,
|
|
156
|
+
skills: [...new Set(recs.map(r => r.skillName))]
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
hasConflict: conflicts.length > 0,
|
|
164
|
+
conflicts
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Classify a conflict into a known type
|
|
170
|
+
* @param {Object} conflict - Conflict object
|
|
171
|
+
* @returns {string} Conflict type
|
|
172
|
+
*/
|
|
173
|
+
classifyConflict(conflict) {
|
|
174
|
+
const { type, recommendations } = conflict;
|
|
175
|
+
|
|
176
|
+
// Check recommendation tags for conflict indicators
|
|
177
|
+
const tags = recommendations.flatMap(r => r.tags || []);
|
|
178
|
+
|
|
179
|
+
if (tags.includes('security') && (tags.includes('speed') || tags.includes('delivery'))) {
|
|
180
|
+
return 'Security vs Speed';
|
|
181
|
+
}
|
|
182
|
+
if (tags.includes('security') && tags.includes('convenience')) {
|
|
183
|
+
return 'Security vs Convenience';
|
|
184
|
+
}
|
|
185
|
+
if (tags.includes('maintainability') && tags.includes('delivery')) {
|
|
186
|
+
return 'Maintainability vs Delivery';
|
|
187
|
+
}
|
|
188
|
+
if (tags.includes('performance') && tags.includes('simplicity')) {
|
|
189
|
+
return 'Performance vs Simplicity';
|
|
190
|
+
}
|
|
191
|
+
if (tags.includes('data-integrity') && tags.includes('performance')) {
|
|
192
|
+
return 'Data Integrity vs Performance';
|
|
193
|
+
}
|
|
194
|
+
if (tags.includes('compliance') && tags.includes('feature-completeness')) {
|
|
195
|
+
return 'Compliance vs Feature Completeness';
|
|
196
|
+
}
|
|
197
|
+
if (tags.includes('ideal-architecture') && tags.includes('constraints')) {
|
|
198
|
+
return 'Ideal Architecture vs Constraints';
|
|
199
|
+
}
|
|
200
|
+
if (tags.includes('user-experience') && tags.includes('technical-purity')) {
|
|
201
|
+
return 'User Experience vs Technical Purity';
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return type || 'Unknown';
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Apply priority rules to resolve a conflict
|
|
209
|
+
* @param {Object} conflict - Classified conflict
|
|
210
|
+
* @param {Object} context - Project context
|
|
211
|
+
* @returns {Object} Resolution with winner and rationale
|
|
212
|
+
*/
|
|
213
|
+
applyPriorityRules(conflict, context = {}) {
|
|
214
|
+
const classification = this.classifyConflict(conflict);
|
|
215
|
+
const ctx = { ...this.context, ...context };
|
|
216
|
+
|
|
217
|
+
// Find applicable priority rule
|
|
218
|
+
let applicableRule = null;
|
|
219
|
+
for (const [ruleKey, rule] of Object.entries(this.priorityRules)) {
|
|
220
|
+
if (this._ruleMatchesConflict(ruleKey, classification, ctx)) {
|
|
221
|
+
applicableRule = { key: ruleKey, ...rule };
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (!applicableRule) {
|
|
227
|
+
// No applicable rule - return first recommendation as default
|
|
228
|
+
return {
|
|
229
|
+
winner: conflict.recommendations[0],
|
|
230
|
+
rationale: 'No applicable priority rule - using default recommendation',
|
|
231
|
+
rule: null,
|
|
232
|
+
escalated: true
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Find winning recommendation based on rule
|
|
237
|
+
const winner = this._findRecommendationByPriority(
|
|
238
|
+
conflict.recommendations,
|
|
239
|
+
applicableRule.higher,
|
|
240
|
+
ctx
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
winner,
|
|
245
|
+
rationale: applicableRule.rationale,
|
|
246
|
+
example: applicableRule.example,
|
|
247
|
+
rule: applicableRule.key,
|
|
248
|
+
escalated: false
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Resolve conflicts between skills
|
|
254
|
+
* @param {Array} skills - Array of activated skills
|
|
255
|
+
* @param {Object} context - Project context
|
|
256
|
+
* @returns {Object} { decision, rationale, tradeoffs, escalated }
|
|
257
|
+
*/
|
|
258
|
+
resolve(skills, context = {}) {
|
|
259
|
+
const ctx = { ...this.context, ...context };
|
|
260
|
+
const conflictResult = this.detectConflict(skills);
|
|
261
|
+
|
|
262
|
+
if (!conflictResult.hasConflict) {
|
|
263
|
+
// No conflicts - return all recommendations
|
|
264
|
+
return {
|
|
265
|
+
decision: this._collectRecommendations(skills),
|
|
266
|
+
rationale: 'No conflicts detected between skill recommendations',
|
|
267
|
+
tradeoffs: [],
|
|
268
|
+
escalated: false,
|
|
269
|
+
conflicts: []
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const decisions = [];
|
|
274
|
+
const tradeoffs = [];
|
|
275
|
+
let escalated = false;
|
|
276
|
+
|
|
277
|
+
for (const conflict of conflictResult.conflicts) {
|
|
278
|
+
const resolution = this.applyPriorityRules(conflict, ctx);
|
|
279
|
+
|
|
280
|
+
decisions.push({
|
|
281
|
+
aspect: conflict.aspect,
|
|
282
|
+
decision: resolution.winner,
|
|
283
|
+
rejected: conflict.recommendations.filter(r => r !== resolution.winner)
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
if (resolution.escalated) {
|
|
287
|
+
escalated = true;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
tradeoffs.push({
|
|
291
|
+
aspect: conflict.aspect,
|
|
292
|
+
chosen: resolution.winner.value,
|
|
293
|
+
rejected: conflict.recommendations
|
|
294
|
+
.filter(r => r !== resolution.winner)
|
|
295
|
+
.map(r => r.value),
|
|
296
|
+
rationale: resolution.rationale
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
// Log decision for audit trail
|
|
300
|
+
this.logDecision({
|
|
301
|
+
conflict,
|
|
302
|
+
resolution,
|
|
303
|
+
context: ctx,
|
|
304
|
+
timestamp: new Date().toISOString()
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return {
|
|
309
|
+
decision: decisions,
|
|
310
|
+
rationale: escalated
|
|
311
|
+
? 'Some conflicts required escalation due to no applicable priority rules'
|
|
312
|
+
: 'All conflicts resolved using priority rules',
|
|
313
|
+
tradeoffs,
|
|
314
|
+
escalated,
|
|
315
|
+
conflicts: conflictResult.conflicts
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Log a decision for audit trail
|
|
321
|
+
* @param {Object} decision - Decision object
|
|
322
|
+
*/
|
|
323
|
+
logDecision(decision) {
|
|
324
|
+
this.decisionLog.push(decision);
|
|
325
|
+
this.logger.info('Conflict resolution decision logged', {
|
|
326
|
+
conflictType: decision.conflict?.type,
|
|
327
|
+
resolution: decision.resolution?.rule,
|
|
328
|
+
escalated: decision.resolution?.escalated,
|
|
329
|
+
timestamp: decision.timestamp
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Get decision log
|
|
335
|
+
* @returns {Array} Array of logged decisions
|
|
336
|
+
*/
|
|
337
|
+
getDecisionLog() {
|
|
338
|
+
return this.decisionLog;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Clear decision log
|
|
343
|
+
*/
|
|
344
|
+
clearDecisionLog() {
|
|
345
|
+
this.decisionLog = [];
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Collect all recommendations from skills
|
|
350
|
+
* @param {Array} skills - Array of skills
|
|
351
|
+
* @returns {Array} Array of recommendations
|
|
352
|
+
* @private
|
|
353
|
+
*/
|
|
354
|
+
_collectRecommendations(skills) {
|
|
355
|
+
const recommendations = [];
|
|
356
|
+
|
|
357
|
+
for (const skill of skills) {
|
|
358
|
+
if (skill.workflow) {
|
|
359
|
+
for (const [phase, actions] of Object.entries(skill.workflow)) {
|
|
360
|
+
if (Array.isArray(actions)) {
|
|
361
|
+
for (const action of actions) {
|
|
362
|
+
recommendations.push({
|
|
363
|
+
skillName: skill.name,
|
|
364
|
+
aspect: phase,
|
|
365
|
+
value: action,
|
|
366
|
+
tags: skill.tags || []
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
if (skill.best_practices) {
|
|
374
|
+
for (const practice of skill.best_practices) {
|
|
375
|
+
recommendations.push({
|
|
376
|
+
skillName: skill.name,
|
|
377
|
+
aspect: 'best_practice',
|
|
378
|
+
value: practice,
|
|
379
|
+
tags: skill.tags || []
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
return recommendations;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Infer conflict type from recommendations
|
|
390
|
+
* @param {Array} recs - Recommendations
|
|
391
|
+
* @returns {string} Conflict type
|
|
392
|
+
* @private
|
|
393
|
+
*/
|
|
394
|
+
_inferConflictType(recs) {
|
|
395
|
+
const tags = recs.flatMap(r => r.tags || []);
|
|
396
|
+
|
|
397
|
+
if (tags.includes('security')) return 'Security vs Speed';
|
|
398
|
+
if (tags.includes('maintainability')) return 'Maintainability vs Delivery';
|
|
399
|
+
if (tags.includes('performance')) return 'Performance vs Simplicity';
|
|
400
|
+
|
|
401
|
+
return 'Unknown';
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Check if a rule matches a conflict
|
|
406
|
+
* @param {string} ruleKey - Rule key
|
|
407
|
+
* @param {string} conflictType - Conflict type
|
|
408
|
+
* @param {Object} context - Project context
|
|
409
|
+
* @returns {boolean} True if rule applies
|
|
410
|
+
* @private
|
|
411
|
+
*/
|
|
412
|
+
_ruleMatchesConflict(ruleKey, conflictType, context) {
|
|
413
|
+
const rule = this.priorityRules[ruleKey];
|
|
414
|
+
if (!rule) return false;
|
|
415
|
+
|
|
416
|
+
// Check if rule has context requirements
|
|
417
|
+
if (rule.context && !rule.context.includes(context.project_phase)) {
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Check if rule matches conflict type
|
|
422
|
+
const ruleMatches = ruleKey.toLowerCase().includes(conflictType.toLowerCase().split(' vs ')[0].toLowerCase());
|
|
423
|
+
return ruleMatches;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Find recommendation matching priority
|
|
428
|
+
* @param {Array} recs - Recommendations
|
|
429
|
+
* @param {string} priority - Priority to match
|
|
430
|
+
* @param {Object} context - Project context
|
|
431
|
+
* @returns {Object} Matching recommendation
|
|
432
|
+
* @private
|
|
433
|
+
*/
|
|
434
|
+
_findRecommendationByPriority(recs, priority, context) {
|
|
435
|
+
for (const rec of recs) {
|
|
436
|
+
if (rec.tags?.includes(priority)) {
|
|
437
|
+
return rec;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
// Fallback to first recommendation
|
|
441
|
+
return recs[0];
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
module.exports = {
|
|
446
|
+
SkillResolver,
|
|
447
|
+
PRIORITY_RULES,
|
|
448
|
+
CONFLICT_TYPES
|
|
449
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Skill Triggers — Trigger-based skill auto-activation
|
|
5
|
+
*
|
|
6
|
+
* Checks skill triggers against context:
|
|
7
|
+
* - Keywords in task description
|
|
8
|
+
* - File patterns in codebase
|
|
9
|
+
* - Commands executed
|
|
10
|
+
* - Stack detection
|
|
11
|
+
* - Project archetypes
|
|
12
|
+
* - Mode matching
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* const { checkTriggers, activateSkillsByTriggers } = require('./skill-triggers.cjs');
|
|
16
|
+
* const shouldActivate = checkTriggers(skill, context);
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const minimatch = require('minimatch');
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Check if a skill's triggers match the context
|
|
23
|
+
* @param {Object} skill - Skill object with triggers
|
|
24
|
+
* @param {Object} context - Context object
|
|
25
|
+
* @returns {boolean} True if skill should activate
|
|
26
|
+
*/
|
|
27
|
+
function checkTriggers(skill, context) {
|
|
28
|
+
const { triggers } = skill;
|
|
29
|
+
if (!triggers) return false;
|
|
30
|
+
|
|
31
|
+
// Keyword matching in task description
|
|
32
|
+
if (triggers.keywords) {
|
|
33
|
+
const taskText = (context.taskDescription || '').toLowerCase();
|
|
34
|
+
const keywordMatch = triggers.keywords.some(k =>
|
|
35
|
+
taskText.includes(k.toLowerCase())
|
|
36
|
+
);
|
|
37
|
+
if (keywordMatch) return true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// File pattern matching (requires codebase scan)
|
|
41
|
+
if (triggers.filePatterns && context.codebaseFiles) {
|
|
42
|
+
const matchingFiles = context.codebaseFiles.filter(f =>
|
|
43
|
+
triggers.filePatterns.some(pattern => minimatch(f, pattern))
|
|
44
|
+
);
|
|
45
|
+
if (matchingFiles.length > 0) return true;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Command matching
|
|
49
|
+
if (triggers.commands && context.executedCommands) {
|
|
50
|
+
const commandMatch = triggers.commands.some(cmd =>
|
|
51
|
+
context.executedCommands.some(execCmd => execCmd.includes(cmd))
|
|
52
|
+
);
|
|
53
|
+
if (commandMatch) return true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Stack matching
|
|
57
|
+
if (triggers.stack && context.stack) {
|
|
58
|
+
const stackStr = typeof context.stack === 'string'
|
|
59
|
+
? context.stack
|
|
60
|
+
: `${context.stack.language}/${context.stack.framework}`;
|
|
61
|
+
if (triggers.stack === stackStr) return true;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Project archetype matching
|
|
65
|
+
if (triggers.projectArchetypes && context.projectType) {
|
|
66
|
+
if (triggers.projectArchetypes.includes(context.projectType)) return true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Mode matching
|
|
70
|
+
if (triggers.modes && context.mode) {
|
|
71
|
+
if (triggers.modes.includes(context.mode)) return true;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Activate skills whose triggers match the context
|
|
79
|
+
* @param {Object[]} skills - Array of skill objects
|
|
80
|
+
* @param {Object} context - Context object
|
|
81
|
+
* @returns {Object[]} Array of skills whose triggers matched
|
|
82
|
+
*/
|
|
83
|
+
function activateSkillsByTriggers(skills, context) {
|
|
84
|
+
return skills.filter(skill => checkTriggers(skill, context));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
module.exports = {
|
|
88
|
+
checkTriggers,
|
|
89
|
+
activateSkillsByTriggers
|
|
90
|
+
};
|