Populate Scripts/data_pipeline/.env in cloud sessions via SessionStart hook#18
Draft
lighthousemacro wants to merge 1 commit into
Draft
Populate Scripts/data_pipeline/.env in cloud sessions via SessionStart hook#18lighthousemacro wants to merge 1 commit into
lighthousemacro wants to merge 1 commit into
Conversation
Cloud sessions previously started with no Scripts/data_pipeline/.env, so the data pipeline could not authenticate to FRED/BLS/BEA without manual setup. This adds a SessionStart hook that mirrors GitHub-injected environment variables into Scripts/data_pipeline/.env (for python-dotenv consumers) and into $CLAUDE_ENV_FILE (so env-var fallback works when python-dotenv is not installed). The hook is non-destructive: missing env vars preserve any existing value in .env across resume/clear/compact events. Update .gitignore to track .claude/hooks/ and .claude/settings.json while keeping the rest of .claude/ ignored. Actual .env values remain gitignored. https://claude.ai/code/session_016GAGsSXbdzM8QmsR2Cmgeu
Reviewer's GuideImplements a Claude Code SessionStart hook script that syncs cloud-injected environment variables into Scripts/data_pipeline/.env and an exportable env file, while updating .gitignore and adding Claude configuration files needed for the hook to run in cloud sessions. Sequence diagram for SessionStart hook populating data_pipeline .envsequenceDiagram
actor Developer
participant GitHubSecrets
participant ClaudeCloudSession
participant SessionStartHook
participant EnvFile as DataPipelineEnvFile
participant ClaudeEnvFile as ClaudeEnvExportFile
participant ConfigConsumer as DataPipelineConfig
Developer->>GitHubSecrets: Configure FRED_API_KEY, BLS_API_KEY, BEA_API_KEY, etc.
Developer->>ClaudeCloudSession: Start cloud session
GitHubSecrets-->>ClaudeCloudSession: Inject env vars into session
ClaudeCloudSession->>SessionStartHook: Trigger SessionStart
alt Running in remote Claude Code
SessionStartHook->>SessionStartHook: Check CLAUDE_CODE_REMOTE == true
SessionStartHook->>EnvFile: Read existing .env values (if file exists)
loop For each key in KEYS
SessionStartHook->>ClaudeCloudSession: Read env var for key
alt Env var set
SessionStartHook->>EnvFile: Write key=value from session env
else Env var not set
SessionStartHook->>EnvFile: Preserve existing key=value
end
end
SessionStartHook->>EnvFile: Atomically replace .env and chmod 600
opt CLAUDE_ENV_FILE set
loop For each key in KEYS
SessionStartHook->>ClaudeEnvFile: Append export key="value"
end
end
SessionStartHook->>SessionStartHook: Check required keys FRED_API_KEY, BLS_API_KEY, BEA_API_KEY
alt Any required key missing
SessionStartHook-->>Developer: Print warning to stderr
end
SessionStartHook-->>Developer: Print path to written .env
else Local session
SessionStartHook-->>ClaudeCloudSession: Exit immediately
end
Developer->>ConfigConsumer: Run data pipeline scripts
ConfigConsumer->>EnvFile: Load .env via python dotenv (if available)
ConfigConsumer->>ClaudeCloudSession: Fallback to process env vars when dotenv is absent
Flow diagram for SessionStart hook .env synchronization logicflowchart TD
A["Start session-start.sh"] --> B{CLAUDE_CODE_REMOTE == true}
B -->|No| Z["Exit without changes"]
B -->|Yes| C["Set ENV_DIR and ENV_FILE paths"]
C --> D["Create Scripts/data_pipeline directory"]
D --> E{ENV_FILE exists?}
E -->|Yes| F["Load existing key=value pairs into map existing"]
E -->|No| G["Initialize empty existing map"]
F --> H["Define KEYS array
FRED_API_KEY, BLS_API_KEY, BEA_API_KEY,
KIMI_API_KEY, TG_API_KEY,
LIGHTHOUSE_DB_PATH, SANTIMENT_API_KEY,
DUNE_API_KEY, COINGLASS_API_KEY"]
G --> H
H --> I["Create temporary file"]
I --> J["Write header comments to temp file"]
J --> K["For each name in KEYS"]
K --> L["Resolve value from session env or existing map"]
L --> M["Append name=value line to temp file"]
M --> N{More KEYS?}
N -->|Yes| K
N -->|No| O["Move temp file to ENV_FILE
and chmod 600"]
O --> P{CLAUDE_ENV_FILE set?}
P -->|No| S["Skip export file population"]
P -->|Yes| Q["For each name in KEYS"]
Q --> R["Resolve value, skip if empty,
escape and append export line to CLAUDE_ENV_FILE"]
R --> T{More KEYS?}
T -->|Yes| Q
T -->|No| S
S --> U["Check required keys
FRED_API_KEY, BLS_API_KEY, BEA_API_KEY"]
U --> V{Any required key empty?}
V -->|Yes| W["Print warnings to stderr"]
V -->|No| X["No warnings"]
W --> Y["Print success message with ENV_FILE path"]
X --> Y
Y --> AA["End script"]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Scripts/data_pipeline/.env, so FRED/BLS/BEA fetchers couldn't authenticate without manual setup. This adds aSessionStarthook that mirrors cloud-injected env vars (intended to come from GitHub repository secrets) into the.envfile, and also exports them via$CLAUDE_ENV_FILEso the env-var fallback inScripts/data_pipeline/lighthouse/config.py:11-17works whenpython-dotenvisn't installed..envvalue is preserved (matters forresume/clear/compactre-fires)..gitignorenow tracks.claude/hooks/and.claude/settings.jsonwhile continuing to ignore the rest of.claude/. Actual.envvalues remain gitignored.How it works
Each session start, the hook walks a known key list (
FRED_API_KEY,BLS_API_KEY,BEA_API_KEY,KIMI_API_KEY,TG_API_KEY, plus optionalLIGHTHOUSE_DB_PATH/SANTIMENT_API_KEY/DUNE_API_KEY/COINGLASS_API_KEY). For each key:.envand to$CLAUDE_ENV_FILE..env.To make this useful in CI/cloud, configure each name as a GitHub repository secret so it's injected as an env var in Claude Code on the web sessions. Names should match exactly.
Test plan
.envfile written with correct value lengths for all five user-supplied keys$CLAUDE_ENV_FILEproduces sourceableexportlines that re-create the env vars in a shellconfig.pyconsumer reads required keys (FRED/BLS/BEA) successfully via env-var fallbackgit ls-files --others --exclude-standardshows only the hook + settings.json (no.envleakage).envis auto-populated from configured GitHub secretspython Scripts/data_pipeline/run_pipeline.py --statsagainst a fresh session to confirm authenticationhttps://claude.ai/code/session_016GAGsSXbdzM8QmsR2Cmgeu
Generated by Claude Code
Summary by Sourcery
Add a cloud session startup hook to sync data pipeline credentials from environment variables into Scripts/data_pipeline/.env and ensure they are available to non-dotenv consumers.
Enhancements:
Build: