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
25 changes: 25 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: ci

on:
push:
pull_request:

jobs:
checks:
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.8"

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Run CI checks
run: make test-all
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ dist
*.tsbuildinfo
.DS_Store
/agentcore
/roboppi

# Local AgentCore workflow state
.agentcore-loop/
Expand Down
156 changes: 156 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# AGENTS.md

This repository ("Roboppi" / package name: `agentcore`) is a Bun + TypeScript (ESM)
codebase that implements an execution-control runtime for agentic workers.

## Build / Lint / Test

Prefer `make` targets (CI uses them), but `bun` equivalents work.

### Install

```bash
bun install
bun install --frozen-lockfile # CI
```

CI currently uses Bun 1.3.8 (see `.github/workflows/ci.yml`).

### Typecheck (acts as "lint")

There is no ESLint/Prettier/Biome config today; use TypeScript strict checks + tests.

```bash
make typecheck
# or
bun run typecheck
```

### Tests

```bash
make test # bun test
make test-unit # bun test test/unit
make test-integration # bun test test/integration
make test-at # bun test tests/at
make test-branch # bash tests/branch/run-branch-verification.sh
make test-all # CI: typecheck + test + test-branch
```

Acceptance test helper runner:

```bash
bash scripts/run-at.sh # typecheck + tests/at
bash scripts/run-at.sh --full # + bun test
```

### Run A Single Test

```bash
bun test test/unit/ipc/protocol.test.ts
bun test test/unit/ipc/protocol.test.ts -t "routes submit_job" # regex on test name
bun test -t "routes submit_job" # match across all tests
bun test --only # only test.only/describe.only
bun test --timeout 20000 test/integration # per-test timeout (ms)
bun test --watch test/unit # watch mode
```

### Build

Builds a native executable `./agentcore` (gitignored).

```bash
make build # or: bun run build
make install # /usr/local/bin/agentcore
make uninstall
```

### Dev / Run

```bash
make dev # bun run src/cli.ts
bun run dev # bun run src/index.ts
bun run dev:scheduler # bun run src/scheduler/index.ts
```

## Project Layout (high-level)

- Runtime entrypoints: `src/cli.ts` (bin), `src/index.ts` (Core process)
- Core safety mechanisms: `src/core/**`
- IPC JSONL protocol/transport: `src/ipc/**`
- Daemon entrypoints: `src/daemon/**`
- Worker adapters + process mgmt: `src/worker/**`
- Workflow runner/executor: `src/workflow/**`
- Scheduler layer: `src/scheduler/**`
- Design notes: `docs/**`
- Unit/integration tests: `test/**`
- Acceptance + branch-safety tests: `tests/**`

## Code Style Guidelines

### TypeScript / Module System

- ESM everywhere (`package.json` has `"type": "module"`).
- Relative imports for local modules MUST include the `.js` extension.
- Example: `import { AgentCore } from "./core/agentcore.js";`
- Use `node:` specifiers for built-in modules.
- Example: `import { readFile } from "node:fs/promises";`
- Use `import type { ... }` for type-only imports.
- Avoid the `@/*` path alias unless you confirm runtime resolution; prefer relative imports.

### Formatting

- 2-space indentation, semicolons, trailing commas in multiline constructs.
- Keep changes minimal: no repo-wide reformatting sweeps (no formatter is enforced).

### Imports

- No enforced ordering; keep import groups consistent within the file you touch.
- Keep `import ...` statements at the top of the file.
- Prefer `../types/index.js` barrel exports for shared types/enums.
- Avoid default exports for local modules; use named exports (existing pattern).

### Types

- `tsconfig.json` is strict (`noUncheckedIndexedAccess`, `noUnusedLocals/Parameters`, etc.).
- Avoid `any` in `src/**`.
- Use `unknown` in `catch` and narrow via `instanceof Error`, `typeof`, etc.
- Add explicit return types for exported functions and public class methods.
- Prefer small discriminated unions / string enums for protocol/state machines.

### Naming

- Files: `kebab-case.ts` (e.g., `json-lines-transport.ts`).
- Classes/types/interfaces/enums: `PascalCase`.
- Functions/locals: `camelCase`.
- Constants: `SCREAMING_SNAKE_CASE`.
- IDs are UUID strings: use `generateId()` / `crypto.randomUUID()`.

