@arvorco/relentless 0.1.18 → 0.1.20

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.
@@ -12,9 +12,10 @@ Create a personalized project constitution that defines your team's coding princ
12
12
  ## The Job
13
13
 
14
14
  1. Ask the user about their project's coding philosophy and standards
15
- 2. Generate a personalized constitution based on their answers
16
- 3. Save to `relentless/constitution.md`
17
- 4. Ensure consistency with project templates and documentation
15
+ 2. Analyze the project structure and documentation
16
+ 3. Generate personalized constitution based on their answers → `relentless/constitution.md`
17
+ 4. Generate personalized agent prompt based on the same analysis → `relentless/prompt.md`
18
+ 5. Ensure consistency with project templates and documentation
18
19
 
19
20
  **Important:** The constitution is the foundation for all feature work - create this before generating features.
20
21
 
@@ -67,31 +68,126 @@ Load the template from `templates/constitution-template.md` and:
67
68
 
68
69
  ---
69
70
 
70
- ## Step 3: Validate & Save
71
+ ## Step 3: Analyze Project Structure
72
+
73
+ Read and analyze project documentation:
74
+
75
+ **Core Files:**
76
+ - `README.md` - Project overview, setup instructions
77
+ - `AGENTS.md` or `CLAUDE.md` - Developer guidelines
78
+ - `package.json` - Scripts, dependencies, tech stack
79
+ - `CONTRIBUTING.md` - Contribution workflow (if exists)
80
+
81
+ **Extract:**
82
+ - Tech stack (TypeScript, React, Node, etc.)
83
+ - Testing framework (vitest, jest, playwright)
84
+ - Quality commands (`typecheck`, `lint`, `test`)
85
+ - Build system (bun, npm, turbo, vite)
86
+ - Linting setup (eslint, biome)
87
+ - File structure patterns
88
+
89
+ ---
90
+
91
+ ## Step 4: Generate Personalized Prompt
92
+
93
+ Using the generic template from relentless, create a personalized `prompt.md` with:
94
+
95
+ **Section 1: Quality Gates**
96
+ ```markdown
97
+ ## CRITICAL: Quality Gates (Non-Negotiable)
98
+
99
+ Before marking ANY story as complete:
100
+
101
+ \`\`\`bash
102
+ # TypeScript (detected from package.json)
103
+ [actual typecheck command from package.json scripts]
104
+
105
+ # Linting (detected from package.json)
106
+ [actual lint command from package.json scripts]
107
+
108
+ # Tests (detected from package.json)
109
+ [actual test command from package.json scripts]
110
+ \`\`\`
111
+
112
+ **If ANY check fails, DO NOT mark the story as complete.**
113
+ ```
114
+
115
+ **Section 2: Project-Specific Patterns** (from README/AGENTS.md)
116
+ - Monorepo structure (if applicable)
117
+ - Component locations
118
+ - Test file patterns
119
+ - Database/backend info
120
+ - Styling approach
121
+
122
+ **Section 3: TDD Workflow** (if tests exist)
123
+ - Test-first workflow
124
+ - Test location patterns
125
+ - Test commands
126
+
127
+ **Section 4: Common Pitfalls** (from AGENTS.md/docs)
128
+ - Project-specific gotchas
129
+ - Known issues
130
+ - Best practices
131
+
132
+ **Footer:**
133
+ ```markdown
134
+ ---
135
+ **Personalized for [Project Name]**
136
+ **Generated:** [date]
137
+ **Re-generate:** /relentless.constitution
138
+ ```
139
+
140
+ Save to: `relentless/prompt.md`
141
+
142
+ ---
143
+
144
+ ## Step 5: Validate & Save
71
145
 
72
146
  Before saving:
73
- - No `[PLACEHOLDER]` tokens remain (unless explicitly marked as TODO)
147
+
148
+ **Constitution:**
149
+ - No `[PLACEHOLDER]` tokens remain
74
150
  - All dates in ISO format (YYYY-MM-DD)
