Skip to content

Add Conductor workspace automation - #44

Merged
saddlepaddle merged 3 commits into
mainfrom
create-script
Nov 9, 2025
Merged

saddlepaddle merged 3 commits into
mainfrom
create-script

Conversation

@saddlepaddle

@saddlepaddle saddlepaddle commented Nov 9, 2025 •

Copy link
Copy Markdown
Collaborator

Summary

Adds Conductor configuration for automated workspace setup:

  • Setup script - Installs dependencies, links direnv, creates isolated Neon database branches
  • Run script - Starts all Turbo dev servers
  • Nonconcurrent mode - Only one dev server runs at a time

How it works

Each workspace gets:

  • Its own Neon database branch (e.g., lisbon, paris)
  • Workspace-specific .env with connection strings
  • Symlinked .envrc for direnv auto-loading

Test plan

  • Tested setup script in lisbon workspace
  • Verified Neon branch creation
  • Verified .env generation with DATABASE_URL
  • Verified .envrc symlink for direnv

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • One-command workspace setup for Superset that verifies required tools, installs dependencies, links environment config, creates a database branch, and populates environment credentials.
  • Chores

    • Added an automated setup script and configuration entry to streamline workspace initialization and provide progress logging.

- Setup script handles dependency installation, direnv, and Neon branches
- Each workspace gets isolated Neon database branch
- Run script starts all dev servers via Turbo

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 9, 2025 •

Copy link
Copy Markdown
Contributor

Walkthrough

Adds a new shell script and conductor config to automate Superset workspace setup: installs dependencies, symlinks .envrc, creates a Neon branch via neonctl, extracts database URLs with jq, and writes a .env file. The config registers the script as a conductor command.

Changes

Cohort / File(s) Summary
Workspace setup script
conductor-setup.sh
New shell script that enforces strict error handling, checks for bun, neonctl, and jq, runs bun install, symlinks .envrc, derives a workspace name, creates a Neon branch (neonctl), extracts DATABASE_URL and optional DATABASE_POOLED_URL via jq, and writes them into a new .env.
Conductor config
conductor.json
New configuration adding scripts.setup that runs ./conductor-setup.sh.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor User
    participant Conductor as conductor.json
    participant Setup as conductor-setup.sh
    participant Bun as bun
    participant Neon as neonctl
    participant JQ as jq
    participant FS as Filesystem

    User->>Conductor: invoke scripts.setup
    Conductor->>Setup: execute ./conductor-setup.sh
    activate Setup
    Setup->>Bun: bun install
    Bun-->>Setup: deps installed
    Setup->>FS: symlink .envrc
    FS-->>Setup: symlink created
    Setup->>Neon: neonctl branch create (workspace)
    Neon-->>Setup: JSON output
    Setup->>JQ: parse DATABASE_URL / DATABASE_POOLED_URL
    JQ-->>Setup: URL values
    Setup->>FS: write .env
    FS-->>Setup: .env created
    Setup-->>User: completion message
    deactivate Setup
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Check JSON parsing with jq for missing/nullable fields and quoting/escaping when writing .env.
  • Verify neonctl command usage and handling of command failures and stdout parsing.
  • Confirm symlink behavior for .envrc and idempotence of repeated runs.

Poem

🐰 I hopped a script into the night,
Created branches, fetched the light,
URLs tucked in a tidy file,
Dependencies danced for a while,
Workspace blooms—one rabbit's delight. 🌱

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title 'Add Conductor workspace automation' clearly and concisely summarizes the main change: adding automation capabilities for Conductor workspaces.
Description check ✅ Passed The pull request description covers most required template sections including a summary of changes, testing completed, and additional context. However, it lacks explicit sections for 'Related Issues', 'Type of Change', and 'Screenshots', and does not fully align with the template structure.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch create-script

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 844b455 and 39a22be.

