Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
78 changes: 78 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# AGENTS.md

## Design Philosophy

1. **Signal-Driven Intelligence** — All agent intelligence derives from observing real-world signals, not from hardcoded rules. If a behavior cannot be learned from signals, it is not in scope.

2. **Context Pipeline as Core** — Signal → Filter (SNR) → Compress (intent-preserving) → Store (multi-layer) → Retrieve (goal-dependent) → Decide. Every feature must map to this pipeline.

3. **Progressive Trust** — Never auto-execute on first encounter. Earn autonomy through repeated success: DRAFT → CANDIDATE → VERIFIED → PRODUCTION.

4. **Occam's Razor** — The simplest correct solution wins. Reject complexity that doesn't directly serve user value. Every abstraction must pay for itself.

5. **LLM-Native Design** — Design for LLM reasoning first. Protocols over classes. Declarative over imperative. Context over configuration.

## Code Quality Requirements

- SOLID principles are non-negotiable
- Occam's Razor: maximize elegance and efficiency, reject unnecessary complexity
- Design for generalization and universality
- Easy to extend, avoid hardcoding and hard rules
- Industrial-grade robustness: every external call has timeout, retry, and fallback
- All comments and docstrings in English
- Type annotations on all public APIs
- No bare except — always specify exception types

## Architecture Principles

- **Dependency Inversion**: Core logic depends on Protocol abstractions, never on concrete implementations
- **Protocol over ABC**: Use `typing.Protocol` with `runtime_checkable` for all extension points
- **Event-Driven Communication**: Modules interact through typed events on EventBus, not direct imports
- **Immutable Domain Types**: Use `@dataclass(frozen=True)` or `NamedTuple` for domain objects
- **Config-Driven Behavior**: Thresholds, intervals, feature flags — all configurable via env vars
- **Graceful Degradation**: Every optional component (LLM, Hub, OS Host) can be absent without crash
- **Single Source of Truth**: DuckDB for persistence, EventBus for communication, Settings for configuration

## Implementation Guidelines

- Define the Protocol first — the contract is the design
- Implement against the Protocol, never against another implementation
- Write unit tests before or alongside the implementation
- Integrate via EventBus events, not direct function calls between modules
- Every module must be importable standalone without side effects
- No placeholder stubs — implement fully or do not add the code
- ANSI output must check `sys.stdout.isatty()` before emitting escape codes

## Testing Philosophy

- **Unit tests must be hermetic**: no network, no OS Host, no LLM calls
- **py_compile all modified files**: syntax errors caught before test run
- **Import chain verification**: every new module must be importable standalone
- **Existing tests must not regress**: all tests must pass after every change
- **Verification sequence**: compile → import → unit test → integration (if applicable)
- **Behavior contracts over snapshots**: assert invariants, not frozen values
- **Mock at boundaries only**: mock external I/O (network, disk, OS Host), never internal logic

## What to Avoid

- Over-engineering: if you need 3+ files for a simple feature, rethink
- Premature optimization: measure first, optimize only bottlenecks
- God objects: no class should exceed 300 lines
- Magic strings: use constants or enums
- Blocking the event loop: all IO must be async or `run_in_executor`
- Hardcoded paths, URLs, thresholds without config escape hatch
- Chinese comments in source code (English only)
- Speculative infrastructure: no hooks or extension points without a concrete consumer
- Bare `except:` clauses — always specify the exception type
- `# TODO: implement` stubs — implement or don't commit

## Naming Conventions

- **Files**: `snake_case.py` — noun for types (`signal_event.py`), verb for actions (`compress_context.py`)
- **Classes**: `PascalCase` — Protocols suffixed with purpose (`SignalSource`, `SkillStore`)
- **Functions/Methods**: `snake_case` — verb-first (`filter_noise`, `retrieve_context`)
- **Constants**: `UPPER_SNAKE_CASE` — grouped in module-level or dedicated `constants.py`
- **Private**: single underscore prefix (`_internal_method`) — never double underscore
- **Modules/Packages**: short, singular nouns (`perception`, `causal`, `memory`)
- **Events**: past-tense domain verbs (`SignalReceived`, `SkillVerified`, `ContextCompressed`)
- **Config keys**: `dot.separated.lowercase` in env/settings (`copilot.idle_threshold_ms`)
95 changes: 4 additions & 91 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,30 +1,7 @@
# ── Variables ─────────────────────────────────────────────────────────────────
LEAPFLOW_DATA_DIR ?= $(HOME)/.leapflow
HOST_ROOT := $(LEAPFLOW_DATA_DIR)/host
HOST_SOCKET := $(LEAPFLOW_DATA_DIR)/var/host.sock
HOST_PID := $(LEAPFLOW_DATA_DIR)/var/host.pid
HOST_LOG := $(LEAPFLOW_DATA_DIR)/var/host.log

# ── OS Host platform detection ────────────────────────────────────────────────
HOST_OS := $(shell uname -s)

