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/.github/workflows/auto-assign.yml b/.github/workflows/auto-assign.yml new file mode 100644 index 0000000..c24974d --- /dev/null +++ b/.github/workflows/auto-assign.yml @@ -0,0 +1,19 @@ +name: Auto Assign +on: + issues: + types: [opened] + pull_request: + types: [opened] +jobs: + run: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - name: "Auto-assign issue" + uses: pozil/auto-assign-issue@v4 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + assignees: cable8mm + numOfAssignee: 1 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d1f0804 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,31 @@ +name: CI + +on: + push: + branches: + - main + - develop + + pull_request: + +jobs: + verify: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version-file: go.mod + cache: true + + - name: Verify + run: make check + + - name: GolangCI-Lint + uses: golangci/golangci-lint-action@v9 + with: + version: v2.2.1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..744c4b9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,54 @@ +# 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 +.repl/runtime/* 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..32fdc17 100644 --- a/.repl/agent.md +++ b/.repl/agent.md @@ -1,22 +1,5 @@ # .repl/agent.md -# REPL Agent Context (MVP) - ---- - -# Purpose - -This file provides execution context for AI inside REPL runtime. - -AI reads this file during: - -- `repl runtime start` -- `repl runtime apply` - -AI is stateless and external to the system. - ---- - # Context Loading Order AI must read files in this order: @@ -33,7 +16,6 @@ AI must read files in this order: AI is only responsible for: - executing tasks -- producing valid output for `repl runtime apply` AI is not responsible for: @@ -48,6 +30,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 @@ -78,6 +61,30 @@ Optional fields: AI must not deviate from the schema defined in product.md. +After completing or blocking any TASK, AI must produce a JSON payload that is directly compatible with `repl runtime apply` and must not output free-form text instead. + +Example success payload: + +```json +{ + "action": "update_runtime", + "taskId": "TASK_1", + "status": "done", + "events": ["step1", "step2"] +} +``` + +Example blocked payload: + +```json +{ + "action": "update_runtime", + "taskId": "TASK_2", + "status": "blocked", + "reason": "dependency missing" +} +``` + --- # Execution Behavior diff --git a/.repl/product.md b/.repl/product.md index 7bcaa45..0b9f476 100644 --- a/.repl/product.md +++ b/.repl/product.md @@ -106,7 +106,7 @@ repl runtime apply "taskId": { "type": "string", - "description": "Target TASK identifier matching TASKS.md (e.g., TASK_1)" + "description": "Target TASK identifier matching tasks.md (e.g., TASK_1)" }, "status": { @@ -171,7 +171,7 @@ REPL CLI does not persist any external or cloud state. ```text repl runtime start ↓ -Load TASKS.md +Load tasks.md ↓ Load .repl context ↓ diff --git a/.repl/tasks.md b/.repl/tasks.md index a38f7cc..c285c1d 100644 --- a/.repl/tasks.md +++ b/.repl/tasks.md @@ -1,4 +1,4 @@ -# TASKS.md +# tasks.md # REPL CLI Execution Tasks (MVP) @@ -13,7 +13,7 @@ Status: MVP - Each TASK corresponds to a single CLI command. - Each TASK must be independently executable. - Each TASK must be independently verifiable. -- TASKS are executed in isolation. +- Tasks are executed in isolation. - No TASK depends on partial completion of another TASK. --- diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..155b8c4 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,16 @@ +# AGENTS.md + +## Rule + +Before doing any work, you **must** read: + +* `.repl/agent.md` + +This file is the single source of truth for: + +* project rules +* coding conventions +* architecture constraints +* workflow instructions + +If there is any conflict, `.repl/agent.md` takes priority. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7a793e6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Samgu Lee + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b9d2f09 --- /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 repl ./cmd/repl diff --git a/README.md b/README.md new file mode 100644 index 0000000..70e9135 --- /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:** + +```bash +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:** + +```bash +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:** + +```bash +Applying AI execution result... +Task TASK_1 marked as: done +Task completed successfully +``` + +### 4. Check Status + +```bash +repl runtime status +``` + +**Output:** + +```bash +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 πŸ—οΈ + +```bash +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 <