📒 Files selected for processing (1)
  • conductor-setup.sh (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • conductor-setup.sh

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
conductor-setup.sh (1)

24-29: Handle empty DATABASE_POOLED_URL more explicitly.

When connection_uris[1] does not exist, the // empty filter produces an empty string, which is written to .env as DATABASE_POOLED_URL= (empty value). Downstream tooling may treat this differently than an unset variable or a commented-out line. Decide whether to:

  • Omit the line entirely if the value is empty, or
  • Keep the current behavior but document it, or
  • Comment it out if empty.

Consider conditionally writing the line:

 cat > .env << EOF
 DATABASE_URL=$DATABASE_URL
+$(if [[ -n "$DATABASE_POOLED_URL" ]]; then echo "DATABASE_POOLED_URL=$DATABASE_POOLED_URL"; fi)
 EOF

This ensures DATABASE_POOLED_URL is only present in .env if it has a non-empty value.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 87d80f3 and 844b455.

📒 Files selected for processing (2)
  • conductor-setup.sh (1 hunks)
  • conductor.json (1 hunks)
🔇 Additional comments (1)
conductor.json (1)

1-5: The second verification point from the review is now confirmed: conductor-setup.sh is already marked executable (-rwxr-xr-x permissions).

However, the first verification point cannot be conclusively determined without clarifying which conductor framework is in use. The web search found multiple projects named "conductor" (Mac app, Netflix Conductor orchestration engine, etc.), each with different validation behaviors.

To complete verification of framework-level script validation, check your project's conductor documentation or conductor.json schema to determine which framework is being used.

Comment thread conductor-setup.sh Outdated
Comment on lines +1 to +31
#!/usr/bin/env bash
set -e

echo "🚀 Setting up Superset workspace..."

# Install dependencies
echo "📥 Installing dependencies..."
bun install

# Link direnv config
echo "🔧 Linking .envrc..."
ln -sf "$CONDUCTOR_ROOT_PATH/.envrc" .envrc

# Create Neon branch for this workspace
echo "🗄️ Creating Neon branch..."
WORKSPACE_NAME=$(basename "${CONDUCTOR_WORKSPACE_PATH:-$PWD}")
NEON_OUTPUT=$(neonctl branches create \
--project-id tiny-cherry-82420694 \
--name "$WORKSPACE_NAME" \
--output json)

# Parse connection strings and create .env
DATABASE_URL=$(echo "$NEON_OUTPUT" | jq -r '.connection_uris[0].connection_uri')
DATABASE_POOLED_URL=$(echo "$NEON_OUTPUT" | jq -r '.connection_uris[1].connection_uri // empty')

cat > .env << EOF
DATABASE_URL=$DATABASE_URL
DATABASE_POOLED_URL=$DATABASE_POOLED_URL
EOF

echo "✨ Done! Neon branch: $WORKSPACE_NAME"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add validation for required tools and better error handling.

The script assumes bun, neonctl, and jq are available in $PATH but does not validate this. If any tool is missing, the script will fail with a cryptic error from the missing command. Additionally, JSON parsing failures are not explicitly handled.

Apply this diff to add tool validation:

 #!/usr/bin/env bash
 set -e
+
+# Validate required tools
+for cmd in bun neonctl jq; do
+  if ! command -v "$cmd" &> /dev/null; then
+    echo "❌ Error: Required tool '$cmd' is not installed or not in \$PATH." >&2
+    exit 1
+  fi
+done
 
 echo "🚀 Setting up Superset workspace..."

Additionally, add validation after JSON parsing to ensure required fields are present:

 # Parse connection strings and create .env
 DATABASE_URL=$(echo "$NEON_OUTPUT" | jq -r '.connection_uris[0].connection_uri')
+if [[ -z "$DATABASE_URL" || "$DATABASE_URL" == "null" ]]; then
+  echo "❌ Error: Failed to extract DATABASE_URL from Neon response. Response was:" >&2
+  echo "$NEON_OUTPUT" >&2
+  exit 1
+fi
 DATABASE_POOLED_URL=$(echo "$NEON_OUTPUT" | jq -r '.connection_uris[1].connection_uri // empty')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#!/usr/bin/env bash
set -e
echo "🚀 Setting up Superset workspace..."
# Install dependencies
echo "📥 Installing dependencies..."
bun install
# Link direnv config
echo "🔧 Linking .envrc..."
ln -sf "$CONDUCTOR_ROOT_PATH/.envrc" .envrc
# Create Neon branch for this workspace
echo "🗄️ Creating Neon branch..."
WORKSPACE_NAME=$(basename "${CONDUCTOR_WORKSPACE_PATH:-$PWD}")
NEON_OUTPUT=$(neonctl branches create \
--project-id tiny-cherry-82420694 \
--name "$WORKSPACE_NAME" \
--output json)
# Parse connection strings and create .env
DATABASE_URL=$(echo "$NEON_OUTPUT" | jq -r '.connection_uris[0].connection_uri')
DATABASE_POOLED_URL=$(echo "$NEON_OUTPUT" | jq -r '.connection_uris[1].connection_uri // empty')
cat > .env << EOF
DATABASE_URL=$DATABASE_URL
DATABASE_POOLED_URL=$DATABASE_POOLED_URL
EOF
echo "✨ Done! Neon branch: $WORKSPACE_NAME"
#!/usr/bin/env bash
set -e
# Validate required tools
for cmd in bun neonctl jq; do
if ! command -v "$cmd" &> /dev/null; then
echo "❌ Error: Required tool '$cmd' is not installed or not in \$PATH." >&2
exit 1
fi
done
echo "🚀 Setting up Superset workspace..."
# Install dependencies
echo "📥 Installing dependencies..."
bun install
# Link direnv config
echo "🔧 Linking .envrc..."
ln -sf "$CONDUCTOR_ROOT_PATH/.envrc" .envrc
# Create Neon branch for this workspace
echo "🗄️ Creating Neon branch..."
WORKSPACE_NAME=$(basename "${CONDUCTOR_WORKSPACE_PATH:-$PWD}")
NEON_OUTPUT=$(neonctl branches create \
--project-id tiny-cherry-82420694 \
--name "$WORKSPACE_NAME" \
--output json)
# Parse connection strings and create .env
DATABASE_URL=$(echo "$NEON_OUTPUT" | jq -r '.connection_uris[0].connection_uri')
if [[ -z "$DATABASE_URL" || "$DATABASE_URL" == "null" ]]; then
echo "❌ Error: Failed to extract DATABASE_URL from Neon response. Response was:" >&2
echo "$NEON_OUTPUT" >&2
exit 1
fi
DATABASE_POOLED_URL=$(echo "$NEON_OUTPUT" | jq -r '.connection_uris[1].connection_uri // empty')
cat > .env << EOF
DATABASE_URL=$DATABASE_URL
DATABASE_POOLED_URL=$DATABASE_POOLED_URL
EOF
echo "✨ Done! Neon branch: $WORKSPACE_NAME"
🤖 Prompt for AI Agents
In conductor-setup.sh around lines 1 to 31, add upfront validation and clearer
error handling: check that bun, neonctl, and jq are present (use command -v and
exit with a clear message if any are missing); capture neonctl command failure
(check its exit status and/or capture stderr) and print a descriptive error
before exiting instead of letting the script fail silently; validate the JSON
output from neonctl with jq and verify the DATABASE_URL and, if required,
DATABASE_POOLED_URL are non-empty (exit with a clear error if parsing failed or
required fields are missing); only write the .env file after those validations
succeed and surface useful error messages for each failure case.

Comment thread conductor-setup.sh
Comment on lines +16 to +20
WORKSPACE_NAME=$(basename "${CONDUCTOR_WORKSPACE_PATH:-$PWD}")
NEON_OUTPUT=$(neonctl branches create \
--project-id tiny-cherry-82420694 \
--name "$WORKSPACE_NAME" \
--output json)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Script is not idempotent; rerunning will attempt duplicate Neon branch creation.

Neon will reject a second branches create call with the same --name. Running this setup script twice in the same workspace will fail. Consider:

  • Checking if the branch already exists before attempting creation, or
  • Documenting that the script should only run once per workspace, or
  • Providing a separate idempotent "refresh" command if re-initialization is needed.

This could be addressed with a check before branch creation:

 WORKSPACE_NAME=$(basename "${CONDUCTOR_WORKSPACE_PATH:-$PWD}")
+
+# Check if branch already exists
+if neonctl branches get "$WORKSPACE_NAME" --project-id "${NEON_PROJECT_ID}" &> /dev/null; then
+  echo "ℹ️  Neon branch already exists: $WORKSPACE_NAME"
+  NEON_OUTPUT=$(neonctl branches get "$WORKSPACE_NAME" --project-id "${NEON_PROJECT_ID}" --output json)
+else
+  echo "Creating new Neon branch..."
 NEON_OUTPUT=$(neonctl branches create \
-  --project-id tiny-cherry-82420694 \
+  --project-id "${NEON_PROJECT_ID:?Error: NEON_PROJECT_ID not set}" \
   --name "$WORKSPACE_NAME" \
   --output json)
+fi

Verify that neonctl branches get and neonctl branches create outputs are compatible with the downstream JSON parsing.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
WORKSPACE_NAME=$(basename "${CONDUCTOR_WORKSPACE_PATH:-$PWD}")
NEON_OUTPUT=$(neonctl branches create \
--project-id tiny-cherry-82420694 \
--name "$WORKSPACE_NAME" \
--output json)
WORKSPACE_NAME=$(basename "${CONDUCTOR_WORKSPACE_PATH:-$PWD}")
# Check if branch already exists
if neonctl branches get "$WORKSPACE_NAME" --project-id "${NEON_PROJECT_ID}" &> /dev/null; then
echo "ℹ️ Neon branch already exists: $WORKSPACE_NAME"
NEON_OUTPUT=$(neonctl branches get "$WORKSPACE_NAME" --project-id "${NEON_PROJECT_ID}" --output json)
else
echo "Creating new Neon branch..."
NEON_OUTPUT=$(neonctl branches create \
--project-id "${NEON_PROJECT_ID:?Error: NEON_PROJECT_ID not set}" \
--name "$WORKSPACE_NAME" \
--output json)
fi
🤖 Prompt for AI Agents
In conductor-setup.sh around lines 16 to 20, the script always calls `neonctl
branches create` which is not idempotent and will fail on reruns; change it to
first check for an existing branch by name (e.g., use `neonctl branches get` or
`neonctl branches list`/filter) and reuse the existing branch output if found,
otherwise call `neonctl branches create`; ensure you handle and parse both `get`
and `create` JSON outputs consistently (extract the branch identifier/URL the
rest of the script expects) and surface any errors clearly so the script can be
safely re-run.

Comment thread conductor-setup.sh
Comment on lines +18 to +20
--project-id tiny-cherry-82420694 \
--name "$WORKSPACE_NAME" \
--output json)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Remove hardcoded project-id from the script.

