{"_id":"@adddog/1password-env","name":"@adddog/1password-env","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.2":{"name":"@adddog/1password-env","type":"module","version":"0.0.2","main":"./dist/index.js","types":"./dist/index.d.ts","bin":{"op-env":"dist/cli.js"},"exports":{"./package.json":"./package.json",".":{"types":"./dist/index.d.ts","import":"./dist/index.js","module":"./dist/index.js","require":"./dist/index.cjs"}},"dependencies":{"@1password/sdk":"^0.4.0","@commander-js/extra-typings":"^14.0.0","commander":"^14.0.3"},"devDependencies":{"@types/node":"^25.5.0","bumpp":"^11.0.1","eslint":"^10.1.0","tsup":"^8.5.1","typescript":"^6.0.2","@adddog/monorepo-consistency":"0.0.15"},"engines":{"node":">= 22","pnpm":">= 10","npm":">= 11"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"scripts":{"build":"tsup ./src --outDir dist --clean --format esm,cjs --shims --dts --platform node --entry.index src/index.ts --entry.cli src/cli.ts","lint":"eslint .","lint:fix":"eslint --fix .","types":"tsc -p tsconfig.typecheck.json","test":"echo 'no tests yet'","knip":"knip","release":"bumpp --yes --no-push --no-tag --release patch","version:patch":"npm version patch --no-git-tag-version"},"_id":"@adddog/1password-env@0.0.2","description":"Single source of truth for secrets via 1Password. Replaces committed `.env` files, scattered GitHub secrets, and manual secret management.","_integrity":"sha512-K0APunKwnVD+HsKVgTYzs6mbMGNtLpI+ubD07GdZLV4WUs1gJvJdoEIsX8JZ1QPEUJ5c7BmC/9Pn7GIiufAu1Q==","_resolved":"/home/runner/work/samelie-monorepo/samelie-monorepo/packages/1password-env/adddog-1password-env-0.0.2.tgz","_from":"file:adddog-1password-env-0.0.2.tgz","_nodeVersion":"24.4.0","_npmVersion":"11.12.0","dist":{"integrity":"sha512-K0APunKwnVD+HsKVgTYzs6mbMGNtLpI+ubD07GdZLV4WUs1gJvJdoEIsX8JZ1QPEUJ5c7BmC/9Pn7GIiufAu1Q==","shasum":"8635bef931c845fd57b885ed78dc85bb9fb23f2b","tarball":"https://registry.npmjs.org/@adddog/1password-env/-/1password-env-0.0.2.tgz","fileCount":19,"unpackedSize":119450,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCnTCHY9QENk3kt60wVFFwoB4H+hlzcCwFNzqN/X32OpwIgGKxW7cAFSQdnyouIXuT9w1FOJJnIc1gJ98Lt+1QkZsU="}]},"_npmUser":{"name":"selie","email":"samradelie@gmail.com"},"directories":{},"maintainers":[{"name":"selie","email":"samradelie@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/1password-env_0.0.2_1774372411869_0.1139094729766128"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-24T17:13:31.764Z","0.0.2":"2026-03-24T17:13:32.021Z","modified":"2026-03-24T17:13:32.291Z"},"maintainers":[{"name":"selie","email":"samradelie@gmail.com"}],"description":"Single source of truth for secrets via 1Password. Replaces committed `.env` files, scattered GitHub secrets, and manual secret management.","readme":"# @adddog/1password-env\n\nSingle source of truth for secrets via 1Password. Replaces committed `.env` files, scattered GitHub secrets, and manual secret management.\n\n## Install\n\n```bash\npnpm add @adddog/1password-env\n```\n\n## How it works\n\n```\nsecrets.ts (config)  -->  1Password vault  -->  .env file / CI env vars\n        ^                       ^                       ^\n   defineSecrets()         op-env init            op-env hydrate\n                                              1password/load-secrets-action (CI)\n```\n\n1. **Define** secrets in a `secrets.ts` config\n2. **Init** scaffolds the 1Password vault and items (`op-env init`)\n3. **Hydrate** resolves secrets and writes `.env` files (`op-env hydrate`)\n4. **CI** uses `1password/load-secrets-action` to inject secrets at runtime\n\n## Config\n\nAdd an `\"op-env\"` key to your `package.json` — no extra config files needed:\n\n```jsonc\n// package.json\n{\n  \"op-env\": {\n    \"vault\": \"my-project\",\n    \"environments\": {\n      \"remote\": {\n        \"item\": \"remote\",\n        \"fields\": [\n          \"COOKIE_SECRET\",\n          \"PASETO_SECRET_KEY\",\n          { \"env\": \"DB_PASS\", \"field\": \"database-password\" }\n        ],\n        \"outputFile\": \".config/.env.dev.remote\",\n        \"literals\": {\n          \"CORS_ORIGINS\": \"https://example.com\"\n        }\n      }\n    }\n  },\n  \"scripts\": {\n    \"hydrate\": \"op-env hydrate\",\n    \"hydrate:init\": \"op-env init --from-env .config/.env.dev.remote\"\n  }\n}\n```\n\n`outputFile` paths are relative to the `package.json` directory.\n\nAlternatively, use a standalone `secrets.ts` file with `--config`:\n\n```typescript\nimport { defineSecrets } from \"@adddog/1password-env\"\n\nexport default defineSecrets({\n  vault: \"my-project\",\n  environments: { /* ... */ },\n})\n```\n\n## CLI\n\n### `op-env init` — scaffold vault and items\n\nReads config and creates the 1Password vault + items via the `op` CLI. Requires the 1Password desktop app integration (not service account).\n\n```bash\n# Auto-discovers config from package.json \"op-env\" key\nop-env init\n\n# Seed values from an existing .env file\nop-env init --from-env .config/.env.dev.remote\n\n# Preview without making changes\nop-env init --dry-run\n\n# Or with pnpm scripts:\npnpm hydrate:init\n```\n\nIdempotent — skips vaults and items that already exist.\n\n### `op-env hydrate` — write .env files\n\nResolves secrets from 1Password and writes the output file. Requires `OP_SERVICE_ACCOUNT_TOKEN`.\n\n```bash\n# Hydrate all environments (reads package.json)\nop-env hydrate\n\n# Hydrate a specific environment\nop-env hydrate -e remote\n\n# Or with pnpm scripts:\npnpm hydrate\n```\n\n### `op-env resolve` — print secrets to stdout\n\n```bash\nop-env resolve -e remote\n# COOKIE_SECRET=abc123...\n# PASETO_SECRET_KEY=k4.local...\n```\n\nAll commands auto-discover config from the nearest `package.json` with an `\"op-env\"` key. Pass `--config <path>` to use a standalone config file instead.\n\n## Programmatic API\n\n```typescript\nimport { defineSecrets, resolveSecrets, hydrateEnv, initFromConfig } from \"@adddog/1password-env\"\n\n// Resolve to a map\nconst secrets = await resolveSecrets(config, \"remote\")\n\n// Write .env file, returns output path\nconst path = await hydrateEnv(config, \"remote\", \"/path/to/base\")\n\n// Scaffold vault + items (uses op CLI)\nconst result = await initFromConfig(config, { fromEnv: \".env.dev.remote\" })\n```\n\n## Setup (one-time)\n\n### 1. Define config\n\nAdd `\"op-env\"` to your project's `package.json`.\n\n### 2. Scaffold 1Password\n\n```bash\n# With existing .env file (seeds values):\nop-env init --from-env .config/.env.dev.remote\n\n# Without (creates placeholders):\nop-env init\n```\n\n### 3. Create service account (manual — 1P web UI)\n\n1. Go to https://my.1password.com/developer-tools/directory\n2. Create a service account\n3. Grant it access to your vault(s)\n4. Copy the token\n\n### 4. Configure token\n\n```bash\n# Local dev\necho 'export OP_SERVICE_ACCOUNT_TOKEN=\"ops_...\"' >> ~/.zshrc\n\n# GitHub Actions\ngh secret set OP_SERVICE_ACCOUNT_TOKEN\n```\n\n### 5. Hydrate\n\n```bash\nop-env hydrate -c .config/secrets.ts\n```\n\n### 6. CI (GitHub Actions)\n\nFor CI, use the official 1Password action instead of this package:\n\n```yaml\n- uses: 1password/load-secrets-action@v2\n  with:\n    export-env: true\n  env:\n    OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}\n    MY_SECRET: op://vault/item/field\n```\n\n## Adding & updating secrets\n\n### Add a new secret\n\n1. **Add the field to your config** (`package.json` or `secrets.ts`):\n   ```jsonc\n   \"fields\": [\n     \"EXISTING_SECRET\",\n     \"NEW_API_KEY\"  // <-- add here\n   ]\n   ```\n\n2. **Create the field in 1Password** via the `op` CLI:\n   ```bash\n   # Add a field to an existing item\n   op item edit \"remote\" --vault \"my-project\" \"NEW_API_KEY=sk-live-abc123\"\n\n   # Or create via the 1Password desktop/web app\n   ```\n\n3. **Re-hydrate** to pull the new value into your `.env`:\n   ```bash\n   op-env hydrate\n   ```\n\n### Update an existing secret\n\nNo config change needed — just update the value in 1Password:\n\n```bash\nop item edit \"remote\" --vault \"my-project\" \"COOKIE_SECRET=new-value-here\"\n```\n\nThen re-hydrate:\n\n```bash\nop-env hydrate\n```\n\n### Add a new environment\n\n1. **Add the environment to your config**:\n   ```jsonc\n   \"environments\": {\n     \"remote\": { /* ... */ },\n     \"staging\": {\n       \"item\": \"staging\",\n       \"fields\": [\"DB_URL\", \"API_KEY\"],\n       \"outputFile\": \".config/.env.staging\"\n     }\n   }\n   ```\n\n2. **Scaffold the new vault item**:\n   ```bash\n   op-env init\n   ```\n\n3. **Set values in 1Password** (via `op` CLI or the app), then hydrate:\n   ```bash\n   op-env hydrate -e staging\n   ```\n\n### Summary\n\n| Task | Config change? | 1Password change? | Command |\n|------|:-:|:-:|---------|\n| Add secret | Yes — add to `fields` | Yes — `op item edit` | `op-env hydrate` |\n| Update secret value | No | Yes — `op item edit` | `op-env hydrate` |\n| Add environment | Yes — add to `environments` | Yes — `op-env init` | `op-env hydrate` |\n| Add literal (non-secret) | Yes — add to `literals` | No | `op-env hydrate` |\n\n## Claude Code Plugin\n\n```bash\nclaude plugin marketplace add samelie/1password-env\nclaude plugin install 1password-env\n```\n\nAdds the `/op-env-setup` skill for interactive 1Password secret management setup.\n\n## Output formats\n\n**dotenv** (default):\n```\nCOOKIE_SECRET=abc123\nCORS_ORIGINS=https://example.com\n```\n\n**shell**:\n```bash\n#!/bin/bash\nexport COOKIE_SECRET=\"abc123\"\nexport CORS_ORIGINS=\"https://example.com\"\n```\n","readmeFilename":"README.md","_rev":"1-e573b7f40d7ae93ac449e02b6928c24d"}