ralphctl 0.8.5 → 0.9.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 +79 -55
- package/dist/cli.mjs +4063 -2408
- package/dist/manifest.json +2 -1
- package/dist/prompts/distill-learnings/template.md +98 -0
- package/dist/prompts/implement/template.md +3 -1
- package/dist/skills/ralphctl-abstraction-first/SKILL.md +1 -0
- package/dist/skills/ralphctl-iterative-review/SKILL.md +1 -0
- package/package.json +6 -2
package/dist/manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
|
-
"generatedAt": "2026-
|
|
3
|
+
"generatedAt": "2026-06-01T11:52:30.706Z",
|
|
4
4
|
"assets": [
|
|
5
5
|
"prompts/_partials/conventions-agents-md.md",
|
|
6
6
|
"prompts/_partials/conventions-claude-md.md",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"prompts/create-pr/template.md",
|
|
13
13
|
"prompts/detect-scripts/template.md",
|
|
14
14
|
"prompts/detect-skills/template.md",
|
|
15
|
+
"prompts/distill-learnings/template.md",
|
|
15
16
|
"prompts/evaluate/template.md",
|
|
16
17
|
"prompts/ideate/template.md",
|
|
17
18
|
"prompts/implement/template.md",
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<role>
|
|
2
|
+
You are an AI coding agent performing a single-shot documentation edit. Your sole job for this call is to
|
|
3
|
+
fold a set of curated, machine-collected learnings into this project's existing context file —
|
|
4
|
+
`{{TARGET_FILENAME}}` — so that future AI sessions on this repository inherit what earlier sessions
|
|
5
|
+
discovered. You are an editor, not a researcher; every learning has already been produced and reviewed.
|
|
6
|
+
Your job is to integrate them cleanly, not to invent new ones.
|
|
7
|
+
</role>
|
|
8
|
+
|
|
9
|
+
<goal>
|
|
10
|
+
Update `{{TARGET_FILENAME}}` so that it carries an up-to-date `## Learnings (ralphctl)` section containing
|
|
11
|
+
the candidate learnings below — folded in idempotently, preserving everything else in the file verbatim.
|
|
12
|
+
</goal>
|
|
13
|
+
|
|
14
|
+
<inputs>
|
|
15
|
+
<target_filename>{{TARGET_FILENAME}}</target_filename>
|
|
16
|
+
|
|
17
|
+
<existing_context_file>
|
|
18
|
+
{{EXISTING_CONTEXT_FILE}}
|
|
19
|
+
</existing_context_file>
|
|
20
|
+
|
|
21
|
+
<candidate_learnings>
|
|
22
|
+
{{CANDIDATE_LEARNINGS}}
|
|
23
|
+
</candidate_learnings>
|
|
24
|
+
</inputs>
|
|
25
|
+
|
|
26
|
+
{{HARNESS_CONTEXT}}
|
|
27
|
+
|
|
28
|
+
<owned_section>
|
|
29
|
+
You own exactly one section of `{{TARGET_FILENAME}}` — the one headed `## Learnings (ralphctl)`. This is
|
|
30
|
+
the only part of the file you may add, reorder, or rewrite. Everything outside that section is
|
|
31
|
+
hand-authored or owned by another tool — preserve it byte-for-byte.
|
|
32
|
+
|
|
33
|
+
- When the file already contains a `## Learnings (ralphctl)` section, treat its current bullets as the
|
|
34
|
+
prior state and reconcile the candidates against them (see the idempotency rule below).
|
|
35
|
+
- When the file has no such section yet, append one at the end of the file — after the last existing
|
|
36
|
+
section, separated by a single blank line.
|
|
37
|
+
- Never create a second `## Learnings (ralphctl)` section — there must be exactly one.
|
|
38
|
+
</owned_section>
|
|
39
|
+
|
|
40
|
+
<idempotency_rule>
|
|
41
|
+
The folding MUST be idempotent — running this call twice on the same inputs leaves the file identical the
|
|
42
|
+
second time:
|
|
43
|
+
|
|
44
|
+
- A candidate learning whose meaning already appears as a bullet in the owned section is a no-op — do not
|
|
45
|
+
duplicate it, even when the wording differs slightly.
|
|
46
|
+
- A candidate that restates an existing bullet more precisely replaces that bullet rather than adding a
|
|
47
|
+
second one.
|
|
48
|
+
- Genuinely new candidates are appended as new bullets.
|
|
49
|
+
- Existing bullets that no candidate touches stay exactly as they are.
|
|
50
|
+
</idempotency_rule>
|
|
51
|
+
|
|
52
|
+
<curation_rules>
|
|
53
|
+
|
|
54
|
+
**Faithfulness.** Each candidate is a learning a prior session recorded — fold its substance in, lightly
|
|
55
|
+
edited for clarity and tense, but do not change its claim. Do not add learnings that are not in the
|
|
56
|
+
candidate list.
|
|
57
|
+
|
|
58
|
+
**Format.** Each learning is a bold Insight bullet — a single sentence, present tense, second-person or
|
|
59
|
+
imperative voice ("Prefer X over Y", "The build emits Z") — optionally followed by indented `Context:` and
|
|
60
|
+
`Applies to:` sub-bullets when the candidate supplies them:
|
|
61
|
+
|
|
62
|
+
- **The build emits ESM only; no CJS entrypoint.**
|
|
63
|
+
- Context: wiring a downstream require()
|
|
64
|
+
- Applies to: packaging
|
|
65
|
+
|
|
66
|
+
Carry a candidate's context / applies-to into the sub-bullets when it has them; omit a sub-bullet when the
|
|
67
|
+
candidate omits it. Keep the Insight bold so the section scans at a glance.
|
|
68
|
+
|
|
69
|
+
**Conciseness.** Drop a candidate that is vague, project-agnostic, or already implied by the file's
|
|
70
|
+
hand-authored guidance — "be careful" is noise. A learning earns its bullet only by telling the next
|
|
71
|
+
session something specific it would not otherwise know.
|
|
72
|
+
|
|
73
|
+
**Tooling references.** When a learning names a build, test, or task command, phrase it against this
|
|
74
|
+
project's tooling — described here:
|
|
75
|
+
|
|
76
|
+
<project_tooling>
|
|
77
|
+
{{PROJECT_TOOLING}}
|
|
78
|
+
</project_tooling>
|
|
79
|
+
|
|
80
|
+
Reference the actual commands that section names; do not substitute commands from another ecosystem. When
|
|
81
|
+
the section is empty, describe the action in prose rather than guessing a command.
|
|
82
|
+
|
|
83
|
+
**Repository conventions.** Reference repository convention directories — such as a `.claude/` directory —
|
|
84
|
+
as "when present"; many repositories do not have one, and a learning must not assume it exists.
|
|
85
|
+
|
|
86
|
+
</curation_rules>
|
|
87
|
+
|
|
88
|
+
<output_contract>
|
|
89
|
+
|
|
90
|
+
1. Read the existing context file body above and locate the `## Learnings (ralphctl)` section, if any.
|
|
91
|
+
2. Reconcile the candidate learnings against the owned section per the idempotency rule.
|
|
92
|
+
3. Write the COMPLETE, updated `{{TARGET_FILENAME}}` back to disk at its original path — the full file, not
|
|
93
|
+
a diff and not only the section. Everything outside the owned section must be unchanged.
|
|
94
|
+
|
|
95
|
+
Make no other edits to the repository. Emit no prose commentary outside the file you write — the harness
|
|
96
|
+
reads the file from disk, not your message.
|
|
97
|
+
|
|
98
|
+
</output_contract>
|
|
@@ -89,7 +89,9 @@ sprint.
|
|
|
89
89
|
changes the behaviour the test asserts. Removing a test to make verify pass counts as task failure.
|
|
90
90
|
- **Do not write to the progress file.** The harness regenerates it from your signals after every
|
|
91
91
|
round; anything you write there is overwritten within seconds. Emit `change`, `learning`, `note`,
|
|
92
|
-
and `decision` signals instead — the harness merges them into the per-task sections.
|
|
92
|
+
and `decision` signals instead — the harness merges them into the per-task sections. A `learning`
|
|
93
|
+
carries an insight plus OPTIONAL context (when / why it arose) and applies-to (where it applies —
|
|
94
|
+
a repo area, task kind, or subsystem).
|
|
93
95
|
- **No sprint-local identifiers in committed artefacts.** Do not mention acceptance-criterion labels
|
|
94
96
|
(`AC1`, `AC2`), ticket numbers, task IDs, or sprint IDs in source files, comments, docstrings, test
|
|
95
97
|
names, commit messages, or any other committed artefact. These identifiers are ephemeral sprint
|
|
@@ -6,6 +6,7 @@ description: Cross-phase skill — design the shape of the change (entities, bou
|
|
|
6
6
|
# Abstraction-First
|
|
7
7
|
|
|
8
8
|
> Concept
|
|
9
|
+
>
|
|
9
10
|
> from [Martin Fowler — "Abstraction-First"](https://martinfowler.com/articles/structured-prompt-driven/abstraction-first.html).
|
|
10
11
|
> Adapted for ralphctl's three phases.
|
|
11
12
|
|
|
@@ -6,6 +6,7 @@ description: Cross-phase skill — treat AI output as a controlled feedback loop
|
|
|
6
6
|
# Iterative Review
|
|
7
7
|
|
|
8
8
|
> Concept
|
|
9
|
+
>
|
|
9
10
|
> from [Martin Fowler — "Iterative Review"](https://martinfowler.com/articles/structured-prompt-driven/iterative-review.html).
|
|
10
11
|
> Adapted for ralphctl's three phases.
|
|
11
12
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ralphctl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Agent harness for long-running AI coding tasks — orchestrates Claude Code, GitHub Copilot, and OpenAI Codex across repositories",
|
|
5
5
|
"homepage": "https://github.com/lukas-grigis/ralphctl",
|
|
6
6
|
"type": "module",
|
|
@@ -38,15 +38,19 @@
|
|
|
38
38
|
"node": ">=24.0.0"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"commander": "^
|
|
41
|
+
"commander": "^15.0.0",
|
|
42
|
+
"cross-spawn": "^7.0.6",
|
|
42
43
|
"ink": "^7.0.3",
|
|
44
|
+
"proper-lockfile": "^4.1.2",
|
|
43
45
|
"react": "^19.2.6",
|
|
44
46
|
"typescript-result": "^3.5.2",
|
|
45
47
|
"zod": "^4.4.3"
|
|
46
48
|
},
|
|
47
49
|
"devDependencies": {
|
|
48
50
|
"@eslint/js": "^10.0.1",
|
|
51
|
+
"@types/cross-spawn": "^6.0.6",
|
|
49
52
|
"@types/node": "^25.8.0",
|
|
53
|
+
"@types/proper-lockfile": "^4.1.4",
|
|
50
54
|
"@types/react": "^19.2.14",
|
|
51
55
|
"@vitest/coverage-v8": "^4.1.6",
|
|
52
56
|
"eslint": "^10.4.0",
|