ralphctl 0.2.1 → 0.2.3

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.
Files changed (28) hide show
  1. package/README.md +104 -86
  2. package/dist/{add-SEDQ3VK7.mjs → add-DWNLZQ7Q.mjs} +4 -4
  3. package/dist/{add-TGJTRHIF.mjs → add-K7LNOYQ4.mjs} +3 -3
  4. package/dist/{chunk-LG6B7QVO.mjs → chunk-7TBO6GOT.mjs} +1 -1
  5. package/dist/{chunk-ZDEVRTGY.mjs → chunk-GLDPHKEW.mjs} +9 -0
  6. package/dist/{chunk-KPTPKLXY.mjs → chunk-ITRZMBLJ.mjs} +1 -1
  7. package/dist/{chunk-Q3VWJARJ.mjs → chunk-LAERLCL5.mjs} +2 -2
  8. package/dist/{chunk-AXNZMHFQ.mjs → chunk-ORVGM6EV.mjs} +80 -18
  9. package/dist/{chunk-XPDI4SYI.mjs → chunk-QYF7QIZJ.mjs} +3 -3
  10. package/dist/{chunk-XQHEKKDN.mjs → chunk-V4ZUDZCG.mjs} +1 -1
  11. package/dist/cli.mjs +105 -16
  12. package/dist/{create-DJHCP7LN.mjs → create-5MILNF7E.mjs} +3 -3
  13. package/dist/{handle-CCTBNAJZ.mjs → handle-2BACSJLR.mjs} +1 -1
  14. package/dist/{project-ZYGNPVGL.mjs → project-XC7AXA4B.mjs} +2 -2
  15. package/dist/prompts/ideate-auto.md +15 -5
  16. package/dist/prompts/ideate.md +28 -12
  17. package/dist/prompts/plan-auto.md +27 -17
  18. package/dist/prompts/plan-common.md +67 -22
  19. package/dist/prompts/plan-interactive.md +26 -27
  20. package/dist/prompts/task-evaluation.md +149 -23
  21. package/dist/prompts/task-execution.md +60 -37
  22. package/dist/prompts/ticket-refine.md +25 -21
  23. package/dist/{resolver-L52KR4GY.mjs → resolver-CFY6DIOP.mjs} +2 -2
  24. package/dist/{sprint-LUXAV3Q3.mjs → sprint-F4VRAEWZ.mjs} +2 -2
  25. package/dist/{wizard-TFJXEYD2.mjs → wizard-RCQ4QQOL.mjs} +6 -6
  26. package/package.json +6 -6
  27. package/schemas/task-import.schema.json +7 -0
  28. package/schemas/tasks.schema.json +8 -0
@@ -4,20 +4,22 @@ You are a requirements analyst. Your goal is to produce a complete, implementati
4
4
  WHAT needs to be built, not HOW. You clarify ambiguity through focused questions and stop when acceptance criteria are
5
5
  unambiguous.
6
6
 
7
- ## Hard Constraints
7
+ <constraints>
8
8
 