Embedding tiny-cherry-82420694 as a hardcoded string violates configuration management best practices and creates a security risk by exposing project identifiers in version control. This should be sourced from an environment variable or configuration file instead.

Apply this diff to externalize the project-id:

 WORKSPACE_NAME=$(basename "${CONDUCTOR_WORKSPACE_PATH:-$PWD}")
-NEON_OUTPUT=$(neonctl branches create \
-  --project-id tiny-cherry-82420694 \
+NEON_OUTPUT=$(neonctl branches create \
+  --project-id "${NEON_PROJECT_ID:?Error: NEON_PROJECT_ID not set}" \
   --name "$WORKSPACE_NAME" \
   --output json)

Ensure NEON_PROJECT_ID is set via environment variable, .env, or passed by the conductor framework before invoking this script.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
--project-id tiny-cherry-82420694 \
--name "$WORKSPACE_NAME" \
--output json)
--project-id "${NEON_PROJECT_ID:?Error: NEON_PROJECT_ID not set}" \
--name "$WORKSPACE_NAME" \
--output json)
🤖 Prompt for AI Agents
In conductor-setup.sh around lines 18 to 20, the script currently hardcodes the
project-id "tiny-cherry-82420694"; replace that literal with an
environment-driven value (e.g., use $NEON_PROJECT_ID), ensure the script
validates that NEON_PROJECT_ID is set (exit with a clear error if missing), and
document or load it from .env or the calling environment so the project id is
not embedded in source control.

