@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
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// Check for EZ Agents updates in background, write result to cache
|
|
3
|
-
// Called by SessionStart hook - runs once per session
|
|
4
|
-
|
|
5
|
-
const fs = require('fs');
|
|
6
|
-
const path = require('path');
|
|
7
|
-
const os = require('os');
|
|
8
|
-
const { spawn } = require('child_process');
|
|
9
|
-
|
|
10
|
-
const homeDir = os.homedir();
|
|
11
|
-
const cwd = process.cwd();
|
|
12
|
-
|
|
13
|
-
// Detect runtime config directory (supports Claude, OpenCode, Gemini)
|
|
14
|
-
// Respects CLAUDE_CONFIG_DIR for custom config directory setups
|
|
15
|
-
function detectConfigDir(baseDir) {
|
|
16
|
-
// Check env override first (supports multi-account setups)
|
|
17
|
-
const envDir = process.env.CLAUDE_CONFIG_DIR;
|
|
18
|
-
if (envDir && fs.existsSync(path.join(envDir, 'ez-agents', 'VERSION'))) {
|
|
19
|
-
return envDir;
|
|
20
|
-
}
|
|
21
|
-
for (const dir of ['.config/opencode', '.opencode', '.gemini', '.claude']) {
|
|
22
|
-
if (fs.existsSync(path.join(baseDir, dir, 'ez-agents', 'VERSION'))) {
|
|
23
|
-
return path.join(baseDir, dir);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return envDir || path.join(baseDir, '.claude');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const globalConfigDir = detectConfigDir(homeDir);
|
|
30
|
-
const projectConfigDir = detectConfigDir(cwd);
|
|
31
|
-
const cacheDir = path.join(globalConfigDir, 'cache');
|
|
32
|
-
const cacheFile = path.join(cacheDir, 'ez-update-check.json');
|
|
33
|
-
|
|
34
|
-
// VERSION file locations (check project first, then global)
|
|
35
|
-
const projectVersionFile = path.join(projectConfigDir, 'ez-agents', 'VERSION');
|
|
36
|
-
const globalVersionFile = path.join(globalConfigDir, 'ez-agents', 'VERSION');
|
|
37
|
-
|
|
38
|
-
// Ensure cache directory exists
|
|
39
|
-
if (!fs.existsSync(cacheDir)) {
|
|
40
|
-
fs.mkdirSync(cacheDir, { recursive: true });
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Run check in background (spawn background process, windowsHide prevents console flash)
|
|
44
|
-
const child = spawn(process.execPath, ['-e', `
|
|
45
|
-
const fs = require('fs');
|
|
46
|
-
const { execSync } = require('child_process');
|
|
47
|
-
|
|
48
|
-
const cacheFile = ${JSON.stringify(cacheFile)};
|
|
49
|
-
const projectVersionFile = ${JSON.stringify(projectVersionFile)};
|
|
50
|
-
const globalVersionFile = ${JSON.stringify(globalVersionFile)};
|
|
51
|
-
|
|
52
|
-
// Check project directory first (local install), then global
|
|
53
|
-
let installed = '0.0.0';
|
|
54
|
-
try {
|
|
55
|
-
if (fs.existsSync(projectVersionFile)) {
|
|
56
|
-
installed = fs.readFileSync(projectVersionFile, 'utf8').trim();
|
|
57
|
-
} else if (fs.existsSync(globalVersionFile)) {
|
|
58
|
-
installed = fs.readFileSync(globalVersionFile, 'utf8').trim();
|
|
59
|
-
}
|
|
60
|
-
} catch (e) {}
|
|
61
|
-
|
|
62
|
-
let latest = null;
|
|
63
|
-
try {
|
|
64
|
-
latest = execSync('npm view ez-agents version', { encoding: 'utf8', timeout: 10000, windowsHide: true }).trim();
|
|
65
|
-
} catch (e) {}
|
|
66
|
-
|
|
67
|
-
const result = {
|
|
68
|
-
update_available: latest && installed !== latest,
|
|
69
|
-
installed,
|
|
70
|
-
latest: latest || 'unknown',
|
|
71
|
-
checked: Math.floor(Date.now() / 1000)
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
fs.writeFileSync(cacheFile, JSON.stringify(result));
|
|
75
|
-
`], {
|
|
76
|
-
stdio: 'ignore',
|
|
77
|
-
windowsHide: true,
|
|
78
|
-
detached: true // Required on Windows for proper process detachment
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
child.unref();
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Check for EZ Agents updates in background, write result to cache
|
|
3
|
+
// Called by SessionStart hook - runs once per session
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const os = require('os');
|
|
8
|
+
const { spawn } = require('child_process');
|
|
9
|
+
|
|
10
|
+
const homeDir = os.homedir();
|
|
11
|
+
const cwd = process.cwd();
|
|
12
|
+
|
|
13
|
+
// Detect runtime config directory (supports Claude, OpenCode, Gemini)
|
|
14
|
+
// Respects CLAUDE_CONFIG_DIR for custom config directory setups
|
|
15
|
+
function detectConfigDir(baseDir) {
|
|
16
|
+
// Check env override first (supports multi-account setups)
|
|
17
|
+
const envDir = process.env.CLAUDE_CONFIG_DIR;
|
|
18
|
+
if (envDir && fs.existsSync(path.join(envDir, 'ez-agents', 'VERSION'))) {
|
|
19
|
+
return envDir;
|
|
20
|
+
}
|
|
21
|
+
for (const dir of ['.config/opencode', '.opencode', '.gemini', '.claude']) {
|
|
22
|
+
if (fs.existsSync(path.join(baseDir, dir, 'ez-agents', 'VERSION'))) {
|
|
23
|
+
return path.join(baseDir, dir);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return envDir || path.join(baseDir, '.claude');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const globalConfigDir = detectConfigDir(homeDir);
|
|
30
|
+
const projectConfigDir = detectConfigDir(cwd);
|
|
31
|
+
const cacheDir = path.join(globalConfigDir, 'cache');
|
|
32
|
+
const cacheFile = path.join(cacheDir, 'ez-update-check.json');
|
|
33
|
+
|
|
34
|
+
// VERSION file locations (check project first, then global)
|
|
35
|
+
const projectVersionFile = path.join(projectConfigDir, 'ez-agents', 'VERSION');
|
|
36
|
+
const globalVersionFile = path.join(globalConfigDir, 'ez-agents', 'VERSION');
|
|
37
|
+
|
|
38
|
+
// Ensure cache directory exists
|
|
39
|
+
if (!fs.existsSync(cacheDir)) {
|
|
40
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Run check in background (spawn background process, windowsHide prevents console flash)
|
|
44
|
+
const child = spawn(process.execPath, ['-e', `
|
|
45
|
+
const fs = require('fs');
|
|
46
|
+
const { execSync } = require('child_process');
|
|
47
|
+
|
|
48
|
+
const cacheFile = ${JSON.stringify(cacheFile)};
|
|
49
|
+
const projectVersionFile = ${JSON.stringify(projectVersionFile)};
|
|
50
|
+
const globalVersionFile = ${JSON.stringify(globalVersionFile)};
|
|
51
|
+
|
|
52
|
+
// Check project directory first (local install), then global
|
|
53
|
+
let installed = '0.0.0';
|
|
54
|
+
try {
|
|
55
|
+
if (fs.existsSync(projectVersionFile)) {
|
|
56
|
+
installed = fs.readFileSync(projectVersionFile, 'utf8').trim();
|
|
57
|
+
} else if (fs.existsSync(globalVersionFile)) {
|
|
58
|
+
installed = fs.readFileSync(globalVersionFile, 'utf8').trim();
|
|
59
|
+
}
|
|
60
|
+
} catch (e) {}
|
|
61
|
+
|
|
62
|
+
let latest = null;
|
|
63
|
+
try {
|
|
64
|
+
latest = execSync('npm view ez-agents version', { encoding: 'utf8', timeout: 10000, windowsHide: true }).trim();
|
|
65
|
+
} catch (e) {}
|
|
66
|
+
|
|
67
|
+
const result = {
|
|
68
|
+
update_available: latest && installed !== latest,
|
|
69
|
+
installed,
|
|
70
|
+
latest: latest || 'unknown',
|
|
71
|
+
checked: Math.floor(Date.now() / 1000)
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
fs.writeFileSync(cacheFile, JSON.stringify(result));
|
|
75
|
+
`], {
|
|
76
|
+
stdio: 'ignore',
|
|
77
|
+
windowsHide: true,
|
|
78
|
+
detached: true // Required on Windows for proper process detachment
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
child.unref();
|
|
@@ -1,141 +1,148 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// Context Monitor - PostToolUse/AfterTool hook (Gemini uses AfterTool)
|
|
3
|
-
// Reads context metrics from the statusline bridge file and injects
|
|
4
|
-
// warnings when context usage is high. This makes the AGENT aware of
|
|
5
|
-
// context limits (the statusline only shows the user).
|
|
6
|
-
//
|
|
7
|
-
// How it works:
|
|
8
|
-
// 1. The statusline hook writes metrics to /tmp/claude-ctx-{session_id}.json
|
|
9
|
-
// 2. This hook reads those metrics after each tool use
|
|
10
|
-
// 3. When remaining context drops below thresholds, it injects a warning
|
|
11
|
-
// as additionalContext, which the agent sees in its conversation
|
|
12
|
-
//
|
|
13
|
-
// Thresholds:
|
|
14
|
-
// WARNING (remaining <= 35%): Agent should wrap up current task
|
|
15
|
-
// CRITICAL (remaining <= 25%): Agent should stop immediately and save state
|
|
16
|
-
//
|
|
17
|
-
// Debounce: 5 tool uses between warnings to avoid spam
|
|
18
|
-
// Severity escalation bypasses debounce (WARNING -> CRITICAL fires immediately)
|
|
19
|
-
|
|
20
|
-
const fs = require('fs');
|
|
21
|
-
const os = require('os');
|
|
22
|
-
const path = require('path');
|
|
23
|
-
|
|
24
|
-
const WARNING_THRESHOLD = 35; // remaining_percentage <= 35%
|
|
25
|
-
const CRITICAL_THRESHOLD = 25; // remaining_percentage <= 25%
|
|
26
|
-
const STALE_SECONDS = 60; // ignore metrics older than 60s
|
|
27
|
-
const DEBOUNCE_CALLS = 5; // min tool uses between warnings
|
|
28
|
-
|
|
29
|
-
let input = '';
|
|
30
|
-
// Timeout guard: if stdin doesn't close within 3s (e.g. pipe issues on
|
|
31
|
-
// Windows/Git Bash), exit silently instead of hanging until Claude Code
|
|
32
|
-
// kills the process and reports "hook error". See #775.
|
|
33
|
-
const stdinTimeout = setTimeout(() => process.exit(0), 3000);
|
|
34
|
-
process.stdin.setEncoding('utf8');
|
|
35
|
-
process.stdin.on('data', chunk => input += chunk);
|
|
36
|
-
process.stdin.on('end', () => {
|
|
37
|
-
clearTimeout(stdinTimeout);
|
|
38
|
-
try {
|
|
39
|
-
const data = JSON.parse(input);
|
|
40
|
-
const sessionId = data.session_id;
|
|
41
|
-
|
|
42
|
-
if (!sessionId) {
|
|
43
|
-
process.exit(0);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const tmpDir = os.tmpdir();
|
|
47
|
-
const metricsPath = path.join(tmpDir, `claude-ctx-${sessionId}.json`);
|
|
48
|
-
|
|
49
|
-
// If no metrics file, this is a subagent or fresh session -- exit silently
|
|
50
|
-
if (!fs.existsSync(metricsPath)) {
|
|
51
|
-
process.exit(0);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const metrics = JSON.parse(fs.readFileSync(metricsPath, 'utf8'));
|
|
55
|
-
const now = Math.floor(Date.now() / 1000);
|
|
56
|
-
|
|
57
|
-
// Ignore stale metrics
|
|
58
|
-
if (metrics.timestamp && (now - metrics.timestamp) > STALE_SECONDS) {
|
|
59
|
-
process.exit(0);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const remaining = metrics.remaining_percentage;
|
|
63
|
-
const usedPct = metrics.used_pct;
|
|
64
|
-
|
|
65
|
-
// No warning needed
|
|
66
|
-
if (remaining > WARNING_THRESHOLD) {
|
|
67
|
-
process.exit(0);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Debounce: check if we warned recently
|
|
71
|
-
const warnPath = path.join(tmpDir, `claude-ctx-${sessionId}-warned.json`);
|
|
72
|
-
let warnData = { callsSinceWarn: 0, lastLevel: null };
|
|
73
|
-
let firstWarn = true;
|
|
74
|
-
|
|
75
|
-
if (fs.existsSync(warnPath)) {
|
|
76
|
-
try {
|
|
77
|
-
warnData = JSON.parse(fs.readFileSync(warnPath, 'utf8'));
|
|
78
|
-
firstWarn = false;
|
|
79
|
-
} catch (e) {
|
|
80
|
-
// Corrupted file, reset
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
warnData.callsSinceWarn = (warnData.callsSinceWarn || 0) + 1;
|
|
85
|
-
|
|
86
|
-
const isCritical = remaining <= CRITICAL_THRESHOLD;
|
|
87
|
-
const currentLevel = isCritical ? 'critical' : 'warning';
|
|
88
|
-
|
|
89
|
-
// Emit immediately on first warning, then debounce subsequent ones
|
|
90
|
-
// Severity escalation (WARNING -> CRITICAL) bypasses debounce
|
|
91
|
-
const severityEscalated = currentLevel === 'critical' && warnData.lastLevel === 'warning';
|
|
92
|
-
if (!firstWarn && warnData.callsSinceWarn < DEBOUNCE_CALLS && !severityEscalated) {
|
|
93
|
-
// Update counter and exit without warning
|
|
94
|
-
fs.writeFileSync(warnPath, JSON.stringify(warnData));
|
|
95
|
-
process.exit(0);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Reset debounce counter
|
|
99
|
-
warnData.callsSinceWarn = 0;
|
|
100
|
-
warnData.lastLevel = currentLevel;
|
|
101
|
-
fs.writeFileSync(warnPath, JSON.stringify(warnData));
|
|
102
|
-
|
|
103
|
-
// Detect if EZ Agents is active (has .planning/STATE.md in working directory)
|
|
104
|
-
const cwd = data.cwd || process.cwd();
|
|
105
|
-
const isEzActive = fs.existsSync(path.join(cwd, '.planning', 'STATE.md'));
|
|
106
|
-
|
|
107
|
-
// Build advisory warning message (never use imperative commands that
|
|
108
|
-
// override user preferences — see #884)
|
|
109
|
-
let message;
|
|
110
|
-
if (isCritical) {
|
|
111
|
-
message = isEzActive
|
|
112
|
-
? `CONTEXT CRITICAL: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
113
|
-
'Context is nearly exhausted. Do NOT start new complex work or write handoff files — ' +
|
|
114
|
-
'EZ Agents state is already tracked in STATE.md. Inform the user so they can run ' +
|
|
115
|
-
'/ez:pause-work at the next natural stopping point.'
|
|
116
|
-
: `CONTEXT CRITICAL: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
117
|
-
'Context is nearly exhausted. Inform the user that context is low and ask how they ' +
|
|
118
|
-
'want to proceed. Do NOT autonomously save state or write handoff files unless the user asks.';
|
|
119
|
-
} else {
|
|
120
|
-
message = isEzActive
|
|
121
|
-
? `CONTEXT WARNING: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
122
|
-
'Context is getting limited. Avoid starting new complex work. If not between ' +
|
|
123
|
-
'defined plan steps, inform the user so they can prepare to pause.'
|
|
124
|
-
: `CONTEXT WARNING: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
125
|
-
'Be aware that context is getting limited. Avoid unnecessary exploration or ' +
|
|
126
|
-
'starting new complex work.';
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Context Monitor - PostToolUse/AfterTool hook (Gemini uses AfterTool)
|
|
3
|
+
// Reads context metrics from the statusline bridge file and injects
|
|
4
|
+
// warnings when context usage is high. This makes the AGENT aware of
|
|
5
|
+
// context limits (the statusline only shows the user).
|
|
6
|
+
//
|
|
7
|
+
// How it works:
|
|
8
|
+
// 1. The statusline hook writes metrics to /tmp/claude-ctx-{session_id}.json
|
|
9
|
+
// 2. This hook reads those metrics after each tool use
|
|
10
|
+
// 3. When remaining context drops below thresholds, it injects a warning
|
|
11
|
+
// as additionalContext, which the agent sees in its conversation
|
|
12
|
+
//
|
|
13
|
+
// Thresholds:
|
|
14
|
+
// WARNING (remaining <= 35%): Agent should wrap up current task
|
|
15
|
+
// CRITICAL (remaining <= 25%): Agent should stop immediately and save state
|
|
16
|
+
//
|
|
17
|
+
// Debounce: 5 tool uses between warnings to avoid spam
|
|
18
|
+
// Severity escalation bypasses debounce (WARNING -> CRITICAL fires immediately)
|
|
19
|
+
|
|
20
|
+
const fs = require('fs');
|
|
21
|
+
const os = require('os');
|
|
22
|
+
const path = require('path');
|
|
23
|
+
|
|
24
|
+
const WARNING_THRESHOLD = 35; // remaining_percentage <= 35%
|
|
25
|
+
const CRITICAL_THRESHOLD = 25; // remaining_percentage <= 25%
|
|
26
|
+
const STALE_SECONDS = 60; // ignore metrics older than 60s
|
|
27
|
+
const DEBOUNCE_CALLS = 5; // min tool uses between warnings
|
|
28
|
+
|
|
29
|
+
let input = '';
|
|
30
|
+
// Timeout guard: if stdin doesn't close within 3s (e.g. pipe issues on
|
|
31
|
+
// Windows/Git Bash), exit silently instead of hanging until Claude Code
|
|
32
|
+
// kills the process and reports "hook error". See #775.
|
|
33
|
+
const stdinTimeout = setTimeout(() => process.exit(0), 3000);
|
|
34
|
+
process.stdin.setEncoding('utf8');
|
|
35
|
+
process.stdin.on('data', chunk => input += chunk);
|
|
36
|
+
process.stdin.on('end', () => {
|
|
37
|
+
clearTimeout(stdinTimeout);
|
|
38
|
+
try {
|
|
39
|
+
const data = JSON.parse(input);
|
|
40
|
+
const sessionId = data.session_id;
|
|
41
|
+
|
|
42
|
+
if (!sessionId) {
|
|
43
|
+
process.exit(0);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const tmpDir = os.tmpdir();
|
|
47
|
+
const metricsPath = path.join(tmpDir, `claude-ctx-${sessionId}.json`);
|
|
48
|
+
|
|
49
|
+
// If no metrics file, this is a subagent or fresh session -- exit silently
|
|
50
|
+
if (!fs.existsSync(metricsPath)) {
|
|
51
|
+
process.exit(0);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const metrics = JSON.parse(fs.readFileSync(metricsPath, 'utf8'));
|
|
55
|
+
const now = Math.floor(Date.now() / 1000);
|
|
56
|
+
|
|
57
|
+
// Ignore stale metrics
|
|
58
|
+
if (metrics.timestamp && (now - metrics.timestamp) > STALE_SECONDS) {
|
|
59
|
+
process.exit(0);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const remaining = metrics.remaining_percentage;
|
|
63
|
+
const usedPct = metrics.used_pct;
|
|
64
|
+
|
|
65
|
+
// No warning needed
|
|
66
|
+
if (remaining > WARNING_THRESHOLD) {
|
|
67
|
+
process.exit(0);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Debounce: check if we warned recently
|
|
71
|
+
const warnPath = path.join(tmpDir, `claude-ctx-${sessionId}-warned.json`);
|
|
72
|
+
let warnData = { callsSinceWarn: 0, lastLevel: null };
|
|
73
|
+
let firstWarn = true;
|
|
74
|
+
|
|
75
|
+
if (fs.existsSync(warnPath)) {
|
|
76
|
+
try {
|
|
77
|
+
warnData = JSON.parse(fs.readFileSync(warnPath, 'utf8'));
|
|
78
|
+
firstWarn = false;
|
|
79
|
+
} catch (e) {
|
|
80
|
+
// Corrupted file, reset
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
warnData.callsSinceWarn = (warnData.callsSinceWarn || 0) + 1;
|
|
85
|
+
|
|
86
|
+
const isCritical = remaining <= CRITICAL_THRESHOLD;
|
|
87
|
+
const currentLevel = isCritical ? 'critical' : 'warning';
|
|
88
|
+
|
|
89
|
+
// Emit immediately on first warning, then debounce subsequent ones
|
|
90
|
+
// Severity escalation (WARNING -> CRITICAL) bypasses debounce
|
|
91
|
+
const severityEscalated = currentLevel === 'critical' && warnData.lastLevel === 'warning';
|
|
92
|
+
if (!firstWarn && warnData.callsSinceWarn < DEBOUNCE_CALLS && !severityEscalated) {
|
|
93
|
+
// Update counter and exit without warning
|
|
94
|
+
fs.writeFileSync(warnPath, JSON.stringify(warnData));
|
|
95
|
+
process.exit(0);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Reset debounce counter
|
|
99
|
+
warnData.callsSinceWarn = 0;
|
|
100
|
+
warnData.lastLevel = currentLevel;
|
|
101
|
+
fs.writeFileSync(warnPath, JSON.stringify(warnData));
|
|
102
|
+
|
|
103
|
+
// Detect if EZ Agents is active (has .planning/STATE.md in working directory)
|
|
104
|
+
const cwd = data.cwd || process.cwd();
|
|
105
|
+
const isEzActive = fs.existsSync(path.join(cwd, '.planning', 'STATE.md'));
|
|
106
|
+
|
|
107
|
+
// Build advisory warning message (never use imperative commands that
|
|
108
|
+
// override user preferences — see #884)
|
|
109
|
+
let message;
|
|
110
|
+
if (isCritical) {
|
|
111
|
+
message = isEzActive
|
|
112
|
+
? `CONTEXT CRITICAL: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
113
|
+
'Context is nearly exhausted. Do NOT start new complex work or write handoff files — ' +
|
|
114
|
+
'EZ Agents state is already tracked in STATE.md. Inform the user so they can run ' +
|
|
115
|
+
'/ez:pause-work at the next natural stopping point.'
|
|
116
|
+
: `CONTEXT CRITICAL: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
117
|
+
'Context is nearly exhausted. Inform the user that context is low and ask how they ' +
|
|
118
|
+
'want to proceed. Do NOT autonomously save state or write handoff files unless the user asks.';
|
|
119
|
+
} else {
|
|
120
|
+
message = isEzActive
|
|
121
|
+
? `CONTEXT WARNING: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
122
|
+
'Context is getting limited. Avoid starting new complex work. If not between ' +
|
|
123
|
+
'defined plan steps, inform the user so they can prepare to pause.'
|
|
124
|
+
: `CONTEXT WARNING: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
125
|
+
'Be aware that context is getting limited. Avoid unnecessary exploration or ' +
|
|
126
|
+
'starting new complex work.';
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Validate API key properly - check existence, length, and not a placeholder
|
|
130
|
+
const hasValidGeminiKey = process.env.GEMINI_API_KEY &&
|
|
131
|
+
typeof process.env.GEMINI_API_KEY === 'string' &&
|
|
132
|
+
process.env.GEMINI_API_KEY.length >= 20 &&
|
|
133
|
+
!process.env.GEMINI_API_KEY.toLowerCase().includes('your-key') &&
|
|
134
|
+
!process.env.GEMINI_API_KEY.toLowerCase().includes('placeholder');
|
|
135
|
+
|
|
136
|
+
const output = {
|
|
137
|
+
hookSpecificOutput: {
|
|
138
|
+
hookEventName: hasValidGeminiKey ? "AfterTool" : "PostToolUse",
|
|
139
|
+
additionalContext: message
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
process.stdout.write(JSON.stringify(output));
|
|
144
|
+
} catch (e) {
|
|
145
|
+
// Silent fail -- never block tool execution
|
|
146
|
+
process.exit(0);
|
|
147
|
+
}
|
|
148
|
+
});
|