agentic-loop 3.13.0 → 3.14.2
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/.claude/skills/idea/SKILL.md +56 -0
- package/.claude/skills/loopgram/SKILL.md +19 -0
- package/.claude/skills/prd/SKILL.md +2 -0
- package/README.md +1 -0
- package/bin/ralph.sh +17 -11
- package/dist/loopgram/claude.d.ts +18 -0
- package/dist/loopgram/claude.d.ts.map +1 -0
- package/dist/loopgram/claude.js +89 -0
- package/dist/loopgram/claude.js.map +1 -0
- package/dist/loopgram/context-search.d.ts +26 -0
- package/dist/loopgram/context-search.d.ts.map +1 -0
- package/dist/loopgram/context-search.js +175 -0
- package/dist/loopgram/context-search.js.map +1 -0
- package/dist/loopgram/conversation.d.ts +39 -0
- package/dist/loopgram/conversation.d.ts.map +1 -0
- package/dist/loopgram/conversation.js +158 -0
- package/dist/loopgram/conversation.js.map +1 -0
- package/dist/loopgram/index.d.ts +3 -0
- package/dist/loopgram/index.d.ts.map +1 -0
- package/dist/loopgram/index.js +246 -0
- package/dist/loopgram/index.js.map +1 -0
- package/dist/loopgram/loop-monitor.d.ts +16 -0
- package/dist/loopgram/loop-monitor.d.ts.map +1 -0
- package/dist/loopgram/loop-monitor.js +149 -0
- package/dist/loopgram/loop-monitor.js.map +1 -0
- package/dist/loopgram/loop-runner.d.ts +28 -0
- package/dist/loopgram/loop-runner.d.ts.map +1 -0
- package/dist/loopgram/loop-runner.js +157 -0
- package/dist/loopgram/loop-runner.js.map +1 -0
- package/dist/loopgram/prd-generator.d.ts +37 -0
- package/dist/loopgram/prd-generator.d.ts.map +1 -0
- package/dist/loopgram/prd-generator.js +134 -0
- package/dist/loopgram/prd-generator.js.map +1 -0
- package/dist/loopgram/saver.d.ts +9 -0
- package/dist/loopgram/saver.d.ts.map +1 -0
- package/dist/loopgram/saver.js +35 -0
- package/dist/loopgram/saver.js.map +1 -0
- package/dist/loopgram/types.d.ts +37 -0
- package/dist/loopgram/types.d.ts.map +1 -0
- package/dist/loopgram/types.js +5 -0
- package/dist/loopgram/types.js.map +1 -0
- package/package.json +6 -2
- package/ralph/hooks/common.sh +89 -0
- package/ralph/hooks/warn-debug.sh +14 -32
- package/ralph/hooks/warn-empty-catch.sh +13 -29
- package/ralph/hooks/warn-secrets.sh +19 -37
- package/ralph/hooks/warn-urls.sh +17 -33
- package/ralph/loop.sh +5 -2
- package/ralph/prd-check.sh +35 -8
- package/ralph/setup/quick-setup.sh +25 -12
- package/ralph/setup/ui.sh +0 -42
- package/ralph/setup.sh +71 -46
- package/ralph/utils.sh +167 -31
- package/templates/config/fastmcp.json +6 -1
- package/templates/config/fullstack.json +8 -0
- package/templates/config/node.json +8 -0
- package/templates/config/python.json +8 -0
|
@@ -64,6 +64,12 @@ Help the user flesh out the idea through conversation:
|
|
|
64
64
|
- Caching needed? How fresh must data be?
|
|
65
65
|
- Database indexes: What will be queried/sorted frequently?
|
|
66
66
|
|
|
67
|
+
**Migration/Refactoring (IMPORTANT - ask if moving or restructuring code):**
|
|
68
|
+
- Source paths: Where does the code currently live?
|
|
69
|
+
- Destination paths: Where should it end up? (be explicit, not vague)
|
|
70
|
+
- Phases: What's the logical order? (move files → update imports → verify)
|
|
71
|
+
- Verification: What commands prove each phase worked?
|
|
72
|
+
|
|
67
73
|
### Step 3: Summarize Before Writing
|
|
68
74
|
|
|
69
75
|
When you have enough information, summarize what you've learned:
|
|
@@ -132,6 +138,36 @@ Once the user confirms, write the idea file:
|
|
|
132
138
|
- **Caching**: What can be cached? For how long?
|
|
133
139
|
- **Database**: What indexes are needed?
|
|
134
140
|
|
|
141
|
+
## Migration Mapping (if moving/restructuring code)
|
|
142
|
+
For refactoring or migration tasks, explicitly map source to destination:
|
|
143
|
+
|
|
144
|
+
| Source | Destination |
|
|
145
|
+
|--------|-------------|
|
|
146
|
+
| `~/Sites/old-project/src/` | `apps/new-location/src/` |
|
|
147
|
+
| `~/Sites/old-project/tests/` | `apps/new-location/tests/` |
|
|
148
|
+
|
|
149
|
+
## Phases & Verification
|
|
150
|
+
Break complex work into phases with explicit verification commands:
|
|
151
|
+
|
|
152
|
+
### Phase 1: [Name]
|
|
153
|
+
**What:** Description of what this phase accomplishes
|
|
154
|
+
**Exit Criteria:**
|
|
155
|
+
```bash
|
|
156
|
+
# These commands must pass before phase is complete
|
|
157
|
+
test -d apps/new-location/src
|
|
158
|
+
cd apps/new-location && uv run pytest -x
|
|
159
|
+
cd apps/new-location && npm run build
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Phase 2: [Name]
|
|
163
|
+
**What:** Description
|
|
164
|
+
**Exit Criteria:**
|
|
165
|
+
```bash
|
|
166
|
+
# Verification commands for phase 2
|
|
167
|
+
docker-compose config | grep -q 'service-name:'
|
|
168
|
+
curl -s http://localhost:8000/health | jq -e '.status == "ok"'
|
|
169
|
+
```
|
|
170
|
+
|
|
135
171
|
## UI Mockup (if applicable)
|
|
136
172
|
```
|
|
137
173
|
┌─────────────────────────────────┐
|
|
@@ -190,6 +226,26 @@ A good idea file has:
|
|
|
190
226
|
- **Specific solution** - Not vague ("improve UX") but concrete ("add inline validation")
|
|
191
227
|
- **Scope boundaries** - What's explicitly out of scope?
|
|
192
228
|
- **Architecture hints** - Where do files go? What patterns to follow?
|
|
229
|
+
- **Verification commands** - How do we know it worked? (executable commands, not prose)
|
|
230
|
+
|
|
231
|
+
### Migration/Refactoring Ideas
|
|
232
|
+
|
|
233
|
+
For ideas that involve moving or restructuring code, MUST include:
|
|
234
|
+
|
|
235
|
+
1. **Explicit path mapping** - Source → Destination for every directory
|
|
236
|
+
```
|
|
237
|
+
❌ "Move GOPA to apps folder"
|
|
238
|
+
✅ "~/Sites/gopa/src/gopa/ → apps/gopa/src/gopa/"
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
2. **Phase-based verification** - Each phase has exit criteria with commands
|
|
242
|
+
```
|
|
243
|
+
❌ "Verify everything still works"
|
|
244
|
+
✅ "cd apps/gopa && uv run pytest -x && uv run python -c 'from gopa.server import mcp'"
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
3. **Order of operations** - What must happen before what?
|
|
248
|
+
- Move files → Update imports → Update configs → Verify
|
|
193
249
|
|
|
194
250
|
### ASCII Art for UI
|
|
195
251
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Review and manage brainstorm ideas from Telegram
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Loopgram Review
|
|
6
|
+
|
|
7
|
+
Review ideas captured from Telegram via Loopgram.
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
- `/loopgram list` - Show all saved ideas
|
|
12
|
+
- `/loopgram review <name>` - Review and refine a specific idea
|
|
13
|
+
- `/loopgram prd <name>` - Convert idea to PRD for Ralph execution
|
|
14
|
+
|
|
15
|
+
## Workflow
|
|
16
|
+
|
|
17
|
+
1. List recent ideas: `ls docs/ideas/`
|
|
18
|
+
2. Read an idea: Read the file
|
|
19
|
+
3. If ready, run `/prd docs/ideas/{name}.md` to convert to executable PRD
|
|
@@ -156,6 +156,7 @@ Does acceptanceCriteria include:
|
|
|
156
156
|
- Does `contextFiles` include the idea file (has ASCII mockups)?
|
|
157
157
|
- Does `contextFiles` include styleguide (if exists)?
|
|
158
158
|
- Is `testUrl` set?
|
|
159
|
+
- Is `mcp` set to `["playwright", "devtools"]`?
|
|
159
160
|
|
|
160
161
|
**Fix any issues you find:**
|
|
161
162
|
|
|
@@ -168,6 +169,7 @@ Does acceptanceCriteria include:
|
|
|
168
169
|
| List endpoint missing pagination | Add pagination criteria to acceptanceCriteria |
|
|
169
170
|
| Frontend missing contextFiles | Add idea file + styleguide paths |
|
|
170
171
|
| Frontend missing testUrl | Add URL from config |
|
|
172
|
+
| Frontend missing mcp | Add `"mcp": ["playwright", "devtools"]` |
|
|
171
173
|
|
|
172
174
|
### Step 7: Reorder if Needed
|
|
173
175
|
|
package/README.md
CHANGED
|
@@ -86,6 +86,7 @@ npx agentic-loop run # Execute PRDs autonomously
|
|
|
86
86
|
- [How Ralph Works](docs/RALPH.md) - Architecture, config, full reference
|
|
87
87
|
- [Cheatsheet](docs/CHEATSHEET.md) - All commands at a glance
|
|
88
88
|
- [Hooks Reference](docs/HOOKS.md) - Pre-commit and Claude Code hooks
|
|
89
|
+
- [Loopgram](docs/LOOPGRAM.md) - Telegram bot for mobile idea capture and loop monitoring
|
|
89
90
|
- [Troubleshooting](docs/TROUBLESHOOTING.md) - Common issues and fixes
|
|
90
91
|
- [Contributing](docs/CONTRIBUTING.md) - How to contribute
|
|
91
92
|
|
package/bin/ralph.sh
CHANGED
|
@@ -61,13 +61,22 @@ if [[ ! -f ".ralph/config.json" ]]; then
|
|
|
61
61
|
_project_type="node"
|
|
62
62
|
fi
|
|
63
63
|
|
|
64
|
+
# Check user template override first
|
|
65
|
+
_user_template="$HOME/.config/ralph/templates/config/${_project_type}.json"
|
|
64
66
|
_config_template="$RALPH_TEMPLATES/config/${_project_type}.json"
|
|
65
|
-
|
|
67
|
+
|
|
68
|
+
if [[ -f "$_user_template" ]]; then
|
|
69
|
+
cp "$_user_template" ".ralph/config.json"
|
|
70
|
+
echo "Using user template: $_user_template" >&2
|
|
71
|
+
elif [[ -f "$_config_template" ]]; then
|
|
66
72
|
cp "$_config_template" ".ralph/config.json"
|
|
67
73
|
else
|
|
68
74
|
# Fall back to minimal config if template doesn't exist
|
|
75
|
+
_user_minimal="$HOME/.config/ralph/templates/config/minimal.json"
|
|
69
76
|
_config_template="$RALPH_TEMPLATES/config/minimal.json"
|
|
70
|
-
if [[ -f "$
|
|
77
|
+
if [[ -f "$_user_minimal" ]]; then
|
|
78
|
+
cp "$_user_minimal" ".ralph/config.json"
|
|
79
|
+
elif [[ -f "$_config_template" ]]; then
|
|
71
80
|
cp "$_config_template" ".ralph/config.json"
|
|
72
81
|
else
|
|
73
82
|
echo '{"projectType": "unknown"}' > ".ralph/config.json"
|
|
@@ -101,6 +110,11 @@ if [[ "${_ralph_needs_autoconfig:-}" == "true" ]]; then
|
|
|
101
110
|
unset _ralph_needs_autoconfig
|
|
102
111
|
fi
|
|
103
112
|
|
|
113
|
+
# Merge user config defaults into project config
|
|
114
|
+
if [[ -f "$RALPH_DIR/config.json" && -f "$HOME/.config/ralph/config.json" ]]; then
|
|
115
|
+
_merge_user_config
|
|
116
|
+
fi
|
|
117
|
+
|
|
104
118
|
# Main entry point
|
|
105
119
|
main() {
|
|
106
120
|
local cmd="${1:-help}"
|
|
@@ -185,15 +199,7 @@ main() {
|
|
|
185
199
|
fi
|
|
186
200
|
;;
|
|
187
201
|
config)
|
|
188
|
-
|
|
189
|
-
print_error "Ralph not initialized. Run 'ralph init' first."
|
|
190
|
-
exit 1
|
|
191
|
-
fi
|
|
192
|
-
echo "Auto-detecting project configuration..."
|
|
193
|
-
auto_configure_project
|
|
194
|
-
echo ""
|
|
195
|
-
echo "Current config:"
|
|
196
|
-
jq '.' "$RALPH_DIR/config.json"
|
|
202
|
+
ralph_config "$@"
|
|
197
203
|
;;
|
|
198
204
|
help|-h|--help)
|
|
199
205
|
ralph_help
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Message } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Build system prompt with optional project context
|
|
4
|
+
*/
|
|
5
|
+
export declare function buildSystemPrompt(projectContext?: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* Send a message to Claude and get a response
|
|
8
|
+
*/
|
|
9
|
+
export declare function chat(history: Message[], model: string, projectContext?: string): Promise<string>;
|
|
10
|
+
/**
|
|
11
|
+
* Generate a summary of the conversation for saving
|
|
12
|
+
*/
|
|
13
|
+
export declare function summarize(history: Message[], model: string): Promise<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Extract a title from a summary document
|
|
16
|
+
*/
|
|
17
|
+
export declare function extractTitle(summary: string): string;
|
|
18
|
+
//# sourceMappingURL=claude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/loopgram/claude.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAuB1C;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAWjE;AAWD;;GAEG;AACH,wBAAsB,IAAI,CACxB,OAAO,EAAE,OAAO,EAAE,EAClB,KAAK,EAAE,MAAM,EACb,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,OAAO,EAAE,EAClB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CAcjB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAepD"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
+
const anthropic = new Anthropic();
|
|
3
|
+
const BASE_SYSTEM_PROMPT = `You are a thoughtful brainstorming partner helping develop software ideas.
|
|
4
|
+
|
|
5
|
+
Your role:
|
|
6
|
+
- Ask clarifying questions to deeply understand the idea
|
|
7
|
+
- Explore edge cases and trade-offs
|
|
8
|
+
- Challenge assumptions constructively
|
|
9
|
+
- Help refine vague concepts into concrete plans
|
|
10
|
+
- Keep responses concise but insightful (2-4 sentences usually)
|
|
11
|
+
|
|
12
|
+
When the user says "save this" or similar:
|
|
13
|
+
- Summarize the key decisions made
|
|
14
|
+
- Format as a structured idea document
|
|
15
|
+
- Confirm what you're saving
|
|
16
|
+
|
|
17
|
+
Don't:
|
|
18
|
+
- Write code unless asked
|
|
19
|
+
- Be overly agreeable - push back on weak ideas
|
|
20
|
+
- Give long lectures - keep it conversational`;
|
|
21
|
+
/**
|
|
22
|
+
* Build system prompt with optional project context
|
|
23
|
+
*/
|
|
24
|
+
export function buildSystemPrompt(projectContext) {
|
|
25
|
+
if (!projectContext) {
|
|
26
|
+
return BASE_SYSTEM_PROMPT;
|
|
27
|
+
}
|
|
28
|
+
return `${BASE_SYSTEM_PROMPT}
|
|
29
|
+
|
|
30
|
+
## Project Context
|
|
31
|
+
You are brainstorming for a specific project. Here's context about it:
|
|
32
|
+
|
|
33
|
+
${projectContext}`;
|
|
34
|
+
}
|
|
35
|
+
const SUMMARY_PROMPT = `Summarize this brainstorming conversation into a structured idea document with:
|
|
36
|
+
- Title (short, descriptive)
|
|
37
|
+
- Summary (2-3 sentences)
|
|
38
|
+
- Key Decisions (bullet points)
|
|
39
|
+
- Open Questions (if any)
|
|
40
|
+
- Next Steps
|
|
41
|
+
|
|
42
|
+
Format as clean markdown.`;
|
|
43
|
+
/**
|
|
44
|
+
* Send a message to Claude and get a response
|
|
45
|
+
*/
|
|
46
|
+
export async function chat(history, model, projectContext) {
|
|
47
|
+
const response = await anthropic.messages.create({
|
|
48
|
+
model,
|
|
49
|
+
max_tokens: 500,
|
|
50
|
+
system: buildSystemPrompt(projectContext),
|
|
51
|
+
messages: history,
|
|
52
|
+
});
|
|
53
|
+
const content = response.content[0];
|
|
54
|
+
return content.type === 'text' ? content.text : '';
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Generate a summary of the conversation for saving
|
|
58
|
+
*/
|
|
59
|
+
export async function summarize(history, model) {
|
|
60
|
+
const conversationText = history
|
|
61
|
+
.map((m) => `${m.role.toUpperCase()}: ${m.content}`)
|
|
62
|
+
.join('\n\n');
|
|
63
|
+
const response = await anthropic.messages.create({
|
|
64
|
+
model,
|
|
65
|
+
max_tokens: 1000,
|
|
66
|
+
system: SUMMARY_PROMPT,
|
|
67
|
+
messages: [{ role: 'user', content: conversationText }],
|
|
68
|
+
});
|
|
69
|
+
const content = response.content[0];
|
|
70
|
+
return content.type === 'text' ? content.text : '';
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Extract a title from a summary document
|
|
74
|
+
*/
|
|
75
|
+
export function extractTitle(summary) {
|
|
76
|
+
// Try to find a markdown heading
|
|
77
|
+
const headingMatch = summary.match(/^#\s*(.+)/m);
|
|
78
|
+
if (headingMatch) {
|
|
79
|
+
return headingMatch[1].replace(/^Title:?\s*/i, '').trim();
|
|
80
|
+
}
|
|
81
|
+
// Try to find "Title:" line
|
|
82
|
+
const titleMatch = summary.match(/^Title:?\s*(.+)/im);
|
|
83
|
+
if (titleMatch) {
|
|
84
|
+
return titleMatch[1].trim();
|
|
85
|
+
}
|
|
86
|
+
// Fallback to timestamp
|
|
87
|
+
return `brainstorm-${Date.now()}`;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/loopgram/claude.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAG1C,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;AAElC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;8CAiBmB,CAAC;AAE/C;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,cAAuB;IACvD,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAED,OAAO,GAAG,kBAAkB;;;;;EAK5B,cAAc,EAAE,CAAA;AAClB,CAAC;AAED,MAAM,cAAc,GAAG;;;;;;;0BAOG,CAAC;AAE3B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,OAAkB,EAClB,KAAa,EACb,cAAuB;IAEvB,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC/C,KAAK;QACL,UAAU,EAAE,GAAG;QACf,MAAM,EAAE,iBAAiB,CAAC,cAAc,CAAC;QACzC,QAAQ,EAAE,OAAO;KAClB,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACpC,OAAO,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,OAAkB,EAClB,KAAa;IAEb,MAAM,gBAAgB,GAAG,OAAO;SAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;SACnD,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC/C,KAAK;QACL,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,cAAc;QACtB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;KACxD,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACpC,OAAO,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,iCAAiC;IACjC,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACjD,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5D,CAAC;IAED,4BAA4B;IAC5B,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACtD,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9B,CAAC;IAED,wBAAwB;IACxB,OAAO,cAAc,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
interface SearchResult {
|
|
2
|
+
file: string;
|
|
3
|
+
matches: string[];
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Search a project for files related to a topic using ripgrep
|
|
7
|
+
*/
|
|
8
|
+
export declare function searchProject(projectPath: string, topic: string): SearchResult[];
|
|
9
|
+
/**
|
|
10
|
+
* Read key project files for additional context
|
|
11
|
+
*/
|
|
12
|
+
export declare function readProjectFiles(projectPath: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Generate a summary of search results using Claude
|
|
15
|
+
*/
|
|
16
|
+
export declare function generateContextSummary(projectName: string, topic: string, searchResults: SearchResult[], projectContext: string, model: string): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Search project and generate context for brainstorming
|
|
19
|
+
*/
|
|
20
|
+
export declare function getTopicContext(projectPath: string, projectName: string, topic: string, model: string): Promise<{
|
|
21
|
+
summary: string;
|
|
22
|
+
filesFound: string[];
|
|
23
|
+
searchTerms: string[];
|
|
24
|
+
}>;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=context-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-search.d.ts","sourceRoot":"","sources":["../../src/loopgram/context-search.ts"],"names":[],"mappings":"AAOA,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AA+BD;;GAEG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE,CA+ChF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA2B5D;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,YAAY,EAAE,EAC7B,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CAsCjB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAyC3E"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import { readFileSync, existsSync } from 'fs';
|
|
3
|
+
import { join, relative } from 'path';
|
|
4
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
5
|
+
const anthropic = new Anthropic();
|
|
6
|
+
/**
|
|
7
|
+
* Use AI to generate smart search terms for a topic
|
|
8
|
+
*/
|
|
9
|
+
async function generateSearchTerms(topic, model) {
|
|
10
|
+
const response = await anthropic.messages.create({
|
|
11
|
+
model,
|
|
12
|
+
max_tokens: 200,
|
|
13
|
+
system: `You generate search terms for code search. Given a topic, output 5-8 relevant keywords/patterns to search for in a codebase. Output ONLY the terms, one per line, no explanations. Include variations (e.g., "auth", "authenticate", "authentication").`,
|
|
14
|
+
messages: [
|
|
15
|
+
{ role: 'user', content: `Topic: ${topic}` },
|
|
16
|
+
],
|
|
17
|
+
});
|
|
18
|
+
const text = response.content[0];
|
|
19
|
+
if (text.type !== 'text')
|
|
20
|
+
return [topic];
|
|
21
|
+
const terms = text.text
|
|
22
|
+
.split('\n')
|
|
23
|
+
.map(t => t.trim().toLowerCase())
|
|
24
|
+
.filter(t => t.length > 0 && t.length < 30);
|
|
25
|
+
// Always include the original topic
|
|
26
|
+
if (!terms.includes(topic.toLowerCase())) {
|
|
27
|
+
terms.unshift(topic.toLowerCase());
|
|
28
|
+
}
|
|
29
|
+
return terms.slice(0, 8);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Search a project for files related to a topic using ripgrep
|
|
33
|
+
*/
|
|
34
|
+
export function searchProject(projectPath, topic) {
|
|
35
|
+
const results = [];
|
|
36
|
+
try {
|
|
37
|
+
// Use ripgrep to find matching files (case insensitive)
|
|
38
|
+
// Escape special regex characters in topic
|
|
39
|
+
const escapedTopic = topic.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
40
|
+
// Use grep instead of rg for compatibility
|
|
41
|
+
const cmd = `grep -r -i -l "${escapedTopic}" "${projectPath}" --include="*.py" --include="*.ts" --include="*.js" --include="*.md" --include="*.json" --include="*.sh" 2>/dev/null | grep -v node_modules | grep -v __pycache__ | grep -v ".git" | head -20 || true`;
|
|
42
|
+
console.log(`[search] Running: ${cmd}`);
|
|
43
|
+
const rgOutput = execSync(cmd, {
|
|
44
|
+
encoding: 'utf-8',
|
|
45
|
+
maxBuffer: 1024 * 1024,
|
|
46
|
+
shell: '/bin/zsh'
|
|
47
|
+
}).trim();
|
|
48
|
+
console.log(`[search] Found ${rgOutput ? rgOutput.split('\n').length : 0} files for "${topic}"`);
|
|
49
|
+
if (!rgOutput) {
|
|
50
|
+
return results;
|
|
51
|
+
}
|
|
52
|
+
const files = rgOutput.split('\n').filter(Boolean);
|
|
53
|
+
for (const file of files.slice(0, 10)) { // Limit to 10 files
|
|
54
|
+
try {
|
|
55
|
+
// Get matching lines with context
|
|
56
|
+
const matchOutput = execSync(`rg -i -C 2 "${topic}" "${file}" 2>/dev/null | head -30`, { encoding: 'utf-8', maxBuffer: 1024 * 1024 }).trim();
|
|
57
|
+
results.push({
|
|
58
|
+
file: relative(projectPath, file),
|
|
59
|
+
matches: matchOutput ? [matchOutput] : [],
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// File might not have readable matches
|
|
64
|
+
results.push({ file: relative(projectPath, file), matches: [] });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
// ripgrep not found or no matches
|
|
70
|
+
console.error('Search error:', error);
|
|
71
|
+
}
|
|
72
|
+
return results;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Read key project files for additional context
|
|
76
|
+
*/
|
|
77
|
+
export function readProjectFiles(projectPath) {
|
|
78
|
+
const contextFiles = [
|
|
79
|
+
'CLAUDE.md',
|
|
80
|
+
'README.md',
|
|
81
|
+
'package.json',
|
|
82
|
+
'pyproject.toml',
|
|
83
|
+
];
|
|
84
|
+
let context = '';
|
|
85
|
+
for (const file of contextFiles) {
|
|
86
|
+
const filePath = join(projectPath, file);
|
|
87
|
+
if (existsSync(filePath)) {
|
|
88
|
+
try {
|
|
89
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
90
|
+
// Truncate large files
|
|
91
|
+
const truncated = content.length > 2000
|
|
92
|
+
? content.substring(0, 2000) + '\n...[truncated]'
|
|
93
|
+
: content;
|
|
94
|
+
context += `\n### ${file}\n${truncated}\n`;
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// Skip unreadable files
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return context;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Generate a summary of search results using Claude
|
|
105
|
+
*/
|
|
106
|
+
export async function generateContextSummary(projectName, topic, searchResults, projectContext, model) {
|
|
107
|
+
if (searchResults.length === 0) {
|
|
108
|
+
return `No code found related to "${topic}" in ${projectName}. This might be a new area to build.`;
|
|
109
|
+
}
|
|
110
|
+
// Build the content to summarize
|
|
111
|
+
let content = `Project: ${projectName}\nTopic: ${topic}\n\n`;
|
|
112
|
+
content += `## Project Context\n${projectContext}\n\n`;
|
|
113
|
+
content += `## Search Results\n`;
|
|
114
|
+
for (const result of searchResults) {
|
|
115
|
+
content += `\n### ${result.file}\n`;
|
|
116
|
+
if (result.matches.length > 0) {
|
|
117
|
+
content += '```\n' + result.matches.join('\n---\n') + '\n```\n';
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const response = await anthropic.messages.create({
|
|
121
|
+
model,
|
|
122
|
+
max_tokens: 800,
|
|
123
|
+
system: `You are summarizing code search results to provide context for brainstorming.
|
|
124
|
+
Be concise but thorough. Focus on:
|
|
125
|
+
- What exists related to this topic
|
|
126
|
+
- Key patterns and approaches used
|
|
127
|
+
- Important files/functions
|
|
128
|
+
- Potential extension points
|
|
129
|
+
|
|
130
|
+
Keep the summary under 500 words.`,
|
|
131
|
+
messages: [
|
|
132
|
+
{
|
|
133
|
+
role: 'user',
|
|
134
|
+
content: `Summarize what exists in this codebase related to "${topic}":\n\n${content}`,
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
});
|
|
138
|
+
const text = response.content[0];
|
|
139
|
+
return text.type === 'text' ? text.text : 'Unable to generate summary.';
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Search project and generate context for brainstorming
|
|
143
|
+
*/
|
|
144
|
+
export async function getTopicContext(projectPath, projectName, topic, model) {
|
|
145
|
+
// Use AI to generate smart search terms
|
|
146
|
+
console.log(`[context] Generating search terms for: ${topic}`);
|
|
147
|
+
const searchTerms = await generateSearchTerms(topic, model);
|
|
148
|
+
console.log(`[context] Search terms: ${searchTerms.join(', ')}`);
|
|
149
|
+
// Search for each term and combine results
|
|
150
|
+
const allResults = new Map();
|
|
151
|
+
for (const term of searchTerms) {
|
|
152
|
+
const results = searchProject(projectPath, term);
|
|
153
|
+
for (const result of results) {
|
|
154
|
+
// Dedupe by file path, merge matches
|
|
155
|
+
if (allResults.has(result.file)) {
|
|
156
|
+
const existing = allResults.get(result.file);
|
|
157
|
+
existing.matches.push(...result.matches);
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
allResults.set(result.file, result);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const searchResults = Array.from(allResults.values()).slice(0, 15);
|
|
165
|
+
// Get basic project context
|
|
166
|
+
const projectContext = readProjectFiles(projectPath);
|
|
167
|
+
// Generate summary
|
|
168
|
+
const summary = await generateContextSummary(projectName, topic, searchResults, projectContext, model);
|
|
169
|
+
return {
|
|
170
|
+
summary,
|
|
171
|
+
filesFound: searchResults.map((r) => r.file),
|
|
172
|
+
searchTerms,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=context-search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-search.js","sourceRoot":"","sources":["../../src/loopgram/context-search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Context } from 'telegraf';
|
|
2
|
+
import type { Message, BrainstormConfig, ProjectConfig } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Set context for a conversation (from /context command)
|
|
5
|
+
*/
|
|
6
|
+
export declare function setConversationContext(chatId: number, context: string): void;
|
|
7
|
+
/**
|
|
8
|
+
* Get context for a conversation
|
|
9
|
+
*/
|
|
10
|
+
export declare function getConversationContext(chatId: number): string | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Get conversation history for a chat, creating if needed
|
|
13
|
+
*/
|
|
14
|
+
export declare function getHistory(chatId: number): Message[];
|
|
15
|
+
/**
|
|
16
|
+
* Clear conversation history for a chat
|
|
17
|
+
*/
|
|
18
|
+
export declare function clearConversation(chatId: number): void;
|
|
19
|
+
/**
|
|
20
|
+
* Handle incoming text messages
|
|
21
|
+
*/
|
|
22
|
+
export declare function handleMessage(ctx: Context, config: BrainstormConfig, project: ProjectConfig | null): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Handle /save command - summarize and save the conversation
|
|
25
|
+
*/
|
|
26
|
+
export declare function handleSaveCommand(ctx: Context, projectPath: string | null, config: BrainstormConfig): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Handle /clear command - clear conversation history
|
|
29
|
+
*/
|
|
30
|
+
export declare function handleClearCommand(ctx: Context): void;
|
|
31
|
+
/**
|
|
32
|
+
* Handle /projects command - list configured projects
|
|
33
|
+
*/
|
|
34
|
+
export declare function handleProjectsCommand(ctx: Context, config: BrainstormConfig): void;
|
|
35
|
+
/**
|
|
36
|
+
* Handle /status command - show current conversation status
|
|
37
|
+
*/
|
|
38
|
+
export declare function handleStatusCommand(ctx: Context, projectPath: string | null, config: BrainstormConfig): void;
|
|
39
|
+
//# sourceMappingURL=conversation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/loopgram/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAa3E;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAE5E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEzE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CAKpD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAGtD;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,aAAa,GAAG,IAAI,GAC5B,OAAO,CAAC,IAAI,CAAC,CA4Cf;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,OAAO,EACZ,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,IAAI,CAAC,CA6Cf;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAMrD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,gBAAgB,GACvB,IAAI,CAUN;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,OAAO,EACZ,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,MAAM,EAAE,gBAAgB,GACvB,IAAI,CAoBN"}
|