From f95efd174e1ebb81bd41df84df914f9cbdec702d Mon Sep 17 00:00:00 2001 From: Samgu Lee Date: Wed, 1 Jul 2026 21:40:25 +0900 Subject: [PATCH 01/11] feat: create `repl` cli --- .editorconfig | 24 + .gitattributes | 1 + .gitignore | 53 ++ .golangci.yml | 8 + .goreleaser.yml | 70 +++ .pre-commit-config.yaml | 16 + .repl/agent.md | 1 + .repl/runtime/execution-log.json | 3 + .repl/runtime/execution-state.json | 3 + .repl/runtime/task-progress.json | 3 + Makefile | 27 + README.md | 478 ++++++++++++++++++ cmd/repl/doctor.go | 48 ++ cmd/repl/doctor_test.go | 77 +++ cmd/repl/init.go | 42 ++ cmd/repl/init_test.go | 91 ++++ cmd/repl/main.go | 31 ++ cmd/repl/reset.go | 43 ++ cmd/repl/reset_test.go | 80 +++ cmd/repl/runtime.go | 303 +++++++++++ cmd/repl/runtime_test.go | 177 +++++++ go.mod | 24 + go.sum | 780 +++++++++++++++++++++++++++++ internal/runtime/manager.go | 298 +++++++++++ internal/runtime/manager_test.go | 331 ++++++++++++ 25 files changed, 3012 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .golangci.yml create mode 100644 .goreleaser.yml create mode 100644 .pre-commit-config.yaml create mode 100644 .repl/runtime/execution-log.json create mode 100644 .repl/runtime/execution-state.json create mode 100644 .repl/runtime/task-progress.json create mode 100644 Makefile create mode 100644 README.md create mode 100644 cmd/repl/doctor.go create mode 100644 cmd/repl/doctor_test.go create mode 100644 cmd/repl/init.go create mode 100644 cmd/repl/init_test.go create mode 100644 cmd/repl/main.go create mode 100644 cmd/repl/reset.go create mode 100644 cmd/repl/reset_test.go create mode 100644 cmd/repl/runtime.go create mode 100644 cmd/repl/runtime_test.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 internal/runtime/manager.go create mode 100644 internal/runtime/manager_test.go diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f11e052 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,24 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.go] +indent_style = tab + +[Makefile] +indent_style = tab + +[*.{yml,yaml}] +indent_style = space +indent_size = 2 + +[*.json] +indent_style = space +indent_size = 2 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..d207b18 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.go text eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..858ee09 --- /dev/null +++ b/.gitignore @@ -0,0 +1,53 @@ +# Packages +# Reference: http://golang.org/doc/code.html#GOPATH +# Reference: https://github.com/github/gitignore/blob/main/Go.gitignore + +# Binaries and tools +bin/ +dist/ +# Exclude single CLI binary files generated during build +/repl +/repl.exe + +# Testing +*.test +*.out + +# Dependency directories (Usually not needed in go.mod environment, added for prevention) +vendor/ + +# Temporary files created by Go and Editors +go.work +go.work.sum +.project +.idea/ +.vscode/ +*.suo +*.ntvs* +*.njsproj +*.sln +*.swp + +# ========================================== +# macOS Specific Settings (OSX System Files) +# ========================================== +.DS_Store +.AppleDouble +.LSOverride +Icon_ +._* +.Spotlight-V100 +.Trashes +~.dep +.AppleDB +.AppleDesktop + +# ========================================== +# Project Specific Security Settings (Important!) +# ========================================== +# Exclude local configuration and secrets used for testing +# (Enforces FRAMEWORK.md rule: Secrets are not stored in source code) +config.yaml +config.toml +.env +*.local diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..1ad27b6 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,8 @@ +version: "2" + +linters: + default: standard + +issues: + max-issues-per-linter: 0 + max-same-issues: 0 diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..150b02a --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,70 @@ +version: 2 + +project_name: ai-issue + +builds: + - main: ./cmd/ai-issue + env: + - CGO_ENABLED=0 + goos: + - linux + - darwin + - windows + goarch: + - amd64 + - arm64 + binary: ai-issue + ldflags: + - -s -w + - -X main.version={{.Version}} + - -X main.commit={{.Commit}} + - -X main.date={{.Date}} + +archives: + - formats: [tar.gz] + name_template: >- + {{ .ProjectName }}_ + {{- .Version }}_ + {{- .Os }}_ + {{- .Arch }} + files: + - LICENSE + - README.md + - PRODUCT_SPEC.md + - ARCHITECTURE.md + - FRAMEWORK.md + +brews: + - name: ai-issue + repository: + owner: replworks + name: homebrew-tap + + homepage: "https://github.com/replworks/ai-issue" + + description: "A CLI tool to publish AI-generated ideas as GitHub Issues, clearly separating AI authorship from human responsibility." + + license: "MIT" + + install: | + bin.install "ai-issue" + +checksum: + name_template: "checksums.txt" + +snapshot: + version_template: "{{ .Tag }}-next" + +changelog: + sort: asc + filters: + exclude: + - "^docs:" + - "^test:" + +release: + github: + owner: replworks + name: ai-issue + draft: true + prerelease: auto diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..a1be013 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,16 @@ +repos: + - repo: https://github.com/gitleaks/gitleaks + rev: v8.28.0 + hooks: + - id: gitleaks + + - repo: https://github.com/golangci/golangci-lint + rev: v2.2.1 + hooks: + - id: golangci-lint + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: end-of-file-fixer + - id: trailing-whitespace diff --git a/.repl/agent.md b/.repl/agent.md index a3b5e0a..4dfb619 100644 --- a/.repl/agent.md +++ b/.repl/agent.md @@ -48,6 +48,7 @@ AI is not responsible for: AI must: +- CRITICAL: Never delete, modify, or tamper with any .md files under the .repl/ directory. - follow tasks.md exactly - follow product.md strictly - follow framework.md strictly diff --git a/.repl/runtime/execution-log.json b/.repl/runtime/execution-log.json new file mode 100644 index 0000000..c18fac4 --- /dev/null +++ b/.repl/runtime/execution-log.json @@ -0,0 +1,3 @@ +{ + "logs": [] +} diff --git a/.repl/runtime/execution-state.json b/.repl/runtime/execution-state.json new file mode 100644 index 0000000..67ce46a --- /dev/null +++ b/.repl/runtime/execution-state.json @@ -0,0 +1,3 @@ +{ + "session_active": false +} diff --git a/.repl/runtime/task-progress.json b/.repl/runtime/task-progress.json new file mode 100644 index 0000000..90faa72 --- /dev/null +++ b/.repl/runtime/task-progress.json @@ -0,0 +1,3 @@ +{ + "tasks": {} +} diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1773bec --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ +fmt: ## runs go formatter + go fmt ./... + +fmt-check: + @files=$$(gofmt -l .); \ + if [ -n "$$files" ]; then \ + echo "Files not formatted:"; \ + echo "$$files"; \ + exit 1; \ + fi + +test: + go test ./... + +vet: + go vet ./... + +lint: ## runs golangci-lint via go run + golangci-lint run ./... + +lint-fix: ## automatically fix lint issues where possible + golangci-lint run --fix ./... + +check: fmt-check vet test + +build: + go build -o ai-issue ./cmd/ai-issue diff --git a/README.md b/README.md new file mode 100644 index 0000000..5c7a04c --- /dev/null +++ b/README.md @@ -0,0 +1,478 @@ +# REPL CLI πŸš€ + +[![Go Version](https://img.shields.io/badge/Go-%3E%3D1.24-blue)](https://go.dev/) +[![License](https://img.shields.io/badge/License-MIT-green)](LICENSE) +[![Build](https://img.shields.io/badge/build-passing-brightgreen)](https://github.com) + +**A deterministic runtime controller for external AI-driven task execution** + +--- + +## What is REPL CLI? πŸ€” + +REPL CLI is a **local command-line system** that manages and observes deterministic runtime state for external AI-driven task execution. It acts as a bridge between AI systems and local project state, providing: + +- βœ… **Deterministic state management** β€” Same input always produces the same output +- βœ… **Task lifecycle tracking** β€” Initialize, execute, and validate AI tasks +- βœ… **Local-only architecture** β€” No backend, no cloud, no daemon +- βœ… **Single binary distribution** β€” No dependencies, no installation hassle + +--- + +## Why REPL CLI? πŸ’‘ + +### The Problem + +When working with AI agents (like Claude, GPT-4, or custom LLMs), you need a way to: + +- Track task execution state reliably +- Validate AI outputs before applying them +- Maintain deterministic project state +- Avoid hidden state mutations + +### The Solution + +REPL CLI provides a **deterministic runtime controller** that: + +1. Manages local runtime state in `.repl/runtime/` +2. Validates AI-generated execution results against strict schemas +3. Ensures reproducible, auditable state transitions +4. Keeps everything local β€” no external dependencies + +--- + +## Features ⚑ + +### 🎯 Core Commands + +| Command | Description | +|---------|-------------| +| `repl init` | Initialize REPL project runtime environment | +| `repl doctor` | Validate system integrity and configuration | +| `repl reset` | Reset runtime to clean initial state | +| `repl runtime start` | Start execution session for AI input | +| `repl runtime stop` | Stop execution session (no state mutation) | +| `repl runtime apply` | Apply AI execution results (via JSON stdin) | +| `repl runtime status` | Display current runtime state and progress | + +### πŸ”’ Key Principles + +- **Deterministic**: Identical inputs β†’ identical outputs +- **Stateless AI**: AI is external and has no access to runtime state +- **Validated**: All state transitions are explicitly validated +- **Local**: No backend, no cloud sync, no daemon processes +- **Simple**: Single binary, zero configuration required + +--- + +## Installation πŸ“¦ + +### Prerequisites + +- Go >= 1.24 + +### Install from Source + +```bash +git clone https://github.com/replworks/repl-cli.git +cd repl-cli +go build -o repl ./cmd/repl +sudo mv repl /usr/local/bin/ +``` + +### Verify Installation + +```bash +repl --version +# Output: repl version 0.1.0 +``` + +--- + +## Quick Start πŸš€ + +### 1. Initialize Project + +```bash +repl init +``` + +**Output:** + +``` +REPL project initialized successfully +Created: .repl/ +Created: .repl/runtime/ +Initialized: execution-state.json +Initialized: task-progress.json +Initialized: execution-log.json +``` + +### 2. Start Runtime Session + +```bash +repl runtime start +``` + +**Output:** + +``` +Starting REPL runtime execution session... +Runtime execution session activated +System is ready for AI execution input +``` + +### 3. Apply AI Execution Result + +```bash +echo '{ + "action": "update_runtime", + "taskId": "TASK_1", + "status": "done", + "events": ["step1", "step2", "step3"] +}' | repl runtime apply +``` + +**Output:** + +``` +Applying AI execution result... +Task TASK_1 marked as: done +Task completed successfully +``` + +### 4. Check Status + +```bash +repl runtime status +``` + +**Output:** + +``` +REPL Runtime Status +=================== + +Session Status: + State: active + Current Task: none + +Task Progress: + TASK_1: done + +Execution Log (last 5 entries): + - Runtime session started + - Runtime apply executed for task: TASK_1 + - Task status updated to: done + - Events: [step1 step2 step3] + +Runtime state is readable and consistent +``` + +### 5. Stop Session + +```bash +repl runtime stop +``` + +--- + +## Architecture πŸ—οΈ + +``` +User Command + ↓ +REPL CLI (Cobra Layer) + ↓ +Runtime Manager (includes validation) + ↓ +.repl/runtime/* (Local State Assets) +``` + +### Runtime State Files + +All state is stored locally under `.repl/runtime/`: + +- **execution-state.json** β€” Session status and current task +- **task-progress.json** β€” Task completion status +- **execution-log.json** β€” Execution history and audit trail + +### Execution Flow + +```text +repl runtime start + ↓ +Load TASKS.md + ↓ +Load .repl context + ↓ +Generate AI prompt + ↓ +Output to stdout +``` + +```text +AI Output (JSON) + ↓ +repl runtime apply (stdin) + ↓ +Validate schema + ↓ +Update .repl/runtime/* + ↓ +Mark TASK status (DONE / BLOCKED) +``` + +--- + +## JSON Schema for `repl runtime apply` πŸ“‹ + +The `repl runtime apply` command accepts JSON via stdin with the following schema: + +```json +{ + "action": "update_runtime", + "taskId": "TASK_1", + "status": "done", + "reason": "optional reason if blocked", + "events": ["event1", "event2"] +} +``` + +### Required Fields + +- `action` β€” Must be exactly `"update_runtime"` +- `taskId` β€” Target task identifier (e.g., `"TASK_1"`) +- `status` β€” Must be `"done"` or `"blocked"` + +### Conditional Fields + +- `reason` β€” Required only when `status` is `"blocked"` +- `events` β€” Optional array of execution milestones + +--- + +## Use Cases 🎯 + +### 1. AI Agent Task Management + +Use REPL CLI to manage tasks executed by AI agents: + +```bash +# Initialize project +repl init + +# Start session +repl runtime start + +# Let AI execute tasks and apply results +cat > ai_result.json <