ifeq ($(HOST_OS),Darwin)
# macOS: direct swiftc (workaround for CLT 26.x SPM manifest bug)
HOST_SRC := os_host/darwin/Sources/OSHost
HOST_SOURCES := $(shell find $(HOST_SRC) -name '*.swift')
SWIFTC_FLAGS := -module-name OSHost -swift-version 5 \
-target arm64-apple-macosx14.0 \
-sdk $(shell xcrun --show-sdk-path) \
-vfsoverlay os_host/darwin/vfs_overlay.yaml
else ifeq ($(HOST_OS),Linux)
$(info OS Host for Linux: not yet implemented)
else
$(info OS Host for $(HOST_OS): not yet implemented)
endif

.PHONY: setup sync test brain host swift-build lint \
host-build host-install host-start host-stop host-restart \
host-status host-setup host-clean host-dev
.PHONY: setup sync test brain lint cua-check

setup: ## Setup scripts permissions and environment
chmod +x scripts/setup.sh scripts/run.sh
Expand All @@ -39,73 +16,9 @@ test: ## Run tests
lint: ## Lint source code
uv run ruff check src/leapflow/ tests/

# LeapFlow CLI (pass PROMPT via ARGS, e.g. make brain ARGS='--mock-host --prompt "hello"')
# LeapFlow CLI (pass PROMPT via ARGS, e.g. make brain ARGS='--prompt "hello"')
brain: ## Start Brain process
uv run leap $(ARGS)

swift-build: ## Build OS Host (debug)
ifeq ($(HOST_OS),Darwin)
@mkdir -p os_host/darwin/.build/debug
swiftc $(SWIFTC_FLAGS) -g -Onone -o os_host/darwin/.build/debug/OSHost $(HOST_SOURCES)
@echo "Built: os_host/darwin/.build/debug/OSHost"
else
@echo "Error: OS Host build not yet supported on $(HOST_OS)" && exit 1
endif

host: ## Run OS Host in foreground (debug)
@$(MAKE) swift-build
LEAPFLOW_BRIDGE_SOCKET=$${LEAPFLOW_BRIDGE_SOCKET:-$(HOST_SOCKET)} os_host/darwin/.build/debug/OSHost

# ── OS Host Service Management ────────────────────────────────────────────────

host-build: ## Build OS Host (release)
ifeq ($(HOST_OS),Darwin)
@mkdir -p os_host/darwin/.build/release
swiftc $(SWIFTC_FLAGS) -O -o os_host/darwin/.build/release/OSHost $(HOST_SOURCES)
@echo "Built: os_host/darwin/.build/release/OSHost"
else
@echo "Error: OS Host build not yet supported on $(HOST_OS)" && exit 1
endif

host-install: host-build ## Build + package as .app bundle + deploy to ~/.leapflow/host/
@mkdir -p $(HOST_ROOT)/LeapHost.app/Contents/MacOS
@mkdir -p $(HOST_ROOT)/LeapHost.app/Contents/Resources
@cp os_host/darwin/.build/release/OSHost $(HOST_ROOT)/LeapHost.app/Contents/MacOS/LeapHost
@cp os_host/darwin/Resources/Info.plist $(HOST_ROOT)/LeapHost.app/Contents/Info.plist
@chmod +x $(HOST_ROOT)/LeapHost.app/Contents/MacOS/LeapHost
@echo "Installed to $(HOST_ROOT)/LeapHost.app"

host-start: ## Start OS Host service
@mkdir -p $(LEAPFLOW_DATA_DIR)/var
$(HOST_ROOT)/LeapHost.app/Contents/MacOS/LeapHost \
--daemon --socket $(HOST_SOCKET) --pid-file $(HOST_PID) --log-file $(HOST_LOG) &
@echo "OS Host started"

host-stop: ## Stop OS Host service
@if [ -f $(HOST_PID) ]; then \
kill $$(cat $(HOST_PID)) 2>/dev/null || true; \
echo "OS Host stopped"; \
else \
echo "OS Host not running"; \
fi

host-restart: host-stop host-start ## Restart OS Host

host-status: ## Show OS Host status
@if [ -f $(HOST_PID) ] && kill -0 $$(cat $(HOST_PID)) 2>/dev/null; then \
echo "● Running (PID $$(cat $(HOST_PID)))"; \
else \
echo "○ Stopped"; \
fi

host-setup: host-install ## Full setup: build + install + register launchd
@python -m leapflow.cli.commands.host _register_launchd 2>/dev/null || \
echo "Run 'leap host setup' for full LaunchAgent registration"
@echo "Setup complete. Run 'leap host start' or re-login for auto-start."

host-clean: ## Remove installed host
@rm -rf $(HOST_ROOT)/LeapHost.app
@echo "Host app removed"

host-dev: ## Run OS Host in dev mode (auto-rebuild on changes)
uv run leap host dev
cua-check: ## Check cua-driver installation status
@which cua-driver > /dev/null 2>&1 && echo "✓ cua-driver: $$(cua-driver --version 2>/dev/null || echo 'installed')" || echo "✗ cua-driver not found. Install: brew install trycua/tap/cua-driver"
Loading