{
  "interval": {
    "intervalStart": "2025-11-12T00:00:00.000Z",
    "intervalEnd": "2025-11-13T00:00:00.000Z",
    "intervalType": "day"
  },
  "repository": "elizaos/eliza",
  "overview": "From 2025-11-12 to 2025-11-13, elizaos/eliza had 0 new PRs (2 merged), 0 new issues, and 4 active contributors.",
  "topIssues": [],
  "topPRs": [
    {
      "id": "PR_kwDOMT5cIs6yoPHs",
      "title": "fix: load environment variables from process.env instead of .env file",
      "author": "standujar",
      "number": 6141,
      "body": "## Relates to\r\n\r\nFixes the issue where `runtime.getSetting(\"ANY_VARIABLES\")` returns `undefined` when environment variables are exported on the host (`export VAR=value`) instead of being defined in a `.env` file, causing agents to use incorrect configuration or fallback to defaults.\r\n\r\n## Risks\r\n\r\n**Low**\r\n\r\n## Background\r\n\r\n### What does this PR do?\r\n\r\nThis PR fixes environment variable loading to work correctly with exported shell variables, not just `.env` files:\r\n\r\n1. **Changes `loadSecretsNodeImpl()`** to read directly from `process.env` instead of re-reading the `.env` file\r\n2. **Creates centralized `loadEnvFile()`** function in `core/utils/environment.ts` for consistent `.env` file loading\r\n3. **Updates CLI and Server** to use the centralized function\r\n4. **Updates all tests** to reflect the new behavior\r\n\r\n### What kind of change is this?\r\n\r\n- ✅ **Bug fixes** (non-breaking change which fixes an issue)\r\n- ✅ **Improvements** (misc. changes to existing features)\r\n\r\n### Why are we doing this?\r\n\r\n#### Problem Discovered\r\n\r\nWhen running agents in environments where variables are exported directly on the host system (e.g., `export POSTGRES_URL=postgresql://...`), the variables were not accessible via `runtime.getSetting()`, even though they were correctly set in the environment.\r\n\r\n**Testing confirmed the issue**:\r\n- ✅ With `.env` file: Works\r\n- ❌ With `export POSTGRES_URL=...`: **Doesn't work**\r\n- ❌ With system environment variables: **Doesn't work**\r\n\r\nThis is problematic for:\r\n- Production deployments where secrets are managed via exported environment variables\r\n- Container orchestration systems (Docker, ECS, Kubernetes) that inject env vars\r\n- CI/CD pipelines that set variables programmatically\r\n- Development workflows that prefer `export` over `.env` files\r\n\r\n#### Root Cause\r\n\r\nThe `loadSecretsNodeImpl()` function in `packages/core/src/secrets.ts` was:\r\n1. **Only** reading the `.env` FILE directly using `fs.readFileSync()`\r\n2. Parsing it with `dotenv.parse()`\r\n3. Merging those parsed values into `character.settings`\r\n\r\nThis approach **completely ignored** `process.env`, which contains:\r\n- Variables loaded from `.env` by the CLI (via `dotenv.config()`)\r\n- **Exported shell variables** (`export FOO=bar`) ← **Main issue**\r\n- Container-injected environment variables\r\n- System environment variables\r\n\r\n**Why was this a problem?**\r\n\r\nWhen you run:\r\n```bash\r\nexport POSTGRES_URL=postgresql://production:5432/eliza\r\nbunx elizaos start --character=./characters/sample.json\r\n```\r\n\r\nThe variable is in `process.env`, but `loadSecretsNodeImpl()` was looking for a `.env` file instead. If no `.env` file existed, it would fail to load ANY environment variables, even though they were available in `process.env`.\r\n\r\n#### Solution\r\n\r\nThe fix reads `process.env` directly instead of re-reading the `.env` file\r\n\r\n**Why this works:**\r\n\r\n1. **When using `.env` files**: The CLI calls `dotenv.config()` which loads `.env` → `process.env`\r\n2. **When using exported variables**: Shell already puts them in `process.env`\r\n3. **When using container env vars**: Runtime injects them into `process.env`\r\n4. **Result**: `loadSecretsNodeImpl()` now sees ALL variables, regardless of source\r\n\r\n## Documentation changes needed?\r\n\r\n- ✅ My changes do not require a change to the project documentation.\r\n\r\nThe behavior is now more intuitive - environment variables work as expected from any source. No user-facing documentation changes needed.\r\n\r\n## Testing\r\n\r\n### Where should a reviewer start?\r\n\r\n1. Review the changes in [packages/core/src/secrets.ts](packages/core/src/secrets.ts:26-66) - the core fix\r\n2. Review [packages/core/src/utils/environment.ts](packages/core/src/utils/environment.ts:384-410) - centralized `loadEnvFile()`\r\n3. Check test updates in [packages/core/src/__tests__/secrets.test.ts](packages/core/src/__tests__/secrets.test.ts:76-190)\r\n4. Verify CLI integration in [packages/cli/src/commands/start/index.ts](packages/cli/src/commands/start/index.ts:38-46)\r\n5. Verify Server integration in [packages/server/src/index.ts](packages/server/src/index.ts:332)\r\n\r\n### Detailed testing steps\r\n\r\n#### Automated Tests\r\n\r\n```bash\r\ncd packages/core\r\nbun test\r\n\r\n# Results:\r\n# ✅ 675 pass\r\n# ❌ 0 fail\r\n# ⏭️ 4 skip\r\n```\r\n\r\nAll tests pass, including:\r\n- `secrets.test.ts` - 8 tests verifying environment variable loading\r\n- `settings.test.ts` - 49 tests verifying character settings merge\r\n- `environment.test.ts` - 29 tests verifying environment abstraction\r\n\r\n#### Manual Testing\r\n\r\n**Test 1: .env file (already working, should still work)**\r\n```bash\r\necho 'POSTGRES_URL=postgresql://localhost:5432/test' > .env\r\nbunx elizaos start --character=./characters/sample.json\r\n# ✅ Agent uses POSTGRES_URL from .env file\r\n```\r\n\r\n**Test 2: Exported environment variable (was broken, NOW FIXED)**\r\n```bash\r\n# Remove .env file to test pure exported variables\r\nrm -f .env\r\n\r\nexport POSTGRES_URL=postgresql://localhost:5432/test\r\nexport OPENAI_API_KEY=sk-test-key\r\nbunx elizaos start --character=./characters/sample.json\r\n\r\n# ✅ Agent now correctly reads exported variables (FIXED)\r\n# ✅ runtime.getSetting(\"POSTGRES_URL\") returns the correct value\r\n```\r\n\r\n**Test 3: Mixed approach (both .env and exports)**\r\n```bash\r\n# .env has some vars\r\necho 'POSTGRES_URL=postgresql://localhost:5432/test' > .env\r\n\r\n# Override with export (export should win because it's already in process.env)\r\nexport POSTGRES_URL=postgresql://production:5432/eliza\r\nbunx elizaos start --character=./characters/sample.json\r\n\r\n# ✅ Uses the exported value (not the .env value)\r\n```\r\n\r\n**Test 4: Server standalone (without CLI)**\r\n```typescript\r\nimport { AgentServer } from '@elizaos/server';\r\n\r\n// Set env var before importing\r\nprocess.env.POSTGRES_URL = 'postgresql://localhost:5432/test';\r\n\r\nconst server = new AgentServer();\r\nawait server.start({\r\n  port: 3000,\r\n  agents: [{ character: myCharacter }]\r\n});\r\n// ✅ Works because Server calls loadEnvFile() at initialization\r\n```\r\n\r\n## Environment Variable Loading Flow (After Fix)\r\n\r\n```\r\n┌─────────────────────────────────────────────────────────────┐\r\n│                     Deployment Context                       │\r\n└─────────────────────────────────────────────────────────────┘\r\n                              │\r\n                              ▼\r\n        ┌─────────────────────────────────────────────┐\r\n        │          Where do env vars come from?       │\r\n        └─────────────────────────────────────────────┘\r\n                              │\r\n           ┌──────────────────┼──────────────────┐\r\n           │                  │                  │\r\n           ▼                  ▼                  ▼\r\n    ┌──────────┐      ┌──────────┐      ┌──────────┐\r\n    │.env file │      │ export   │      │ System   │\r\n    │  (CLI)   │      │VAR=value │      │ env vars │\r\n    └──────────┘      └──────────┘      └──────────┘\r\n           │                  │                  │\r\n           │                  │                  │\r\n           └──────────────────┼──────────────────┘\r\n                              │\r\n                              ▼\r\n                       ┌─────────────┐\r\n                       │ process.env │ ← All sources merged here\r\n                       └─────────────┘\r\n                              │\r\n                              ▼\r\n                    ┌──────────────────┐\r\n                    │loadSecretsNodeImpl│ ← Reads process.env\r\n                    └──────────────────┘\r\n                              │\r\n                              ▼\r\n                  ┌────────────────────────┐\r\n                  │character.settings.secrets│\r\n                  └────────────────────────┘\r\n                              │\r\n                              ▼\r\n                      ┌──────────────┐\r\n                      │runtime.getSetting()│ ✅ Works!\r\n                      └──────────────┘\r\n```\r\n\r\n## Benefits\r\n\r\n1. ✅ **Exported variables work** - `export FOO=bar` is now accessible (main fix)\r\n2. ✅ **No `.env` file required** - Works in environments without `.env` files\r\n3. ✅ **Backward compatible** - `.env` files still work as before\r\n4. ✅ **Production-ready** - Secrets can be injected via environment, not files\r\n5. ✅ **Container-friendly** - Works with Docker, ECS, Kubernetes env injection\r\n6. ✅ **Simpler code** - No need to re-read `.env` file\r\n7. ✅ **Consistent behavior** - Works the same in all environments\r\n8. ✅ **Idempotent** - Safe to call `loadEnvFile()` multiple times",
      "repository": "elizaos/eliza",
      "createdAt": "2025-11-10T21:55:04Z",
      "mergedAt": "2025-11-12T11:03:00Z",
      "additions": 363,
      "deletions": 284
    },
    {
      "id": "PR_kwDOMT5cIs6xNLv_",
      "title": "feat: add ElizaOS reference to runtime",
      "author": "standujar",
      "number": 6111,
      "body": "<!-- Use this template by filling in information and copying and pasting relevant items out of the HTML comments. -->\r\n\r\n# Relates to\r\n\r\nRelates to #6095 - Unified messaging API\r\n\r\n# Risks\r\n\r\n**Low risk**\r\n\r\nThis change is non-breaking and fully backward compatible:\r\n- Adds optional `elizaOS?` property to runtime (existing code unaffected)\r\n- Only affects plugins that explicitly use `runtime.elizaOS`\r\n- Includes proper cleanup to prevent memory leaks\r\n- Well-tested with plugin-discord integration\r\n\r\nPotential areas affected:\r\n- Runtime lifecycle (addition of ElizaOS reference)\r\n- Memory management (cleanup in `stop()`)\r\n- Plugin development patterns (new unified API access)\r\n\r\n# Background\r\n\r\n## What does this PR do?\r\n\r\nThis PR enables plugins to access the unified messaging API (`elizaOS.sendMessage()`) introduced in #6095 by adding an optional reference to the ElizaOS instance in the runtime.\r\n\r\n**Key changes:**\r\n- Created `IElizaOS` interface for clean abstraction\r\n- Added `elizaOS?: IElizaOS` property to `IAgentRuntime`\r\n- Added `hasElizaOS()` type guard helper\r\n- ElizaOS auto-assigns itself to runtimes during registration\r\n- Added cleanup in `runtime.stop()` to prevent memory leaks\r\n\r\n**Benefits:**\r\n- Plugins can now use `runtime.elizaOS.sendMessage()` for standardized messaging\r\n- Type-safe access with `hasElizaOS()` guard\r\n- Auto-filling, connection management, SYNC/ASYNC modes\r\n- Clean architecture with no circular dependencies\r\n\r\n## What kind of change is this?\r\n\r\n- [x] Features (non-breaking change which adds functionality)\r\n- [x] Improvements (misc. changes to existing features)\r\n\r\n## Why are we doing this?\r\n\r\nThe unified messaging API (#6095) provides a standardized entry point for sending messages to agents, but plugins currently have no way to access it. They must use `messageService.handleMessage()` directly, which bypasses the benefits of the unified API (auto-filling, connection management, callbacks, etc.).\r\n\r\nThis PR solves that by giving the runtime a reference to its parent ElizaOS instance, allowing plugins to call `runtime.elizaOS.sendMessage()` when available, while maintaining a fallback for standalone mode.\r\n\r\n# Documentation changes needed?\r\n\r\n- [x] My changes require a change to the project documentation.\r\n- [ ] If documentation change is needed: I have updated the documentation accordingly.\r\n\r\n**Documentation needed:**\r\n- Plugin development guide should mention `runtime.elizaOS.sendMessage()` API\r\n- Example usage in plugin templates\r\n- Migration guide for existing plugins (optional, recommended)\r\n\r\n# Testing\r\n\r\n## Where should a reviewer start?\r\n\r\n1. Review the architecture: `packages/core/src/types/elizaos.ts` - new interface\r\n2. Check runtime changes: `packages/core/src/types/runtime.ts` and `packages/core/src/runtime.ts`\r\n3. Verify ElizaOS auto-assignment: `packages/core/src/elizaos.ts` lines 158 and 203\r\n4. Look at cleanup: `packages/core/src/runtime.ts` line 384\r\n\r\n## Detailed testing steps\r\n\r\n**Automated:**\r\n- [x] TypeScript compilation passes\r\n- [x] No circular dependencies\r\n- [x] Type safety verified\r\n\r\n**Manual testing (with plugin-discord):**\r\n- [x] Runtime has `elizaOS` reference after initialization\r\n- [x] `hasElizaOS()` returns `true` when ElizaOS is present\r\n- [x] Plugins can call `runtime.elizaOS.sendMessage()` successfully\r\n- [x] Fallback to `messageService.handleMessage()` works when ElizaOS is undefined\r\n- [x] Memory cleanup on `runtime.stop()` works correctly\r\n\r\n**Test with plugin-discord:**\r\n```typescript\r\n// In plugin-discord/src/messages.ts\r\nif (this.runtime.hasElizaOS()) {\r\n  // Uses unified API - confirmed via logs\r\n  await this.runtime.elizaOS.sendMessage(agentId, message, options);\r\n} else {\r\n  // Fallback for standalone\r\n  await this.runtime.messageService.handleMessage(runtime, message, callback);\r\n}\r\n```\r\n\r\nLogs confirm unified API is used:\r\n```\r\nInfo [Discord] Using unified messaging API\r\n```",
      "repository": "elizaos/eliza",
      "createdAt": "2025-11-03T14:51:50Z",
      "mergedAt": "2025-11-12T16:26:21Z",
      "additions": 312,
      "deletions": 69
    }
  ],
  "codeChanges": {
    "additions": 675,
    "deletions": 353,
    "files": 20,
    "commitCount": 10
  },
  "completedItems": [
    {
      "title": "feat: add ElizaOS reference to runtime",
      "prNumber": 6111,
      "type": "feature",
      "body": "<!-- Use this template by filling in information and copying and pasting relevant items out of the HTML comments. -->\r\n\r\n# Relates to\r\n\r\nRelates to #6095 - Unified messaging API\r\n\r\n# Risks\r\n\r\n**Low risk**\r\n\r\nThis change is non-breaking and ",
      "files": [
        "packages/core/src/__tests__/elizaos.test.ts",
        "packages/core/src/elizaos.ts",
        "packages/core/src/runtime.ts",
        "packages/core/src/types/elizaos.ts",
        "packages/core/src/types/index.ts",
        "packages/core/src/types/runtime.ts",
        "packages/plugin-sql/src/__tests__/integration/postgres-init.test.ts",
        "packages/plugin-sql/src/__tests__/unit/index.test.ts",
        "packages/project-starter/src/__tests__/utils/core-test-utils.ts",
        "packages/project-tee-starter/src/__tests__/utils/core-test-utils.ts",
        "packages/server/src/__tests__/integration/jobs-message-flow.test.ts",
        "packages/core/src/__tests__/runtime-embedding.test.ts"
      ]
    },
    {
      "title": "fix: load environment variables from process.env instead of .env file",
      "prNumber": 6141,
      "type": "bugfix",
      "body": "## Relates to\r\n\r\nFixes the issue where `runtime.getSetting(\"ANY_VARIABLES\")` returns `undefined` when environment variables are exported on the host (`export VAR=value`) instead of being defined in a `.env` file, causing agents to use incor",
      "files": [
        "bun.lock",
        "packages/cli/src/commands/start/index.ts",
        "packages/core/src/__tests__/secrets.test.ts",
        "packages/core/src/__tests__/settings.test.ts",
        "packages/core/src/__tests__/utils/environment.test.ts",
        "packages/core/src/secrets.ts",
        "packages/core/src/utils/environment.ts",
        "packages/server/src/index.ts"
      ]
    }
  ],
  "topContributors": [
    {
      "username": "standujar",
      "avatarUrl": "https://avatars.githubusercontent.com/u/16385918?u=718bdcd1585be8447bdfffb8c11ce249baa7532d&v=4",
      "totalScore": 0.33999999999999997,
      "prScore": 0,
      "issueScore": 0,
      "reviewScore": 0,
      "commentScore": 0.33999999999999997,
      "summary": null
    },
    {
      "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": null
    }
  ],
  "newPRs": 0,
  "mergedPRs": 2,
  "newIssues": 0,
  "closedIssues": 0,
  "activeContributors": 4
}