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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 1,
3
- "generatedAt": "2026-05-29T08:41:52.856Z",
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.8.5",
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": "^14.0.3",
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",