9
- - Do NOT explore the codebase, reference files, or suggest implementations
10
- - Do NOT select affected repositories
11
- - Do NOT use technical jargon that assumes implementation details
12
- - Focus exclusively on requirements, acceptance criteria, and scope
9
+ - Focus exclusively on requirements, acceptance criteria, and scope — codebase exploration and repository selection
10
+ happen in a later planning phase, not here
11
+ - Frame requirements as observable behavior ("user can filter by date") rather than technical jargon ("add SQL WHERE
12
+ clause") implementation-agnostic specs give the planner maximum flexibility
13
13
 
14
- ## Common Interview Anti-Patterns
14
+ </constraints>
15
15
 
16
- - **Asking what the ticket already says** — Read the ticket first; only ask about gaps
17
- - **Over-specifying** — Constrain WHAT, not HOW (e.g., "must support undo" not "use command pattern")
16
+ ## Interview Anti-Patterns
17
+
18
+ - **Asking what the ticket already says** — read the ticket first; only ask about gaps
19
+ - **Over-specifying** — constrain WHAT, not HOW (e.g., "must support undo" not "use command pattern")
18
20
  - **Asking too many questions** — 3-6 focused questions is typical; stop when criteria are met
19
- - **Combining multiple concerns** — Each question should address one dimension
20
- - **Adding a freeform option** — Users get an automatic "Other" option; do not add your own
21
+ - **Combining multiple concerns** — each question should address one dimension
22
+ - **Adding a freeform option** — users get an automatic "Other" option; do not add your own
21
23
 
22
24
  ## Protocol
23
25
 
@@ -76,16 +78,17 @@ Stop asking questions when ALL of these are true:
76
78
  2. Every functional requirement has at least one acceptance criterion
77
79
  3. Scope boundaries (in/out) are explicitly defined
78
80
  4. Major edge cases and error states are addressed
79
- 5. No remaining ambiguity that would cause two developers to implement differently
81
+ 5. No remaining ambiguity about what the feature should do — two developers reading these requirements would build the
82
+ same observable behavior
80
83
 
81
84
  If you find yourself asking questions the ticket already answers, you have gone too far. Move to Step 4.
82
85
 
83
86
  ### Step 4: Present Requirements for Approval
84
87
 
85
- **SHOW BEFORE WRITE.** Present the complete requirements in readable markdown. Use proper headers, bullets, and
86
- formatting. Make it easy to scan and review.
88
+ Present the complete requirements in readable markdown before writing to file — the user must see and approve them first.
89
+ Use proper headers, bullets, and formatting. Make it easy to scan and review.
87
90
 
88
- Then ask for approval using AskUserQuestion:
91
+ Ask for approval using AskUserQuestion:
89
92
 
90
93
  ```
91
94
  Question: "Does this look correct? Any changes needed?"
@@ -105,16 +108,17 @@ approval. Iterate until approved.
105
108
  Before writing to file, verify ALL of these are true:
106
109
 
107
110
  - [ ] Problem statement is clear and agreed upon
108
- - [ ] Every requirement has 2+ acceptance criteria with multiple scenarios each (happy path + edge case minimum)
111
+ - [ ] Every requirement has acceptance criteria covering key scenarios (happy path + edge/error cases at minimum)
109
112
  - [ ] Scope boundaries are explicit (what's in AND what's out)
110
113
  - [ ] Edge cases and error states are addressed
111
114
  - [ ] No implementation details leaked into requirements
112
115
  - [ ] Given/When/Then format used where possible
113
116
  - [ ] Multi-topic tickets use numbered headings (# 1., # 2., etc.)
114
117
 
115
- ### Step 6: Write to File (Only After User Confirms)
118
+ ### Step 6: Write to File
116
119
 
117
- **ONLY AFTER the user explicitly approves**, write the requirements to the output file.
120
+ Write the requirements to the output file after the user approves. Do not write before approval the user needs to
121
+ validate completeness and correctness first.
118
122
 
119
123
  ## Asking Clarifying Questions
120
124
 
@@ -168,10 +172,10 @@ Options:
168
172
 
169
173
  Write to: {{OUTPUT_FILE}}
170
174
 
171
- **IMPORTANT:** Output exactly ONE JSON object in the array for this ticket. If the ticket covers multiple sub-topics (
172
- e.g., map fixes, route planning, UI layout), consolidate them into a single `requirements` string using numbered
173
- markdown headings (`# 1. Topic`, `# 2. Topic`, etc.) separated by `---` dividers. Do NOT output multiple JSON objects
174
- for the same ticket.
175
+ Output exactly one JSON object in the array for this ticket. If the ticket covers multiple sub-topics (e.g., map fixes,
176
+ route planning, UI layout), consolidate them into a single `requirements` string using numbered markdown headings
177
+ (`# 1. Topic`, `# 2. Topic`, etc.) separated by `---` dividers. Multiple JSON objects for the same ticket will break
178
+ the import pipeline.
175
179
 
176
180
  JSON Schema:
177
181
 
@@ -11,7 +11,7 @@ var dynamicResolvers = {
11
11
  "--project": async () => {
12
12
  const result = await wrapAsync(
13
13
  async () => {
14
- const { listProjects } = await import("./project-ZYGNPVGL.mjs");
14
+ const { listProjects } = await import("./project-XC7AXA4B.mjs");
15
15
  return listProjects();
16
16
  },
17
17
  (err) => new IOError("Failed to load projects for completion", err instanceof Error ? err : void 0)
@@ -45,7 +45,7 @@ var configValueCompletions = {
45
45
  async function getSprintCompletions() {
46
46
  const result = await wrapAsync(
47
47
  async () => {
48
- const { listSprints } = await import("./sprint-LUXAV3Q3.mjs");
48
+ const { listSprints } = await import("./sprint-F4VRAEWZ.mjs");
49
49
  return listSprints();
50
50
  },
51
51
  (err) => new IOError("Failed to load sprints for completion", err instanceof Error ? err : void 0)
@@ -12,9 +12,9 @@ import {
12
12
  listSprints,
13
13
  resolveSprintId,
14
14
  saveSprint
15
- } from "./chunk-KPTPKLXY.mjs";
15
+ } from "./chunk-ITRZMBLJ.mjs";
16
16
  import "./chunk-OEUJDSHY.mjs";
17
- import "./chunk-ZDEVRTGY.mjs";
17
+ import "./chunk-GLDPHKEW.mjs";
18
18
  import {
19
19
  NoCurrentSprintError,
20
20
  SprintNotFoundError,
@@ -3,25 +3,25 @@ import {
3
3
  sprintPlanCommand,
4
4
  sprintRefineCommand,
5
5
  sprintStartCommand
6
- } from "./chunk-AXNZMHFQ.mjs";
6
+ } from "./chunk-ORVGM6EV.mjs";
7
7
  import "./chunk-7LZ6GOGN.mjs";
8
8
  import {
9
9
  sprintCreateCommand
10
- } from "./chunk-XQHEKKDN.mjs";
10
+ } from "./chunk-V4ZUDZCG.mjs";
11
11
  import {
12
12
  addSingleTicketInteractive
13
- } from "./chunk-XPDI4SYI.mjs";
13
+ } from "./chunk-QYF7QIZJ.mjs";
14
14
  import "./chunk-7TG3EAQ2.mjs";
15
- import "./chunk-LG6B7QVO.mjs";
15
+ import "./chunk-7TBO6GOT.mjs";
16
16
  import {
17
17
  getCurrentSprint,
18
18
  getSprint
19
- } from "./chunk-KPTPKLXY.mjs";
19
+ } from "./chunk-ITRZMBLJ.mjs";
20
20
  import {
21
21
  ensureError,
22
22
  wrapAsync
23
23
  } from "./chunk-OEUJDSHY.mjs";
24
- import "./chunk-ZDEVRTGY.mjs";
24
+ import "./chunk-GLDPHKEW.mjs";
25
25
  import "./chunk-EDJX7TT6.mjs";
26
26
  import {
27
27
  colors,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ralphctl",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Agent harness for long-running AI coding tasks — orchestrates Claude Code & GitHub Copilot across repositories",
5
5
  "homepage": "https://github.com/lukas-grigis/ralphctl",
6
6
  "type": "module",
@@ -50,10 +50,10 @@
50
50
  },
51
51
  "devDependencies": {
52
52
  "@eslint/js": "^10.0.1",
53
- "@types/node": "^25.5.0",
53
+ "@types/node": "^25.5.2",
54
54
  "@types/tabtab": "^3.0.4",
55
- "@vitest/coverage-v8": "^4.1.1",
56
- "eslint": "^10.1.0",
55
+ "@vitest/coverage-v8": "^4.1.2",
56
+ "eslint": "^10.2.0",
57
57
  "eslint-config-prettier": "^10.1.8",
58
58
  "globals": "^17.4.0",
59
59
  "husky": "^9.1.7",
@@ -62,8 +62,8 @@
62
62
  "tsup": "^8.5.1",
63
63
  "tsx": "^4.21.0",
64
64
  "typescript": "^5.9.3",
65
- "typescript-eslint": "^8.57.2",
66
- "vitest": "^4.1.1"
65
+ "typescript-eslint": "^8.58.0",
66
+ "vitest": "^4.1.2"
67
67
  },
68
68
  "lint-staged": {
69
69
  "*.ts": [
@@ -24,6 +24,13 @@
24
24
  "type": "string"
25
25
  }
26
26
  },
27
+ "verificationCriteria": {
28
+ "type": "array",
29
+ "description": "Definition-of-done checks used to evaluate task completion",
30
+ "items": {
31
+ "type": "string"
32
+ }
33
+ },
27
34
  "ticketId": {
28
35
  "type": "string",
29
36
  "description": "Reference to parent ticket ID (e.g., TICKET-001)"
@@ -30,6 +30,14 @@
30
30
  "type": "string"
31
31
  }
32
32
  },
33
+ "verificationCriteria": {
34
+ "type": "array",
35
+ "default": [],
36
+ "description": "Definition-of-done checks used to evaluate task completion",
37
+ "items": {
38
+ "type": "string"
39
+ }
40
+ },
33
41
  "status": {
34
42
  "type": "string",
35
43
  "enum": ["todo", "in_progress", "done"],