ralphctl 0.25.0 → 0.27.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/README.md +11 -5
- package/THIRD-PARTY-NOTICES.md +65 -2
- package/dist/agent-definitions/ralphctl-generator.md +3 -2
- package/dist/{cli-GQBXYNFN.mjs → cli-EYDXERW6.mjs} +9423 -6665
- package/dist/cli.mjs +1 -1
- package/dist/manifest.json +20 -3
- package/dist/prompts/_partials/approval-gate.md +5 -5
- package/dist/prompts/_partials/autonomous-operation.md +23 -6
- package/dist/prompts/_partials/conventions-agents-md.md +8 -20
- package/dist/prompts/_partials/conventions-claude-md.md +12 -15
- package/dist/prompts/_partials/conventions-copilot-instructions.md +6 -10
- package/dist/prompts/_partials/decisions.md +3 -9
- package/dist/prompts/_partials/evaluator-failure-modes.md +11 -5
- package/dist/prompts/_partials/evaluator-grading-rules.md +25 -10
- package/dist/prompts/_partials/evidence-bound.md +2 -2
- package/dist/prompts/_partials/git-boundary.md +7 -0
- package/dist/prompts/_partials/harness-context.md +1 -1
- package/dist/prompts/_partials/one-shot-operation.md +6 -0
- package/dist/prompts/_partials/question-format.md +7 -0
- package/dist/prompts/_partials/skill-body.md +5 -0
- package/dist/prompts/_partials/task-blocked.md +10 -0
- package/dist/prompts/_partials/task-fields.md +19 -3
- package/dist/prompts/_partials/task-sizing.md +2 -2
- package/dist/prompts/_partials/validation-checklist.md +6 -8
- package/dist/prompts/apply-feedback/template.md +24 -25
- package/dist/prompts/create-pr/template.md +21 -15
- package/dist/prompts/detect-scripts/template.md +10 -9
- package/dist/prompts/detect-skills/template.md +19 -23
- package/dist/prompts/distill-learnings/template.md +10 -8
- package/dist/prompts/evaluate/template.md +74 -93
- package/dist/prompts/evaluate-continuation/template.md +19 -22
- package/dist/prompts/ideate/template.md +36 -47
- package/dist/prompts/implement/template.md +59 -73
- package/dist/prompts/implement-continuation/template.md +21 -20
- package/dist/prompts/implement-crash-resume/template.md +13 -4
- package/dist/prompts/plan/template.md +75 -64
- package/dist/prompts/readiness/template.md +36 -27
- package/dist/prompts/refine/template.md +37 -50
- package/dist/prompts/reproduce/template.md +9 -7
- package/dist/prompts/select-candidate/template.md +17 -10
- package/dist/skills/ralphctl-api-and-interface-design/SKILL.md +117 -0
- package/dist/skills/ralphctl-code-review-and-quality/SKILL.md +119 -8
- package/dist/skills/ralphctl-code-simplification/SKILL.md +100 -0
- package/dist/skills/ralphctl-codebase-design/SKILL.md +82 -0
- package/dist/skills/ralphctl-debugging-and-error-recovery/SKILL.md +23 -5
- package/dist/skills/ralphctl-deprecation-and-migration/SKILL.md +106 -0
- package/dist/skills/ralphctl-frontend-ui-engineering/SKILL.md +94 -0
- package/dist/skills/ralphctl-humanizer/SKILL.md +137 -0
- package/dist/skills/ralphctl-idea-refinement/SKILL.md +2 -0
- package/dist/skills/ralphctl-iterative-review/SKILL.md +10 -4
- package/dist/skills/ralphctl-observability-and-instrumentation/SKILL.md +104 -0
- package/dist/skills/ralphctl-performance-optimization/SKILL.md +123 -0
- package/dist/skills/ralphctl-ponytail/SKILL.md +38 -28
- package/dist/skills/ralphctl-security-and-hardening/SKILL.md +259 -0
- package/dist/skills/ralphctl-source-driven-development/SKILL.md +103 -0
- package/dist/skills/ralphctl-spec-driven-development/SKILL.md +148 -0
- package/dist/skills/ralphctl-test-driven-development/SKILL.md +29 -2
- package/dist/skills/ralphctl-writing-for-agents/SKILL.md +113 -0
- package/package.json +10 -10
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ralphctl-test-driven-development
|
|
3
|
-
description: Execute-phase skill — write the failing test before the code that makes it pass; for bug fixes, this is the reproduction test itself. Use for any logic change, bug fix, or behavioural modification; for the full root-cause triage pipeline around an unexpected failure, see ralphctl-debugging-and-error-recovery.
|
|
3
|
+
description: Execute-phase skill — drive changes with the red-green-refactor loop; write the failing test before the code that makes it pass; for bug fixes, this is the reproduction test itself. Use for any logic change, bug fix, or behavioural modification; for the full root-cause triage pipeline around an unexpected failure, see ralphctl-debugging-and-error-recovery.
|
|
4
4
|
license: MIT
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Test-Driven Development
|
|
8
8
|
|
|
9
9
|
> Concept from [Addy Osmani — "Test-Driven Development"](https://github.com/addyosmani/agent-skills)
|
|
10
|
-
> (agent-skills, MIT)
|
|
10
|
+
> (agent-skills, MIT), with the tautological-assertion anti-pattern drawn from
|
|
11
|
+
> [mattpocock/skills](https://github.com/mattpocock/skills) (MIT). Adapted for ralphctl's execute phase.
|
|
11
12
|
|
|
12
13
|
Write a failing test before writing the code that makes it pass. For bug fixes, reproduce the bug with a
|
|
13
14
|
test before attempting a fix. Tests are proof — "seems right" is not done. A codebase with good tests is an
|
|
@@ -23,6 +24,28 @@ AI agent's superpower; a codebase without tests is a liability.
|
|
|
23
24
|
**When NOT to use:** Pure configuration changes, documentation updates, or static content changes with no
|
|
24
25
|
behavioural impact.
|
|
25
26
|
|
|
27
|
+
## Discover the Stack First
|
|
28
|
+
|
|
29
|
+
The TDD cycle is universal; the commands are not. Before writing the first test, find out how _this_
|
|
30
|
+
repository tests, and use its commands for every RED, GREEN, and narrow-check step:
|
|
31
|
+
|
|
32
|
+
- **Commands the harness hands you** — the prompt's project-tooling or check-gate section, when present, is
|
|
33
|
+
the authoritative source; prefer it over anything you infer.
|
|
34
|
+
- **Language and build system** — the dependency manifest or build file (`package.json`, `pom.xml` /
|
|
35
|
+
`build.gradle`, `pyproject.toml`, `go.mod`, `Cargo.toml`, `Gemfile`, a `Makefile`).
|
|
36
|
+
- **Checked-in wrappers** — prefer a repo wrapper or script (`./gradlew`, `./mvnw`, a `Makefile` target) over
|
|
37
|
+
a globally installed tool.
|
|
38
|
+
- **Test framework and configuration** — and how it runs a single focused test versus the full suite.
|
|
39
|
+
- **Existing conventions** — where tests live, how files are named, what patterns neighbouring tests follow.
|
|
40
|
+
- **Documented commands** — the project's AI context file, README, CONTRIBUTING, and CI workflows show the
|
|
41
|
+
commands that actually gate merges.
|
|
42
|
+
|
|
43
|
+
Run the repository's focused-test command during the loop. Never assume a default test command from another
|
|
44
|
+
ecosystem — a Gradle, Cargo, or pytest project has its own equivalent.
|
|
45
|
+
|
|
46
|
+
The examples below use TypeScript for illustration; the workflow is identical in any language once you have
|
|
47
|
+
discovered the project's own tooling.
|
|
48
|
+
|
|
26
49
|
## The TDD Cycle
|
|
27
50
|
|
|
28
51
|
```
|
|
@@ -298,6 +321,7 @@ describe('TaskService', () => {
|
|
|
298
321
|
| Anti-Pattern | Problem | Fix |
|
|
299
322
|
| ------------------------------------- | ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
300
323
|
| Testing implementation details | Tests break when refactoring even if behaviour is unchanged | Test inputs and outputs, not internal structure |
|
|
324
|
+
| Tautological assertions | Recomputes the expected value the way the code does | Expected values come from an independent source — a literal, a worked example, the spec — never the code's own formula |
|
|
301
325
|
| Flaky tests (timing, order-dependent) | Erode trust in the test suite | Use deterministic assertions, isolate test state |
|
|
302
326
|
| Testing framework code | Wastes time testing third-party behaviour | Only test YOUR code |
|
|
303
327
|
| Snapshot abuse | Large snapshots nobody reviews, break on any change | Use snapshots sparingly and review every change |
|
|
@@ -319,7 +343,10 @@ describe('TaskService', () => {
|
|
|
319
343
|
## Red Flags
|
|
320
344
|
|
|
321
345
|
- Writing code without any corresponding tests
|
|
346
|
+
- Reaching for a default test command without checking what this repository actually uses
|
|
322
347
|
- Tests that pass on the first run (they may not be testing what you think)
|
|
348
|
+
- An expected value computed with the code's own formula (`add(a, b)` checked against `a + b`) — it passes by
|
|
349
|
+
construction
|
|
323
350
|
- "All tests pass" but no tests were actually run
|
|
324
351
|
- Bug fixes without a reproduction test
|
|
325
352
|
- Tests that verify framework behaviour instead of application behaviour
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ralphctl-writing-for-agents
|
|
3
|
+
description: How to write documents an AI agent consumes — project context files (AGENTS.md, CLAUDE.md, and similar), skills, task specs, and requirements. Covers trigger-worded pointers, the cost of always-loaded context, steps that end on checkable completion criteria, leading words, positive phrasing over prohibitions, and pruning restatements, no-ops, and stale lines. Use when drafting or editing any of those documents.
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Writing for Agents
|
|
8
|
+
|
|
9
|
+
> Adapted from [mattpocock/skills — "Writing for Agents"](https://github.com/mattpocock/skills) (MIT).
|
|
10
|
+
> Adapted for ralphctl's harness contract.
|
|
11
|
+
|
|
12
|
+
A reference for writing any document an agent consumes: a project context file, a skill, a task spec, a
|
|
13
|
+
set of requirements. The packaging differs; the writing does not. The same levers make each one
|
|
14
|
+
predictable — the agent takes the same _process_ every run, rather than producing the same output.
|
|
15
|
+
|
|
16
|
+
The session's prompt still owns the output: its length targets, required sections, and what-to-leave-out
|
|
17
|
+
rules win over anything here.
|
|
18
|
+
|
|
19
|
+
## When this applies
|
|
20
|
+
|
|
21
|
+
- **Readiness** — the context-file proposal. Every line is loaded into every future session, so each one
|
|
22
|
+
must change behaviour versus the default. Point at what the environment already states instead of
|
|
23
|
+
restating it, but keep every exact command the prompt asks for (build and test lines, setup and verify
|
|
24
|
+
skill bodies).
|
|
25
|
+
- **Refine** — the requirements are read by the planner and every implementing session. Give each
|
|
26
|
+
criterion a checkable completion condition, keep each meaning in one place, and phrase the target
|
|
27
|
+
behaviour positively.
|
|
28
|
+
|
|
29
|
+
## Context pointers
|
|
30
|
+
|
|
31
|
+
A **context pointer** is a line in context that names material outside it and encodes when to reach it —
|
|
32
|
+
a skill's description, or a context-file line naming a doc. The pointer's _wording_, not its target,
|
|
33
|
+
decides when and how reliably the agent reaches the material. A must-have target behind a weakly worded
|
|
34
|
+
pointer is a variance bug: sharpen the wording first; inline the material only if that fails.
|
|
35
|
+
|
|
36
|
+
A pointer states what the material is and lists the **branches** — distinct cases — that should trigger
|
|
37
|
+
it. Every word of an always-loaded pointer costs on every turn, so prune it hardest:
|
|
38
|
+
|
|
39
|
+
- **Front-load the leading word**; the start of the pointer does the triggering.
|
|
40
|
+
- **One trigger per branch.** Synonyms naming one branch are one branch written twice.
|
|
41
|
+
- **Cut identity the body already carries.**
|
|
42
|
+
|
|
43
|
+
## The two loads
|
|
44
|
+
|
|
45
|
+
- **Context load** — always-loaded material (a context-file line, a skill description) spends tokens and
|
|
46
|
+
attention every turn, whether or not it fires.
|
|
47
|
+
- **Cognitive load** — the human has to know which documents exist and when each matters. Spend it where
|
|
48
|
+
human judgement matters; remove it where it does not.
|
|
49
|
+
|
|
50
|
+
Material behind a pointer escapes context load at the price of the pointer's own line.
|
|
51
|
+
|
|
52
|
+
## Information hierarchy
|
|
53
|
+
|
|
54
|
+
A document mixes **steps** (ordered actions) and **reference** (definitions, rules, facts consulted on
|
|
55
|
+
demand). Place each piece on a ladder ranked by how immediately the agent needs it:
|
|
56
|
+
|
|
57
|
+
1. **In-file steps** — what the agent does, in order.
|
|
58
|
+
2. **In-file reference** — consulted on demand; a flat set of peer rules is fine.
|
|
59
|
+
3. **Disclosed reference** — material in another file, reached through a pointer only when needed.
|
|
60
|
+
|
|
61
|
+
Inline what every branch needs; disclose what only some branches reach. Keep a concept's definition,
|
|
62
|
+
rules, and caveats together under one heading rather than scattered. The failure mode is **sprawl** — a
|
|
63
|
+
document so long that attention thins across it even when every line is live. In a session that writes
|
|
64
|
+
only its proposal, disclose by pointing at a file that already exists.
|
|
65
|
+
|
|
66
|
+
## Steps and completion criteria
|
|
67
|
+
|
|
68
|
+
Every step ends on a **completion criterion** — the condition that tells the agent it is done.
|
|
69
|
+
|
|
70
|
+
- **Clarity** — can the agent tell done from not done? A vague bound ("once understanding is reached")
|
|
71
|
+
invites premature completion, with attention slipping to the steps still ahead. Sharpen the bound
|
|
72
|
+
first. Hiding later steps only helps across a real context boundary (a hand-off to a separate session
|
|
73
|
+
or task).
|
|
74
|
+
- **Demand** — how much the criterion requires. "Every modified model accounted for" forces thorough work
|
|
75
|
+
where "produce a change list" does not. Demand binds flat reference too: "every rule applied".
|
|
76
|
+
|
|
77
|
+
The strongest criteria are both checkable and exhaustive.
|
|
78
|
+
|
|
79
|
+
## Leading words
|
|
80
|
+
|
|
81
|
+
A **leading word** is a compact concept the model already knows — _tight_ (a tight feedback loop),
|
|
82
|
+
_red_ (a test that fails on the bug), _tracer bullet_. Repeated as a token, it anchors a whole region of
|
|
83
|
+
behaviour in few words by recruiting priors the model already holds. Hunt for passages that spell out a
|
|
84
|
+
triad or a sentence where one such word would do.
|
|
85
|
+
|
|
86
|
+
**Prohibitions backfire.** Naming the forbidden behaviour puts it in context and makes it more
|
|
87
|
+
available. State the target behaviour ("write one-line comments"). Keep a prohibition only as a hard
|
|
88
|
+
guardrail you cannot phrase positively, and pair it with the positive target.
|
|
89
|
+
|
|
90
|
+
## Pruning
|
|
91
|
+
|
|
92
|
+
- **One meaning, one place.** Duplication costs maintenance and tokens and inflates a meaning's
|
|
93
|
+
prominence. (A leading word repeats a token on purpose, never the meaning.)
|
|
94
|
+
- **The environment is a source of truth.** Config files, the directory layout, `--help` output, and
|
|
95
|
+
what a manifest script does already state themselves; a document that restates them is a cache that
|
|
96
|
+
goes stale. Which command to run is different: where the document exists to tell the agent what to run,
|
|
97
|
+
or the output contract asks for commands, give the exact runnable command, checked against the manifest.
|
|
98
|
+
Beyond that, write down what the agent cannot find by looking — the unwritten convention, the reason
|
|
99
|
+
behind a choice, the gotcha no config admits.
|
|
100
|
+
- **Relevance.** A line that never bears on the task, or describes behaviour that has since changed, is
|
|
101
|
+
sediment. Remove it.
|
|
102
|
+
- **No-ops.** An instruction the model already follows by default says nothing. Delete the whole
|
|
103
|
+
sentence. A word too weak to beat the default (_be thorough_) needs a stronger word, not more words.
|
|
104
|
+
|
|
105
|
+
## Self-check
|
|
106
|
+
|
|
107
|
+
- [ ] Every always-loaded line changes behaviour versus the default.
|
|
108
|
+
- [ ] Each pointer front-loads its trigger and lists one trigger per branch.
|
|
109
|
+
- [ ] Every step ends on a checkable completion criterion.
|
|
110
|
+
- [ ] Nothing restates what the environment already states, and every command the contract asks for is
|
|
111
|
+
exact and runnable.
|
|
112
|
+
- [ ] Target behaviours are phrased positively.
|
|
113
|
+
- [ ] The prompt's own length and section rules are met.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ralphctl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"description": "A ralph harness for long-running AI coding tasks — a generator-evaluator loop that drives Claude Code, GitHub Copilot CLI, OpenAI Codex CLI, OpenCode or Grok Build CLI across one or more repositories",
|
|
5
5
|
"homepage": "https://github.com/lukas-grigis/ralphctl",
|
|
6
6
|
"type": "module",
|
|
@@ -49,19 +49,19 @@
|
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"commander": "^15.0.0",
|
|
51
51
|
"cross-spawn": "^7.0.6",
|
|
52
|
-
"ink": "^
|
|
52
|
+
"ink": "^8.0.0",
|
|
53
53
|
"proper-lockfile": "^4.1.2",
|
|
54
54
|
"react": "^19.3.0",
|
|
55
55
|
"typescript-result": "^3.5.2",
|
|
56
|
-
"zod": "^4.6.
|
|
56
|
+
"zod": "^4.6.7"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@eslint/js": "^10.0.1",
|
|
60
60
|
"@types/cross-spawn": "^6.0.6",
|
|
61
|
-
"@types/node": "^26.6.
|
|
61
|
+
"@types/node": "^26.6.5",
|
|
62
62
|
"@types/proper-lockfile": "^4.1.4",
|
|
63
63
|
"@types/react": "^19.3.0",
|
|
64
|
-
"@vitest/coverage-v8": "^5.0.
|
|
64
|
+
"@vitest/coverage-v8": "^5.0.4",
|
|
65
65
|
"eslint": "^10.11.0",
|
|
66
66
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
67
67
|
"eslint-plugin-sonarjs": "^4.2.0",
|
|
@@ -71,13 +71,13 @@
|
|
|
71
71
|
"jiti": "^2.7.0",
|
|
72
72
|
"knip": "^6.37.0",
|
|
73
73
|
"lint-staged": "^17.5.0",
|
|
74
|
-
"prettier": "^3.9.
|
|
75
|
-
"tsup": "^
|
|
74
|
+
"prettier": "^3.9.10",
|
|
75
|
+
"tsup": "^9.0.0",
|
|
76
76
|
"tsx": "^4.23.15",
|
|
77
77
|
"typescript": "^6.0.3",
|
|
78
|
-
"typescript-eslint": "^8.
|
|
78
|
+
"typescript-eslint": "^8.71.2",
|
|
79
79
|
"vite": "^8.2.2",
|
|
80
|
-
"vitest": "^5.0.
|
|
80
|
+
"vitest": "^5.0.4"
|
|
81
81
|
},
|
|
82
82
|
"lint-staged": {
|
|
83
83
|
"*.{ts,tsx}": [
|
|
@@ -90,6 +90,7 @@
|
|
|
90
90
|
"build": "tsup && tsx scripts/build-assets.ts",
|
|
91
91
|
"dev": "NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 tsx src/index.ts",
|
|
92
92
|
"mock": "tsx scripts/seed-mock.ts",
|
|
93
|
+
"demo:record": "NODE_ENV=production tsx scripts/record-demo.ts",
|
|
93
94
|
"dev:heap-snapshot": "mkdir -p .diagnostics && NODE_OPTIONS='--max-old-space-size=8192 --heapsnapshot-near-heap-limit=2 --diagnostic-dir=.diagnostics' tsx src/index.ts",
|
|
94
95
|
"start": "NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 tsx src/index.ts",
|
|
95
96
|
"typecheck": "tsc",
|
|
@@ -100,7 +101,6 @@
|
|
|
100
101
|
"test:watch": "vitest",
|
|
101
102
|
"coverage": "vitest run --coverage",
|
|
102
103
|
"verify:coverage": "pnpm coverage",
|
|
103
|
-
"coverage:unused": "tsx scripts/find-unused.ts",
|
|
104
104
|
"deadcode": "knip",
|
|
105
105
|
"skills:update": "tsx scripts/sync-skills.ts",
|
|
106
106
|
"eval": "tsx scripts/eval/main.ts",
|