@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,176 +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
|
-
};
|
|
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
|
+
};
|