ralphctl 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +94 -0
- package/LICENSE +21 -0
- package/README.md +189 -0
- package/bin/ralphctl +13 -0
- package/package.json +92 -0
- package/schemas/config.schema.json +20 -0
- package/schemas/ideate-output.schema.json +22 -0
- package/schemas/projects.schema.json +53 -0
- package/schemas/requirements-output.schema.json +24 -0
- package/schemas/sprint.schema.json +109 -0
- package/schemas/task-import.schema.json +49 -0
- package/schemas/tasks.schema.json +72 -0
- package/src/ai/executor.ts +973 -0
- package/src/ai/lifecycle.ts +45 -0
- package/src/ai/parser.ts +40 -0
- package/src/ai/permissions.ts +207 -0
- package/src/ai/process-manager.ts +248 -0
- package/src/ai/prompts/ideate-auto.md +144 -0
- package/src/ai/prompts/ideate.md +165 -0
- package/src/ai/prompts/index.ts +89 -0
- package/src/ai/prompts/plan-auto.md +131 -0
- package/src/ai/prompts/plan-common.md +157 -0
- package/src/ai/prompts/plan-interactive.md +190 -0
- package/src/ai/prompts/task-execution.md +159 -0
- package/src/ai/prompts/ticket-refine.md +230 -0
- package/src/ai/rate-limiter.ts +89 -0
- package/src/ai/runner.ts +478 -0
- package/src/ai/session.ts +319 -0
- package/src/ai/task-context.ts +270 -0
- package/src/cli-metadata.ts +7 -0
- package/src/cli.ts +65 -0
- package/src/commands/completion/index.ts +33 -0
- package/src/commands/config/config.ts +58 -0
- package/src/commands/config/index.ts +33 -0
- package/src/commands/dashboard/dashboard.ts +5 -0
- package/src/commands/dashboard/index.ts +6 -0
- package/src/commands/doctor/doctor.ts +271 -0
- package/src/commands/doctor/index.ts +25 -0
- package/src/commands/progress/index.ts +25 -0
- package/src/commands/progress/log.ts +64 -0
- package/src/commands/progress/show.ts +14 -0
- package/src/commands/project/add.ts +336 -0
- package/src/commands/project/index.ts +104 -0
- package/src/commands/project/list.ts +31 -0
- package/src/commands/project/remove.ts +43 -0
- package/src/commands/project/repo.ts +118 -0
- package/src/commands/project/show.ts +49 -0
- package/src/commands/sprint/close.ts +180 -0
- package/src/commands/sprint/context.ts +109 -0
- package/src/commands/sprint/create.ts +60 -0
- package/src/commands/sprint/current.ts +75 -0
- package/src/commands/sprint/delete.ts +72 -0
- package/src/commands/sprint/health.ts +229 -0
- package/src/commands/sprint/ideate.ts +496 -0
- package/src/commands/sprint/index.ts +226 -0
- package/src/commands/sprint/list.ts +86 -0
- package/src/commands/sprint/plan-utils.ts +207 -0
- package/src/commands/sprint/plan.ts +549 -0
- package/src/commands/sprint/refine.ts +359 -0
- package/src/commands/sprint/requirements.ts +58 -0
- package/src/commands/sprint/show.ts +140 -0
- package/src/commands/sprint/start.ts +119 -0
- package/src/commands/sprint/switch.ts +20 -0
- package/src/commands/task/add.ts +316 -0
- package/src/commands/task/import.ts +150 -0
- package/src/commands/task/index.ts +123 -0
- package/src/commands/task/list.ts +145 -0
- package/src/commands/task/next.ts +45 -0
- package/src/commands/task/remove.ts +47 -0
- package/src/commands/task/reorder.ts +45 -0
- package/src/commands/task/show.ts +111 -0
- package/src/commands/task/status.ts +99 -0
- package/src/commands/ticket/add.ts +265 -0
- package/src/commands/ticket/edit.ts +166 -0
- package/src/commands/ticket/index.ts +114 -0
- package/src/commands/ticket/list.ts +128 -0
- package/src/commands/ticket/refine-utils.ts +89 -0
- package/src/commands/ticket/refine.ts +268 -0
- package/src/commands/ticket/remove.ts +48 -0
- package/src/commands/ticket/show.ts +74 -0
- package/src/completion/handle.ts +30 -0
- package/src/completion/resolver.ts +241 -0
- package/src/interactive/dashboard.ts +268 -0
- package/src/interactive/escapable.ts +81 -0
- package/src/interactive/file-browser.ts +153 -0
- package/src/interactive/index.ts +429 -0
- package/src/interactive/menu.ts +403 -0
- package/src/interactive/selectors.ts +273 -0
- package/src/interactive/wizard.ts +221 -0
- package/src/providers/claude.ts +53 -0
- package/src/providers/copilot.ts +86 -0
- package/src/providers/index.ts +43 -0
- package/src/providers/types.ts +85 -0
- package/src/schemas/index.ts +130 -0
- package/src/store/config.ts +74 -0
- package/src/store/progress.ts +230 -0
- package/src/store/project.ts +276 -0
- package/src/store/sprint.ts +229 -0
- package/src/store/task.ts +443 -0
- package/src/store/ticket.ts +178 -0
- package/src/theme/index.ts +215 -0
- package/src/theme/ui.ts +872 -0
- package/src/utils/detect-scripts.ts +247 -0
- package/src/utils/editor-input.ts +41 -0
- package/src/utils/editor.ts +37 -0
- package/src/utils/exit-codes.ts +27 -0
- package/src/utils/file-lock.ts +135 -0
- package/src/utils/git.ts +185 -0
- package/src/utils/ids.ts +37 -0
- package/src/utils/issue-fetch.ts +244 -0
- package/src/utils/json-extract.ts +62 -0
- package/src/utils/multiline.ts +61 -0
- package/src/utils/path-selector.ts +236 -0
- package/src/utils/paths.ts +108 -0
- package/src/utils/provider.ts +34 -0
- package/src/utils/requirements-export.ts +63 -0
- package/src/utils/storage.ts +107 -0
- package/tsconfig.json +25 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to RalphCTL will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [0.1.0] - 2026-03-07
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **npm publishing** — `ralphctl` is now available via `npm install -g ralphctl`
|
|
12
|
+
- Release pipeline publishes to npm and creates GitHub Releases with changelog-based notes
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Streamlined README for end-user onboarding with `npm install -g` as primary install method
|
|
17
|
+
- Added release process documentation to CONTRIBUTING.md
|
|
18
|
+
- Version bumped to 0.1.0 for first public npm release
|
|
19
|
+
|
|
20
|
+
## [0.0.3] - 2026-03-06
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- Normalized git author identity across commit history
|
|
25
|
+
- Updated package metadata for open-source release (description, homepage, private flag)
|
|
26
|
+
- Moved `tsx` from devDependencies to dependencies (runtime requirement for `bin/ralphctl`)
|
|
27
|
+
- Fixed stale path references in SECURITY.md, CONTRIBUTING.md, and agent memory files
|
|
28
|
+
- Fixed changelog compare link in release workflow to include `v` prefix
|
|
29
|
+
- Corrected documentation table descriptions in README.md
|
|
30
|
+
- Cleaned up stale `dist/` build artifacts
|
|
31
|
+
- Edited documentation for public release
|
|
32
|
+
|
|
33
|
+
## [0.0.2] - 2026-03-03
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- **Doctor command** — `ralphctl doctor` checks Node.js version, git, AI provider binary, data directory, project repos, and current sprint health
|
|
38
|
+
- **Shell tab-completion** — `ralphctl completion install` for bash, zsh, and fish via tabtab
|
|
39
|
+
- **Branch management** — `sprint start` prompts for branch strategy (keep current, auto, custom); `--branch` and `--branch-name` flags; pre-flight verification; `sprint close --create-pr` creates PRs
|
|
40
|
+
- **Provider abstraction** — `config set provider claude|copilot` with adapter layer; experimental Copilot CLI support with headless execution and session ID capture
|
|
41
|
+
- **Draft re-plan** — running `sprint plan` on a draft with existing tasks passes all tickets + tasks as AI context for atomic replacement
|
|
42
|
+
- **Check script model** — single idempotent `checkScript` per repo replaces old `setupScript`/`verifyScript`; runs at sprint start and as a post-task gate
|
|
43
|
+
- **Lifecycle hooks** — `runLifecycleHook()` abstraction in `src/ai/lifecycle.ts` with `RALPHCTL_LIFECYCLE_EVENT` env var
|
|
44
|
+
- **Ecosystem detection** — `EcosystemDetector[]` registry (node, python, go, rust, gradle, maven, makefile) for check script suggestions during project setup
|
|
45
|
+
- **Sprint health** — duplicate task order and pending requirements diagnostics; branch consistency checks across repos
|
|
46
|
+
- **Interactive mode** — Escape key navigation, styled section titles, flat workflow section, provider config in REPL, refined/planned counts in status header, guards for unrefined/unplanned tickets
|
|
47
|
+
- **Inline multiline editor** — replaced with `@inquirer/editor` and configurable editor settings via `config set editor`
|
|
48
|
+
- **CI/CD** — GitHub Actions pipeline with lint, typecheck, test, format check; Dependabot; automated GitHub Release pipeline
|
|
49
|
+
- **Schema sync tests** — JSON schema ↔ Zod schema validation
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
|
|
53
|
+
- Renamed `claude` module to `ai` for provider-agnostic naming
|
|
54
|
+
- Replaced tsup build with bash wrapper approach for CLI outside repo root
|
|
55
|
+
- Default data directory changed to `~/.ralphctl` (was `ralphctl-data/`)
|
|
56
|
+
- Separated repo root from data directory with smart `RALPHCTL_ROOT` handling
|
|
57
|
+
- Removed `externalId` field and `--id`/`--editor` CLI flags from ticket command
|
|
58
|
+
- Documentation restructured — moved to `.claude/docs/`, slimmed CLAUDE.md from 613 to 160 lines with skill-based reference material
|
|
59
|
+
- Replaced raw color functions with theme helpers across all commands
|
|
60
|
+
- Improved card rendering and terminal width awareness
|
|
61
|
+
|
|
62
|
+
### Fixed
|
|
63
|
+
|
|
64
|
+
- Sanitize session IDs and harden file operations against path traversal
|
|
65
|
+
- Fixed pre-flight execution checks for security and correctness
|
|
66
|
+
- Preserve error cause in re-thrown errors
|
|
67
|
+
- Thread provider through `checkTaskPermissions()`
|
|
68
|
+
- Branch management error handling and retry logic
|
|
69
|
+
- Interactive mode duplicate quote, closed sprint status header, and dashboard duplication
|
|
70
|
+
- ANSI code handling in CLI test field extraction
|
|
71
|
+
- Removed redundant file reads in interactive menu context loading
|
|
72
|
+
|
|
73
|
+
### Dependencies
|
|
74
|
+
|
|
75
|
+
- Bumped `zod` from 3.x to 4.x
|
|
76
|
+
- Bumped `@inquirer/prompts` from 7.x to 8.x
|
|
77
|
+
- Bumped `@types/node`, `globals`, `ora`, `typescript-eslint`, and other dev dependencies
|
|
78
|
+
|
|
79
|
+
## [0.0.1] - 2026-02-15
|
|
80
|
+
|
|
81
|
+
### Added
|
|
82
|
+
|
|
83
|
+
- **Project management** — register multi-repo projects with named paths
|
|
84
|
+
- **Sprint lifecycle** — create, activate, close sprints with state machine enforcement (draft -> active -> closed)
|
|
85
|
+
- **Ticket tracking** — add work items linked to projects, with optional external IDs
|
|
86
|
+
- **Two-phase planning** — refine requirements (WHAT) then generate tasks (HOW) with human approval gates
|
|
87
|
+
- **Task dependencies** — `blockedBy` references with topological sort and cycle detection
|
|
88
|
+
- **Task execution** — headless, watch, session, and interactive modes via Claude CLI
|
|
89
|
+
- **Parallel execution** — one task per repo concurrently, with rate limit backoff and session resume
|
|
90
|
+
- **Interactive menu mode** — context-aware REPL with persistent status header and Quick Start wizard
|
|
91
|
+
- **Sprint health checks** — diagnose blockers, stale tasks, and missing dependencies
|
|
92
|
+
- **Requirements export** — markdown export of refined requirements
|
|
93
|
+
- **Progress logging** — append-only timestamped progress log per sprint
|
|
94
|
+
- **Ralph Wiggum personality** — themed UI with donut spinners, random quotes, and gradient banner
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Lukas Grigis
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
[](https://www.npmjs.com/package/ralphctl)
|
|
2
|
+
[](https://github.com/lukas-grigis/ralphctl/actions/workflows/ci.yml)
|
|
3
|
+
[](./LICENSE)
|
|
4
|
+
[](https://www.typescriptlang.org/)
|
|
5
|
+
[](https://nodejs.org/)
|
|
6
|
+
[](./CONTRIBUTING.md)
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
🍩 ██████╗ █████╗ ██╗ ██████╗ ██╗ ██╗ ██████╗████████╗██╗ 🍩
|
|
10
|
+
██╔══██╗██╔══██╗██║ ██╔══██╗██║ ██║██╔════╝╚══██╔══╝██║
|
|
11
|
+
██████╔╝███████║██║ ██████╔╝███████║██║ ██║ ██║
|
|
12
|
+
██╔══██╗██╔══██║██║ ██╔═══╝ ██╔══██║██║ ██║ ██║
|
|
13
|
+
██║ ██║██║ ██║███████╗██║ ██║ ██║╚██████╗ ██║ ███████╗
|
|
14
|
+
╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Sprint and task management CLI for AI-assisted coding with Claude Code or GitHub Copilot.**
|
|
18
|
+
|
|
19
|
+
> _"I'm helping!"_ — Ralph Wiggum
|
|
20
|
+
|
|
21
|
+
> [!NOTE]
|
|
22
|
+
> **Early access.** RalphCTL is under active development. Things work, but expect rough edges and breaking changes before 1.0. Read the [blog post](https://lukasgrigis.dev/blog/building-ralphctl) for the backstory.
|
|
23
|
+
|
|
24
|
+
You write tickets, your AI buddy (Claude or Copilot) refines the requirements, then breaks them into tasks and executes them. RalphCTL keeps track of the state so nothing gets lost between sessions. Ralph Wiggum personality included because why not.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install -g ralphctl
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
This installs the `ralphctl` command globally.
|
|
35
|
+
|
|
36
|
+
### Prerequisites
|
|
37
|
+
|
|
38
|
+
- [Node.js](https://nodejs.org/) **>= 24.0.0**
|
|
39
|
+
- [Git](https://git-scm.com/)
|
|
40
|
+
- Either [Claude CLI](https://docs.anthropic.com/en/docs/claude-code) or [GitHub Copilot CLI](https://docs.github.com/en/copilot/github-copilot-in-the-cli) installed and authenticated
|
|
41
|
+
|
|
42
|
+
### 2-Minute Quick Start
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# 1. Register a project (points to your repo)
|
|
46
|
+
ralphctl project add
|
|
47
|
+
|
|
48
|
+
# 2. Create a sprint
|
|
49
|
+
ralphctl sprint create --name "my-first-sprint"
|
|
50
|
+
|
|
51
|
+
# 3. Add a ticket
|
|
52
|
+
ralphctl ticket add --project my-app --title "Add user authentication"
|
|
53
|
+
|
|
54
|
+
# 4. Let AI refine requirements, plan tasks, and execute
|
|
55
|
+
ralphctl sprint refine
|
|
56
|
+
ralphctl sprint plan
|
|
57
|
+
ralphctl sprint start
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Or just run `ralphctl` with no arguments for an interactive menu that walks you through everything.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Table of Contents
|
|
65
|
+
|
|
66
|
+
- [Features](#features)
|
|
67
|
+
- [CLI Overview](#cli-overview)
|
|
68
|
+
- [AI Provider Configuration](#ai-provider-configuration)
|
|
69
|
+
- [Documentation](#documentation)
|
|
70
|
+
- [Development](#development)
|
|
71
|
+
- [Contributing](#contributing)
|
|
72
|
+
- [License](#license)
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Features
|
|
77
|
+
|
|
78
|
+
- **Two-phase planning** — clarify requirements first (what), then generate tasks (how), with a human approval gate between them
|
|
79
|
+
- **Multi-repo sprints** — a single sprint can track tickets across multiple repositories
|
|
80
|
+
- **Task dependencies** — `blockedBy` references with topological sort; tasks run in the right order
|
|
81
|
+
- **Interactive or headless** — pair with Claude in a session, or let it run unattended
|
|
82
|
+
- **Sprint lifecycle** — state machine (draft -> active -> closed) with file locking for concurrent safety
|
|
83
|
+
- **Parallel execution** — one task per repo at a time, with automatic rate limit backoff and session resume
|
|
84
|
+
- **Menu mode** — run `ralphctl` with no arguments for an interactive menu
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## CLI Overview
|
|
89
|
+
|
|
90
|
+
| Command | Description |
|
|
91
|
+
| ------------------------------ | --------------------------------------- |
|
|
92
|
+
| `ralphctl` | Interactive menu mode |
|
|
93
|
+
| `ralphctl doctor` | Check environment health and setup |
|
|
94
|
+
| `ralphctl config show` | Show current configuration |
|
|
95
|
+
| `ralphctl config set` | Set configuration values |
|
|
96
|
+
| `ralphctl project add` | Register a project and its repos |
|
|
97
|
+
| `ralphctl sprint create` | Create a new sprint |
|
|
98
|
+
| `ralphctl sprint list` | List all sprints |
|
|
99
|
+
| `ralphctl sprint show` | Show current sprint details |
|
|
100
|
+
| `ralphctl sprint switch` | Quick sprint switcher |
|
|
101
|
+
| `ralphctl ticket add` | Add a work item to a sprint |
|
|
102
|
+
| `ralphctl sprint refine` | Refine requirements with AI |
|
|
103
|
+
| `ralphctl sprint plan` | Generate tasks from requirements |
|
|
104
|
+
| `ralphctl sprint ideate` | Quick single-session refine + plan |
|
|
105
|
+
| `ralphctl sprint requirements` | Export refined requirements to markdown |
|
|
106
|
+
| `ralphctl sprint start` | Execute tasks with AI |
|
|
107
|
+
| `ralphctl sprint health` | Diagnose blockers and stale tasks |
|
|
108
|
+
| `ralphctl sprint close` | Close an active sprint |
|
|
109
|
+
| `ralphctl sprint delete` | Delete a sprint permanently |
|
|
110
|
+
| `ralphctl task list` | List tasks in the current sprint |
|
|
111
|
+
| `ralphctl task next` | Show the next unblocked task |
|
|
112
|
+
| `ralphctl dashboard` | Sprint overview with progress bar |
|
|
113
|
+
| `ralphctl completion install` | Enable shell tab-completion |
|
|
114
|
+
|
|
115
|
+
Run `ralphctl <command> --help` for details on any command.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## AI Provider Configuration
|
|
120
|
+
|
|
121
|
+
RalphCTL supports **Claude Code** and **GitHub Copilot** as AI backends. Both use the same prompt templates and workflow.
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
ralphctl config set provider claude # Use Claude Code
|
|
125
|
+
ralphctl config set provider copilot # Use GitHub Copilot
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Auto-prompts on first AI command if not set. Both CLIs must be in your PATH and authenticated.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Documentation
|
|
133
|
+
|
|
134
|
+
| Document | Description |
|
|
135
|
+
| ----------------------------------------------------------- | ---------------------------------------------- |
|
|
136
|
+
| [REQUIREMENTS.md](./.claude/docs/REQUIREMENTS.md) | Acceptance criteria and feature requirements |
|
|
137
|
+
| [ARCHITECTURE.md](./.claude/docs/ARCHITECTURE.md) | Data models, file storage, and error reference |
|
|
138
|
+
| [CLAUDE.md](./CLAUDE.md) | Developer guide and Claude Code project config |
|
|
139
|
+
| [CONTRIBUTING.md](./CONTRIBUTING.md) | How to contribute |
|
|
140
|
+
| [CHANGELOG.md](./CHANGELOG.md) | Version history |
|
|
141
|
+
| [Blog post](https://lukasgrigis.dev/blog/building-ralphctl) | Background and motivation |
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Data Directory
|
|
146
|
+
|
|
147
|
+
RalphCTL stores all data in `~/.ralphctl/` by default. Override with `RALPHCTL_ROOT`:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
export RALPHCTL_ROOT="/path/to/custom/data-dir"
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Development
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
git clone https://github.com/lukas-grigis/ralphctl.git
|
|
159
|
+
cd ralphctl
|
|
160
|
+
pnpm install
|
|
161
|
+
pnpm dev --help # Run CLI in dev mode
|
|
162
|
+
pnpm build # Type check
|
|
163
|
+
pnpm test # Run tests
|
|
164
|
+
pnpm lint # Lint
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
No compilation step — the CLI runs TypeScript source directly via [tsx](https://tsx.is/).
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Contributing
|
|
172
|
+
|
|
173
|
+
Contributions are welcome! Please **open an issue first** to discuss what you'd like to change.
|
|
174
|
+
|
|
175
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for the full guide — dev setup, code style, PR process, and releasing.
|
|
176
|
+
|
|
177
|
+
This project follows the [Contributor Covenant](./CODE_OF_CONDUCT.md) code of conduct.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Security
|
|
182
|
+
|
|
183
|
+
To report a vulnerability, use [GitHub's private reporting](https://github.com/lukas-grigis/ralphctl/security/advisories/new). See [SECURITY.md](./SECURITY.md) for details.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## License
|
|
188
|
+
|
|
189
|
+
MIT — see [LICENSE](./LICENSE) for details.
|
package/bin/ralphctl
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Resolve symlinks so this works via npm link / pnpm link --global
|
|
3
|
+
SOURCE="${BASH_SOURCE[0]}"
|
|
4
|
+
while [ -L "$SOURCE" ]; do
|
|
5
|
+
DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
|
|
6
|
+
SOURCE="$(readlink "$SOURCE")"
|
|
7
|
+
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
|
|
8
|
+
done
|
|
9
|
+
SCRIPT_DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
|
|
10
|
+
REPO_DIR="$SCRIPT_DIR/.."
|
|
11
|
+
|
|
12
|
+
export TSX_TSCONFIG_PATH="$REPO_DIR/tsconfig.json"
|
|
13
|
+
exec node --import tsx "$REPO_DIR/src/cli.ts" "$@"
|
package/package.json
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ralphctl",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Sprint and task management CLI for AI-assisted coding",
|
|
5
|
+
"homepage": "https://github.com/lukas-grigis/ralphctl",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"author": "Lukas Grigis",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/lukas-grigis/ralphctl.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/lukas-grigis/ralphctl/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"cli",
|
|
18
|
+
"claude",
|
|
19
|
+
"ai",
|
|
20
|
+
"sprint",
|
|
21
|
+
"task-management",
|
|
22
|
+
"planning",
|
|
23
|
+
"anthropic",
|
|
24
|
+
"developer-tools"
|
|
25
|
+
],
|
|
26
|
+
"bin": {
|
|
27
|
+
"ralphctl": "./bin/ralphctl"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"bin/",
|
|
31
|
+
"src/",
|
|
32
|
+
"!src/**/*.test.ts",
|
|
33
|
+
"!src/test-utils/",
|
|
34
|
+
"!src/integration/",
|
|
35
|
+
"schemas/",
|
|
36
|
+
"tsconfig.json",
|
|
37
|
+
"README.md",
|
|
38
|
+
"LICENSE",
|
|
39
|
+
"CHANGELOG.md"
|
|
40
|
+
],
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsc --noEmit",
|
|
46
|
+
"dev": "tsx src/cli.ts",
|
|
47
|
+
"lint": "eslint .",
|
|
48
|
+
"lint:fix": "eslint . --fix",
|
|
49
|
+
"format": "prettier --write .",
|
|
50
|
+
"format:check": "prettier --check .",
|
|
51
|
+
"typecheck": "tsc --noEmit",
|
|
52
|
+
"test": "vitest run",
|
|
53
|
+
"test:watch": "vitest",
|
|
54
|
+
"test:coverage": "vitest run --coverage",
|
|
55
|
+
"prepare": "husky"
|
|
56
|
+
},
|
|
57
|
+
"packageManager": "pnpm@10.29.3",
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=24.0.0"
|
|
60
|
+
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"@inquirer/prompts": "^8.3.0",
|
|
63
|
+
"colorette": "^2.0.20",
|
|
64
|
+
"commander": "^14.0.3",
|
|
65
|
+
"gradient-string": "^3.0.0",
|
|
66
|
+
"ora": "^9.3.0",
|
|
67
|
+
"tabtab": "^3.0.2",
|
|
68
|
+
"tsx": "^4.21.0",
|
|
69
|
+
"zod": "^4.3.6"
|
|
70
|
+
},
|
|
71
|
+
"devDependencies": {
|
|
72
|
+
"@eslint/js": "^10.0.1",
|
|
73
|
+
"@types/node": "^25.3.3",
|
|
74
|
+
"@types/tabtab": "^3.0.4",
|
|
75
|
+
"eslint": "^10.0.2",
|
|
76
|
+
"eslint-config-prettier": "^10.1.8",
|
|
77
|
+
"globals": "^17.4.0",
|
|
78
|
+
"husky": "^9.1.7",
|
|
79
|
+
"lint-staged": "^16.3.1",
|
|
80
|
+
"prettier": "^3.8.1",
|
|
81
|
+
"typescript": "^5.9.3",
|
|
82
|
+
"typescript-eslint": "^8.56.1",
|
|
83
|
+
"vitest": "^4.0.18"
|
|
84
|
+
},
|
|
85
|
+
"lint-staged": {
|
|
86
|
+
"*.ts": [
|
|
87
|
+
"eslint --cache --fix",
|
|
88
|
+
"prettier --write"
|
|
89
|
+
],
|
|
90
|
+
"*.{md,json,yml,yaml}": "prettier --write"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "config.schema.json",
|
|
4
|
+
"title": "Config",
|
|
5
|
+
"description": "RalphCTL configuration",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"currentSprint": {
|
|
9
|
+
"type": ["string", "null"],
|
|
10
|
+
"default": null,
|
|
11
|
+
"description": "Current sprint ID (which sprint CLI commands target)"
|
|
12
|
+
},
|
|
13
|
+
"aiProvider": {
|
|
14
|
+
"type": ["string", "null"],
|
|
15
|
+
"enum": ["claude", "copilot", null],
|
|
16
|
+
"default": null,
|
|
17
|
+
"description": "AI provider to use for code generation (claude or copilot)"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Ideate Output Schema",
|
|
4
|
+
"description": "Combined requirements and tasks from sprint ideate command",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["requirements", "tasks"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"requirements": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"minLength": 1,
|
|
11
|
+
"description": "Refined requirements in markdown format"
|
|
12
|
+
},
|
|
13
|
+
"tasks": {
|
|
14
|
+
"type": "array",
|
|
15
|
+
"description": "Array of implementation tasks",
|
|
16
|
+
"items": {
|
|
17
|
+
"$ref": "task-import.schema.json#/definitions/ImportTask"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"additionalProperties": false
|
|
22
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "projects.schema.json",
|
|
4
|
+
"title": "Projects",
|
|
5
|
+
"description": "Array of project definitions",
|
|
6
|
+
"type": "array",
|
|
7
|
+
"items": {
|
|
8
|
+
"type": "object",
|
|
9
|
+
"required": ["name", "displayName", "repositories"],
|
|
10
|
+
"properties": {
|
|
11
|
+
"name": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"pattern": "^[a-z0-9-]+$",
|
|
14
|
+
"minLength": 1,
|
|
15
|
+
"description": "Project slug (lowercase, numbers, hyphens only)"
|
|
16
|
+
},
|
|
17
|
+
"displayName": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"minLength": 1,
|
|
20
|
+
"description": "Human-readable project name"
|
|
21
|
+
},
|
|
22
|
+
"repositories": {
|
|
23
|
+
"type": "array",
|
|
24
|
+
"minItems": 1,
|
|
25
|
+
"description": "Array of repositories for this project",
|
|
26
|
+
"items": {
|
|
27
|
+
"type": "object",
|
|
28
|
+
"required": ["name", "path"],
|
|
29
|
+
"properties": {
|
|
30
|
+
"name": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"minLength": 1,
|
|
33
|
+
"description": "Repository name (auto-derived from path basename)"
|
|
34
|
+
},
|
|
35
|
+
"path": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"minLength": 1,
|
|
38
|
+
"description": "Absolute path to the repository"
|
|
39
|
+
},
|
|
40
|
+
"checkScript": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"description": "Idempotent check command that bootstraps and verifies the environment (e.g., pnpm install && pnpm typecheck && pnpm lint && pnpm test)"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"description": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"description": "Optional project description"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "requirements-output.schema.json",
|
|
4
|
+
"title": "Requirements Output",
|
|
5
|
+
"description": "Schema for refined requirements output from ralphctl sprint refine",
|
|
6
|
+
"type": "array",
|
|
7
|
+
"items": {
|
|
8
|
+
"type": "object",
|
|
9
|
+
"required": ["ref", "requirements"],
|
|
10
|
+
"additionalProperties": false,
|
|
11
|
+
"properties": {
|
|
12
|
+
"ref": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"minLength": 1,
|
|
15
|
+
"description": "Reference to the ticket - either internal ID, external ID, or exact title"
|
|
16
|
+
},
|
|
17
|
+
"requirements": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"minLength": 1,
|
|
20
|
+
"description": "Refined requirements in markdown format - should include problem statement, requirements, acceptance criteria, scope, and constraints"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "sprint.schema.json",
|
|
4
|
+
"title": "Sprint",
|
|
5
|
+
"description": "Sprint metadata and tickets",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["id", "name", "status", "createdAt"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"id": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"pattern": "^\\d{8}-\\d{6}-[a-z0-9-]+$",
|
|
12
|
+
"description": "Sprint ID in format YYYYMMDD-HHmmss-<slug> (lexicographically sortable)"
|
|
13
|
+
},
|
|
14
|
+
"name": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"minLength": 1,
|
|
17
|
+
"description": "Human-readable sprint name"
|
|
18
|
+
},
|
|
19
|
+
"status": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"enum": ["draft", "active", "closed"],
|
|
22
|
+
"default": "draft",
|
|
23
|
+
"description": "Sprint status (one-way: draft → active → closed)"
|
|
24
|
+
},
|
|
25
|
+
"createdAt": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"format": "date-time",
|
|
28
|
+
"description": "ISO 8601 timestamp when sprint was created"
|
|
29
|
+
},
|
|
30
|
+
"activatedAt": {
|
|
31
|
+
"type": ["string", "null"],
|
|
32
|
+
"format": "date-time",
|
|
33
|
+
"default": null,
|
|
34
|
+
"description": "ISO 8601 timestamp when sprint was activated"
|
|
35
|
+
},
|
|
36
|
+
"closedAt": {
|
|
37
|
+
"type": ["string", "null"],
|
|
38
|
+
"format": "date-time",
|
|
39
|
+
"default": null,
|
|
40
|
+
"description": "ISO 8601 timestamp when sprint was closed"
|
|
41
|
+
},
|
|
42
|
+
"checkRanAt": {
|
|
43
|
+
"type": "object",
|
|
44
|
+
"default": {},
|
|
45
|
+
"description": "Map of projectPath → ISO 8601 timestamp recording when check script last ran (per sprint lifecycle)",
|
|
46
|
+
"additionalProperties": {
|
|
47
|
+
"type": "string",
|
|
48
|
+
"format": "date-time"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"branch": {
|
|
52
|
+
"type": ["string", "null"],
|
|
53
|
+
"default": null,
|
|
54
|
+
"description": "Branch name used for sprint execution. When set, all repos checkout this branch before task execution."
|
|
55
|
+
},
|
|
56
|
+
"tickets": {
|
|
57
|
+
"type": "array",
|
|
58
|
+
"default": [],
|
|
59
|
+
"description": "Tickets to be planned into tasks",
|
|
60
|
+
"items": {
|
|
61
|
+
"type": "object",
|
|
62
|
+
"required": ["id", "title", "projectName"],
|
|
63
|
+
"properties": {
|
|
64
|
+
"id": {
|
|
65
|
+
"type": "string",
|
|
66
|
+
"minLength": 1,
|
|
67
|
+
"description": "Internal ticket ID (uuid8, auto-generated)"
|
|
68
|
+
},
|
|
69
|
+
"title": {
|
|
70
|
+
"type": "string",
|
|
71
|
+
"minLength": 1,
|
|
72
|
+
"description": "Short summary of the work"
|
|
73
|
+
},
|
|
74
|
+
"description": {
|
|
75
|
+
"type": "string",
|
|
76
|
+
"description": "Detailed description of requirements, acceptance criteria, context"
|
|
77
|
+
},
|
|
78
|
+
"link": {
|
|
79
|
+
"type": "string",
|
|
80
|
+
"format": "uri",
|
|
81
|
+
"description": "URL to external issue tracker"
|
|
82
|
+
},
|
|
83
|
+
"projectName": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"minLength": 1,
|
|
86
|
+
"description": "Reference to project name (from projects.json)"
|
|
87
|
+
},
|
|
88
|
+
"requirementStatus": {
|
|
89
|
+
"type": "string",
|
|
90
|
+
"enum": ["pending", "approved"],
|
|
91
|
+
"default": "pending",
|
|
92
|
+
"description": "Status of requirement refinement"
|
|
93
|
+
},
|
|
94
|
+
"affectedRepositories": {
|
|
95
|
+
"type": "array",
|
|
96
|
+
"items": {
|
|
97
|
+
"type": "string"
|
|
98
|
+
},
|
|
99
|
+
"description": "Repository paths selected during planning"
|
|
100
|
+
},
|
|
101
|
+
"requirements": {
|
|
102
|
+
"type": "string",
|
|
103
|
+
"description": "Refined requirements (set during sprint refine)"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|