@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,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EDGE-06: Team Overhead Guard
|
|
3
|
+
*
|
|
4
|
+
* Detects organizational change suggestions.
|
|
5
|
+
* Prevents suggesting team restructuring without explicit need.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Organizational change keywords
|
|
9
|
+
const ORG_CHANGE_KEYWORDS = [
|
|
10
|
+
// Team structure
|
|
11
|
+
'team structure', 'reorganize team', 'restructure team', 'new team',
|
|
12
|
+
'scrum team', 'squad', 'tribe', 'chapter', 'guild',
|
|
13
|
+
|
|
14
|
+
// Roles and positions
|
|
15
|
+
'new role', 'create role', 'hire', 'recruiting', 'job description',
|
|
16
|
+
'team lead', 'tech lead', 'engineering manager', 'product owner',
|
|
17
|
+
'scrum master', 'architect role', 'dedicated person',
|
|
18
|
+
|
|
19
|
+
// Meetings and ceremonies
|
|
20
|
+
'daily standup', 'sprint planning', 'retrospective', 'sprint review',
|
|
21
|
+
'new meeting', 'weekly sync', 'bi-weekly', 'ceremony',
|
|
22
|
+
|
|
23
|
+
// Process changes
|
|
24
|
+
'change process', 'new workflow', 'approval process', 'sign-off',
|
|
25
|
+
'gate keeping', 'code review process', 'pr review requirement',
|
|
26
|
+
|
|
27
|
+
// Communication
|
|
28
|
+
'communication channel', 'slack channel', 'teams channel',
|
|
29
|
+
'reporting structure', 'escalation path', 'chain of command',
|
|
30
|
+
|
|
31
|
+
// Documentation overhead
|
|
32
|
+
'documentation requirement', 'design doc', 'rfc process',
|
|
33
|
+
'architecture review board', 'change advisory board'
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
// Legitimate technical suggestions (not org changes)
|
|
37
|
+
const TECHNICAL_SUGGESTIONS = [
|
|
38
|
+
'add test', 'write test', 'create component', 'implement feature',
|
|
39
|
+
'refactor', 'optimize', 'fix bug', 'update dependency',
|
|
40
|
+
'add logging', 'add monitoring', 'improve performance'
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Detect organizational changes in text
|
|
45
|
+
* @param {string} output - AI generated text
|
|
46
|
+
* @returns {object} { hasOrgChanges: boolean, suggestions: array, overhead: string }
|
|
47
|
+
*/
|
|
48
|
+
function detectOrgChanges(output) {
|
|
49
|
+
const lowerOutput = output.toLowerCase();
|
|
50
|
+
const foundKeywords = [];
|
|
51
|
+
const suggestions = [];
|
|
52
|
+
|
|
53
|
+
// Check for org change keywords
|
|
54
|
+
for (const keyword of ORG_CHANGE_KEYWORDS) {
|
|
55
|
+
if (lowerOutput.includes(keyword)) {
|
|
56
|
+
foundKeywords.push(keyword);
|
|
57
|
+
|
|
58
|
+
// Extract the surrounding suggestion
|
|
59
|
+
const context = extractContext(output, keyword);
|
|
60
|
+
suggestions.push({
|
|
61
|
+
keyword,
|
|
62
|
+
context: context.trim()
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Check if these are actually org changes vs technical suggestions
|
|
68
|
+
const isTechnicalOnly = TECHNICAL_SUGGESTIONS.some(tech =>
|
|
69
|
+
lowerOutput.includes(tech) && foundKeywords.length === 0
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
hasOrgChanges: foundKeywords.length > 0 && !isTechnicalOnly,
|
|
74
|
+
suggestions,
|
|
75
|
+
keywordCount: foundKeywords.length,
|
|
76
|
+
overhead: estimateOverhead(suggestions),
|
|
77
|
+
recommendation: foundKeywords.length > 0
|
|
78
|
+
? 'Consider if organizational changes are necessary for this task'
|
|
79
|
+
: 'No organizational changes detected'
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Flag team restructuring suggestions
|
|
85
|
+
* @param {string} suggestion - The suggestion text
|
|
86
|
+
* @returns {object} Flagged suggestion details
|
|
87
|
+
*/
|
|
88
|
+
function flagTeamRestructure(suggestion) {
|
|
89
|
+
const result = detectOrgChanges(suggestion);
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
flagged: result.hasOrgChanges,
|
|
93
|
+
...result,
|
|
94
|
+
severity: result.keywordCount > 3
|
|
95
|
+
? 'high'
|
|
96
|
+
: result.keywordCount > 1
|
|
97
|
+
? 'medium'
|
|
98
|
+
: 'low',
|
|
99
|
+
action: result.hasOrgChanges
|
|
100
|
+
? 'Requires explicit justification and user approval'
|
|
101
|
+
: 'No action needed'
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Check overhead of organizational changes
|
|
107
|
+
* @param {array} suggestions - Array of organizational suggestions
|
|
108
|
+
* @returns {string} Estimated overhead description
|
|
109
|
+
*/
|
|
110
|
+
function estimateOverhead(suggestions) {
|
|
111
|
+
if (suggestions.length === 0) {
|
|
112
|
+
return 'No organizational overhead';
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const categories = new Set();
|
|
116
|
+
|
|
117
|
+
for (const suggestion of suggestions) {
|
|
118
|
+
if (['team structure', 'reorganize', 'restructure', 'squad', 'tribe'].some(k => suggestion.keyword.includes(k))) {
|
|
119
|
+
categories.add('team-restructure');
|
|
120
|
+
}
|
|
121
|
+
if (['role', 'hire', 'recruit', 'lead', 'manager'].some(k => suggestion.keyword.includes(k))) {
|
|
122
|
+
categories.add('hiring-roles');
|
|
123
|
+
}
|
|
124
|
+
if (['meeting', 'standup', 'ceremony', 'sync'].some(k => suggestion.keyword.includes(k))) {
|
|
125
|
+
categories.add('meeting-overhead');
|
|
126
|
+
}
|
|
127
|
+
if (['process', 'workflow', 'approval', 'sign-off'].some(k => suggestion.keyword.includes(k))) {
|
|
128
|
+
categories.add('process-overhead');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const overheadEstimates = {
|
|
133
|
+
'team-restructure': 'High: Team restructuring has long-term impact',
|
|
134
|
+
'hiring-roles': 'High: New roles require budget and time',
|
|
135
|
+
'meeting-overhead': 'Medium: Recurring time commitment',
|
|
136
|
+
'process-overhead': 'Medium: Ongoing process overhead'
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const estimates = Array.from(categories).map(c => overheadEstimates[c]);
|
|
140
|
+
|
|
141
|
+
if (estimates.length === 0) {
|
|
142
|
+
return 'Low: Minor organizational impact';
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return estimates.join('; ');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Check for team overhead in task context
|
|
150
|
+
* @param {string} taskContext - Task description
|
|
151
|
+
* @returns {object} Team overhead analysis
|
|
152
|
+
*/
|
|
153
|
+
function checkOverhead(taskContext) {
|
|
154
|
+
const orgChanges = detectOrgChanges(taskContext);
|
|
155
|
+
const flagged = flagTeamRestructure(taskContext);
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
hasOrgChanges: orgChanges.hasOrgChanges,
|
|
159
|
+
suggestions: orgChanges.suggestions,
|
|
160
|
+
overhead: orgChanges.overhead,
|
|
161
|
+
severity: flagged.severity,
|
|
162
|
+
actionable: flagged.flagged,
|
|
163
|
+
recommendation: flagged.flagged
|
|
164
|
+
? 'Remove organizational suggestions or explicitly justify them'
|
|
165
|
+
: 'Task context is appropriate'
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Extract context around a keyword
|
|
171
|
+
* @param {string} text - Full text
|
|
172
|
+
* @param {string} keyword - Keyword to find context for
|
|
173
|
+
* @returns {string} Context around keyword
|
|
174
|
+
*/
|
|
175
|
+
function extractContext(text, keyword) {
|
|
176
|
+
const index = text.toLowerCase().indexOf(keyword);
|
|
177
|
+
if (index === -1) return '';
|
|
178
|
+
|
|
179
|
+
const start = Math.max(0, index - 50);
|
|
180
|
+
const end = Math.min(text.length, index + keyword.length + 100);
|
|
181
|
+
|
|
182
|
+
return text.substring(start, end)
|
|
183
|
+
.replace(/\s+/g, ' ')
|
|
184
|
+
.trim();
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Full team overhead check
|
|
189
|
+
* @param {string} output - AI generated output
|
|
190
|
+
* @returns {object} Complete team overhead analysis
|
|
191
|
+
*/
|
|
192
|
+
function checkTeamOverhead(output) {
|
|
193
|
+
const orgChanges = detectOrgChanges(output);
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
...orgChanges,
|
|
197
|
+
summary: orgChanges.hasOrgChanges
|
|
198
|
+
? `⚠️ Found ${orgChanges.keywordCount} organizational change suggestion(s)`
|
|
199
|
+
: '✅ No organizational changes detected',
|
|
200
|
+
actionable: orgChanges.hasOrgChanges
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* CLI entry point
|
|
206
|
+
*/
|
|
207
|
+
if (require.main === module) {
|
|
208
|
+
const args = process.argv.slice(2);
|
|
209
|
+
const command = args[0];
|
|
210
|
+
|
|
211
|
+
if (command === 'check') {
|
|
212
|
+
const text = args.slice(1).join(' ') || process.stdin.read();
|
|
213
|
+
|
|
214
|
+
if (!text.trim()) {
|
|
215
|
+
console.log('Usage: node team-overhead-guard.cjs check <text>');
|
|
216
|
+
console.log(' or: echo "text" | node team-overhead-guard.cjs check');
|
|
217
|
+
process.exit(1);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const result = checkTeamOverhead(text);
|
|
221
|
+
|
|
222
|
+
console.log('Team Overhead Analysis');
|
|
223
|
+
console.log('======================');
|
|
224
|
+
console.log(result.summary);
|
|
225
|
+
|
|
226
|
+
if (result.suggestions.length > 0) {
|
|
227
|
+
console.log('');
|
|
228
|
+
console.log('Organizational suggestions found:');
|
|
229
|
+
result.suggestions.forEach((s, i) => {
|
|
230
|
+
console.log(` ${i + 1}. "${s.context}"`);
|
|
231
|
+
console.log(` Keyword: ${s.keyword}`);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
console.log('');
|
|
235
|
+
console.log(`Estimated overhead: ${result.overhead}`);
|
|
236
|
+
console.log('');
|
|
237
|
+
console.log('Recommendation:');
|
|
238
|
+
console.log(` ${result.recommendation}`);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
process.exit(result.hasOrgChanges ? 1 : 0);
|
|
242
|
+
|
|
243
|
+
} else if (command === 'keywords') {
|
|
244
|
+
console.log('Organizational change keywords:');
|
|
245
|
+
ORG_CHANGE_KEYWORDS.forEach(k => console.log(` - ${k}`));
|
|
246
|
+
process.exit(0);
|
|
247
|
+
|
|
248
|
+
} else {
|
|
249
|
+
console.log('Usage: node team-overhead-guard.cjs <command> [args]');
|
|
250
|
+
console.log('Commands:');
|
|
251
|
+
console.log(' check [text] - Analyze for organizational changes');
|
|
252
|
+
console.log(' keywords - List organizational change keywords');
|
|
253
|
+
process.exit(1);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
module.exports = {
|
|
258
|
+
detectOrgChanges,
|
|
259
|
+
flagTeamRestructure,
|
|
260
|
+
estimateOverhead,
|
|
261
|
+
checkOverhead,
|
|
262
|
+
checkTeamOverhead,
|
|
263
|
+
extractContext,
|
|
264
|
+
ORG_CHANGE_KEYWORDS,
|
|
265
|
+
TECHNICAL_SUGGESTIONS
|
|
266
|
+
};
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EDGE-05: Tool Sprawl Guard
|
|
3
|
+
*
|
|
4
|
+
* Enforces 3-7 skills/tools per task limit.
|
|
5
|
+
* Prevents cognitive overload and maintains focus.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Recommended skill/tool categories
|
|
9
|
+
const SKILL_CATEGORIES = {
|
|
10
|
+
core: ['runtime', 'framework', 'language'],
|
|
11
|
+
testing: ['test-runner', 'assertion', 'mocking', 'coverage'],
|
|
12
|
+
database: ['orm', 'query-builder', 'migration', 'driver'],
|
|
13
|
+
ui: ['component-library', 'styling', 'state-management', 'routing'],
|
|
14
|
+
devops: ['bundler', 'linter', 'formatter', 'ci-cd']
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get active tools/skills from task context
|
|
19
|
+
* @param {string} taskContext - Task description or context
|
|
20
|
+
* @returns {string[]} Array of active tools/skills
|
|
21
|
+
*/
|
|
22
|
+
function getActiveTools(taskContext) {
|
|
23
|
+
const toolPatterns = [
|
|
24
|
+
/(?:using|with|via|through|use|via)\s+(?:the\s+)?(['"]?)([^'"\s,]+)\1(?:\s+(?:library|tool|package|framework|skill))?/gi,
|
|
25
|
+
/(?:tool|library|package|framework|skill)[:\s]+(['"]?)([^'"\s,]+)\1/gi,
|
|
26
|
+
/@([a-z0-9_-]+\/[a-z0-9_-]+)/gi, // npm scoped packages
|
|
27
|
+
/(?:npm|yarn|pnpm)\s+(?:install|add)\s+([^&|;\n]+)/gi
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
const tools = new Set();
|
|
31
|
+
|
|
32
|
+
for (const pattern of toolPatterns) {
|
|
33
|
+
let match;
|
|
34
|
+
while ((match = pattern.exec(taskContext)) !== null) {
|
|
35
|
+
// Extract the tool name (group 2 for most patterns, group 1 for scoped)
|
|
36
|
+
const toolName = match[2] || match[1];
|
|
37
|
+
if (toolName) {
|
|
38
|
+
tools.add(toolName.toLowerCase().replace(/['"]/g, ''));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return Array.from(tools);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Check tool count against limits
|
|
48
|
+
* @param {string[]} activeTools - Array of active tools/skills
|
|
49
|
+
* @returns {object} { count: number, withinLimit: boolean, exceeded: number }
|
|
50
|
+
*/
|
|
51
|
+
function checkToolCount(activeTools) {
|
|
52
|
+
const count = activeTools.length;
|
|
53
|
+
const minRecommended = 3;
|
|
54
|
+
const maxRecommended = 7;
|
|
55
|
+
|
|
56
|
+
let withinLimit = true;
|
|
57
|
+
let exceeded = 0;
|
|
58
|
+
|
|
59
|
+
if (count > maxRecommended) {
|
|
60
|
+
withinLimit = false;
|
|
61
|
+
exceeded = count - maxRecommended;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
count,
|
|
66
|
+
withinLimit,
|
|
67
|
+
exceeded,
|
|
68
|
+
minRecommended,
|
|
69
|
+
maxRecommended,
|
|
70
|
+
status: count < minRecommended
|
|
71
|
+
? 'below-recommended'
|
|
72
|
+
: count > maxRecommended
|
|
73
|
+
? 'exceeded'
|
|
74
|
+
: 'optimal'
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Enforce skill limit on a task
|
|
80
|
+
* @param {string} taskContext - Task description
|
|
81
|
+
* @returns {object} Enforcement result with recommendations
|
|
82
|
+
*/
|
|
83
|
+
function enforceSkillLimit(taskContext) {
|
|
84
|
+
const activeTools = getActiveTools(taskContext);
|
|
85
|
+
const toolCheck = checkToolCount(activeTools);
|
|
86
|
+
|
|
87
|
+
if (toolCheck.withinLimit) {
|
|
88
|
+
return {
|
|
89
|
+
enforced: true,
|
|
90
|
+
tools: activeTools,
|
|
91
|
+
...toolCheck,
|
|
92
|
+
recommendation: 'Tool count is within recommended limits'
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Categorize tools
|
|
97
|
+
const categorized = categorizeTools(activeTools);
|
|
98
|
+
|
|
99
|
+
// Recommend which tools to keep
|
|
100
|
+
const recommended = recommendTools(categorized, taskContext);
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
enforced: false,
|
|
104
|
+
tools: activeTools,
|
|
105
|
+
...toolCheck,
|
|
106
|
+
categorized,
|
|
107
|
+
recommended,
|
|
108
|
+
recommendation: `Reduce from ${toolCheck.count} to ${toolCheck.maxRecommended} tools. Consider removing: ${activeTools.filter(t => !recommended.includes(t)).join(', ')}`
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Categorize tools by function
|
|
114
|
+
* @param {string[]} tools - Array of tools
|
|
115
|
+
* @returns {object} Categorized tools
|
|
116
|
+
*/
|
|
117
|
+
function categorizeTools(tools) {
|
|
118
|
+
const categories = {
|
|
119
|
+
core: [],
|
|
120
|
+
testing: [],
|
|
121
|
+
database: [],
|
|
122
|
+
ui: [],
|
|
123
|
+
devops: [],
|
|
124
|
+
other: []
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// Simple categorization based on tool name patterns
|
|
128
|
+
const categoryPatterns = {
|
|
129
|
+
testing: ['jest', 'vitest', 'mocha', 'chai', 'sinon', 'playwright', 'cypress', 'test'],
|
|
130
|
+
database: ['prisma', 'mongoose', 'sequelize', 'typeorm', 'knex', 'mongo', 'postgres', 'mysql'],
|
|
131
|
+
ui: ['react', 'vue', 'angular', 'svelte', 'tailwind', 'bootstrap', 'material', 'chakra'],
|
|
132
|
+
devops: ['webpack', 'vite', 'rollup', 'eslint', 'prettier', 'husky', 'lint']
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
for (const tool of tools) {
|
|
136
|
+
let categorized = false;
|
|
137
|
+
|
|
138
|
+
for (const [category, patterns] of Object.entries(categoryPatterns)) {
|
|
139
|
+
if (patterns.some(p => tool.toLowerCase().includes(p))) {
|
|
140
|
+
categories[category].push(tool);
|
|
141
|
+
categorized = true;
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (!categorized) {
|
|
147
|
+
categories.other.push(tool);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return categories;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Recommend which tools to keep based on task context
|
|
156
|
+
* @param {object} categorized - Categorized tools
|
|
157
|
+
* @param {string} taskContext - Task description
|
|
158
|
+
* @returns {string[]} Recommended tools to keep
|
|
159
|
+
*/
|
|
160
|
+
function recommendTools(categorized, taskContext) {
|
|
161
|
+
const recommended = [];
|
|
162
|
+
const lowerContext = taskContext.toLowerCase();
|
|
163
|
+
|
|
164
|
+
// Always keep core tools
|
|
165
|
+
recommended.push(...categorized.core);
|
|
166
|
+
|
|
167
|
+
// Add category based on task context
|
|
168
|
+
if (lowerContext.includes('test') || lowerContext.includes('spec')) {
|
|
169
|
+
recommended.push(...categorized.testing.slice(0, 2));
|
|
170
|
+
}
|
|
171
|
+
if (lowerContext.includes('database') || lowerContext.includes('model') || lowerContext.includes('schema')) {
|
|
172
|
+
recommended.push(...categorized.database.slice(0, 2));
|
|
173
|
+
}
|
|
174
|
+
if (lowerContext.includes('ui') || lowerContext.includes('component') || lowerContext.includes('render')) {
|
|
175
|
+
recommended.push(...categorized.ui.slice(0, 2));
|
|
176
|
+
}
|
|
177
|
+
if (lowerContext.includes('build') || lowerContext.includes('bundle') || lowerContext.includes('deploy')) {
|
|
178
|
+
recommended.push(...categorized.devops.slice(0, 2));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Add some other tools if space allows
|
|
182
|
+
const remaining = 7 - recommended.length;
|
|
183
|
+
if (remaining > 0) {
|
|
184
|
+
recommended.push(...categorized.other.slice(0, remaining));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Deduplicate
|
|
188
|
+
return [...new Set(recommended)];
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Full tool sprawl check
|
|
193
|
+
* @param {string} taskContext - Task description
|
|
194
|
+
* @returns {object} Complete tool sprawl analysis
|
|
195
|
+
*/
|
|
196
|
+
function checkToolSprawl(taskContext) {
|
|
197
|
+
const activeTools = getActiveTools(taskContext);
|
|
198
|
+
const toolCheck = checkToolCount(activeTools);
|
|
199
|
+
const enforcement = enforceSkillLimit(taskContext);
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
...toolCheck,
|
|
203
|
+
tools: activeTools,
|
|
204
|
+
enforcement,
|
|
205
|
+
actionable: !toolCheck.withinLimit,
|
|
206
|
+
summary: toolCheck.withinLimit
|
|
207
|
+
? `✅ Using ${toolCheck.count} tools (optimal: 3-7)`
|
|
208
|
+
: `⚠️ Using ${toolCheck.count} tools (${toolCheck.exceeded} over limit)`
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* CLI entry point
|
|
214
|
+
*/
|
|
215
|
+
if (require.main === module) {
|
|
216
|
+
const args = process.argv.slice(2);
|
|
217
|
+
const command = args[0];
|
|
218
|
+
|
|
219
|
+
if (command === 'check') {
|
|
220
|
+
const context = args.slice(1).join(' ') || process.stdin.read();
|
|
221
|
+
|
|
222
|
+
if (!context.trim()) {
|
|
223
|
+
console.log('Usage: node tool-sprawl-guard.cjs check <task context>');
|
|
224
|
+
console.log(' or: echo "task context" | node tool-sprawl-guard.cjs check');
|
|
225
|
+
process.exit(1);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const result = checkToolSprawl(context);
|
|
229
|
+
|
|
230
|
+
console.log('Tool Sprawl Analysis');
|
|
231
|
+
console.log('====================');
|
|
232
|
+
console.log(`Tools found: ${result.count}`);
|
|
233
|
+
console.log(`Status: ${result.status}`);
|
|
234
|
+
console.log('');
|
|
235
|
+
|
|
236
|
+
if (result.tools.length > 0) {
|
|
237
|
+
console.log('Active tools:');
|
|
238
|
+
result.tools.forEach(t => console.log(` - ${t}`));
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
console.log('');
|
|
242
|
+
console.log(result.summary);
|
|
243
|
+
|
|
244
|
+
if (!result.withinLimit) {
|
|
245
|
+
console.log('');
|
|
246
|
+
console.log('Recommendation:');
|
|
247
|
+
console.log(` ${result.enforcement.recommendation}`);
|
|
248
|
+
console.log('');
|
|
249
|
+
console.log('Recommended tools to keep:');
|
|
250
|
+
result.enforcement.recommended.forEach(t => console.log(` - ${t}`));
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
process.exit(result.withinLimit ? 0 : 1);
|
|
254
|
+
|
|
255
|
+
} else {
|
|
256
|
+
console.log('Usage: node tool-sprawl-guard.cjs <command> [args]');
|
|
257
|
+
console.log('Commands:');
|
|
258
|
+
console.log(' check [context] - Analyze tool usage (reads from stdin if no args)');
|
|
259
|
+
process.exit(1);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
module.exports = {
|
|
264
|
+
getActiveTools,
|
|
265
|
+
checkToolCount,
|
|
266
|
+
enforceSkillLimit,
|
|
267
|
+
categorizeTools,
|
|
268
|
+
recommendTools,
|
|
269
|
+
checkToolSprawl,
|
|
270
|
+
SKILL_CATEGORIES
|
|
271
|
+
};
|