75
151
  - Principles are declarative and testable
76
152
  - Version format is semantic (X.Y.Z)
77
153
 
78
- Save to: `relentless/constitution.md`
154
+ **Prompt:**
155
+ - All quality commands are actual commands from package.json
156
+ - File patterns match project structure
157
+ - No generic placeholders remain
158
+
159
+ Save both files:
160
+ - `relentless/constitution.md`
161
+ - `relentless/prompt.md`
79
162
 
80
163
  ---
81
164
 
82
- ## Step 4: Report
165
+ ## Step 6: Report
83
166
 
84
167
  Output summary:
85
- - Constitution version created
86
- - Number of principles defined
87
- - Key MUST/SHOULD rules
88
- - Next steps: "Now create your first feature with `/relentless.specify`"
168
+ ```
169
+ Created constitution.md
170
+ - Version: 1.0.0
171
+ - Principles: [count]
172
+ - Key rules: [summary]
173
+
174
+ ✓ Created prompt.md
175
+ - Quality gates: [count]
176
+ - Tech stack: [detected stack]
177
+ - Test framework: [detected]
178
+
179
+ Next steps:
180
+ 1. Review both files
181
+ 2. Create your first feature: /relentless.specify "feature description"
182
+ ```
89
183
 
90
184
  ---
91
185
 
92
- ## Updating Existing Constitution
186
+ ## Updating Existing Files
187
+
188
+ If `relentless/constitution.md` or `relentless/prompt.md` exist:
93
189
 
94
- If `relentless/constitution.md` exists:
190
+ **For Constitution Updates:**
95
191
  1. Load current version
96
192
  2. Ask what needs to change
97
193
  3. Increment version appropriately:
@@ -101,6 +197,15 @@ If `relentless/constitution.md` exists:
101
197
  4. Update `LAST_AMENDED_DATE` to today
102
198
  5. Add amendment notes at top
103
199
 
200
+ **For Prompt Updates:**
201
+ 1. Re-analyze project structure (package.json, docs)
202
+ 2. Detect any new quality commands or patterns
203
+ 3. Regenerate personalized sections
204
+ 4. Preserve any manual customizations in comments
205
+ 5. Update "Generated" date
206
+
207
+ **Both files can be regenerated at any time by running `/relentless.constitution` again.**
208
+
104
209
  ---
105
210
 
106
211
  ## Example Constitution Structure
package/README.md CHANGED
@@ -30,8 +30,11 @@ bun install -g github:ArvorCo/Relentless
30
30
  cd your-project
31
31
  relentless init
32
32
 
33
- # 3. Create constitution (personalized governance)
33
+ # 3. Create constitution and prompt (personalized governance + agent instructions)
34
34
  /relentless.constitution
35
+ # This creates BOTH:
36
+ # - relentless/constitution.md (project principles)
37
+ # - relentless/prompt.md (personalized agent instructions)
35
38
 
36
39
  # 4. Create feature specification
37
40
  /relentless.specify Add user authentication with OAuth2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arvorco/relentless",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "description": "Universal AI agent orchestrator - works with Claude Code, Amp, OpenCode, Codex, Droid, and Gemini",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -57,64 +57,64 @@ const RELENTLESS_FILES: Record<string, () => string> = {
57
57
 
