@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,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,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EDGE-02: Context Budget Guard
|
|
3
|
+
*
|
|
4
|
+
* Monitors token usage and provides progressive warnings.
|
|
5
|
+
* Prevents context budget exhaustion that degrades AI quality.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
// Model token limits (approximate)
|
|
12
|
+
const MODEL_LIMITS = {
|
|
13
|
+
'claude-3-5-sonnet': 200000,
|
|
14
|
+
'claude-3-opus': 200000,
|
|
15
|
+
'claude-3-sonnet': 200000,
|
|
16
|
+
'claude-3-haiku': 200000,
|
|
17
|
+
'gpt-4-turbo': 128000,
|
|
18
|
+
'gpt-4': 8192,
|
|
19
|
+
'gemini-pro': 32000,
|
|
20
|
+
'default': 100000
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Warning thresholds
|
|
24
|
+
const THRESHOLDS = {
|
|
25
|
+
info: 50, // Quality degradation begins
|
|
26
|
+
warning: 70, // Efficiency mode engaged
|
|
27
|
+
error: 80 // Hard stop
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get token usage from executor context
|
|
32
|
+
* @param {string} contextPath - Path to context file
|
|
33
|
+
* @returns {object} { current: number, max: number, model: string }
|
|
34
|
+
*/
|
|
35
|
+
function getTokenUsage(contextPath) {
|
|
36
|
+
// Try to read from context file
|
|
37
|
+
if (contextPath && fs.existsSync(contextPath)) {
|
|
38
|
+
try {
|
|
39
|
+
const content = fs.readFileSync(contextPath, 'utf8');
|
|
40
|
+
// Look for token usage markers
|
|
41
|
+
const currentMatch = content.match(/tokens_used[:\s]+(\d+)/i);
|
|
42
|
+
const maxMatch = content.match(/token_limit[:\s]+(\d+)/i);
|
|
43
|
+
const modelMatch = content.match(/model[:\s]+(['"]?)([^'"\s,]+)\1/i);
|
|
44
|
+
|
|
45
|
+
if (currentMatch && maxMatch) {
|
|
46
|
+
return {
|
|
47
|
+
current: parseInt(currentMatch[1], 10),
|
|
48
|
+
max: parseInt(maxMatch[1], 10),
|
|
49
|
+
model: modelMatch ? modelMatch[2] : 'default'
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
} catch (e) {
|
|
53
|
+
// Could not parse context file
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Default: return estimated usage
|
|
58
|
+
return {
|
|
59
|
+
current: 0,
|
|
60
|
+
max: MODEL_LIMITS.default,
|
|
61
|
+
model: 'default'
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Check context budget and return warnings
|
|
67
|
+
* @param {number} tokenUsage - Current token usage
|
|
68
|
+
* @param {number} modelLimit - Model's token limit
|
|
69
|
+
* @returns {object} { percent: number, warnings: array, shouldStop: boolean }
|
|
70
|
+
*/
|
|
71
|
+
function checkContextBudget(tokenUsage, modelLimit) {
|
|
72
|
+
const percent = (tokenUsage / modelLimit) * 100;
|
|
73
|
+
const warnings = [];
|
|
74
|
+
|
|
75
|
+
if (percent >= THRESHOLDS.info) {
|
|
76
|
+
warnings.push({
|
|
77
|
+
level: 'info',
|
|
78
|
+
threshold: THRESHOLDS.info,
|
|
79
|
+
message: `Context usage at ${Math.round(percent)}% - quality degradation begins`,
|
|
80
|
+
recommendation: 'Consider splitting task or summarizing context'
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (percent >= THRESHOLDS.warning) {
|
|
85
|
+
warnings.push({
|
|
86
|
+
level: 'warning',
|
|
87
|
+
threshold: THRESHOLDS.warning,
|
|
88
|
+
message: `Context usage at ${Math.round(percent)}% - efficiency mode engaged`,
|
|
89
|
+
recommendation: 'Strongly recommended to split task'
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (percent >= THRESHOLDS.error) {
|
|
94
|
+
warnings.push({
|
|
95
|
+
level: 'error',
|
|
96
|
+
threshold: THRESHOLDS.error,
|
|
97
|
+
message: `Context usage at ${Math.round(percent)}% - hard stop`,
|
|
98
|
+
recommendation: 'Task MUST be split - context budget exhausted'
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
percent: Math.round(percent * 100) / 100,
|
|
104
|
+
warnings,
|
|
105
|
+
shouldStop: percent >= THRESHOLDS.error,
|
|
106
|
+
remaining: modelLimit - tokenUsage,
|
|
107
|
+
remainingPercent: Math.round((100 - percent) * 100) / 100
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Determine if execution should stop
|
|
113
|
+
* @param {number} tokenUsage - Current token usage
|
|
114
|
+
* @param {number} modelLimit - Model's token limit
|
|
115
|
+
* @returns {boolean} True if should stop
|
|
116
|
+
*/
|
|
117
|
+
function shouldStop(tokenUsage, modelLimit) {
|
|
118
|
+
const percent = (tokenUsage / modelLimit) * 100;
|
|
119
|
+
return percent >= THRESHOLDS.error;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Get recommended action based on context usage
|
|
124
|
+
* @param {number} tokenUsage - Current token usage
|
|
125
|
+
* @param {number} modelLimit - Model's token limit
|
|
126
|
+
* @returns {string} Recommended action
|
|
127
|
+
*/
|
|
128
|
+
function getRecommendedAction(tokenUsage, modelLimit) {
|
|
129
|
+
const percent = (tokenUsage / modelLimit) * 100;
|
|
130
|
+
|
|
131
|
+
if (percent >= THRESHOLDS.error) {
|
|
132
|
+
return 'STOP: Split task immediately and start new context';
|
|
133
|
+
} else if (percent >= THRESHOLDS.warning) {
|
|
134
|
+
return 'WARNING: Plan to split task soon - summarize or defer non-essential context';
|
|
135
|
+
} else if (percent >= THRESHOLDS.info) {
|
|
136
|
+
return 'INFO: Monitor context usage - consider being more concise';
|
|
137
|
+
} else {
|
|
138
|
+
return 'OK: Context usage is healthy';
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Full context budget check with auto-detection
|
|
144
|
+
* @param {string} contextPath - Path to context file (optional)
|
|
145
|
+
* @param {string} model - Model name (optional, auto-detected if not provided)
|
|
146
|
+
* @returns {object} Complete context budget status
|
|
147
|
+
*/
|
|
148
|
+
function checkBudget(contextPath, model) {
|
|
149
|
+
const usage = getTokenUsage(contextPath);
|
|
150
|
+
|
|
151
|
+
// Override model if provided
|
|
152
|
+
if (model && MODEL_LIMITS[model]) {
|
|
153
|
+
usage.max = MODEL_LIMITS[model];
|
|
154
|
+
usage.model = model;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const budgetCheck = checkContextBudget(usage.current, usage.max);
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
model: usage.model,
|
|
161
|
+
limit: usage.max,
|
|
162
|
+
used: usage.current,
|
|
163
|
+
...budgetCheck,
|
|
164
|
+
action: getRecommendedAction(usage.current, usage.max)
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* CLI entry point
|
|
170
|
+
*/
|
|
171
|
+
if (require.main === module) {
|
|
172
|
+
const args = process.argv.slice(2);
|
|
173
|
+
const command = args[0];
|
|
174
|
+
|
|
175
|
+
if (command === 'check' && args[1] && args[2]) {
|
|
176
|
+
const current = parseInt(args[1], 10);
|
|
177
|
+
const max = parseInt(args[2], 10);
|
|
178
|
+
|
|
179
|
+
console.log(`Context Budget Check`);
|
|
180
|
+
console.log(`====================`);
|
|
181
|
+
console.log(`Current: ${current.toLocaleString()} tokens`);
|
|
182
|
+
console.log(`Limit: ${max.toLocaleString()} tokens`);
|
|
183
|
+
console.log(`Usage: ${((current/max)*100).toFixed(1)}%`);
|
|
184
|
+
console.log('');
|
|
185
|
+
|
|
186
|
+
const result = checkContextBudget(current, max);
|
|
187
|
+
|
|
188
|
+
if (result.warnings.length > 0) {
|
|
189
|
+
console.log('Warnings:');
|
|
190
|
+
result.warnings.forEach(w => {
|
|
191
|
+
console.log(` [${w.level.toUpperCase()}] ${w.message}`);
|
|
192
|
+
console.log(` → ${w.recommendation}`);
|
|
193
|
+
});
|
|
194
|
+
} else {
|
|
195
|
+
console.log('✅ Context usage is healthy');
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
console.log('');
|
|
199
|
+
console.log(`Remaining: ${result.remaining.toLocaleString()} tokens (${result.remainingPercent}%)`);
|
|
200
|
+
console.log(`Action: ${getRecommendedAction(current, max)}`);
|
|
201
|
+
|
|
202
|
+
process.exit(result.shouldStop ? 1 : 0);
|
|
203
|
+
|
|
204
|
+
} else if (command === 'status') {
|
|
205
|
+
const contextPath = args[1];
|
|
206
|
+
const result = checkBudget(contextPath);
|
|
207
|
+
|
|
208
|
+
console.log(`Context Budget Status`);
|
|
209
|
+
console.log(`=====================`);
|
|
210
|
+
console.log(`Model: ${result.model}`);
|
|
211
|
+
console.log(`Limit: ${result.limit.toLocaleString()} tokens`);
|
|
212
|
+
console.log(`Used: ${result.used.toLocaleString()} tokens`);
|
|
213
|
+
console.log(`Usage: ${result.percent}%`);
|
|
214
|
+
console.log('');
|
|
215
|
+
|
|
216
|
+
if (result.warnings.length > 0) {
|
|
217
|
+
console.log('Warnings:');
|
|
218
|
+
result.warnings.forEach(w => {
|
|
219
|
+
console.log(` [${w.level.toUpperCase()}] ${w.message}`);
|
|
220
|
+
});
|
|
221
|
+
} else {
|
|
222
|
+
console.log('✅ Context usage is healthy');
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
console.log('');
|
|
226
|
+
console.log(`Action: ${result.action}`);
|
|
227
|
+
|
|
228
|
+
process.exit(result.shouldStop ? 1 : 0);
|
|
229
|
+
|
|
230
|
+
} else {
|
|
231
|
+
console.log('Usage: node context-budget-guard.cjs <command> [args]');
|
|
232
|
+
console.log('Commands:');
|
|
233
|
+
console.log(' check <current> <max> - Check budget with explicit values');
|
|
234
|
+
console.log(' status [contextPath] - Check budget from context file');
|
|
235
|
+
process.exit(1);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
module.exports = {
|
|
240
|
+
getTokenUsage,
|
|
241
|
+
checkContextBudget,
|
|
242
|
+
shouldStop,
|
|
243
|
+
getRecommendedAction,
|
|
244
|
+
checkBudget,
|
|
245
|
+
THRESHOLDS,
|
|
246
|
+
MODEL_LIMITS
|
|
247
|
+
};
|