Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
f7a0138
Plan 1.1: Add RuntimeConfig to config.py
liranhason Apr 14, 2026
8332788
Plan 2.1: Update connect.py to use RuntimeConfig
liranhason Apr 14, 2026
6abd3b5
Plan 2.2: Update run.py to use RuntimeConfig
liranhason Apr 14, 2026
80e5bbc
Plan 3.1+3.2: Runtime-aware workspace paths in utils, create, info
liranhason Apr 14, 2026
824eece
Plan 4.1+4.2: Rename spec to 06-runtime.md, generalize runtime framing
liranhason Apr 14, 2026
c4196ea
Plan 4.3: Document runtime configurability in READMEs
liranhason Apr 14, 2026
c7e070d
Fix code review issues: immutability, shell injection, validation
liranhason Apr 14, 2026
1986787
Plan 1.1+2.1: Generalize review-agent and create /review command
liranhason Apr 14, 2026
8fd9f73
Fix code review issues: argument injection, process safety, validation
liranhason Apr 14, 2026
432fbea
Plan: E2E tests for Canopy CLI
liranhason Apr 14, 2026
2829469
Plan 1.1: Set up pytest and subprocess test helper
liranhason Apr 14, 2026
c4c169e
Plan 2.1: E2E tests for canopy create
liranhason Apr 14, 2026
305a37f
Plan 2.2: E2E tests for canopy ls
liranhason Apr 14, 2026
1e66b25
Plan 2.3: E2E tests for canopy info
liranhason Apr 14, 2026
3b8d7b2
Plan 2.4: E2E tests for canopy delete
liranhason Apr 14, 2026
de06bc0
Plan 2.5: E2E lifecycle integration test
liranhason Apr 14, 2026
3c72e89
Plan 3.1+3.2: E2E tests for canopy run (happy path and error cases)
liranhason Apr 14, 2026
717b8de
Plan 4.1: E2E tests for canopy connect
liranhason Apr 14, 2026
e17745d
Plan 5.1: E2E tests for custom runtime configuration
liranhason Apr 14, 2026
9a56b6f
Plan 5.2: E2E tests for env file loading
liranhason Apr 14, 2026
3355ea6
Plan 6.1: E2E tests for fuzzy workspace resolution
liranhason Apr 14, 2026
19124a0
Plan 6.2: E2E tests for malformed data and edge cases
liranhason Apr 14, 2026
729890f
docs: add Development section to cli/README.md with test and lint com…
liranhason Apr 14, 2026
02809a9
chore: commit conftest.py fixture additions and uv.lock update
liranhason Apr 14, 2026
0057d33
fix: add inter-test delay in requires_api_key to avoid rate limiting
liranhason Apr 14, 2026
90e57ea
Plan 1.1-1.3: merge redundant tests, remove timeouts, bump delay default
liranhason Apr 15, 2026
292870e
fix: add retry-with-backoff to run_cli fixture for 429 rate limits
liranhason Apr 16, 2026
0c1b469
update plan status to completed
liranhason Apr 16, 2026
f8ce679
Remove completed plans
liranhason Apr 16, 2026
f77eda4
Plan 1.1: Add --template flag and CANOPY_TEMPLATE env var to resolve_…
liranhason Apr 19, 2026
d411764
Plan 2.1: Add validate_template() with semver/name validation and uni…
liranhason Apr 19, 2026
be25bba
Plan 2.2: Validate template in create before filesystem writes
liranhason Apr 19, 2026
ada9581
Plan 3.1: Pin _canopy_source and _canopy_created in workspace version…
liranhason Apr 19, 2026
dac54b2
Plan 3.2: Show Source and Created fields in canopy info
liranhason Apr 19, 2026
ac9e692
Plan 4.1: Qualify chmod 0o444 as UX guard in architecture and securit…
liranhason Apr 19, 2026
88b77fa
Open-source readiness: scrub names, metadata, CI, OSS files
liranhason Apr 19, 2026
5f176d6
Plan 3.2: Unit tests for utils.py — scan, resolve, read_version_json,…
liranhason Apr 19, 2026
d373cde
Plan 3.3: Unit tests for config.py and run.py helpers
liranhason Apr 19, 2026
8876f62
Mark open-source readiness plan complete; fix unused pytest import in…
liranhason Apr 19, 2026
d362074
Remove remaining Olly and Coralogix references from cc-stream-format.md
liranhason Apr 19, 2026
1d955e8
Plan 1.1: Remove internal artifacts and fix placeholders
liranhason Apr 19, 2026
9aa1869
Plan 2.1: Rewrite README.md and CLAUDE.md for runtime-agnostic framing
liranhason Apr 19, 2026
22247a7
Plan 2.2: Rewrite specs/06-runtime.md with Supported Runtimes overview
liranhason Apr 19, 2026
80f29c7
Plan 2.3: Rewrite specs/01-architecture.md for runtime-agnostic framing
liranhason Apr 19, 2026
64f9aa1
Plan 2.4: Rewrite security, sessions, and multi-tenancy specs for run…
liranhason Apr 19, 2026
2f2b5b0
Plan 2.5: Rewrite adoption guide, cli/README, and templates for runti…
liranhason Apr 19, 2026
6e84990
Mark Milestone 2 complete in release plan
liranhason Apr 19, 2026
689b683
Fix unqualified Claude Code reference in README philosophy section
liranhason Apr 19, 2026
4abfb4b
Plan M3: Add example templates and replace example-template/
liranhason Apr 19, 2026
61739ac
Mark Milestone 3 complete in release plan
liranhason Apr 19, 2026
2890b9b
Plan M4: Bundle templates in package and add PyPI publish workflow
liranhason Apr 19, 2026
46be1f4
Mark Milestone 4 complete in release plan
liranhason Apr 19, 2026
7b4f19d
Switch license from MIT to Apache 2.0
liranhason Apr 19, 2026
ace8d61
Fix all ruff lint errors and update CI action versions
liranhason Apr 20, 2026
7ac4877
Restructure release plan: split Ship It into M5 (polish) and M6 (go l…
liranhason Apr 20, 2026
16c5f83
Plan 5.1: Add CHANGELOG.md for v0.1.0-alpha
liranhason Apr 20, 2026
2372bc8
fix: add ruff to dev deps and update CI lint step
liranhason Apr 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
name: Bug report
about: Something isn't working as expected
labels: bug
---

## Description

A clear description of the bug.

## Steps to Reproduce

1.
2.
3.

## Expected Behavior

What you expected to happen.

## Actual Behavior

What actually happened. Include the full error message / stack trace if applicable.

## Environment

- OS:
- Python version:
- canopy-cli version (`canopy --version`):
- uv version (`uv --version`):
17 changes: 17 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: Feature request
about: Propose a new feature or improvement
labels: enhancement
---

## Problem

What problem does this solve? Who is affected?

## Proposed Solution

Describe what you'd like to see added or changed.

## Alternatives Considered

Other approaches you've considered and why you prefer your proposal.
14 changes: 14 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## Summary

<!-- What does this PR do and why? -->

## Changes

<!-- Bullet list of notable changes -->

## Checklist

- [ ] Tests added or updated for new behavior
- [ ] `cd cli && uv run ruff check .` passes
- [ ] `cd cli && uv run --with pytest pytest` passes
- [ ] Docs updated if behavior changed (specs/, README, examples/)
29 changes: 29 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: CI

on:
push:
branches: [master]
pull_request:

jobs:
lint-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5

- name: Install uv
uses: astral-sh/setup-uv@v5
with:
version: "latest"

- name: Set up Python
run: uv python install 3.12

- name: Install dependencies
run: uv sync --directory cli

- name: Lint
run: uv run --directory cli --with ruff ruff check .

- name: Test
run: uv run --directory cli --with pytest pytest --tb=short
32 changes: 32 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Publish to PyPI

on:
push:
tags:
- "v*"

jobs:
publish:
runs-on: ubuntu-latest
environment: pypi
permissions:
id-token: write # Required for OIDC trusted publisher

steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v5
with:
version: "latest"

- name: Set up Python
run: uv python install 3.12

- name: Build package
run: uv build --directory cli

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: cli/dist/
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,9 @@ __pycache__/

# Workspace data (never commit user workspaces)
workspaces/

# Internal scratch files
context-analysis.md
.claude/scheduled_tasks.lock
.claude/agents/
.claude/commands/
42 changes: 42 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

---

## [0.1.0-alpha] - 2026-04-20

This is the first public release of Canopy. We're building in public — expect rough edges, and feel free to open issues or PRs.

### Added

**CLI** — `pip install canopy-cli` gives you 6 commands to manage agent workspaces locally:
- `canopy create <account_id> <user_id>` — provision a workspace from a template
- `canopy connect <name>` — open an interactive agent session in a workspace
- `canopy run <name> -p "<prompt>"` — run a one-shot prompt and stream the response
- `canopy ls` — list all workspaces
- `canopy info <name>` — show workspace details (path, template, version, layers, MCP servers)
- `canopy delete <name>` — delete a workspace

**Example Templates** — three ready-to-use templates in `examples/`, each demonstrating a different Canopy capability:
- `codebase-navigator` — explains architecture, finds code examples, traces data flow (showcases Layer 1 + skills)
- `release-pilot` — changelog drafting, pre-release audits, CI checks (showcases multi-step skills + MCP patterns)
- `daily-standup` — morning briefings, standup summaries, work tracking (showcases per-user Layer 3 memory)

**Runtime Configuration** — Canopy is runtime-agnostic. Claude Code is the default, but any coding agent can be configured via `CANOPY_RUNTIME`. Custom runtimes use `CANOPY_RUNTIME=custom` with individual `CANOPY_RUNTIME_*` env vars.

**Workspace Architecture** — 3-layer filesystem model:
- Layer 1 (template) — developer-controlled, immutable at runtime
- Layer 2 (user) — per-user customizations
- Layer 3 (agent) — runtime-generated memory and learned context

**Framework Specifications** — 7 architecture docs covering the full Canopy model:
- 01 Architecture, 02 Security, 03 Versioning, 04 Sessions, 05 Multi-Tenancy, 06 Runtime, 07 Adoption Guide

**CI/CD** — GitHub Actions workflow for lint (ruff) and tests (pytest) on every push and PR.

**Community Files** — CONTRIBUTING.md, SECURITY.md, issue templates, PR template.

**License** — Apache 2.0 (aligned with Docker/Kubernetes ecosystem tooling).
18 changes: 9 additions & 9 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,44 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Project Overview

Canopy is infrastructure for building agent-native applications using Claude Code as the runtime engine. The core abstraction is the **Workspace** — an isolated directory-based workspace that defines an agent's behavior, memory, and capabilities through `.md` files and Claude Code configuration.
Canopy is infrastructure for building agent-native applications with pluggable runtimes. The core abstraction is the **Workspace** — an isolated directory-based workspace that defines an agent's behavior, memory, and capabilities through `.md` files and runtime configuration.

**How it works:** Developers author a template folder (CLAUDE.md, skills, agents, tool configs). Canopy infra provisions a Workspace directory for every user from that template, handles triggers (scheduler, chat, webhooks), and spawns isolated Claude Code instances per user. CC returns results as stdout; Canopy captures and routes the output.
**How it works:** Developers author a template folder (CLAUDE.md, skills, agents, tool configs). Canopy infra provisions a Workspace directory for every user from that template, handles triggers (scheduler, chat, webhooks), and spawns isolated runtime instances per user. The runtime returns results as stdout; Canopy captures and routes the output. Claude Code is the default runtime; any coding agent can be configured via `CANOPY_RUNTIME`.

**Philosophy:** Documents are database. Skills are functions. The LLM is the CPU. Code is only for I/O.

**Doc purpose:** These docs are an implementation spec — copy this folder into your project, point Claude at it, and it can build the entire Canopy platform for your agent.

**Status:** Documentation + templates + CLI (`cli/`). No build system or automated tests yet.
**Status:** Documentation + templates + CLI (`cli/`). 90+ tests, CI via GitHub Actions, PyPI-ready packaging.

## Repository Structure

- `specs/01-architecture.md` through `specs/07-adoption-guide.md` — Framework specification docs
- `templates/` — Starter templates (CLAUDE.md.template, skill.md.template, tool-config.md.template, settings.json.template, workspace-structure.md, version.json)
- `example-template/` — Reference implementation: a generic SRE observability agent
- `examples/` — Example agent templates (`codebase-navigator`, `release-pilot`, `daily-standup`)
- `cli/` — Developer CLI for managing workspaces (create, run, connect, delete)

## Core Architecture

**Claude Code as Runtime:** Every Workspace is a directory. Canopy spawns `claude --print --cwd /path/to/workspace` per trigger. CC natively handles CLAUDE.md loading, skills (`.claude/commands/`), sub-agents (`.claude/agents/`), MCP tools (`settings.json`), auto-memory, hooks, and sandboxing. No custom runtime code.
**Configurable Runtime:** Every Workspace is a directory. Canopy spawns a runtime process against that directory per trigger. The runtime handles context loading, skills, agents, MCP tools, memory, hooks, and sandboxing. No custom runtime code. Runtime is configurable via `CANOPY_RUNTIME` (default: `claude-code`) — see `specs/06-runtime.md`.

**3-Layer Workspace Model** (assembly order: L1 → L2 → L3):
1. **Layer 1 (Template)** — Developer-controlled, immutable at runtime. Agent personality, skills, agents, tool configs, settings.
2. **Layer 2 (User)** — User customizations, validated writes only. Preferences, custom instructions.
3. **Layer 3 (Agent)** — Agent-generated via CC auto-memory. Memory, knowledge, learned skills.
3. **Layer 3 (Agent)** — Agent-generated via runtime memory system. Memory, knowledge, learned skills. (When using Claude Code: auto-memory.)

Higher layers append but **cannot remove or override** Layer 1 safety rules.

**B2B extends to 4 layers:** Template → Org (admin-controlled) → User → Agent memory.

**Canopy Infra:** The thin infrastructure layer that provisions Workspace directories from templates, handles triggers, spawns CC processes, captures stdout, and manages auth/billing.
**Canopy Infra:** The thin infrastructure layer that provisions Workspace directories from templates, handles triggers, spawns runtime processes, captures stdout, and manages auth/billing.

## Writing Guidelines

- **Generic only** — Never reference Shadow, Olly, or any specific product. Use examples like "Personal EA", "SRE Agent", "Customer Support Agent".
- **Generic only** — Never reference specific commercial products or internal product names. Use generic examples like "Personal EA", "SRE Agent", "Customer Support Agent".
- **Stack-agnostic** — No specific tech stack prescribed. Describe what needs to happen, not how to implement it.
- **Security model** — 7 controls: template immutability, scoped agent writes, tool allowlist, sandboxed learned skills, validated user overrides, workspace isolation, token vault. All must be preserved in any changes.
- **Implementable spec** — Docs must be precise enough that Claude can implement the entire Canopy platform from them.
- **Template files** use `{{ placeholder }}` syntax with inline comments explaining what to fill in.
- **Workspace directories** (`workspaces/`) are gitignored — never commit user workspaces.
- **CC-native paths** — Skills in `.claude/commands/`, agents in `.claude/agents/`, memory in `.claude/projects/*/memory/`, settings in `.claude/settings.json`.
- **Runtime-agnostic language** — Use "the runtime" instead of "Claude Code" when describing general Canopy behavior. Qualify CC-specific details: "When using Claude Code: skills in `.claude/commands/`, agents in `.claude/agents/`, memory in `.claude/projects/*/memory/`, settings in `.claude/settings.json`."
48 changes: 48 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Contributing to Canopy

## Getting Started

```bash
git clone https://github.com/coralogix/canopy.git
cd canopy
uv pip install -e "cli[test]"
canopy --help
```

Requires Python 3.12+ and [uv](https://docs.astral.sh/uv/).

## Development

**Run tests:**
```bash
cd cli && uv run --with pytest pytest
```

**Run lint:**
```bash
cd cli && uv run ruff check .
```

**Run a single test file:**
```bash
cd cli && uv run --with pytest pytest tests/test_create.py -v
```

## What We Welcome

- **Architecture feedback** — open an issue to discuss design questions before implementing
- **Worked examples** — additions to the Adoption Guide or new example templates
- **MCP server examples** — tool-config docs for popular MCP servers
- **Bug reports** — include OS, Python version, `canopy --version`, and reproduction steps
- **Bug fixes** — open an issue first for anything non-trivial

## PR Process

1. Fork the repo and create a branch from `master`
2. Make your changes with tests where applicable
3. Ensure `ruff check` and `pytest` pass
4. Open a PR with a clear description of the change and why

## Code Style

Follow existing patterns. `ruff` enforces style automatically — run it before pushing.
Loading
Loading