### Error Handling

- Throw `Error` (or subclasses), never strings.
- Set `err.name` on custom error classes; attach `cause` when useful.
- When surfacing errors across boundaries (IPC/worker/workflow), include context: `requestId`, `jobId`, `permitId`, `stepId`.
- Use `ErrorClass` for retryability when returning `WorkerResult`-style failures.

### Cancellation / Timeouts / Cleanup

- If a function can block (IO, process spawn, long loop), accept an `AbortSignal`
and stop promptly when aborted.
- Always clear timers and remove event listeners in `finally` blocks.
- When spawning subprocesses, prefer `ProcessManager` (abort, timeout, best-effort process-group termination).

### IPC Safety

- IPC is JSON Lines over stdout. In server/Core mode, NEVER write non-JSON to stdout (use stderr/loggers).
- Validate message shape before acting (see `src/ipc/protocol.ts`).

### Tests

- Use `bun:test` (`describe`, `test`/`it`, `expect`).
- Keep tests deterministic; avoid network and real worker CLIs in unit tests.
- Use temp dirs for filesystem work; clean up after.

## Cursor / Copilot Rules

- No `.cursor/rules/`, `.cursorrules`, or `.github/copilot-instructions.md` found in this repo.
46 changes: 33 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,42 +1,62 @@
.PHONY: all build test test-unit test-integration test-at test-all typecheck clean help

BIN := agentcore
.PHONY: all build test tests test-unit test-integration test-at test-branch test-all typecheck clean install uninstall dev help

BIN := roboppi
LEGACY_BIN := agentcore

# Legacy build artifacts (no longer built by default)
EXTRA_BINS := roboppi-core roboppi-workflow roboppi-daemon

SRC := src/cli.ts

# Allow passing Bun runtime flags (e.g. BUN_FLAGS=--smol)
BUN ?= bun
BUN_FLAGS ?=

# Extra flags passed to `bun build` (e.g. BUN_BUILD_FLAGS=--compile-exec-argv=--smol)
BUN_BUILD_FLAGS ?=

all: build ## Build the binary (default)

build: ## Build single binary
bun build --compile $(SRC) --outfile $(BIN)
build: ## Build a single binary (roboppi)
$(BUN) $(BUN_FLAGS) build $(BUN_BUILD_FLAGS) --compile $(SRC) --outfile $(BIN)
@ln -sf $(BIN) $(LEGACY_BIN) 2>/dev/null || cp $(BIN) $(LEGACY_BIN)

test: ## Run all tests
bun test
$(BUN) $(BUN_FLAGS) test

tests: test ## Alias for `make test`

test-unit: ## Run unit tests only
bun test test/unit
$(BUN) $(BUN_FLAGS) test test/unit

test-integration: ## Run integration tests only
bun test test/integration
$(BUN) $(BUN_FLAGS) test test/integration

test-at: ## Run acceptance tests only
bun test tests/at
$(BUN) $(BUN_FLAGS) test tests/at

test-branch: ## Run branch safety verification tests
bash tests/branch/run-branch-verification.sh

test-all: typecheck test ## Run type check + all tests
test-all: typecheck test test-branch ## Run type check + all tests
@echo "All checks passed"

typecheck: ## Run TypeScript type checker
bun x tsc --noEmit
$(BUN) $(BUN_FLAGS) x tsc --noEmit

clean: ## Remove build artifacts
rm -f $(BIN)
rm -f $(BIN) $(LEGACY_BIN) $(EXTRA_BINS)

install: build ## Install binary to /usr/local/bin
install -m 755 $(BIN) /usr/local/bin/$(BIN)
@ln -sf /usr/local/bin/$(BIN) /usr/local/bin/$(LEGACY_BIN) 2>/dev/null || cp /usr/local/bin/$(BIN) /usr/local/bin/$(LEGACY_BIN)

uninstall: ## Remove binary from /usr/local/bin
rm -f /usr/local/bin/$(BIN)
rm -f /usr/local/bin/$(BIN) /usr/local/bin/$(LEGACY_BIN) $(addprefix /usr/local/bin/,$(EXTRA_BINS))

dev: ## Run in dev mode (no build)
bun run $(SRC)
$(BUN) $(BUN_FLAGS) run $(SRC)

help: ## Show this help
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}'
Loading