{
  "interval": {
    "intervalStart": "2026-01-15T00:00:00.000Z",
    "intervalEnd": "2026-01-16T00:00:00.000Z",
    "intervalType": "day"
  },
  "repository": "elizaos/eliza",
  "overview": "From 2026-01-15 to 2026-01-16, elizaos/eliza had 0 new PRs (2 merged), 0 new issues, and 3 active contributors.",
  "topIssues": [],
  "topPRs": [
    {
      "id": "PR_kwDOMT5cIs688Xux",
      "title": "fix(cli): prevent shell environment variable leakage into agent secrets",
      "author": "0xbbjoker",
      "number": 6360,
      "body": "## Summary\n\nFixes shell environment variable leakage into ElizaOS plugin loading decisions and agent secrets.\n\n**Problem:** `dotenv.config()` does NOT override existing `process.env` values by default. This means shell environment variables (from `.zshrc`/`.bashrc`) leak into plugin loading:\n\n```\nUser shell has: ANTHROPIC_API_KEY, OPENAI_API_KEY\nProject .env has: OPENROUTER_API_KEY\n\nExpected plugins: openrouter, bootstrap\nActual plugins: anthropic, openai, openrouter, bootstrap (LEAKED!)\n```\n\n**Solution:**\n- Scan installed plugins for declared env vars via `package.json` `agentConfig.pluginParameters`\n- Set global filter so only declared vars are captured into agent secrets\n- Load `.env` files with proper precedence (closest file wins)\n\n## Changes\n\n- **`packages/cli/src/utils/plugin-env-filter.ts`** - New utility to scan plugins for env var declarations\n- **`packages/core/src/secrets.ts`** - Add `setAllowedEnvVars()` filter to restrict captured vars\n- **`packages/core/src/utils/environment.ts`** - Add `loadEnvFilesWithPrecedence()` for proper hierarchy\n- **`packages/cli/src/commands/start/index.ts`** - Integrate filter before character loading\n\n## Test plan\n\n- [x] Unit tests for plugin env var scanning (`plugin-env-filter.test.ts`)\n- [x] Unit tests for secrets filtering (`secrets-filtering.test.ts`)\n- [x] Unit tests for env precedence loading (`env-precedence.test.ts`)\n- [ ] Manual test with shell env vars vs project .env\n- [ ] Test in monorepo context\n\n## Notes\n\n- 40 tests passing\n- Backwards compatible (null filter = existing behavior)\n- Core env vars (POSTGRES_URL, LOG_LEVEL, etc.) always allowed\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\n<!-- CURSOR_SUMMARY -->\n---\n\n> [!NOTE]\n> Strengthens environment handling to block shell var leakage and honor project .env precedence.\n> \n> - Adds `utils/plugin-env-filter.ts` to scan installed plugins' `agentConfig.pluginParameters`, assemble `allowedVars`, filter env maps, detect shell-only vars, and warn on missing declarations\n> - Integrates scanning in `cli start`: calls `scanPluginsForEnvDeclarations`, sets global `setAllowedEnvVars`, and loads `.env` files via `loadEnvFilesWithPrecedence` (monorepo-aware)\n> - Updates core `secrets.ts`: introduces `setAllowedEnvVars`/`getAllowedEnvVars`, filters `process.env` when merging into `character.settings.secrets`, optimizes `hasCharacterSecrets`\n> - Enhances core env utils: memoized `detectEnvironment`, `resetEnvironmentCache`, `loadEnvFile({ override })`, `findAllEnvFiles`, and `loadEnvFilesWithPrecedence` (closest wins, optional boundary)\n> - Adds comprehensive tests covering plugin scanning/filtering, .env precedence, and secrets filtering\n> \n> <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 23693e47517cf535cd1aba510d3b1337c1e549c4. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup>\n<!-- /CURSOR_SUMMARY -->\n\n<!-- greptile_comment -->\n\n<h2>Greptile Overview</h2>\n\n### Greptile Summary\n\nThis PR implements a robust solution to prevent shell environment variable leakage into ElizaOS agent secrets by introducing plugin-based environment variable filtering.\n\n## Key Changes\n\n- **Plugin Environment Scanning**: New `plugin-env-filter.ts` utility scans installed plugins' `package.json` files for declared environment variables via `agentConfig.pluginParameters`\n- **Global Filter in Secrets Module**: Added `setAllowedEnvVars()` to restrict which environment variables are captured into agent secrets\n- **Environment File Precedence**: New `loadEnvFilesWithPrecedence()` ensures closest `.env` file wins, respecting monorepo boundaries\n- **Integration in Start Command**: Filter is applied before character loading, preventing shell vars from leaking into plugin selection\n\n## Architecture\n\nThe solution follows a clear flow: scan plugins → set filter → load env files → filter on capture. Core environment variables (e.g., `POSTGRES_URL`, `LOG_LEVEL`) are always allowed. The filter is null by default for backward compatibility.\n\n## Issues Found\n\n- Line 72 in `plugin-env-filter.ts` already correctly checks for null declarations before accessing length\n- Line 19 in `secrets.ts` uses underscore variable as TypeScript idiom for unused loop variable (valid pattern)\n- Consider caching regex compilation in `detectShellOnlyVars` for performance\n- `CORE_ALLOWED_VARS` hardcoded in CLI could be centralized in core package\n\n## Testing\n\n40 tests passing across 3 new test files with comprehensive coverage of filtering, precedence, and integration scenarios.\n\n### Confidence Score: 4/5\n\n- This PR is safe to merge with minor considerations\n- The implementation is well-tested with 40 passing tests, addresses a real security concern (shell env leakage), and maintains backward compatibility. Code quality is high with proper error handling and optimization. Minor issues include hardcoded core vars list and potential for regex caching, but these don't affect functionality.\n- Pay close attention to `packages/cli/src/utils/plugin-env-filter.ts` for the regex caching optimization and consider centralizing `CORE_ALLOWED_VARS`\n\n<h3>Important Files Changed</h3>\n\n\n\nFile Analysis\n\n\n\n| Filename | Score | Overview |\n|----------|-------|----------|\n| packages/cli/src/utils/plugin-env-filter.ts | 4/5 | added plugin environment variable scanning utility with deduplication and filtering logic |\n| packages/core/src/secrets.ts | 4/5 | refactored to add environment variable filtering capability with global allowed vars set |\n| packages/core/src/utils/environment.ts | 4/5 | added `.env` file precedence loading with boundary directory support |\n| packages/cli/src/commands/start/index.ts | 4/5 | integrated plugin env scanning and filtering before character loading to prevent shell leakage |\n\n</details>\n\n\n\n<h3>Sequence Diagram</h3>\n\n```mermaid\nsequenceDiagram\n    participant CLI as CLI Start Command\n    participant Scanner as Plugin Scanner\n    participant Core as Core (secrets.ts)\n    participant Env as Environment Loader\n    participant Agent as Agent/Character\n\n    CLI->>Scanner: scanPluginsForEnvDeclarations(cwd)\n    Scanner->>Scanner: Scan node_modules for plugins\n    Scanner->>Scanner: Read package.json files\n    Scanner->>Scanner: Extract pluginParameters\n    Scanner-->>CLI: allowedVars Set + plugin info\n    \n    CLI->>Core: setAllowedEnvVars(allowedVars)\n    Note over Core: Global filter set\n    \n    CLI->>Env: loadEnvFilesWithPrecedence(cwd)\n    Env->>Env: findAllEnvFiles (parent dirs)\n    Env->>Env: Load files (farthest to closest)\n    Env-->>CLI: Loaded env files\n    Note over CLI: process.env populated\n    \n    CLI->>Agent: Load character/agent\n    Agent->>Core: setDefaultSecretsFromEnv(character)\n    Core->>Core: Filter process.env by allowedVars\n    Core->>Agent: Merge filtered vars into secrets\n    Note over Agent: Only declared vars captured\n```\n\n<!-- greptile_other_comments_section -->\n\n<!-- /greptile_comment -->",
      "repository": "elizaos/eliza",
      "createdAt": "2026-01-13T14:23:17Z",
      "mergedAt": "2026-01-15T15:10:57Z",
      "additions": 1343,
      "deletions": 395
    },
    {
      "id": "PR_kwDOMT5cIs689QK9",
      "title": "fix: prevent infinite rebuild loop in dev-watch mode",
      "author": "0xbbjoker",
      "number": 6361,
      "body": "## Summary\n- Fixed infinite rebuild loop in `bun run dev` caused by `generate-version.ts` writing to `src/version.ts` on every build\n- The watcher was detecting these changes and triggering rebuilds endlessly\n\n## Changes\n- **scripts/dev-watch.js**: Added `ignoredFiles` Set to skip watching `version.ts` and `version.js` files\n- **packages/cli/src/scripts/generate-version.ts**: Made version generation smart - only rewrites file if version/name/description actually changed\n- Removed unused variables (`stdoutData`, `stderrData`, `buildOutput`) from dev-watch.js\n\n## Root Cause\n1. `generate-version.ts` writes `BUILD_TIME = '${new Date().toISOString()}'` which changes every build\n2. The file watcher sees changes in `cli/src/version.ts` \n3. This triggers a rebuild, which generates a new `version.ts` with a new timestamp\n4. Infinite loop\n\n## Test plan\n- [x] Run `bun run dev` from monorepo root\n- [x] Verify initial startup completes without looping\n- [x] Touch a source file (e.g., `packages/core/src/runtime.ts`)\n- [x] Verify single rebuild occurs (no loop)\n- [x] Verify `version.ts is up to date` message appears on subsequent builds\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\n<!-- CURSOR_SUMMARY -->\n---\n\n> [!NOTE]\n> Prevents watch-mode rebuild loops caused by auto-generated version files.\n> \n> - `packages/cli/src/scripts/generate-version.ts`: Adds idempotent generation (extracts existing `CLI_VERSION/NAME/DESCRIPTION`, compares, and skips write if unchanged), uses `JSON.stringify` for safe string literals, and introduces small FS helpers.\n> - `scripts/dev-watch.js`: Ignores auto-generated `version.ts`/`version.js` via `shouldIgnoreFile`, forwards build stdout/stderr directly (removes unused buffers), and logs ignored files; preserves TypeScript-only watching with debounce.\n> \n> <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 6d4587096a9638ed53319750ee301cf17891076d. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup>\n<!-- /CURSOR_SUMMARY -->\n\n<!-- greptile_comment -->\n\n<h2>Greptile Overview</h2>\n\n### Greptile Summary\n\nThis PR fixes an infinite rebuild loop in dev-watch mode caused by the auto-generated `version.ts` file changing on every build. The fix involves two approaches:\n\n1. **Smart version generation** (`generate-version.ts`): Only rewrites `version.ts` if version/name/description actually changed, not on every build. This means `BUILD_TIME` becomes stale in dev mode (intentional tradeoff).\n\n2. **Watcher ignore list** (`dev-watch.js`): Added ignore logic to skip watching `version.ts` and `version.js` files.\n\n## Critical Issue Found\n\nThe watcher ignore implementation is **too broad** and will incorrectly ignore legitimate files. It uses `path.basename(filename)` to match filenames, which means ANY file named `version.ts` in ANY subdirectory will be ignored, including:\n- `packages/server/src/api/system/version.ts` (the version API endpoint)\n\nThis breaks hot reload for legitimate source files that happen to be named `version.ts`.\n\n## Root Cause Analysis\n\nThe original problem was that `generate-version.ts` writes `BUILD_TIME = '${new Date().toISOString()}'` which changes every build, triggering the watcher. The fix addresses this but introduces a new bug in the ignore logic.\n\n## Additional Changes\n\n- Removed unused variables (`stdoutData`, `stderrData`, `buildOutput`) - good cleanup\n\n### Confidence Score: 2/5\n\n- This PR contains a critical bug that will break hot reload for legitimate files\n- Score reflects a critical logic error in the file ignore implementation that will cause the watcher to ignore legitimate source files (packages/server/src/api/system/version.ts). While the smart version generation logic is sound, the overly broad ignore pattern undermines the PR's goal of fixing the development workflow.\n- Pay close attention to scripts/dev-watch.js - the shouldIgnoreFile function needs fixing before merge\n\n<h3>Important Files Changed</h3>\n\n\n\nFile Analysis\n\n\n\n| Filename | Score | Overview |\n|----------|-------|----------|\n| scripts/dev-watch.js | 2/5 | Added file ignore logic to prevent rebuild loops, but the implementation is too broad and will incorrectly ignore legitimate files like packages/server/src/api/system/version.ts. Also removed unused variables (good cleanup). |\n| packages/cli/src/scripts/generate-version.ts | 4/5 | Added smart version comparison to prevent unnecessary file writes. Core logic is sound but lacks input sanitization for special characters in package.json fields. BUILD_TIME will become stale in dev mode (intentional tradeoff). |\n\n</details>\n\n\n\n<h3>Sequence Diagram</h3>\n\n```mermaid\nsequenceDiagram\n    participant DevWatch as dev-watch.js\n    participant Builder as Build Process\n    participant GenVer as generate-version.ts\n    participant FS as File System\n    participant Watcher as File Watcher\n\n    Note over DevWatch: Initial Startup\n    DevWatch->>Builder: Start CLI build\n    Builder->>GenVer: Execute generate-version.ts\n    GenVer->>FS: Read package.json\n    FS-->>GenVer: version, name, description\n    GenVer->>FS: Check existing version.ts\n    alt version.ts exists with same version info\n        GenVer->>GenVer: Skip write (no change)\n        Note over GenVer: Prevents rebuild loop\n    else version.ts missing or different\n        GenVer->>FS: Write new version.ts\n        Note over GenVer: Includes BUILD_TIME (stale in dev)\n    end\n    Builder-->>DevWatch: Build complete\n    DevWatch->>Watcher: Start watching source directories\n    \n    Note over Watcher: User modifies source file\n    Watcher->>Watcher: Detect file change\n    Watcher->>Watcher: Check shouldIgnoreFile(filename)\n    alt filename basename is \"version.ts\" or \"version.js\"\n        Watcher->>Watcher: Ignore (too broad - BUG!)\n        Note over Watcher: Also ignores api/system/version.ts\n    else Other TypeScript file\n        Watcher->>DevWatch: Trigger rebuild\n        DevWatch->>Builder: Rebuild CLI\n        Builder->>GenVer: Execute generate-version.ts\n        Note over GenVer: Smart comparison prevents<br/>unnecessary writes\n    end\n```\n\n<!-- greptile_other_comments_section -->\n\n<!-- /greptile_comment -->",
      "repository": "elizaos/eliza",
      "createdAt": "2026-01-13T15:21:52Z",
      "mergedAt": "2026-01-15T13:51:10Z",
      "additions": 120,
      "deletions": 43
    }
  ],
  "codeChanges": {
    "additions": 1463,
    "deletions": 438,
    "files": 10,
    "commitCount": 15
  },
  "completedItems": [
    {
      "title": "fix: prevent infinite rebuild loop in dev-watch mode",
      "prNumber": 6361,
      "type": "bugfix",
      "body": "## Summary\n- Fixed infinite rebuild loop in `bun run dev` caused by `generate-version.ts` writing to `src/version.ts` on every build\n- The watcher was detecting these changes and triggering rebuilds endlessly\n\n## Changes\n- **scripts/dev-wat",
      "files": [
        "packages/cli/src/scripts/generate-version.ts",
        "scripts/dev-watch.js"
      ]
    },
    {
      "title": "fix(cli): prevent shell environment variable leakage into agent secrets",
      "prNumber": 6360,
      "type": "bugfix",
      "body": "## Summary\n\nFixes shell environment variable leakage into ElizaOS plugin loading decisions and agent secrets.\n\n**Problem:** `dotenv.config()` does NOT override existing `process.env` values by default. This means shell environment variables",
      "files": [
        "packages/cli/src/__tests__/plugin-env-filter.test.ts",
        "packages/cli/src/commands/start/index.ts",
        "packages/cli/src/utils/plugin-env-filter.ts",
        "packages/core/src/__tests__/env-precedence.test.ts",
        "packages/core/src/__tests__/secrets-filtering.test.ts",
        "packages/core/src/__tests__/utils/environment.test.ts",
        "packages/core/src/secrets.ts",
        "packages/core/src/utils/environment.ts"
      ]
    }
  ],
  "topContributors": [
    {
      "username": "madjin",
      "avatarUrl": "https://avatars.githubusercontent.com/u/32600939?u=cdcf89f44c7a50906c7a80d889efa85023af2049&v=4",
      "totalScore": 48.06626433794567,
      "prScore": 45.726264337945665,
      "issueScore": 2,
      "reviewScore": 0,
      "commentScore": 0.33999999999999997,
      "summary": "madjin: Focused on enhancing API documentation and user experience, successfully merging a substantial PR in elizaos/elizaos.github.io (#213) that involved significant additions and removals of content, while also creating an issue to address unused dependencies. Their work primarily involved feature development, bug fixes, and documentation, with a focus on configuration and code changes."
    },
    {
      "username": "standujar",
      "avatarUrl": "https://avatars.githubusercontent.com/u/16385918?u=718bdcd1585be8447bdfffb8c11ce249baa7532d&v=4",
      "totalScore": 5,
      "prScore": 0,
      "issueScore": 0,
      "reviewScore": 5,
      "commentScore": 0,
      "summary": "standujar: Focused on refactoring efforts, modifying 16 files with 2 commits (+79/-49 lines) and approving one pull request, indicating a focus on code quality and maintainability."
    },
    {
      "username": "BinaryBluePeach",
      "avatarUrl": "https://avatars.githubusercontent.com/u/192237769?v=4",
      "totalScore": 2,
      "prScore": 0,
      "issueScore": 2,
      "reviewScore": 0,
      "commentScore": 0,
      "summary": "BinaryBluePeach: Today, BinaryBluePeach focused on identifying and reporting a critical bug in the Discord plugin, creating issue elizaos-plugins/plugin-discord#43 to address an undefined `sendMessage` function."
    },
    {
      "username": "odilitime",
      "avatarUrl": "https://avatars.githubusercontent.com/u/16395496?u=c9bac48e632aae594a0d85aaf9e9c9c69b674d8b&v=4",
      "totalScore": 0.2,
      "prScore": 0,
      "issueScore": 0,
      "reviewScore": 0,
      "commentScore": 0.2,
      "summary": "odilitime: Focused on significant code changes, modifying 620 files (+37318/-14462 lines) across 6 commits, with a primary focus on bugfix work (67%) and some feature work (17%)."
    }
  ],
  "newPRs": 0,
  "mergedPRs": 2,
  "newIssues": 0,
  "closedIssues": 0,
  "activeContributors": 3
}