ccsetup 1.2.0 → 1.2.1

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,12 +1,12 @@
1
1
  #!/bin/bash
2
2
  # Ralph Wiggum - Long-running AI agent loop
3
- # Usage: ./ralph.sh [--tool amp|claude] [--model opus|sonnet|haiku] [max_iterations]
3
+ # Usage: ./ralph.sh [--tool claude|codex] [--model <model>] [max_iterations]
4
4
 
5
5
  set -e
6
6
 
7
7
  # Parse arguments
8
- TOOL="amp" # Default to amp for backwards compatibility
9
- MODEL="" # Model for claude (opus, sonnet, haiku)
8
+ TOOL="claude"
9
+ MODEL=""
10
10
  MAX_ITERATIONS=10
11
11
 
12
12
  while [[ $# -gt 0 ]]; do
@@ -38,8 +38,8 @@ while [[ $# -gt 0 ]]; do
38
38
  done
39
39
 
40
40
  # Validate tool choice
41
- if [[ "$TOOL" != "amp" && "$TOOL" != "claude" ]]; then
42
- echo "Error: Invalid tool '$TOOL'. Must be 'amp' or 'claude'."
41
+ if [[ "$TOOL" != "claude" && "$TOOL" != "codex" ]]; then
42
+ echo "Error: Invalid tool '$TOOL'. Must be 'claude' or 'codex'."
43
43
  exit 1
44
44
  fi
45
45
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@@ -47,6 +47,25 @@ PRD_FILE="$SCRIPT_DIR/prd.json"
47
47
  PROGRESS_FILE="$SCRIPT_DIR/progress.txt"
48
48
  ARCHIVE_DIR="$SCRIPT_DIR/archive"
49
49
  LAST_BRANCH_FILE="$SCRIPT_DIR/.last-branch"
50
+ CLAUDE_PROMPT_FILE="$SCRIPT_DIR/CLAUDE.md"
51
+ CODEX_PROMPT_FILE="$SCRIPT_DIR/CODEX.md"
52
+
53
+ if ! command -v jq &>/dev/null; then
54
+ echo "Error: jq is required for Ralph. Install jq and try again."
55
+ exit 1
56
+ fi
57
+
58
+ if [[ "$TOOL" == "claude" ]]; then
59
+ if ! command -v claude &>/dev/null; then
60
+ echo "Error: claude CLI is not installed. Install Claude Code and try again."
61
+ exit 1
62
+ fi
63
+ else
64
+ if ! command -v codex &>/dev/null; then
65
+ echo "Error: codex CLI is not installed. Install it with: npm install -g @openai/codex"
66
+ exit 1
67
+ fi
68
+ fi
50
69
 
51
70
  # Archive previous run if branch changed
52
71
  if [ -f "$PRD_FILE" ] && [ -f "$LAST_BRANCH_FILE" ]; then
@@ -98,15 +117,19 @@ for i in $(seq 1 $MAX_ITERATIONS); do
98
117
  echo "==============================================================="
99
118
 
100
119
  # Run the selected tool with the ralph prompt
101
- if [[ "$TOOL" == "amp" ]]; then
102
- OUTPUT=$(cat "$SCRIPT_DIR/prompt.md" | amp --dangerously-allow-all 2>&1 | tee /dev/stderr) || true
103
- else
120
+ if [[ "$TOOL" == "claude" ]]; then
104
121
  # Claude Code: use --dangerously-skip-permissions for autonomous operation, --print for output
105
122
  MODEL_FLAG=""
106
123
  if [[ -n "$MODEL" ]]; then
107
124
  MODEL_FLAG="--model $MODEL"
108
125
  fi
109
- OUTPUT=$(claude $MODEL_FLAG --dangerously-skip-permissions --chrome --print < "$SCRIPT_DIR/CLAUDE.md" 2>&1 | tee /dev/stderr) || true
126
+ OUTPUT=$(claude $MODEL_FLAG --dangerously-skip-permissions --chrome --print < "$CLAUDE_PROMPT_FILE" 2>&1 | tee /dev/stderr) || true
127
+ else
128
+ CMD_ARGS=()
129
+ if [[ -n "$MODEL" ]]; then
130
+ CMD_ARGS+=(--model "$MODEL")
131
+ fi
132
+ OUTPUT=$(codex exec ${CMD_ARGS[@]+"${CMD_ARGS[@]}"} "$(<"$CODEX_PROMPT_FILE")" 2>&1 | tee /dev/stderr) || true
110
133
  fi
111
134
 
112
135
  # Check for completion signal
@@ -1,287 +0,0 @@
1
- class ContextGenerator {
2
- constructor(scanResults) {
3
- this.scanResults = scanResults;
4
- }
5
-
6
- generate() {
7
- return {
8
- overview: this.generateOverview(),
9
- techStack: this.generateTechStack(),
10
- commands: this.generateCommands(),
11
- structure: this.generateStructure(),
12
- patterns: this.generatePatterns(),
13
- context: this.generateImportantContext()
14
- };
15
- }
16
-
17
- generateOverview() {
18
- const { projectType, purpose, frameworks } = this.scanResults;
19
-
20
- if (purpose) {
21
- return purpose;
22
- }
23
-
24
- let overview = `This is a ${projectType || 'Unknown'} project`;
25
-
26
- if (frameworks && frameworks.length > 0) {
27
- overview += ` using ${frameworks.join(', ')}`;
28
- }
29
-
30
- overview += '.';
31
-
32
- return overview;
33
- }
34
-
35
- generateTechStack() {
36
- const techStack = {
37
- languages: [],
38
- frameworks: [],
39
- databases: [],
40
- devTools: [],
41
- testing: [],
42
- deployment: []
43
- };
44
-
45
- // All results now come from Claude Code
46
- if (this.scanResults.projectType) {
47
- techStack.languages.push(this.scanResults.projectType);
48
- }
49
-
50
- if (this.scanResults.frameworks && Array.isArray(this.scanResults.frameworks)) {
51
- techStack.frameworks.push(...this.scanResults.frameworks);
52
- }
53
-
54
- if (this.scanResults.dependencies) {
55
- if (this.scanResults.dependencies.runtime) {
56
- const dbPackages = ['mysql', 'postgresql', 'mongodb', 'redis', 'sqlite'];
57
-
58
- for (const dep of this.scanResults.dependencies.runtime) {
59
- if (dbPackages.some(db => dep.toLowerCase().includes(db))) {
60
- techStack.databases.push(dep);
61
- }
62
- }
63
- }
64
-
65
- if (this.scanResults.dependencies.dev) {
66
- const devToolPackages = ['eslint', 'prettier', 'webpack', 'rollup', 'vite'];
67
-
68
- for (const dep of this.scanResults.dependencies.dev) {
69
- if (devToolPackages.some(tool => dep.toLowerCase().includes(tool))) {
70
- techStack.devTools.push(dep);
71
- }
72
- }
73
- }
74
- }
75
-
76
- if (this.scanResults.patterns) {
77
- if (this.scanResults.patterns.testing) {
78
- techStack.testing.push(...this.scanResults.patterns.testing);
79
- }
80
-
81
- if (this.scanResults.patterns.deployment) {
82
- techStack.deployment.push(...this.scanResults.patterns.deployment);
83
- }
84
- }
85
-
86
- techStack.languages = [...new Set(techStack.languages)];
87
- techStack.frameworks = [...new Set(techStack.frameworks)];
88
- techStack.databases = [...new Set(techStack.databases)];
89
- techStack.devTools = [...new Set(techStack.devTools)];
90
- techStack.testing = [...new Set(techStack.testing)];
91
- techStack.deployment = [...new Set(techStack.deployment)];
92
-
93
- return techStack;
94
- }
95
-
96
- generateCommands() {
97
- const commands = {};
98
-
99
- // All results now come from Claude Code
100
- if (this.scanResults.commands && Array.isArray(this.scanResults.commands)) {
101
- commands.available = this.scanResults.commands.map(cmd => ({
102
- name: cmd.command,
103
- description: cmd.description,
104
- command: cmd.command
105
- }));
106
- }
107
-
108
- return commands;
109
- }
110
-
111
- generateStructure() {
112
- const structure = {
113
- overview: '',
114
- keyDirectories: []
115
- };
116
-
117
- if (this.scanResults.structure && Array.isArray(this.scanResults.structure)) {
118
- structure.keyDirectories = this.scanResults.structure.map(dir => ({
119
- name: dir.path,
120
- purpose: dir.purpose
121
- }));
122
-
123
- if (structure.keyDirectories.length > 0) {
124
- structure.overview = `Project organized into ${structure.keyDirectories.length} key directories`;
125
- }
126
- }
127
-
128
- return structure;
129
- }
130
-
131
- generatePatterns() {
132
- const patterns = {
133
- architecture: [],
134
- testing: [],
135
- deployment: []
136
- };
137
-
138
- if (this.scanResults.patterns) {
139
- if (this.scanResults.patterns.architecture) {
140
- patterns.architecture = this.scanResults.patterns.architecture.map(name => ({
141
- name,
142
- description: `${name} pattern detected`
143
- }));
144
- }
145
-
146
- if (this.scanResults.patterns.testing) {
147
- patterns.testing = this.scanResults.patterns.testing.map(name => ({
148
- name,
149
- description: `${name} testing framework`
150
- }));
151
- }
152
-
153
- if (this.scanResults.patterns.deployment) {
154
- patterns.deployment = this.scanResults.patterns.deployment.map(name => ({
155
- name,
156
- description: `${name} deployment method`
157
- }));
158
- }
159
- }
160
-
161
- return patterns;
162
- }
163
-
164
- generateImportantContext() {
165
- const context = [];
166
-
167
- if (this.scanResults.frameworks && this.scanResults.frameworks.length > 0) {
168
- context.push(`Primary frameworks: ${this.scanResults.frameworks.join(', ')}`);
169
- }
170
-
171
- if (this.scanResults.patterns && this.scanResults.patterns.architecture && this.scanResults.patterns.architecture.length > 0) {
172
- context.push(`Architecture: ${this.scanResults.patterns.architecture.join(', ')}`);
173
- }
174
-
175
- const hasDatabases = this.scanResults.dependencies &&
176
- this.scanResults.dependencies.runtime &&
177
- this.scanResults.dependencies.runtime.some(dep =>
178
- ['mysql', 'postgresql', 'mongodb', 'redis', 'sqlite'].some(db =>
179
- dep.toLowerCase().includes(db)
180
- )
181
- );
182
-
183
- if (hasDatabases) {
184
- context.push('Uses database connectivity');
185
- }
186
-
187
- if (this.scanResults.patterns && this.scanResults.patterns.deployment && this.scanResults.patterns.deployment.includes('Docker')) {
188
- context.push('Containerized with Docker');
189
- }
190
-
191
- return context;
192
- }
193
-
194
- formatForClaude() {
195
- const generated = this.generate();
196
- const sections = [];
197
-
198
- sections.push('\n## Additional Notes\n');
199
-
200
- if (generated.overview) {
201
- sections.push('### Project Overview');
202
- sections.push(generated.overview);
203
- sections.push('');
204
- }
205
-
206
- const techStack = generated.techStack;
207
- if (Object.values(techStack).some(arr => arr.length > 0)) {
208
- sections.push('### Tech Stack');
209
-
210
- if (techStack.languages.length > 0) {
211
- sections.push(`- **Languages**: ${techStack.languages.join(', ')}`);
212
- }
213
- if (techStack.frameworks.length > 0) {
214
- sections.push(`- **Frameworks**: ${techStack.frameworks.join(', ')}`);
215
- }
216
- if (techStack.databases.length > 0) {
217
- sections.push(`- **Databases**: ${techStack.databases.join(', ')}`);
218
- }
219
- if (techStack.devTools.length > 0 && techStack.devTools.length <= 8) {
220
- sections.push(`- **Dev Tools**: ${techStack.devTools.join(', ')}`);
221
- }
222
- if (techStack.testing.length > 0) {
223
- sections.push(`- **Testing**: ${techStack.testing.join(', ')}`);
224
- }
225
- if (techStack.deployment.length > 0) {
226
- sections.push(`- **Deployment**: ${techStack.deployment.join(', ')}`);
227
- }
228
- sections.push('');
229
- }
230
-
231
- const commands = generated.commands;
232
- if (commands.available && commands.available.length > 0) {
233
- sections.push('### Key Commands');
234
-
235
- for (const cmd of commands.available.slice(0, 10)) {
236
- sections.push(`- \`${cmd.command}\` - ${cmd.description}`);
237
- }
238
-
239
- sections.push('');
240
- }
241
-
242
- const structure = generated.structure;
243
- if (structure.keyDirectories.length > 0) {
244
- sections.push('### Project Structure');
245
-
246
- for (const dir of structure.keyDirectories.slice(0, 8)) {
247
- sections.push(`- \`${dir.name}\` - ${dir.purpose}`);
248
- }
249
- sections.push('');
250
- }
251
-
252
- const patterns = generated.patterns;
253
- const allPatterns = [
254
- ...patterns.architecture,
255
- ...patterns.testing,
256
- ...patterns.deployment
257
- ];
258
-
259
- if (allPatterns.length > 0) {
260
- sections.push('### Architecture & Patterns');
261
- for (const pattern of allPatterns.slice(0, 8)) {
262
- sections.push(`- **${pattern.name}**: ${pattern.description}`);
263
- }
264
- sections.push('');
265
- }
266
-
267
- if (generated.context.length > 0) {
268
- sections.push('### Important Context');
269
- for (const item of generated.context) {
270
- sections.push(`- ${item}`);
271
- }
272
- sections.push('');
273
- }
274
-
275
- const scanInfo = this.scanResults;
276
- if (scanInfo.scanDate) {
277
- sections.push('### Scan Information');
278
- sections.push(`- Analyzed using Claude Code AI`);
279
- sections.push(`- Last scanned: ${new Date(scanInfo.scanDate).toLocaleString()}`);
280
- sections.push('');
281
- }
282
-
283
- return sections.join('\n');
284
- }
285
- }
286
-
287
- module.exports = ContextGenerator;
@@ -1,28 +0,0 @@
1
- const ClaudeInterface = require('../claudeInterface');
2
-
3
- class RepositoryScanner {
4
- constructor(projectPath, options = {}) {
5
- this.projectPath = projectPath;
6
- this.options = options;
7
- this.claudeInterface = new ClaudeInterface(this.projectPath);
8
- }
9
-
10
- /**
11
- * Scan repository using ONLY Claude Code CLI
12
- */
13
- async scan() {
14
- // Check if Claude Code is available
15
- const isAvailable = await this.claudeInterface.isAvailable();
16
-
17
- if (!isAvailable) {
18
- throw new Error('Claude Code CLI is required but not found. Please install it first: npm install -g @anthropic-ai/claude-code');
19
- }
20
-
21
- console.log('✓ Claude Code detected, starting AI-powered analysis...');
22
-
23
- // Use Claude Code to scan the repository
24
- return await this.claudeInterface.scanRepository();
25
- }
26
- }
27
-
28
- module.exports = RepositoryScanner;