@pageai/ralph-loop 1.2.0 → 1.4.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/.agent/PROMPT.md +3 -3
- package/.agent/STEERING.md +3 -1
- package/.agent/skills/prd-creator/JSON.md +7 -1
- package/.agent/skills/prd-creator/PRD.md +2 -0
- package/.claude/settings.json +38 -49
- package/AGENTS.md +1 -1
- package/README.md +103 -61
- package/bin/cli.js +39 -22
- package/bin/lib/display.js +7 -2
- package/package.json +1 -1
- package/scripts/lib/display.sh +13 -13
package/.agent/PROMPT.md
CHANGED
|
@@ -42,15 +42,15 @@ Tasks are listed in @.agent/tasks.json
|
|
|
42
42
|
## Help Tags
|
|
43
43
|
|
|
44
44
|
Try solving tasks yourself first.
|
|
45
|
-
|
|
45
|
+
When stuck after all possible solutions exhausted, output one of the following tags:
|
|
46
46
|
|
|
47
|
-
**BLOCKED** — technical issues: Playwright broken, deps won't install, env issues, no network, service outages, invalid credentials. Output:
|
|
47
|
+
1. **BLOCKED** — technical issues: Playwright broken, dev server not working, deps won't install, env issues, no network, service outages, invalid/missing credentials. Output:
|
|
48
48
|
|
|
49
49
|
```
|
|
50
50
|
<promise>BLOCKED:brief description</promise>
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
**DECIDE** — need human input: lib choices, architecture, unclear requirements, breaking changes. Output:
|
|
53
|
+
2. **DECIDE** — need human input: lib choices, architecture, unclear requirements, breaking changes. Output:
|
|
54
54
|
|
|
55
55
|
```
|
|
56
56
|
<promise>DECIDE:question (Option A vs B)</promise>
|
package/.agent/STEERING.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
# **Critical Steering Work**
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Go to the source code directory and install dependencies.
|
|
4
|
+
|
|
5
|
+
Check that Playwright is running by starting the dev server and taking a screenshot. Save the screenshot to the .agent/screenshots directory.
|
|
@@ -546,7 +546,7 @@ Acceptance criteria must be verifiable, not vague. "Works correctly" is bad. "Bu
|
|
|
546
546
|
For any story with UI changes: Always include "Verify in browser using playwright" as acceptance criteria. This ensures visual verification of frontend work.
|
|
547
547
|
|
|
548
548
|
**Important:**
|
|
549
|
-
|
|
549
|
+
End to end tests or unit tests are individual steps (verification criteria) in a task, but *CANNOT* be tasks themselves.
|
|
550
550
|
|
|
551
551
|
### Initialize All Tasks to `"passes": false`
|
|
552
552
|
|
|
@@ -580,6 +580,12 @@ Save the complete task list as `PROJECT_ROOT/.agent/tasks.json`:
|
|
|
580
580
|
]
|
|
581
581
|
```
|
|
582
582
|
|
|
583
|
+
**Important:**
|
|
584
|
+
When outputting tasks, create them, sequentially. Output them one by one so the user can review each.
|
|
585
|
+
*DO NOT* output in parallel.
|
|
586
|
+
*DO NOT* use background agents.
|
|
587
|
+
*DO NOT* use subagents.
|
|
588
|
+
|
|
583
589
|
## After Generation
|
|
584
590
|
|
|
585
591
|
Present the tasks to the user:
|
|
@@ -10,6 +10,8 @@ Help beginner-level developers transform software ideas into comprehensive PRD.m
|
|
|
10
10
|
4. Keep tone friendly and supportive, use plain language
|
|
11
11
|
5. Track assumptions throughout - they'll go in the PRD
|
|
12
12
|
|
|
13
|
+
**Important**: Grill the user for information to make sure you have all the required details in order to implement the PRD.
|
|
14
|
+
|
|
13
15
|
## Topics to Cover
|
|
14
16
|
|
|
15
17
|
Gather information on these aspects:
|
package/.claude/settings.json
CHANGED
|
@@ -1,54 +1,43 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
"permissions": {
|
|
3
|
+
"deny": ["Read(.agent/history/**)"],
|
|
4
|
+
"allow": ["**"]
|
|
5
|
+
},
|
|
6
|
+
"defaultMode": "acceptEdits",
|
|
7
|
+
"enableAllProjectMcpServers": true,
|
|
8
|
+
"enabledMcpjsonServers": ["playwright", "context7", "sequential-thinking"],
|
|
9
|
+
"hooks": {
|
|
10
|
+
"UserPromptSubmit": [
|
|
11
|
+
{
|
|
12
|
+
"hooks": [
|
|
13
|
+
{
|
|
14
|
+
"type": "command",
|
|
15
|
+
"command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/pre-tool-use.js"
|
|
16
|
+
}
|
|
11
17
|
]
|
|
12
|
-
|
|
13
|
-
"defaultMode": "acceptEdits",
|
|
14
|
-
"enableAllProjectMcpServers": true,
|
|
15
|
-
"enabledMcpjsonServers": [
|
|
16
|
-
"playwright",
|
|
17
|
-
"context7",
|
|
18
|
-
"sequential-thinking"
|
|
18
|
+
}
|
|
19
19
|
],
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
]
|
|
29
|
-
}
|
|
30
|
-
],
|
|
31
|
-
"PreToolUse": [
|
|
32
|
-
{
|
|
33
|
-
"matcher": "Edit|Write|Bash",
|
|
34
|
-
"hooks": [
|
|
35
|
-
{
|
|
36
|
-
"type": "command",
|
|
37
|
-
"command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/pre-tool-use.js"
|
|
38
|
-
}
|
|
39
|
-
]
|
|
40
|
-
}
|
|
41
|
-
],
|
|
42
|
-
"Notification": [
|
|
43
|
-
{
|
|
44
|
-
"matcher": "",
|
|
45
|
-
"hooks": [
|
|
46
|
-
{
|
|
47
|
-
"type": "command",
|
|
48
|
-
"command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/play-sound.js notification"
|
|
49
|
-
}
|
|
50
|
-
]
|
|
51
|
-
}
|
|
20
|
+
"PreToolUse": [
|
|
21
|
+
{
|
|
22
|
+
"matcher": "Edit|Write|Bash",
|
|
23
|
+
"hooks": [
|
|
24
|
+
{
|
|
25
|
+
"type": "command",
|
|
26
|
+
"command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/pre-tool-use.js"
|
|
27
|
+
}
|
|
52
28
|
]
|
|
53
|
-
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"Notification": [
|
|
32
|
+
{
|
|
33
|
+
"matcher": "",
|
|
34
|
+
"hooks": [
|
|
35
|
+
{
|
|
36
|
+
"type": "command",
|
|
37
|
+
"command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/play-sound.js notification"
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
54
43
|
}
|
package/AGENTS.md
CHANGED
|
@@ -41,4 +41,4 @@ Verify written code by:
|
|
|
41
41
|
- Checking for type errors
|
|
42
42
|
- Checking for lint errors
|
|
43
43
|
- Smoke testing and checking for runtime errors with Playwright
|
|
44
|
-
-
|
|
44
|
+
- Taking screenshots and verifying the UI is as expected
|
package/README.md
CHANGED
|
@@ -7,12 +7,13 @@ This is an implementation that actually works, containing a hackable script so y
|
|
|
7
7
|

|
|
8
8
|
|
|
9
9
|
- [Getting Started](#getting-started)
|
|
10
|
-
- [
|
|
11
|
-
- [Step
|
|
12
|
-
- [Step
|
|
13
|
-
- [Step
|
|
14
|
-
- [
|
|
10
|
+
- [(Optional) Set up code base](#optional-set-up-code-base)
|
|
11
|
+
- [1️⃣ Step 1: Install Ralph](#1️⃣-step-1-install-ralph)
|
|
12
|
+
- [2️⃣ Step 2: Create a PRD + task list](#2️⃣-step-2-create-a-prd--task-list)
|
|
13
|
+
- [3️⃣ Step 3: Set up the agent inside Docker sandbox](#3️⃣-step-3-set-up-the-agent-inside-docker-sandbox)
|
|
14
|
+
- [4️⃣ Step 4: Run Ralph](#4️⃣-step-4-run-ralph)
|
|
15
15
|
- [Run the loop](#run-the-loop)
|
|
16
|
+
- [(Optional) Adjusting to your language/framework](#optional-adjusting-to-your-languageframework)
|
|
16
17
|
- [How It Works](#how-it-works)
|
|
17
18
|
- [How Is This Different from Other Ralphs?](#how-is-this-different-from-other-ralphs)
|
|
18
19
|
- [Steering the Agent](#steering-the-agent)
|
|
@@ -27,11 +28,27 @@ This is an implementation that actually works, containing a hackable script so y
|
|
|
27
28
|
- [Reference](#reference)
|
|
28
29
|
- [Playwright configuration](#playwright-configuration)
|
|
29
30
|
- [Vitest configuration](#vitest-configuration)
|
|
31
|
+
- [Running with a different agentic CLI](#running-with-a-different-agentic-cli)
|
|
32
|
+
- [Starting from scratch](#starting-from-scratch)
|
|
30
33
|
- [License](#license)
|
|
31
34
|
|
|
35
|
+
---------------------------------
|
|
36
|
+
|
|
32
37
|
## Getting Started
|
|
33
38
|
|
|
34
|
-
###
|
|
39
|
+
### (Optional) Set up code base
|
|
40
|
+
|
|
41
|
+
I recommend using a CLI to bootstrap your project with the necessary tools and dependencies, e.g.:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx create-vite@latest src --template react-ts
|
|
45
|
+
# or
|
|
46
|
+
npx create-next-app@latest src
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
> If you must start from a blank slate, which is not recommended, see [Starting from scratch](#starting-from-scratch).
|
|
50
|
+
|
|
51
|
+
### 1️⃣ Step 1: Install Ralph
|
|
35
52
|
|
|
36
53
|
Run this in your project's directory to install Ralph.
|
|
37
54
|
|
|
@@ -39,13 +56,17 @@ Run this in your project's directory to install Ralph.
|
|
|
39
56
|
npx @pageai/ralph-loop
|
|
40
57
|
```
|
|
41
58
|
|
|
42
|
-
### Step 2: Create a PRD + task list
|
|
59
|
+
### 2️⃣ Step 2: Create a PRD + task list
|
|
43
60
|
|
|
44
61
|
Use the `prd-creator` skill to generate a PRD from your requirements.<br/>
|
|
45
62
|
Open up Claude Code and prompt it with **your requirements**. Like so:
|
|
46
63
|
|
|
47
64
|
```
|
|
48
|
-
Use the prd-creator skill to help me create a PRD and task list for
|
|
65
|
+
Use the prd-creator skill to help me create a PRD and task list for the below requirements.
|
|
66
|
+
|
|
67
|
+
An app is already set up with Next.js, Tailwind CSS and TypeScript.
|
|
68
|
+
|
|
69
|
+
Requirements:
|
|
49
70
|
|
|
50
71
|
- A SaaS product that helps users manage their finances.
|
|
51
72
|
- Target audience: Small business owners and freelancers.
|
|
@@ -57,16 +78,26 @@ Use the prd-creator skill to help me create a PRD and task list for these requir
|
|
|
57
78
|
- Connect to bank accounts and credit cards.
|
|
58
79
|
- Connect to accounting software.
|
|
59
80
|
- Connect to payment processors.
|
|
60
|
-
- Next.js web app with Tailwind CSS and TypeScript.
|
|
61
81
|
- Use the shadcn/ui library for components.
|
|
82
|
+
- Integrate with Stripe for payments.
|
|
83
|
+
- Use Supabase for database.
|
|
84
|
+
- You can find env variables in the .env.example file: SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, STRIPE_SECRET_KEY, etc. are available in the runtime.
|
|
62
85
|
|
|
63
86
|
// etc.
|
|
64
87
|
```
|
|
65
88
|
|
|
89
|
+
Pro tips:
|
|
90
|
+
- mention libraries and frameworks you want to use
|
|
91
|
+
- mention env variables, e.g. for database, 3rd party API keys, etc. Store them in a .env file that you add to **.gitignore**
|
|
92
|
+
- describe user flows and journeys
|
|
93
|
+
- add relevant docs and UI references if applicable inside `/docs` and mention them in the requirements
|
|
94
|
+
- be as descriptive as possible
|
|
95
|
+
- *it's fine to write in your own language*
|
|
96
|
+
|
|
66
97
|
Then follow the Skill's instructions and verify the PRD and then tasks.<br/>
|
|
67
98
|
**It is highly recommended that you review individual task requirements before starting the loop. Review EACH TASK INDIVIDUALLY.**
|
|
68
99
|
|
|
69
|
-
### Step 3: Set up the agent inside Docker sandbox
|
|
100
|
+
### 3️⃣ Step 3: Set up the agent inside Docker sandbox
|
|
70
101
|
|
|
71
102
|
Authenticate inside the Docker sandbox before running Ralph. Run:
|
|
72
103
|
|
|
@@ -76,48 +107,16 @@ docker sandbox run claude .
|
|
|
76
107
|
|
|
77
108
|
And follow the instructions to log in into Claude Code.
|
|
78
109
|
|
|
79
|
-
|
|
110
|
+
👉 Answer "Yes" to `Bypass Permissions mode`, that's the exact reason why you are using the Docker sandbox.
|
|
80
111
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
```bash
|
|
84
|
-
./ralph.sh -n 50 # Run Ralph Loop with 50 iterations
|
|
85
|
-
```
|
|
112
|
+
> If you want to use a different agentic CLI, see [Running with a different agentic CLI](#running-with-a-different-agentic-cli).
|
|
86
113
|
|
|
87
|
-
###
|
|
88
|
-
|
|
89
|
-
This script assumes the following are installed:
|
|
90
|
-
- [Playwright](https://playwright.dev/) for e2e testing
|
|
91
|
-
- [Vitest](https://vitest.dev/) for unit testing
|
|
92
|
-
- [TypeScript](https://www.typescriptlang.org/) for type checking
|
|
93
|
-
- [ESLint](https://eslint.org/) for linting
|
|
94
|
-
- [Prettier](https://prettier.io/) for formatting
|
|
95
|
-
|
|
96
|
-
I recommend using a CLI to bootstrap your project with the necessary tools and dependencies, e.g.:
|
|
97
|
-
|
|
98
|
-
```bash
|
|
99
|
-
npx create-vite@latest src --template react-ts
|
|
100
|
-
# or
|
|
101
|
-
npx create-next-app@latest src
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
If you must start from a blank slate, which is not recommended, you can use the following commands to install the necessary tools and dependencies:
|
|
105
|
-
|
|
106
|
-
Install with:
|
|
114
|
+
### 4️⃣ Step 4: Run Ralph
|
|
107
115
|
|
|
108
116
|
```bash
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
# If using React, also recommend installing:
|
|
112
|
-
npm i @vitejs/plugin-react @testing-library/dom @testing-library/jest-dom @testing-library/react @testing-library/user-event -D
|
|
117
|
+
./ralph.sh -n 50 # Run Ralph Loop with 50 iterations
|
|
113
118
|
```
|
|
114
119
|
|
|
115
|
-
--------------------------------
|
|
116
|
-
|
|
117
|
-
⚠️ If you are using a different language or testing framework, please adjust `.agent/PROMPT.md` to reflect your setup, server ports and startup commands etc.
|
|
118
|
-
|
|
119
|
-
⚠️ The default "mode" is "implementation". Depending on your use case, you might want to change `.agent/PROMPT.md` to a different mode, e.g. "refactor", "review", "test" etc.
|
|
120
|
-
|
|
121
120
|
## Run the loop
|
|
122
121
|
|
|
123
122
|
```bash
|
|
@@ -138,6 +137,25 @@ npm i @vitejs/plugin-react @testing-library/dom @testing-library/jest-dom @testi
|
|
|
138
137
|
|
|
139
138
|
> NB: you might need to run `chmod +x ralph.sh` to make the script executable.
|
|
140
139
|
|
|
140
|
+
> ⚠️ The default "mode" is "implementation". Depending on your use case, you might want to change `.agent/PROMPT.md` to a different mode, e.g. "refactor", "review", "test" etc.
|
|
141
|
+
|
|
142
|
+
⚠️ If you want to use a different language or testing framework, see below.
|
|
143
|
+
|
|
144
|
+
### (Optional) Adjusting to your language/framework
|
|
145
|
+
|
|
146
|
+
This script assumes the following are installed:
|
|
147
|
+
- [Playwright](https://playwright.dev/) for e2e testing
|
|
148
|
+
- [Vitest](https://vitest.dev/) for unit testing
|
|
149
|
+
- [TypeScript](https://www.typescriptlang.org/) for type checking
|
|
150
|
+
- [ESLint](https://eslint.org/) for linting
|
|
151
|
+
- [Prettier](https://prettier.io/) for formatting
|
|
152
|
+
|
|
153
|
+
If you'd like to use a different language, testing framework etc. please adjust `.agent/PROMPT.md` to reflect your setup, server ports and startup commands etc.
|
|
154
|
+
|
|
155
|
+
👉 The loop is controlled by this prompt, which will be sent to the agent each iteration.
|
|
156
|
+
|
|
157
|
+
---------------------------------
|
|
158
|
+
|
|
141
159
|
## How It Works
|
|
142
160
|
|
|
143
161
|
Each iteration, Ralph will:
|
|
@@ -189,7 +207,7 @@ The agent will check this file each iteration and if it finds any critical work,
|
|
|
189
207
|
The `ralph.sh` script is designed to be hackable.
|
|
190
208
|
It is configured to use Claude Code in a Docker sandbox by default, but with a one-liner change you can change it to use any other agentic AI CLI.
|
|
191
209
|
|
|
192
|
-
Check the `ralph.sh` script around `#
|
|
210
|
+
Check the `ralph.sh` script around `# This is the main command loop.` for the main command loop.
|
|
193
211
|
|
|
194
212
|
> NB: skills are supported by all major agentic AI CLIs via symlinks.
|
|
195
213
|
|
|
@@ -265,8 +283,8 @@ Skills are symlinked from `.agent/skills/` to multiple locations for cross-tool
|
|
|
265
283
|
.cursor/skills/
|
|
266
284
|
```
|
|
267
285
|
|
|
268
|
-
|
|
269
286
|
## Reference
|
|
287
|
+
|
|
270
288
|
### Playwright configuration
|
|
271
289
|
|
|
272
290
|
If you are using Playwright, here is a recommended configuration:
|
|
@@ -279,28 +297,19 @@ import { defineConfig, devices } from '@playwright/test';
|
|
|
279
297
|
*/
|
|
280
298
|
export default defineConfig({
|
|
281
299
|
testDir: './tests',
|
|
282
|
-
/* Total timeout for the entire test run (30 minutes) */
|
|
283
|
-
globalTimeout: 30 * 60 * 1000,
|
|
284
|
-
/* Run tests in files in parallel */
|
|
285
300
|
fullyParallel: true,
|
|
286
|
-
|
|
301
|
+
globalTimeout: 30 * 60 * 1000,
|
|
287
302
|
forbidOnly: !!process.env.CI,
|
|
288
|
-
/* Retry on failure - 2 on CI, 1 locally */
|
|
289
303
|
retries: process.env.CI ? 2 : 1,
|
|
290
|
-
|
|
291
|
-
workers: process.env.CI ? 1 : 6,
|
|
292
|
-
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
|
304
|
+
workers: process.env.CI ? 3 : 6,
|
|
293
305
|
reporter: 'html',
|
|
294
|
-
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
|
295
306
|
use: {
|
|
296
|
-
/* Base URL to use in actions like `await page.goto('')`. */
|
|
297
307
|
baseURL: 'http://localhost:3000',
|
|
298
|
-
|
|
299
|
-
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
|
300
308
|
trace: 'on-first-retry',
|
|
301
309
|
},
|
|
302
310
|
|
|
303
|
-
|
|
311
|
+
|
|
312
|
+
// NB: only chromium will run in Docker (arm64).
|
|
304
313
|
projects: [
|
|
305
314
|
{
|
|
306
315
|
name: 'chromium',
|
|
@@ -366,6 +375,39 @@ vi.mock('next/link', () => ({
|
|
|
366
375
|
}))
|
|
367
376
|
```
|
|
368
377
|
|
|
378
|
+
### Running with a different agentic CLI
|
|
379
|
+
|
|
380
|
+
If you want to use a different agentic CLI, you can adjust the `ralph.sh` script to reflect your CLI of choice.
|
|
381
|
+
|
|
382
|
+
Check the `ralph.sh` script around `# This is the main command loop.` for the main command loop.
|
|
383
|
+
|
|
384
|
+
Replace `docker sandbox run claude . --` with the your favorite CLI. Remember to also update the options after the `--`.
|
|
385
|
+
|
|
386
|
+
```
|
|
387
|
+
docker sandbox run codex . # for Codex CLI
|
|
388
|
+
docker sandbox run gemini . # for Gemini CLI
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
Docker currently supports: `claude`, `codex`, `gemini`, `cagent`, `kiro`.
|
|
392
|
+
See more in [Docker's docs](https://docs.docker.com/ai/sandboxes/migration/).
|
|
393
|
+
|
|
394
|
+
### Starting from scratch
|
|
395
|
+
|
|
396
|
+
For AI to actually verify its implementation and for the loop to work, you need a way to verify it.
|
|
397
|
+
|
|
398
|
+
To that end, at the minimum you need an end-to-end test framework and a unit test framework.
|
|
399
|
+
|
|
400
|
+
For example, you can use the following commands to install Playwright and Vitest:
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
npm i @playwright/test vitest jsdom typescript eslint prettier -D
|
|
404
|
+
|
|
405
|
+
# If using React, also recommend installing:
|
|
406
|
+
npm i @vitejs/plugin-react @testing-library/dom @testing-library/jest-dom @testing-library/react @testing-library/user-event -D
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
It is recommended that you add skills for your specific language and framework. See [skills.sh](https://skills.sh) to discover existing skills.
|
|
410
|
+
|
|
369
411
|
## License
|
|
370
412
|
|
|
371
413
|
MIT
|
package/bin/cli.js
CHANGED
|
@@ -19,12 +19,24 @@ const DEFAULT_APP_DIR = 'src';
|
|
|
19
19
|
// Directories to ensure exist (created even if source doesn't exist)
|
|
20
20
|
const DIRS_TO_ENSURE = [
|
|
21
21
|
'.agent/history',
|
|
22
|
+
'.agent/logs',
|
|
23
|
+
'.agent/prd',
|
|
24
|
+
'.agent/screenshots',
|
|
25
|
+
'.agent/tasks',
|
|
22
26
|
'.agents/skills',
|
|
23
27
|
'.claude/skills',
|
|
24
28
|
'.codex/skills',
|
|
25
29
|
'.cursor/skills',
|
|
26
30
|
];
|
|
27
31
|
|
|
32
|
+
// Directories that should have a .gitkeep file
|
|
33
|
+
const DIRS_WITH_GITKEEP = [
|
|
34
|
+
'.agent/logs',
|
|
35
|
+
'.agent/prd',
|
|
36
|
+
'.agent/screenshots',
|
|
37
|
+
'.agent/tasks',
|
|
38
|
+
];
|
|
39
|
+
|
|
28
40
|
// Symlinks to create in skills directories (relative to each skills dir)
|
|
29
41
|
const SKILL_SYMLINKS = [
|
|
30
42
|
{ name: 'component-refactoring', target: '../../.agent/skills/component-refactoring/' },
|
|
@@ -201,36 +213,41 @@ async function main() {
|
|
|
201
213
|
}
|
|
202
214
|
}
|
|
203
215
|
|
|
204
|
-
// Ensure required directories exist and create
|
|
205
|
-
console.log();
|
|
206
|
-
display.printStep('🔧', 'Ensuring directories & symlinks');
|
|
216
|
+
// Ensure required directories exist and create markers
|
|
207
217
|
for (const dir of DIRS_TO_ENSURE) {
|
|
208
218
|
const dest = path.join(TARGET_DIR, dir);
|
|
209
219
|
ensureDir(dest);
|
|
210
220
|
|
|
211
|
-
|
|
212
|
-
if (dir.endsWith('/skills')) {
|
|
213
|
-
for (const link of SKILL_SYMLINKS) {
|
|
214
|
-
const linkPath = path.join(dest, link.name);
|
|
215
|
-
if (!exists(linkPath)) {
|
|
216
|
-
try {
|
|
217
|
-
fs.symlinkSync(link.target, linkPath);
|
|
218
|
-
} catch {
|
|
219
|
-
// Symlink might fail on some systems, that's ok
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
display.printSuccess(`${dir}/ (with symlinks)`);
|
|
224
|
-
} else if (dir === '.agent/history') {
|
|
225
|
-
// Create .gitignore for history folder
|
|
221
|
+
if (dir === '.agent/history') {
|
|
226
222
|
const gitignorePath = path.join(dest, '.gitignore');
|
|
227
223
|
if (!exists(gitignorePath)) {
|
|
228
224
|
fs.writeFileSync(gitignorePath, '*\n!.gitignore\n');
|
|
229
225
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
226
|
+
} else if (DIRS_WITH_GITKEEP.includes(dir)) {
|
|
227
|
+
const gitkeepPath = path.join(dest, '.gitkeep');
|
|
228
|
+
if (!exists(gitkeepPath)) {
|
|
229
|
+
fs.writeFileSync(gitkeepPath, '');
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Create symlinks for AI config skills directories
|
|
235
|
+
console.log();
|
|
236
|
+
display.printStep('🔗', 'AI config symlinks');
|
|
237
|
+
for (const dir of DIRS_TO_ENSURE) {
|
|
238
|
+
if (!dir.endsWith('/skills')) continue;
|
|
239
|
+
const dest = path.join(TARGET_DIR, dir);
|
|
240
|
+
for (const link of SKILL_SYMLINKS) {
|
|
241
|
+
const linkPath = path.join(dest, link.name);
|
|
242
|
+
if (!exists(linkPath)) {
|
|
243
|
+
try {
|
|
244
|
+
fs.symlinkSync(link.target, linkPath);
|
|
245
|
+
} catch {
|
|
246
|
+
// Symlink might fail on some systems, that's ok
|
|
247
|
+
}
|
|
248
|
+
}
|
|
233
249
|
}
|
|
250
|
+
display.printSuccess(`${dir}/`);
|
|
234
251
|
}
|
|
235
252
|
|
|
236
253
|
// Copy extra files from directories (with exclusions)
|
|
@@ -280,7 +297,7 @@ async function main() {
|
|
|
280
297
|
console.log();
|
|
281
298
|
display.printStep('📂', 'App directory');
|
|
282
299
|
const content = fs.readFileSync(promptFile, 'utf8');
|
|
283
|
-
const updated = content.replaceAll('`
|
|
300
|
+
const updated = content.replaceAll('`src`', `\`${appDir}\``);
|
|
284
301
|
fs.writeFileSync(promptFile, updated, 'utf8');
|
|
285
302
|
display.printSuccess(`.agent/PROMPT.md → ${appDir}`);
|
|
286
303
|
}
|
package/bin/lib/display.js
CHANGED
|
@@ -28,11 +28,16 @@ function formatCatchphrase(text) {
|
|
|
28
28
|
const suffix = '■▒▒▓■';
|
|
29
29
|
const contentWidth = LINE_WIDTH - prefix.length - suffix.length; // 52 chars for content
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
if (text.length === 0) {
|
|
32
|
+
return prefix + '▒'.repeat(contentWidth) + suffix;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const textWithSpaces = ' ' + text + ' ';
|
|
36
|
+
const padding = contentWidth - textWithSpaces.length;
|
|
32
37
|
const leftPad = Math.floor(padding / 2);
|
|
33
38
|
const rightPad = padding - leftPad;
|
|
34
39
|
|
|
35
|
-
return prefix + '
|
|
40
|
+
return prefix + '▒'.repeat(leftPad) + textWithSpaces + '▒'.repeat(rightPad) + suffix;
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
// Catchphrases (text only, will be formatted)
|
package/package.json
CHANGED
package/scripts/lib/display.sh
CHANGED
|
@@ -53,19 +53,19 @@ show_ralph() {
|
|
|
53
53
|
|
|
54
54
|
local catchphrases=(
|
|
55
55
|
"■▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒■▒▒▓■"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"■▒▒▒▒▒▒▒My cat's breath smells like cat food
|
|
61
|
-
"■▒▒▒▒▒▒▒▒Me fail English? That's unpossible
|
|
62
|
-
"
|
|
63
|
-
"■▒▒▒▒▒▒▒▒▒▒I found a moon rock in my nose
|
|
64
|
-
"■▒▒▒▒▒▒▒▒▒▒▒▒▒▒It tastes like burning
|
|
65
|
-
"■▒▒▒▒▒▒When I grow up, I want to be a computer
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
56
|
+
"■▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ I'm helping! ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒■▒▒▓■"
|
|
57
|
+
"■▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ I'm doing my best! ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒■▒▒▓■"
|
|
58
|
+
"■▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ I'm in danger! ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒■▒▒▓■"
|
|
59
|
+
"■▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ I'm learnding! ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒■▒▒▓■"
|
|
60
|
+
"■▒▒▒▒▒▒▒ My cat's breath smells like cat food. ▒▒▒▒▒▒▒■▒▒▓■"
|
|
61
|
+
"■▒▒▒▒▒▒▒▒ Me fail English? That's unpossible! ▒▒▒▒▒▒▒▒■▒▒▓■"
|
|
62
|
+
"■▒▒▒▒▒▒▒▒▒▒ I'm asking Claude to cook pasta! ▒▒▒▒▒▒▒▒▒■▒▒▓■"
|
|
63
|
+
"■▒▒▒▒▒▒▒▒▒▒ I found a moon rock in my nose! ▒▒▒▒▒▒▒▒▒▒■▒▒▓■"
|
|
64
|
+
"■▒▒▒▒▒▒▒▒▒▒▒▒▒▒ It tastes like burning! ▒▒▒▒▒▒▒▒▒▒▒▒▒▒■▒▒▓■"
|
|
65
|
+
"■▒▒▒▒▒▒ When I grow up, I want to be a computer! ▒▒▒▒▒■▒▒▓■"
|
|
66
|
+
"■▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ I'm a develotron! ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒■▒▒▓■"
|
|
67
|
+
"■▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ I'm helpding AI! ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒■▒▒▓■"
|
|
68
|
+
"■▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ I'm essential! ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒■▒▒▓■"
|
|
69
69
|
"■▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒■▒▒▓■"
|
|
70
70
|
)
|
|
71
71
|
|