Skip to content

Add install.sh — zero to running in one command (#385) - #428

Merged
joelteply merged 1 commit into
mainfrom
fix/install-script-385
Mar 25, 2026
Merged

Add install.sh — zero to running in one command (#385)#428
joelteply merged 1 commit into
mainfrom
fix/install-script-385

Conversation

@joelteply

Copy link
Copy Markdown
Contributor

Summary

New users can now:

curl -fsSL https://raw.githubusercontent.com/CambrianTech/continuum/main/install.sh | bash

Or from the repo:

./install.sh

The installer:

  1. Detects platform (macOS ARM/Intel, Linux, WSL2)
  2. Installs prerequisites (Node.js, Rust, Git)
  3. Bootstraps ~/.continuum/config.env with safe defaults
  4. Runs npm install + npm start

Zero API keys required — local inference works out of the box. Cloud keys are optional.

Test plan

  • Script syntax valid (shellcheck-style)
  • Test on clean macOS
  • Test on clean Ubuntu
  • Test on WSL2

🤖 Generated with Claude Code

curl -fsSL https://.../install.sh | bash

Detects platform (macOS/Linux/WSL2), installs prerequisites (Node, Rust, Git),
bootstraps ~/.continuum/config.env with safe defaults (zero API keys = local mode),
installs npm deps, builds, and starts.

Zero API keys required. Local inference works out of the box.
Copilot AI review requested due to automatic review settings March 25, 2026 13:55
@joelteply
joelteply merged commit f7b23f0 into main Mar 25, 2026
@joelteply
joelteply deleted the fix/install-script-385 branch March 25, 2026 13:55

Copilot AI 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.

Pull request overview

Adds a new top-level install.sh intended to provide a “curl | bash” path from zero → running Continuum with minimal manual setup.

Changes:

  • Introduces a root install.sh that detects OS/arch/WSL and installs basic prerequisites (Node, Rust, Git).
  • Bootstraps ~/.continuum/config.env if missing with minimal defaults.
  • Clones the repo (when not already in it), runs npm install, and starts the system.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread install.sh
# Installs all prerequisites, builds the system, and starts it.
# Works on macOS (ARM + Intel) and Linux (Ubuntu/Debian, WSL2).
# Zero API keys required — local inference works out of the box.
set -e

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

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

set -e alone won’t catch failures in pipelines later in this script (e.g., npm install | tail -3), and will allow the installer to continue after a failed command. Switch to set -euo pipefail (or at minimum set -e + set -o pipefail) so install failures reliably abort.

Suggested change
set -e
set -euo pipefail

Copilot uses AI. Check for mistakes.
Comment thread install.sh
Comment on lines +54 to +57
sudo apt-get install -y "$pkg" 2>/dev/null || sudo dnf install -y "$pkg" 2>/dev/null || {
echo " ❌ Failed to install $name (tried apt + dnf)"
return 1
}

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

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

This helper installs via apt-get without running apt-get update first, which commonly fails on fresh Ubuntu/Debian images. Consider updating the package index once (or in this helper) before the first apt-get install call.

Copilot uses AI. Check for mistakes.
Comment thread install.sh
Comment on lines +62 to +97
# ─── Step 1: System Prerequisites ───────────────────────────────────
echo "📋 Step 1: Checking prerequisites"
echo "----------------------------------"

# Homebrew (macOS only)
if [ "$IS_MAC" = true ] && ! command -v brew &>/dev/null; then
echo " 📦 Installing Homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi

# Node.js
if ! command -v node &>/dev/null; then
echo " 📦 Installing Node.js..."
if [ "$IS_MAC" = true ]; then
brew install node
else
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejs
fi
fi
echo " ✅ Node.js: $(node --version)"

# Rust
if ! command -v rustc &>/dev/null; then
echo " 📦 Installing Rust..."
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
fi
echo " ✅ Rust: $(rustc --version | awk '{print $2}')"

# Git (should exist but check)
if ! command -v git &>/dev/null; then
install_pkg git "Git"
fi
echo " ✅ Git: $(git --version | awk '{print $3}')"

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

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

On a clean Linux/macOS machine, Continuum typically requires additional system dependencies beyond Node/Rust/Git (e.g. build tooling, pkg-config, cmake, libssl-dev, protobuf compiler, etc.). The repo already has a comprehensive installer at src/scripts/install.sh used by bootstrap.sh; consider delegating to that script (or npm run install) so this entrypoint doesn’t become an incomplete parallel installer that fails during npm install/build.

Copilot uses AI. Check for mistakes.
Comment thread install.sh
Comment on lines +132 to +153
echo " 📝 Creating config.env with defaults (zero API keys = local-only mode)"
cat > "$CONFIG_FILE" << 'ENVEOF'
# Continuum Configuration
# All API keys are OPTIONAL — the system works with zero keys using local inference.
# Add keys to enable cloud providers for better quality on complex tasks.

# Cloud providers (uncomment and add your key to enable):
# ANTHROPIC_API_KEY=sk-ant-...
# OPENAI_API_KEY=sk-...
# DEEPSEEK_API_KEY=sk-...
# GROQ_API_KEY=gsk_...
# FIREWORKS_API_KEY=fw_...
# XAI_API_KEY=xai-...
# TOGETHER_API_KEY=tgp_...
# GOOGLE_API_KEY=AIza...

# Server config (defaults are fine)
HTTP_PORT=9000
WS_PORT=9001
ENVEOF
echo " ✅ Config created: $CONFIG_FILE"
echo " 💡 Add API keys later: nano $CONFIG_FILE"

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

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

This writes a minimal ~/.continuum/config.env that diverges from the canonical template in src/scripts/ensure-config.ts (which is also invoked by npm scripts like prepare/prebuild). Consider generating config via that script (or keeping the template content in sync) to avoid new users ending up with missing keys and confusing “new configuration key(s)” warnings later.

Suggested change
echo " 📝 Creating config.env with defaults (zero API keys = local-only mode)"
cat > "$CONFIG_FILE" << 'ENVEOF'
# Continuum Configuration
# All API keys are OPTIONAL — the system works with zero keys using local inference.
# Add keys to enable cloud providers for better quality on complex tasks.
# Cloud providers (uncomment and add your key to enable):
# ANTHROPIC_API_KEY=sk-ant-...
# OPENAI_API_KEY=sk-...
# DEEPSEEK_API_KEY=sk-...
# GROQ_API_KEY=gsk_...
# FIREWORKS_API_KEY=fw_...
# XAI_API_KEY=xai-...
# TOGETHER_API_KEY=tgp_...
# GOOGLE_API_KEY=AIza...
# Server config (defaults are fine)
HTTP_PORT=9000
WS_PORT=9001
ENVEOF
echo " ✅ Config created: $CONFIG_FILE"
echo " 💡 Add API keys later: nano $CONFIG_FILE"
echo " ℹ️ No config.env found at $CONFIG_FILE"
echo " 📝 A canonical config will be created automatically by Continuum on first run."
echo " 💡 You can edit it afterwards to add API keys and adjust settings."

Copilot uses AI. Check for mistakes.
Comment thread install.sh
echo "📋 Step 4: Installing dependencies"
echo "-----------------------------------"
cd src
npm install --no-audit --no-fund 2>&1 | tail -3

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

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

npm install ... | tail -3 will mask the real exit status without pipefail, and it also hides useful logs for diagnosing install failures. Prefer running npm install directly (or capturing logs to a file and summarizing) so failures are visible and correctly stop the installer.

Suggested change
npm install --no-audit --no-fund 2>&1 | tail -3
npm install --no-audit --no-fund

Copilot uses AI. Check for mistakes.
Comment thread install.sh
Comment on lines +173 to +180
npm start

echo ""
echo "🧬 Continuum is running!"
echo "========================"
echo ""
echo " 🌐 Open: http://localhost:9000"
echo " 📝 Config: $CONFIG_FILE"

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

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

The lines after npm start won’t run until the process exits (and typically npm start is long-running), so the “Continuum is running!” message is printed only after shutdown. Print the “running” instructions before launching, or run npm start in the background and then print the post-start instructions.

Copilot uses AI. Check for mistakes.
Comment thread install.sh
local name="${2:-$pkg}"

if command -v "$pkg" &>/dev/null; then
echo " ✅ $name: $(command -v $pkg)"

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

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

Minor: command -v $pkg should be quoted (command -v "$pkg") to avoid word-splitting issues and to match the quoting used elsewhere in the script.

Suggested change
echo "$name: $(command -v $pkg)"
echo "$name: $(command -v "$pkg")"

Copilot uses AI. Check for mistakes.
joelteply added a commit that referenced this pull request Aug 14, 2026
…State reaches minds via the ViewState pipe (#426) (#2298)

The renderable existed with a doctrine-citing comment ("a citizen standing in
the run's room can perceive the run's state through the same pipe the human's
screen uses") and was NEVER BOUND — supervisor bound only the Roster. Worse,
binding alone would have read an empty store: the bench emitter published only
into the websocket substrate, so the mind-side had no data to read. Citizens'
only route to run state was the benchmark/runs command, whose implementation
scrapes the progress dir — the exact acceptance-test failure
BENCHMARKS-ARE-ADAPTERS-NOT-A-RUNNER.md names.

The fix is the roster repair's one-definition-two-render-targets contract
applied to the bench outlier:

- ipc::global_bench_substrate() — the ONE mind-side handle. The bench board is
  a single global fold (unlike the per-room roster), so its handle is one
  substrate, not PerRoomSubstrates.
- spawn_bench_emitter dual-publishes the SAME builder.session(view) revision
  into the websocket substrate (human eyes) and the global bench substrate
  (citizen minds) — a screen and a mind can never disagree about the board.
- PersonaCognition gains bench_source + set_bench_source (same capture-sink
  decoration as roster/doctrine — deliveries recorded + replayable), pushed
  through THE budgeter in compose_for_turn; budget rides the generic
  floor_tokens arm (the renderable's own 18-token floor), no new constants.
- supervisor binds ViewStateRagSource::<BenchViewState> at persona boot.

// what this catches (new test): a bound bench source delivers REAL run rows
through the same compose path as every other source — if the push or setter
regresses, minds go blind to the board again and only this fails.

Found by the 2026-08-14 citizenship audit (AXIS 1c). Siblings tracked: #425
(retire the detached-runner auto-dispatch, Joel's timing call), #427 (L1 fork
capture contamination), #428 (doc/dead-wire hygiene).


Claude-Session: https://claude.ai/code/session_01LoTjvf5j3Ez13g6k8mRkFo

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
joelteply added a commit that referenced this pull request Aug 14, 2026
…428) (#2300)

Three fixes, no behavior change on any live path:

1. Delete the orphan agent:solve:complete publish (solve.rs). Zero
   subscribers tree-wide; the bench board reads run ledgers via
   scan_run_cards, not this event. Dead wire on the detached-runner
   path #425 will retire.

2. Correct the stale service_loop.rs turn-servicing comment. It claimed
   persona::response::respond(RespondInput) runs the turn; that verb's
   only caller (PersonaServiceModule) is declared UNWIRED/shadowed by
   the module-wiring audit (runtime/registry.rs). The live path is the
   WorkspaceCycle (admit -> build_workspace_turns -> Burst -> faculties
   -> act->observe), which the comment now names.

3. PERSONA-COGNITION-PIPELINE.md paragraph 2: add a per-verb Status column.
   Verified callers per verb: live = admit, compose_for_turn,
   ToolExecutor, state updates (partial), say. Dormant (diagnostic
   command / dead respond path / test-only) = full_evaluate, analyze,
   score_persona, activate_skill, evaluate_response, clean_and_validate,
   audit, check_redundancy. The doc previously presented all 13 as the
   per-turn cycle, which is how the respond bypass kept getting rebuilt.


Claude-Session: https://claude.ai/code/session_01LoTjvf5j3Ez13g6k8mRkFo

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants