@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,346 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EDGE-04: Autonomy Guard
|
|
3
|
+
*
|
|
4
|
+
* Detects irreversible operations requiring human approval.
|
|
5
|
+
* Prevents unbounded autonomy for sensitive operations.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
// Operations that require human approval
|
|
12
|
+
const IRREVERSIBLE_OPERATIONS = [
|
|
13
|
+
// Database operations
|
|
14
|
+
'drop database',
|
|
15
|
+
'drop table',
|
|
16
|
+
'truncate',
|
|
17
|
+
'delete all',
|
|
18
|
+
'delete from',
|
|
19
|
+
'drop column',
|
|
20
|
+
'drop index',
|
|
21
|
+
'schema migration',
|
|
22
|
+
'data migration',
|
|
23
|
+
|
|
24
|
+
// File operations
|
|
25
|
+
'rm -rf',
|
|
26
|
+
'del /f',
|
|
27
|
+
'delete directory',
|
|
28
|
+
'remove directory',
|
|
29
|
+
'format',
|
|
30
|
+
|
|
31
|
+
// Deployment operations
|
|
32
|
+
'production deploy',
|
|
33
|
+
'deploy to production',
|
|
34
|
+
'release to production',
|
|
35
|
+
'push to production',
|
|
36
|
+
|
|
37
|
+
// Security operations
|
|
38
|
+
'delete user',
|
|
39
|
+
'revoke access',
|
|
40
|
+
'reset credentials',
|
|
41
|
+
'delete api key',
|
|
42
|
+
'rotate secrets',
|
|
43
|
+
|
|
44
|
+
// Infrastructure
|
|
45
|
+
'terminate instance',
|
|
46
|
+
'delete cluster',
|
|
47
|
+
'destroy environment',
|
|
48
|
+
'scale down to zero'
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
// Operations that are generally safe
|
|
52
|
+
const SAFE_OPERATIONS = [
|
|
53
|
+
'read',
|
|
54
|
+
'list',
|
|
55
|
+
'get',
|
|
56
|
+
'fetch',
|
|
57
|
+
'query',
|
|
58
|
+
'select',
|
|
59
|
+
'create',
|
|
60
|
+
'insert',
|
|
61
|
+
'update',
|
|
62
|
+
'build',
|
|
63
|
+
'compile',
|
|
64
|
+
'test',
|
|
65
|
+
'lint',
|
|
66
|
+
'format'
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Check if an operation is irreversible
|
|
71
|
+
* @param {string} operation - Operation description
|
|
72
|
+
* @returns {object} { irreversible: boolean, reason: string, category: string }
|
|
73
|
+
*/
|
|
74
|
+
function checkIrreversibleOps(operation) {
|
|
75
|
+
const lowerOp = operation.toLowerCase();
|
|
76
|
+
|
|
77
|
+
for (const irreversible of IRREVERSIBLE_OPERATIONS) {
|
|
78
|
+
if (lowerOp.includes(irreversible)) {
|
|
79
|
+
return {
|
|
80
|
+
irreversible: true,
|
|
81
|
+
requiresApproval: true,
|
|
82
|
+
reason: `Operation contains irreversible action: "${irreversible}"`,
|
|
83
|
+
category: categorizeOperation(irreversible)
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Check for safe operations
|
|
89
|
+
for (const safe of SAFE_OPERATIONS) {
|
|
90
|
+
if (lowerOp.includes(safe)) {
|
|
91
|
+
return {
|
|
92
|
+
irreversible: false,
|
|
93
|
+
requiresApproval: false,
|
|
94
|
+
reason: `Operation is reversible: "${safe}"`,
|
|
95
|
+
category: 'safe'
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Unknown operation - flag for review
|
|
101
|
+
return {
|
|
102
|
+
irreversible: false,
|
|
103
|
+
requiresApproval: false,
|
|
104
|
+
reason: 'Operation not classified - assuming safe',
|
|
105
|
+
category: 'unknown'
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Categorize an operation
|
|
111
|
+
* @param {string} operation - Operation description
|
|
112
|
+
* @returns {string} Category name
|
|
113
|
+
*/
|
|
114
|
+
function categorizeOperation(operation) {
|
|
115
|
+
const lowerOp = operation.toLowerCase();
|
|
116
|
+
|
|
117
|
+
if (lowerOp.includes('database') || lowerOp.includes('table') || lowerOp.includes('schema')) {
|
|
118
|
+
return 'database';
|
|
119
|
+
}
|
|
120
|
+
if (lowerOp.includes('file') || lowerOp.includes('directory') || lowerOp.includes('rm ') || lowerOp.includes('del ')) {
|
|
121
|
+
return 'filesystem';
|
|
122
|
+
}
|
|
123
|
+
if (lowerOp.includes('deploy') || lowerOp.includes('production') || lowerOp.includes('release')) {
|
|
124
|
+
return 'deployment';
|
|
125
|
+
}
|
|
126
|
+
if (lowerOp.includes('user') || lowerOp.includes('access') || lowerOp.includes('credential') || lowerOp.includes('secret')) {
|
|
127
|
+
return 'security';
|
|
128
|
+
}
|
|
129
|
+
if (lowerOp.includes('instance') || lowerOp.includes('cluster') || lowerOp.includes('environment')) {
|
|
130
|
+
return 'infrastructure';
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return 'general';
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Check if operation requires human approval
|
|
138
|
+
* @param {string} operation - Operation description
|
|
139
|
+
* @returns {boolean} True if approval required
|
|
140
|
+
*/
|
|
141
|
+
function requiresHumanApproval(operation) {
|
|
142
|
+
const result = checkIrreversibleOps(operation);
|
|
143
|
+
return result.requiresApproval;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Flag an operation for approval
|
|
148
|
+
* @param {string} operation - Operation description
|
|
149
|
+
* @param {string} reason - Reason for flagging
|
|
150
|
+
* @param {string} approvalFile - Path to write approval request
|
|
151
|
+
* @returns {object} Approval request result
|
|
152
|
+
*/
|
|
153
|
+
function flagOperation(operation, reason, approvalFile) {
|
|
154
|
+
const approvalRequest = {
|
|
155
|
+
timestamp: new Date().toISOString(),
|
|
156
|
+
operation,
|
|
157
|
+
reason,
|
|
158
|
+
status: 'pending',
|
|
159
|
+
category: categorizeOperation(operation)
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
try {
|
|
163
|
+
// Ensure directory exists
|
|
164
|
+
const dir = path.dirname(approvalFile);
|
|
165
|
+
if (!fs.existsSync(dir)) {
|
|
166
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Write approval request
|
|
170
|
+
fs.writeFileSync(
|
|
171
|
+
approvalFile,
|
|
172
|
+
`# Approval Request
|
|
173
|
+
|
|
174
|
+
**Created:** ${approvalRequest.timestamp}
|
|
175
|
+
**Category:** ${approvalRequest.category}
|
|
176
|
+
**Status:** ${approvalRequest.status}
|
|
177
|
+
|
|
178
|
+
## Operation
|
|
179
|
+
|
|
180
|
+
\`\`\`
|
|
181
|
+
${operation}
|
|
182
|
+
\`\`\`
|
|
183
|
+
|
|
184
|
+
## Reason for Approval
|
|
185
|
+
|
|
186
|
+
${reason}
|
|
187
|
+
|
|
188
|
+
## Approval
|
|
189
|
+
|
|
190
|
+
- [ ] Approved by: _______________
|
|
191
|
+
- [ ] Date: _______________
|
|
192
|
+
- [ ] Comments: _______________
|
|
193
|
+
`
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
success: true,
|
|
198
|
+
file: approvalFile,
|
|
199
|
+
request: approvalRequest
|
|
200
|
+
};
|
|
201
|
+
} catch (e) {
|
|
202
|
+
return {
|
|
203
|
+
success: false,
|
|
204
|
+
error: e.message,
|
|
205
|
+
request: approvalRequest
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Full autonomy check
|
|
212
|
+
* @param {string} output - AI generated output describing operations
|
|
213
|
+
* @param {string} phaseDir - Phase directory
|
|
214
|
+
* @returns {object} Complete autonomy check result
|
|
215
|
+
*/
|
|
216
|
+
function checkAutonomy(output, phaseDir) {
|
|
217
|
+
const operations = extractOperations(output);
|
|
218
|
+
const flaggedOperations = [];
|
|
219
|
+
const safeOperations = [];
|
|
220
|
+
|
|
221
|
+
for (const op of operations) {
|
|
222
|
+
const result = checkIrreversibleOps(op);
|
|
223
|
+
if (result.requiresApproval) {
|
|
224
|
+
flaggedOperations.push({
|
|
225
|
+
operation: op,
|
|
226
|
+
...result
|
|
227
|
+
});
|
|
228
|
+
} else {
|
|
229
|
+
safeOperations.push({
|
|
230
|
+
operation: op,
|
|
231
|
+
...result
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Flag operations if any need approval
|
|
237
|
+
const approvalFiles = [];
|
|
238
|
+
if (flaggedOperations.length > 0 && phaseDir) {
|
|
239
|
+
const approvalsDir = path.join(phaseDir, '.planning', 'approvals');
|
|
240
|
+
for (let i = 0; i < flaggedOperations.length; i++) {
|
|
241
|
+
const flag = flaggedOperations[i];
|
|
242
|
+
const approvalFile = path.join(approvalsDir, `approval-${Date.now()}-${i}.md`);
|
|
243
|
+
const result = flagOperation(flag.operation, flag.reason, approvalFile);
|
|
244
|
+
if (result.success) {
|
|
245
|
+
approvalFiles.push(result.file);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
requiresApproval: flaggedOperations.length > 0,
|
|
252
|
+
flaggedOperations,
|
|
253
|
+
safeOperations,
|
|
254
|
+
approvalFiles,
|
|
255
|
+
recommendation: flaggedOperations.length > 0
|
|
256
|
+
? `Human approval required for ${flaggedOperations.length} operation(s). Check .planning/approvals/`
|
|
257
|
+
: 'All operations are safe to execute autonomously'
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Extract operations from text
|
|
263
|
+
* @param {string} text - Text to analyze
|
|
264
|
+
* @returns {string[]} Array of operations
|
|
265
|
+
*/
|
|
266
|
+
function extractOperations(text) {
|
|
267
|
+
const operationPatterns = [
|
|
268
|
+
/(?:will|would|should|must|need to)\s+(?:then\s+)?([A-Z][^.!?]*(?:database|table|file|directory|deploy|production|user)[^.!?]*)/gi,
|
|
269
|
+
/(?:step \d+[:\s]+)([A-Z][^.!?]+)/gi,
|
|
270
|
+
/(?:command|operation)[:\s]+([A-Z][^.!?]+)/gi
|
|
271
|
+
];
|
|
272
|
+
|
|
273
|
+
const operations = new Set();
|
|
274
|
+
|
|
275
|
+
for (const pattern of operationPatterns) {
|
|
276
|
+
let match;
|
|
277
|
+
while ((match = pattern.exec(text)) !== null) {
|
|
278
|
+
const op = match[1].trim();
|
|
279
|
+
if (op.length > 10 && op.length < 200) {
|
|
280
|
+
operations.add(op);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return Array.from(operations);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* CLI entry point
|
|
290
|
+
*/
|
|
291
|
+
if (require.main === module) {
|
|
292
|
+
const args = process.argv.slice(2);
|
|
293
|
+
const command = args[0];
|
|
294
|
+
|
|
295
|
+
if (command === 'check' && args[1]) {
|
|
296
|
+
const operation = args.slice(1).join(' ');
|
|
297
|
+
console.log(`Checking operation: "${operation}"`);
|
|
298
|
+
|
|
299
|
+
const result = checkIrreversibleOps(operation);
|
|
300
|
+
|
|
301
|
+
if (result.requiresApproval) {
|
|
302
|
+
console.log(`⚠️ Requires human approval`);
|
|
303
|
+
console.log(` Category: ${result.category}`);
|
|
304
|
+
console.log(` Reason: ${result.reason}`);
|
|
305
|
+
process.exit(1);
|
|
306
|
+
} else {
|
|
307
|
+
console.log(`✅ Safe to execute autonomously`);
|
|
308
|
+
console.log(` Category: ${result.category}`);
|
|
309
|
+
console.log(` Reason: ${result.reason}`);
|
|
310
|
+
process.exit(0);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
} else if (command === 'flag' && args[1]) {
|
|
314
|
+
const operation = args[2] || args[1];
|
|
315
|
+
const reason = args[3] || 'Flagged for review';
|
|
316
|
+
const approvalFile = args[4] || `.planning/approvals/approval-${Date.now()}.md`;
|
|
317
|
+
|
|
318
|
+
const result = flagOperation(operation, reason, approvalFile);
|
|
319
|
+
|
|
320
|
+
if (result.success) {
|
|
321
|
+
console.log(`✅ Approval request created: ${result.file}`);
|
|
322
|
+
process.exit(0);
|
|
323
|
+
} else {
|
|
324
|
+
console.log(`❌ Failed to create approval request: ${result.error}`);
|
|
325
|
+
process.exit(1);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
} else {
|
|
329
|
+
console.log('Usage: node autonomy-guard.cjs <command> [args]');
|
|
330
|
+
console.log('Commands:');
|
|
331
|
+
console.log(' check <operation> - Check if operation requires approval');
|
|
332
|
+
console.log(' flag <operation> [reason] - Create approval request');
|
|
333
|
+
process.exit(1);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
module.exports = {
|
|
338
|
+
checkIrreversibleOps,
|
|
339
|
+
requiresHumanApproval,
|
|
340
|
+
flagOperation,
|
|
341
|
+
checkAutonomy,
|
|
342
|
+
extractOperations,
|
|
343
|
+
categorizeOperation,
|
|
344
|
+
IRREVERSIBLE_OPERATIONS,
|
|
345
|
+
SAFE_OPERATIONS
|
|
346
|
+
};
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Context Budget Guard - Prevents context budget exhaustion with progressive warnings
|
|
9
|
+
*
|
|
10
|
+
* Monitors token usage and provides warnings at:
|
|
11
|
+
* - 50%: Info - Context degradation begins
|
|
12
|
+
* - 70%: Warning - Efficiency mode engaged
|
|
13
|
+
* - 80%: Error - Hard stop, should stop processing
|
|
14
|
+
*
|
|
15
|
+
* Exports:
|
|
16
|
+
* - checkContextBudget(tokenUsage, modelLimits) - Calculate usage and warnings
|
|
17
|
+
* - getTokenUsage() - Read current token usage from executor context
|
|
18
|
+
* - shouldStop() - Check if usage >= 80%
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Warning thresholds for context budget
|
|
23
|
+
*/
|
|
24
|
+
const THRESHOLDS = {
|
|
25
|
+
INFO: 50, // 50% - Info warning
|
|
26
|
+
WARNING: 70, // 70% - Warning level
|
|
27
|
+
ERROR: 80 // 80% - Hard stop
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Warning messages for each threshold level
|
|
32
|
+
*/
|
|
33
|
+
const WARNING_MESSAGES = {
|
|
34
|
+
[THRESHOLDS.INFO]: 'Context usage at {percent}% - quality degradation begins',
|
|
35
|
+
[THRESHOLDS.WARNING]: 'Context usage at {percent}% - efficiency mode engaged',
|
|
36
|
+
[THRESHOLDS.ERROR]: 'Context usage at {percent}% - hard stop'
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Check context budget and return progressive warnings
|
|
41
|
+
* @param {number} tokenUsage - Current token count
|
|
42
|
+
* @param {number} modelLimits - Maximum token limit for the model
|
|
43
|
+
* @returns {{
|
|
44
|
+
* percent: number,
|
|
45
|
+
* level: 'none' | 'info' | 'warning' | 'error',
|
|
46
|
+
* message: string | null,
|
|
47
|
+
* warnings: Array<{level: string, message: string}>,
|
|
48
|
+
* shouldStop: boolean
|
|
49
|
+
* }}
|
|
50
|
+
*/
|
|
51
|
+
function checkContextBudget(tokenUsage, modelLimits) {
|
|
52
|
+
if (modelLimits <= 0) {
|
|
53
|
+
return {
|
|
54
|
+
percent: 0,
|
|
55
|
+
level: 'none',
|
|
56
|
+
message: null,
|
|
57
|
+
warnings: [],
|
|
58
|
+
shouldStop: false
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const percent = Math.round((tokenUsage / modelLimits) * 100);
|
|
63
|
+
const warnings = [];
|
|
64
|
+
let level = 'none';
|
|
65
|
+
let message = null;
|
|
66
|
+
let shouldStop = false;
|
|
67
|
+
|
|
68
|
+
// Check thresholds and add progressive warnings
|
|
69
|
+
if (percent >= THRESHOLDS.ERROR) {
|
|
70
|
+
level = 'error';
|
|
71
|
+
message = WARNING_MESSAGES[THRESHOLDS.ERROR].replace('{percent}', percent);
|
|
72
|
+
shouldStop = true;
|
|
73
|
+
warnings.push({
|
|
74
|
+
level: 'error',
|
|
75
|
+
message: WARNING_MESSAGES[THRESHOLDS.ERROR].replace('{percent}', percent)
|
|
76
|
+
});
|
|
77
|
+
} else if (percent >= THRESHOLDS.WARNING) {
|
|
78
|
+
level = 'warning';
|
|
79
|
+
message = WARNING_MESSAGES[THRESHOLDS.WARNING].replace('{percent}', percent);
|
|
80
|
+
warnings.push({
|
|
81
|
+
level: 'warning',
|
|
82
|
+
message: WARNING_MESSAGES[THRESHOLDS.WARNING].replace('{percent}', percent)
|
|
83
|
+
});
|
|
84
|
+
// Also include info warning for context
|
|
85
|
+
if (percent >= THRESHOLDS.INFO) {
|
|
86
|
+
warnings.unshift({
|
|
87
|
+
level: 'info',
|
|
88
|
+
message: WARNING_MESSAGES[THRESHOLDS.INFO].replace('{percent}', THRESHOLDS.INFO)
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
} else if (percent >= THRESHOLDS.INFO) {
|
|
92
|
+
level = 'info';
|
|
93
|
+
message = WARNING_MESSAGES[THRESHOLDS.INFO].replace('{percent}', percent);
|
|
94
|
+
warnings.push({
|
|
95
|
+
level: 'info',
|
|
96
|
+
message: WARNING_MESSAGES[THRESHOLDS.INFO].replace('{percent}', percent)
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
percent,
|
|
102
|
+
level,
|
|
103
|
+
message,
|
|
104
|
+
warnings,
|
|
105
|
+
shouldStop
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Get current token usage from executor context file
|
|
111
|
+
* @param {string} contextFile - Path to executor context file (optional)
|
|
112
|
+
* @returns {{ currentTokens: number, maxTokens: number, percent: number } | null}
|
|
113
|
+
*/
|
|
114
|
+
function getTokenUsage(contextFile) {
|
|
115
|
+
// Default context file locations
|
|
116
|
+
const possiblePaths = [
|
|
117
|
+
contextFile,
|
|
118
|
+
path.join(process.cwd(), '.planning', 'context.json'),
|
|
119
|
+
path.join(process.cwd(), '.planning', 'executor-context.json'),
|
|
120
|
+
path.join(process.cwd(), 'ez-agents', 'context.json'),
|
|
121
|
+
path.join(process.cwd(), '.qwen', 'context.json')
|
|
122
|
+
].filter(Boolean);
|
|
123
|
+
|
|
124
|
+
for (const filePath of possiblePaths) {
|
|
125
|
+
if (filePath && fs.existsSync(filePath)) {
|
|
126
|
+
try {
|
|
127
|
+
const data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
128
|
+
return {
|
|
129
|
+
currentTokens: data.tokenUsage || data.currentTokens || 0,
|
|
130
|
+
maxTokens: data.modelLimits || data.maxTokens || 0,
|
|
131
|
+
percent: data.percent || 0
|
|
132
|
+
};
|
|
133
|
+
} catch (err) {
|
|
134
|
+
// Continue to next file
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Check if context budget has reached the hard stop threshold
|
|
144
|
+
* @param {number} tokenUsage - Current token count
|
|
145
|
+
* @param {number} modelLimits - Maximum token limit
|
|
146
|
+
* @returns {boolean} - True if usage >= 80%
|
|
147
|
+
*/
|
|
148
|
+
function shouldStop(tokenUsage, modelLimits) {
|
|
149
|
+
if (!modelLimits || modelLimits <= 0) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
const percent = (tokenUsage / modelLimits) * 100;
|
|
153
|
+
return percent >= THRESHOLDS.ERROR;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Get the current warning level based on usage percentage
|
|
158
|
+
* @param {number} percent - Usage percentage (0-100)
|
|
159
|
+
* @returns {'none' | 'info' | 'warning' | 'error'}
|
|
160
|
+
*/
|
|
161
|
+
function getWarningLevel(percent) {
|
|
162
|
+
if (percent >= THRESHOLDS.ERROR) {
|
|
163
|
+
return 'error';
|
|
164
|
+
} else if (percent >= THRESHOLDS.WARNING) {
|
|
165
|
+
return 'warning';
|
|
166
|
+
} else if (percent >= THRESHOLDS.INFO) {
|
|
167
|
+
return 'info';
|
|
168
|
+
}
|
|
169
|
+
return 'none';
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Get warning message for a specific threshold
|
|
174
|
+
* @param {number} percent - Current percentage
|
|
175
|
+
* @param {number} threshold - Threshold to get message for
|
|
176
|
+
* @returns {string}
|
|
177
|
+
*/
|
|
178
|
+
function getWarningMessage(percent, threshold = THRESHOLDS.INFO) {
|
|
179
|
+
const template = WARNING_MESSAGES[threshold] || WARNING_MESSAGES[THRESHOLDS.INFO];
|
|
180
|
+
return template.replace('{percent}', percent);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* CLI entry point
|
|
185
|
+
*/
|
|
186
|
+
function main() {
|
|
187
|
+
const args = process.argv.slice(2);
|
|
188
|
+
|
|
189
|
+
if (args.length === 0) {
|
|
190
|
+
console.log('Context Budget Guard - Token usage monitoring with progressive warnings');
|
|
191
|
+
console.log('');
|
|
192
|
+
console.log('Usage:');
|
|
193
|
+
console.log(' node context-budget-guard.cjs check <current_tokens> <max_tokens>');
|
|
194
|
+
console.log(' node context-budget-guard.cjs status [context-file]');
|
|
195
|
+
console.log(' node context-budget-guard.cjs thresholds');
|
|
196
|
+
console.log('');
|
|
197
|
+
console.log('Commands:');
|
|
198
|
+
console.log(' check - Check budget for specific token values');
|
|
199
|
+
console.log(' status - Read and display current context status from file');
|
|
200
|
+
console.log(' thresholds - Show warning threshold configuration');
|
|
201
|
+
console.log('');
|
|
202
|
+
console.log('Thresholds:');
|
|
203
|
+
console.log(` ${THRESHOLDS.INFO}% - Info warning (quality degradation begins)`);
|
|
204
|
+
console.log(` ${THRESHOLDS.WARNING}% - Warning (efficiency mode engaged)`);
|
|
205
|
+
console.log(` ${THRESHOLDS.ERROR}% - Error (hard stop)`);
|
|
206
|
+
process.exit(0);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const command = args[0];
|
|
210
|
+
|
|
211
|
+
switch (command) {
|
|
212
|
+
case 'check': {
|
|
213
|
+
const currentTokens = parseInt(args[1], 10);
|
|
214
|
+
const maxTokens = parseInt(args[2], 10);
|
|
215
|
+
|
|
216
|
+
if (isNaN(currentTokens) || isNaN(maxTokens)) {
|
|
217
|
+
console.error('Error: Both current_tokens and max_tokens must be numbers');
|
|
218
|
+
console.error('Usage: node context-budget-guard.cjs check <current_tokens> <max_tokens>');
|
|
219
|
+
process.exit(1);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const result = checkContextBudget(currentTokens, maxTokens);
|
|
223
|
+
console.log(JSON.stringify(result, null, 2));
|
|
224
|
+
process.exit(result.shouldStop ? 1 : 0);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
case 'status': {
|
|
228
|
+
const contextFile = args[1];
|
|
229
|
+
const usage = getTokenUsage(contextFile);
|
|
230
|
+
|
|
231
|
+
if (!usage) {
|
|
232
|
+
console.log('No context file found or unable to read token usage');
|
|
233
|
+
process.exit(1);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const result = checkContextBudget(usage.currentTokens, usage.maxTokens);
|
|
237
|
+
console.log('Context Budget Status:');
|
|
238
|
+
console.log(` Current: ${usage.currentTokens.toLocaleString()} tokens`);
|
|
239
|
+
console.log(` Maximum: ${usage.maxTokens.toLocaleString()} tokens`);
|
|
240
|
+
console.log(` Usage: ${result.percent}%`);
|
|
241
|
+
console.log(` Level: ${result.level.toUpperCase()}`);
|
|
242
|
+
if (result.message) {
|
|
243
|
+
console.log(` Message: ${result.message}`);
|
|
244
|
+
}
|
|
245
|
+
console.log(` Stop: ${result.shouldStop ? 'YES' : 'no'}`);
|
|
246
|
+
process.exit(result.shouldStop ? 1 : 0);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
case 'thresholds': {
|
|
250
|
+
console.log('Context Budget Thresholds:');
|
|
251
|
+
console.log(` ${THRESHOLDS.INFO}% - Info: ${WARNING_MESSAGES[THRESHOLDS.INFO].replace('{percent}', THRESHOLDS.INFO)}`);
|
|
252
|
+
console.log(` ${THRESHOLDS.WARNING}% - Warning: ${WARNING_MESSAGES[THRESHOLDS.WARNING].replace('{percent}', THRESHOLDS.WARNING)}`);
|
|
253
|
+
console.log(` ${THRESHOLDS.ERROR}% - Error: ${WARNING_MESSAGES[THRESHOLDS.ERROR].replace('{percent}', THRESHOLDS.ERROR)}`);
|
|
254
|
+
process.exit(0);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
default:
|
|
258
|
+
console.error(`Unknown command: ${command}`);
|
|
259
|
+
console.log('Use "node context-budget-guard.cjs" for usage information');
|
|
260
|
+
process.exit(1);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Export functions for programmatic use
|
|
265
|
+
module.exports = {
|
|
266
|
+
checkContextBudget,
|
|
267
|
+
getTokenUsage,
|
|
268
|
+
shouldStop,
|
|
269
|
+
getWarningLevel,
|
|
270
|
+
getWarningMessage,
|
|
271
|
+
THRESHOLDS,
|
|
272
|
+
WARNING_MESSAGES
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
// Run CLI if executed directly
|
|
276
|
+
if (require.main === module) {
|
|
277
|
+
main();
|
|
278
|
+
}
|