58
58
  const PROMPT_TEMPLATE = `# Relentless Agent Instructions
59
59
 
60
- You are an autonomous coding agent working on a software project.
60
+ You are an autonomous coding agent. Follow these instructions exactly.
61
61
 
62
- ## Before You Start
62
+ **⚠️ This is a generic template. Personalize it for your project using:**
63
+ \`\`\`bash
64
+ /relentless.prompt
65
+ \`\`\`
66
+
67
+ ---
68
+
69
+ ## Your Task (Per Iteration)
63
70
 
64
- 1. **Review the codebase** - Understand the current state, architecture, and patterns
65
- 2. **Read progress.txt** - Check the Codebase Patterns section for learnings from previous iterations
66
- 3. **Read the PRD** - Understand what needs to be done
71
+ 1. Read \`relentless/features/<feature>/prd.json\`
72
+ 2. Read \`relentless/features/<feature>/progress.txt\`
73
+ 3. Check you're on the correct branch from PRD \`branchName\`
74
+ 4. Pick the **highest priority** story where \`passes: false\`
75
+ 5. Review existing code to understand patterns
76
+ 6. Implement the story
77
+ 7. Run quality checks (typecheck, lint, test)
78
+ 8. If ALL checks pass, commit: \`feat: [Story ID] - [Story Title]\`
79
+ 9. Update PRD: set \`passes: true\`
80
+ 10. Append progress to \`progress.txt\`
81
+
82
+ ---
83
+
84
+ ## Quality Requirements
67
85
 
68
- ## Your Task
86
+ Before marking a story complete:
87
+ - [ ] All quality checks pass (typecheck, lint, test)
88
+ - [ ] Zero errors and zero warnings
89
+ - [ ] No debug code (console.log, debugger)
90
+ - [ ] No unused imports or variables
91
+ - [ ] Follows existing patterns
69
92
 
70
- 1. Read the PRD at \`relentless/features/<feature>/prd.json\`
71
- 2. Read the progress log at \`relentless/features/<feature>/progress.txt\`
72
- 3. Check you're on the correct branch from PRD \`branchName\`. If not, check it out or create from main.
73
- 4. Pick the **highest priority** user story where \`passes: false\`
74
- 5. **Review relevant code** before implementing - understand existing patterns
75
- 6. Implement that single user story
76
- 7. Run quality checks (typecheck, lint, test - whatever your project requires)
77
- 8. If checks pass, commit ALL changes with message: \`feat: [Story ID] - [Story Title]\`
78
- 9. Update the PRD to set \`passes: true\` for the completed story
79
- 10. Append your progress to \`relentless/features/<feature>/progress.txt\`
93
+ ---
80
94
 
81
95
  ## Progress Report Format
82
96
 
83
- APPEND to progress.txt (never replace, always append):
97
+ APPEND to progress.txt:
84
98
  \`\`\`
85
99
  ## [Date/Time] - [Story ID]
86
100
  - What was implemented
87
101
  - Files changed
88
- - **Learnings for future iterations:**
89
- - Patterns discovered
90
- - Gotchas encountered
91
- - Useful context
102
+ - Learnings for future iterations
92
103
  ---
93
104
  \`\`\`
94
105
 
95
- ## Quality Requirements
96
-
97
- - ALL commits must pass your project's quality checks (typecheck, lint, test)
98
- - Do NOT commit broken code
99
- - Keep changes focused and minimal
100
- - Follow existing code patterns
101
- - Review code before modifying it
106
+ ---
102
107
 
103
108
  ## Stop Condition
104
109
 
105
- After completing a user story, check if ALL stories have \`passes: true\`.
110
+ After completing a story, check if ALL stories have \`passes: true\`.
106
111
 
107
- If ALL stories are complete and passing, reply with:
112
+ If ALL complete:
113
+ \`\`\`
108
114
  <promise>COMPLETE</promise>
115
+ \`\`\`
109
116
 
110
- If there are still stories with \`passes: false\`, end your response normally (another iteration will pick up the next story).
111
-
112
- ## Important
113
-
114
- - Work on ONE story per iteration
115
- - Review existing code before implementing
116
- - Commit frequently
117
- - Keep CI green
117
+ Otherwise, end normally (next iteration continues).
118
118
  `;
119
119
 
