@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,175 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* EZ Audit Exec — Command execution with full audit logging
|
|
5
|
+
*
|
|
6
|
+
* Logs all command executions to audit file for security review:
|
|
7
|
+
* - Timestamp, command, arguments, context
|
|
8
|
+
* - Duration and result status
|
|
9
|
+
* - Error details if failed
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* const { auditExec } = require('./audit-exec.cjs');
|
|
13
|
+
* const result = await auditExec('git', ['status'], { context: 'my-module' });
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const { execFile } = require('child_process');
|
|
17
|
+
const { promisify } = require('util');
|
|
18
|
+
const { appendFileSync, existsSync, mkdirSync, writeFileSync } = require('fs');
|
|
19
|
+
const { join } = require('path');
|
|
20
|
+
const Logger = require('./logger.cjs');
|
|
21
|
+
const logger = new Logger();
|
|
22
|
+
|
|
23
|
+
const execFileAsync = promisify(execFile);
|
|
24
|
+
|
|
25
|
+
// Audit log file path - stored in temp directory (not in .planning/logs)
|
|
26
|
+
let _AUDIT_DIR;
|
|
27
|
+
let _AUDIT_FILE;
|
|
28
|
+
|
|
29
|
+
function getAuditDir() {
|
|
30
|
+
if (!_AUDIT_DIR) {
|
|
31
|
+
// Use temp directory instead of .planning/logs
|
|
32
|
+
_AUDIT_DIR = join(process.env.TEMP || process.env.TMPDIR || '/tmp', 'ez-agents-audit');
|
|
33
|
+
if (!existsSync(_AUDIT_DIR)) {
|
|
34
|
+
mkdirSync(_AUDIT_DIR, { recursive: true });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return _AUDIT_DIR;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function getAuditFile() {
|
|
41
|
+
if (!_AUDIT_FILE) {
|
|
42
|
+
_AUDIT_FILE = join(getAuditDir(), `audit-${new Date().toISOString().split('T')[0]}.jsonl`);
|
|
43
|
+
}
|
|
44
|
+
return _AUDIT_FILE;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Write audit log entry
|
|
49
|
+
* @param {Object} entry - Audit entry
|
|
50
|
+
*/
|
|
51
|
+
function writeAudit(entry) {
|
|
52
|
+
try {
|
|
53
|
+
const line = JSON.stringify(entry) + '\n';
|
|
54
|
+
appendFileSync(getAuditFile(), line, 'utf-8');
|
|
55
|
+
} catch (err) {
|
|
56
|
+
// Log audit failures to stderr - never silently ignore
|
|
57
|
+
// This ensures security issues are visible even if file write fails
|
|
58
|
+
console.error('AUDIT LOG FAILURE:', err.message);
|
|
59
|
+
console.error('Audit entry:', JSON.stringify(entry));
|
|
60
|
+
|
|
61
|
+
// In strict mode, throw to prevent execution without audit trail
|
|
62
|
+
if (process.env.AUDIT_STRICT === 'true') {
|
|
63
|
+
throw err;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Execute command with full audit logging
|
|
70
|
+
* @param {string} cmd - Command to execute
|
|
71
|
+
* @param {string[]} args - Command arguments
|
|
72
|
+
* @param {Object} options - Execution options
|
|
73
|
+
* @param {string} options.context - Calling context (which module/function)
|
|
74
|
+
* @param {string} options.user - User identifier
|
|
75
|
+
* @returns {Promise<string>} - Command stdout
|
|
76
|
+
*/
|
|
77
|
+
async function auditExec(cmd, args = [], options = {}) {
|
|
78
|
+
const { context = 'unknown', user = 'system', timeout = 30000 } = options;
|
|
79
|
+
|
|
80
|
+
const entry = {
|
|
81
|
+
timestamp: new Date().toISOString(),
|
|
82
|
+
cmd,
|
|
83
|
+
args,
|
|
84
|
+
context,
|
|
85
|
+
user,
|
|
86
|
+
status: 'started'
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// Log start
|
|
90
|
+
writeAudit(entry);
|
|
91
|
+
logger.info('Audit: command started', { cmd, args: args.join(' '), context });
|
|
92
|
+
|
|
93
|
+
const startTime = Date.now();
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
const result = await execFileAsync(cmd, args, {
|
|
97
|
+
timeout,
|
|
98
|
+
maxBuffer: 1 * 1024 * 1024 // 1MB buffer (reduced from 10MB for security)
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const duration = Date.now() - startTime;
|
|
102
|
+
|
|
103
|
+
// Log success
|
|
104
|
+
const successEntry = {
|
|
105
|
+
...entry,
|
|
106
|
+
status: 'success',
|
|
107
|
+
duration,
|
|
108
|
+
stdout_length: result.stdout?.length || 0
|
|
109
|
+
};
|
|
110
|
+
writeAudit(successEntry);
|
|
111
|
+
|
|
112
|
+
logger.debug('Audit: command completed', { cmd, duration, context });
|
|
113
|
+
|
|
114
|
+
return result.stdout.trim();
|
|
115
|
+
} catch (err) {
|
|
116
|
+
const duration = Date.now() - startTime;
|
|
117
|
+
|
|
118
|
+
// Log failure
|
|
119
|
+
const errorEntry = {
|
|
120
|
+
...entry,
|
|
121
|
+
status: 'error',
|
|
122
|
+
duration,
|
|
123
|
+
error: err.message,
|
|
124
|
+
code: err.code,
|
|
125
|
+
signal: err.signal
|
|
126
|
+
};
|
|
127
|
+
writeAudit(errorEntry);
|
|
128
|
+
|
|
129
|
+
logger.error('Audit: command failed', { cmd, error: err.message, duration, context });
|
|
130
|
+
|
|
131
|
+
throw err;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Get today's audit log path
|
|
137
|
+
* @returns {string} - Audit file path
|
|
138
|
+
*/
|
|
139
|
+
function getAuditFilePath() {
|
|
140
|
+
return AUDIT_FILE;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Read audit log entries for a specific date
|
|
145
|
+
* @param {string} date - Date string (YYYY-MM-DD)
|
|
146
|
+
* @returns {Object[]} - Array of audit entries
|
|
147
|
+
*/
|
|
148
|
+
function readAuditLog(date = new Date().toISOString().split('T')[0]) {
|
|
149
|
+
const filePath = join(AUDIT_DIR, `audit-${date}.jsonl`);
|
|
150
|
+
|
|
151
|
+
if (!existsSync(filePath)) {
|
|
152
|
+
return [];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const content = require('fs').readFileSync(filePath, 'utf-8');
|
|
156
|
+
return content.trim().split('\n').map(line => JSON.parse(line));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Search audit log for specific command
|
|
161
|
+
* @param {string} cmdFilter - Command to filter by
|
|
162
|
+
* @param {string} date - Date string
|
|
163
|
+
* @returns {Object[]} - Matching entries
|
|
164
|
+
*/
|
|
165
|
+
function searchAuditLog(cmdFilter, date) {
|
|
166
|
+
const entries = readAuditLog(date);
|
|
167
|
+
return entries.filter(e => e.cmd === cmdFilter);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
module.exports = {
|
|
171
|
+
auditExec,
|
|
172
|
+
getAuditFilePath,
|
|
173
|
+
readAuditLog,
|
|
174
|
+
searchAuditLog
|
|
175
|
+
};
|
package/bin/lib/auth.cjs
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* EZ Auth — Secure credential storage using system keychain
|
|
5
|
+
*
|
|
6
|
+
* Stores API keys securely using:
|
|
7
|
+
* - keytar for system keychain (Windows Credential Manager, macOS Keychain, libsecret)
|
|
8
|
+
* - Fallback to encrypted file storage if keytar unavailable
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* const { saveCredential, loadCredential } = require('./auth.cjs');
|
|
12
|
+
* await saveCredential('anthropic', 'sk-...');
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const Logger = require('./logger.cjs');
|
|
16
|
+
const logger = new Logger();
|
|
17
|
+
const path = require('path');
|
|
18
|
+
const fs = require('fs');
|
|
19
|
+
const os = require('os');
|
|
20
|
+
|
|
21
|
+
const SERVICE_NAME = 'ez-agents';
|
|
22
|
+
|
|
23
|
+
// Provider account names
|
|
24
|
+
const PROVIDERS = {
|
|
25
|
+
ANTHROPIC: 'anthropic',
|
|
26
|
+
MOONSHOT: 'moonshot',
|
|
27
|
+
ALIBABA: 'alibaba',
|
|
28
|
+
QWEN: 'qwen',
|
|
29
|
+
OPENAI: 'openai'
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Fallback storage path
|
|
33
|
+
const FALLBACK_FILE = path.join(os.homedir(), '.ez-credentials.json');
|
|
34
|
+
|
|
35
|
+
// Try to load keytar
|
|
36
|
+
let keytar = null;
|
|
37
|
+
try {
|
|
38
|
+
keytar = require('keytar');
|
|
39
|
+
logger.info('keytar loaded — using system keychain');
|
|
40
|
+
} catch (err) {
|
|
41
|
+
logger.warn('keytar not available — using fallback storage');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Save credential securely
|
|
46
|
+
* @param {string} provider - Provider name (anthropic, moonshot, etc.)
|
|
47
|
+
* @param {string} secret - API key or secret
|
|
48
|
+
* @returns {Promise<boolean>} - Success status
|
|
49
|
+
*/
|
|
50
|
+
async function saveCredential(provider, secret) {
|
|
51
|
+
try {
|
|
52
|
+
if (keytar) {
|
|
53
|
+
await keytar.setPassword(SERVICE_NAME, provider, secret);
|
|
54
|
+
logger.info('Credential saved to system keychain', { provider });
|
|
55
|
+
return true;
|
|
56
|
+
} else {
|
|
57
|
+
// Fallback: save to file
|
|
58
|
+
let credentials = {};
|
|
59
|
+
if (fs.existsSync(FALLBACK_FILE)) {
|
|
60
|
+
const content = fs.readFileSync(FALLBACK_FILE, 'utf-8');
|
|
61
|
+
try {
|
|
62
|
+
credentials = JSON.parse(content);
|
|
63
|
+
} catch (e) {
|
|
64
|
+
credentials = {};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
credentials[provider] = secret;
|
|
68
|
+
fs.writeFileSync(FALLBACK_FILE, JSON.stringify(credentials, null, 2), 'utf-8');
|
|
69
|
+
logger.warn('Credential saved to fallback file', { provider, path: FALLBACK_FILE });
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
} catch (err) {
|
|
73
|
+
logger.error('Failed to save credential', { provider, error: err.message });
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Load credential securely
|
|
80
|
+
* @param {string} provider - Provider name
|
|
81
|
+
* @returns {Promise<string|null>} - API key or null if not found
|
|
82
|
+
*/
|
|
83
|
+
async function loadCredential(provider) {
|
|
84
|
+
try {
|
|
85
|
+
if (keytar) {
|
|
86
|
+
const secret = await keytar.getPassword(SERVICE_NAME, provider);
|
|
87
|
+
if (secret) {
|
|
88
|
+
logger.debug('Credential loaded from keychain', { provider });
|
|
89
|
+
}
|
|
90
|
+
return secret || null;
|
|
91
|
+
} else {
|
|
92
|
+
// Fallback: load from file
|
|
93
|
+
if (fs.existsSync(FALLBACK_FILE)) {
|
|
94
|
+
const content = fs.readFileSync(FALLBACK_FILE, 'utf-8');
|
|
95
|
+
const credentials = JSON.parse(content);
|
|
96
|
+
return credentials[provider] || null;
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
} catch (err) {
|
|
101
|
+
logger.error('Failed to load credential', { provider, error: err.message });
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Delete credential
|
|
108
|
+
* @param {string} provider - Provider name
|
|
109
|
+
* @returns {Promise<boolean>} - Success status
|
|
110
|
+
*/
|
|
111
|
+
async function deleteCredential(provider) {
|
|
112
|
+
try {
|
|
113
|
+
if (keytar) {
|
|
114
|
+
await keytar.deletePassword(SERVICE_NAME, provider);
|
|
115
|
+
logger.info('Credential deleted from keychain', { provider });
|
|
116
|
+
return true;
|
|
117
|
+
} else {
|
|
118
|
+
// Fallback: remove from file
|
|
119
|
+
if (fs.existsSync(FALLBACK_FILE)) {
|
|
120
|
+
const content = fs.readFileSync(FALLBACK_FILE, 'utf-8');
|
|
121
|
+
const credentials = JSON.parse(content);
|
|
122
|
+
if (credentials[provider]) {
|
|
123
|
+
delete credentials[provider];
|
|
124
|
+
fs.writeFileSync(FALLBACK_FILE, JSON.stringify(credentials, null, 2), 'utf-8');
|
|
125
|
+
logger.info('Credential deleted from fallback file', { provider });
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
} catch (err) {
|
|
132
|
+
logger.error('Failed to delete credential', { provider, error: err.message });
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* List all stored providers
|
|
139
|
+
* @returns {Promise<string[]>} - Array of provider names
|
|
140
|
+
*/
|
|
141
|
+
async function listProviders() {
|
|
142
|
+
const stored = [];
|
|
143
|
+
|
|
144
|
+
if (keytar) {
|
|
145
|
+
for (const [, name] of Object.entries(PROVIDERS)) {
|
|
146
|
+
const cred = await keytar.getPassword(SERVICE_NAME, name);
|
|
147
|
+
if (cred) stored.push(name);
|
|
148
|
+
}
|
|
149
|
+
} else {
|
|
150
|
+
if (fs.existsSync(FALLBACK_FILE)) {
|
|
151
|
+
const content = fs.readFileSync(FALLBACK_FILE, 'utf-8');
|
|
152
|
+
const credentials = JSON.parse(content);
|
|
153
|
+
return Object.keys(credentials);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return stored;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Check if keytar is available
|
|
162
|
+
* @returns {boolean} - True if using system keychain
|
|
163
|
+
*/
|
|
164
|
+
function isKeychainAvailable() {
|
|
165
|
+
return keytar !== null;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
module.exports = {
|
|
169
|
+
saveCredential,
|
|
170
|
+
loadCredential,
|
|
171
|
+
deleteCredential,
|
|
172
|
+
listProviders,
|
|
173
|
+
isKeychainAvailable,
|
|
174
|
+
PROVIDERS,
|
|
175
|
+
SERVICE_NAME
|
|
176
|
+
};
|