Comment thread conductor-setup.sh
Comment on lines +23 to +24
DATABASE_URL=$(echo "$NEON_OUTPUT" | jq -r '.connection_uris[0].connection_uri')
DATABASE_POOLED_URL=$(echo "$NEON_OUTPUT" | jq -r '.connection_uris[1].connection_uri // empty')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fragile JSON parsing; assume specific Neon API response structure without graceful degradation.

The jq filters assume connection_uris[0] and connection_uris[1] always exist. If the Neon API response structure differs (e.g., fewer URIs, different keys, or schema changes), parsing will silently fail or produce null. The // empty fallback for DATABASE_POOLED_URL is good, but DATABASE_URL has no fallback and will be set to "null" string if missing, which will corrupt the .env file.

Strengthen the parsing logic and add validation (see previous comment for a full fix). Additionally, verify the jq output:

# Debug: Print the Neon output structure before parsing
echo "$NEON_OUTPUT" | jq '.'

Confirm that .connection_uris[0].connection_uri and .connection_uris[1].connection_uri are the correct paths in all cases.

🤖 Prompt for AI Agents
In conductor-setup.sh around lines 23 to 24, the jq parsing assumes
connection_uris[0] always exists and will write the string "null" into the .env
if missing; change the parsing to (1) print/debug the raw NEON_OUTPUT (echo
"$NEON_OUTPUT" | jq '.') before extraction, (2) use jq with safe fallbacks for
DATABASE_URL and DATABASE_POOLED_URL (e.g. fall back to empty string or
alternate keys) so neither becomes the literal "null", (3) validate after
extraction that DATABASE_URL is non-empty and exit with a clear error if it is
missing, and (4) add a brief comment verifying the expected JSON paths and
handling alternate shapes so the script degrades gracefully when URIs are
absent.