120
120
  /**
package/src/tui/App.tsx CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import React from "react";
8
- import { Box, Text } from "ink";
8
+ import { Box, Text, useStdout } from "ink";
9
9
  import { Header } from "./components/Header.js";
10
10
  import { ProgressBar } from "./components/ProgressBar.js";
11
11
  import { CurrentStory } from "./components/CurrentStory.js";
@@ -20,8 +20,23 @@ interface AppProps {
20
20
  }
21
21
 
22
22
  export function App({ state }: AppProps): React.ReactElement {
23
+ const { stdout } = useStdout();
24
+ const terminalRows = stdout.rows ?? 24;
25
+
23
26
  const completedCount = state.stories.filter((s) => s.passes).length;
24
27
  const totalCount = state.stories.length;
28
+
29
+ // Calculate available rows for stories based on terminal height
30
+ // Chrome: Header(2) + Feature/Progress(2) + CurrentStory(2) + AgentOutputHeader(1) + AgentStatusFooter(2) + Padding(2) = ~11 lines
31
+ // AgentOutput: 6 lines
32
+ // Remaining space for stories
33
+ const chromeHeight = 11;
34
+ const agentOutputLines = 6;
35
+ const availableForStories = Math.max(8, terminalRows - chromeHeight - agentOutputLines);
36
+
37
+ // Calculate story rows needed for 2-column layout
38
+ const storyRows = Math.ceil(totalCount / 2);
39
+ const maxStoryRows = Math.min(storyRows, availableForStories);
25
40
 
26
41
  return (
27
42
  <Box flexDirection="column" width="100%">
@@ -50,13 +65,13 @@ export function App({ state }: AppProps): React.ReactElement {
50
65
  </Box>
51
66
 
52
67
  {/* Agent output */}
53
- <AgentOutput lines={state.outputLines} maxLines={8} />
68
+ <AgentOutput lines={state.outputLines} maxLines={agentOutputLines} />
54
69
 
55
70
  {/* Story grid */}
56
71
  <StoryGrid
57
72
  stories={state.stories}
58
73
  currentStoryId={state.currentStory?.id}
59
- maxRows={8}
74
+ maxRows={maxStoryRows}
60
75
  />
61
76
 
62
77
  {/* Agent status footer */}
@@ -37,14 +37,43 @@ export function StoryGrid({
37
37
  rows.push(row);
38
38
  }
39
39
 
40
- // Constrain to maxRows
41
- const visibleRows = maxRows ? rows.slice(0, maxRows) : rows;
40
+ // Window around current story to show context
41
+ let visibleRows = rows;
42
+ let startRow = 0;
43
+ let endRow = rows.length;
44
+
45
+ if (maxRows && rows.length > maxRows) {
46
+ // Find the row containing the current story
47
+ const currentRowIdx = currentStoryId
48
+ ? rows.findIndex((row) => row.some((story) => story.id === currentStoryId))
49
+ : -1;
50
+
51
+ if (currentRowIdx >= 0) {
52
+ // Center the window around the current story
53
+ const half = Math.floor(maxRows / 2);
54
+ startRow = Math.max(0, currentRowIdx - half);
55
+
56
+ // Adjust if window goes past the end
57
+ if (startRow + maxRows > rows.length) {
58
+ startRow = Math.max(0, rows.length - maxRows);
59
+ }
60
+
61
+ endRow = Math.min(rows.length, startRow + maxRows);
62
+ visibleRows = rows.slice(startRow, endRow);
63
+ } else {
64
+ // No current story, just show first N rows
65
+ visibleRows = rows.slice(0, maxRows);
66
+ endRow = Math.min(rows.length, maxRows);
67
+ }
68
+ }
42
69
 
43
70
  return (
44
71
  <Box flexDirection="column" paddingY={1}>
45
72
  <Box paddingX={1}>
46
73
  <Text color={colors.dim} bold>
47
- ── Stories ({stories.length}) ──
74
+ {visibleRows.length < rows.length
75
+ ? `── Stories (rows ${startRow + 1}-${endRow} of ${rows.length}, ${stories.length} total) ──`
76
+ : `── Stories (${stories.length}) ──`}
48
77
  </Text>
49
78
  </Box>
50
79
  <Box flexDirection="column" paddingX={1}>