Comment thread conductor-setup.sh
Comment on lines +26 to +29
cat > .env << EOF
DATABASE_URL=$DATABASE_URL
DATABASE_POOLED_URL=$DATABASE_POOLED_URL
EOF

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

.env file is overwritten without warning, backup, or existence check.

If a user has manually edited or created a .env file with custom values, running this script will silently overwrite it. Consider:

  • Checking if .env already exists and prompting the user, or
  • Creating a backup before overwriting, or
  • Generating a workspace-specific .env.conductor and sourcing it if needed.

Apply this diff to add a safety check:

-cat > .env << EOF
+if [[ -f .env ]]; then
+  echo "⚠️  Warning: .env already exists. Backing up to .env.bak"
+  mv .env .env.bak
+fi
+
+cat > .env << EOF
 DATABASE_URL=$DATABASE_URL
 DATABASE_POOLED_URL=$DATABASE_POOLED_URL
 EOF
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
cat > .env << EOF
DATABASE_URL=$DATABASE_URL
DATABASE_POOLED_URL=$DATABASE_POOLED_URL
EOF
if [[ -f .env ]]; then
echo "⚠️ Warning: .env already exists. Backing up to .env.bak"
mv .env .env.bak
fi
cat > .env << EOF
DATABASE_URL=$DATABASE_URL
DATABASE_POOLED_URL=$DATABASE_POOLED_URL
EOF
🤖 Prompt for AI Agents
In conductor-setup.sh around lines 26 to 29, the script blindly writes a .env
file which can overwrite a user's existing file; modify the script to first
check for an existing .env and if found either prompt the user to confirm
overwrite, create a timestamped backup (e.g., .env.bak.YYYYMMDD_HHMMSS), or
write to a workspace-specific file like .env.conductor and optionally source it;
implement one of these flows and ensure the script communicates the action to
the user (prompt/backup created/alternate file written) before proceeding.

@saddlepaddle
saddlepaddle merged commit 2fc97c0 into main Nov 9, 2025
2 of 5 checks passed
AviPeltz pushed a commit that referenced this pull request Nov 9, 2025
* Add Conductor workspace automation

- Setup script handles dependency installation, direnv, and Neon branches
- Each workspace gets isolated Neon database branch
- Run script starts all dev servers via Turbo

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Remove run script - let developers choose which apps to run

* Add dependency checks with clear error messages

---------

Co-authored-by: Claude <noreply@anthropic.com>
@coderabbitai coderabbitai Bot mentioned this pull request Nov 9, 2025
1 of 5 tasks
@Kitenite Kitenite mentioned this pull request Nov 9, 2025
5 tasks
@Kitenite
Kitenite deleted the create-script branch November 11, 2025 18:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant