sylas-edge-worker 0.2.21
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/README.md +293 -0
- package/dist/ActivityPoster.d.ts +15 -0
- package/dist/ActivityPoster.d.ts.map +1 -0
- package/dist/ActivityPoster.js +194 -0
- package/dist/ActivityPoster.js.map +1 -0
- package/dist/AgentSessionManager.d.ts +280 -0
- package/dist/AgentSessionManager.d.ts.map +1 -0
- package/dist/AgentSessionManager.js +1412 -0
- package/dist/AgentSessionManager.js.map +1 -0
- package/dist/AskUserQuestionHandler.d.ts +97 -0
- package/dist/AskUserQuestionHandler.d.ts.map +1 -0
- package/dist/AskUserQuestionHandler.js +206 -0
- package/dist/AskUserQuestionHandler.js.map +1 -0
- package/dist/AttachmentService.d.ts +69 -0
- package/dist/AttachmentService.d.ts.map +1 -0
- package/dist/AttachmentService.js +369 -0
- package/dist/AttachmentService.js.map +1 -0
- package/dist/ChatSessionHandler.d.ts +87 -0
- package/dist/ChatSessionHandler.d.ts.map +1 -0
- package/dist/ChatSessionHandler.js +231 -0
- package/dist/ChatSessionHandler.js.map +1 -0
- package/dist/ConfigManager.d.ts +91 -0
- package/dist/ConfigManager.d.ts.map +1 -0
- package/dist/ConfigManager.js +227 -0
- package/dist/ConfigManager.js.map +1 -0
- package/dist/EdgeWorker.d.ts +670 -0
- package/dist/EdgeWorker.d.ts.map +1 -0
- package/dist/EdgeWorker.js +3801 -0
- package/dist/EdgeWorker.js.map +1 -0
- package/dist/GitService.d.ts +39 -0
- package/dist/GitService.d.ts.map +1 -0
- package/dist/GitService.js +432 -0
- package/dist/GitService.js.map +1 -0
- package/dist/GlobalSessionRegistry.d.ts +142 -0
- package/dist/GlobalSessionRegistry.d.ts.map +1 -0
- package/dist/GlobalSessionRegistry.js +254 -0
- package/dist/GlobalSessionRegistry.js.map +1 -0
- package/dist/PromptBuilder.d.ts +175 -0
- package/dist/PromptBuilder.d.ts.map +1 -0
- package/dist/PromptBuilder.js +884 -0
- package/dist/PromptBuilder.js.map +1 -0
- package/dist/RepositoryRouter.d.ts +152 -0
- package/dist/RepositoryRouter.d.ts.map +1 -0
- package/dist/RepositoryRouter.js +480 -0
- package/dist/RepositoryRouter.js.map +1 -0
- package/dist/RunnerSelectionService.d.ts +62 -0
- package/dist/RunnerSelectionService.d.ts.map +1 -0
- package/dist/RunnerSelectionService.js +379 -0
- package/dist/RunnerSelectionService.js.map +1 -0
- package/dist/SharedApplicationServer.d.ts +107 -0
- package/dist/SharedApplicationServer.d.ts.map +1 -0
- package/dist/SharedApplicationServer.js +247 -0
- package/dist/SharedApplicationServer.js.map +1 -0
- package/dist/SharedWebhookServer.d.ts +39 -0
- package/dist/SharedWebhookServer.d.ts.map +1 -0
- package/dist/SharedWebhookServer.js +150 -0
- package/dist/SharedWebhookServer.js.map +1 -0
- package/dist/SlackChatAdapter.d.ts +25 -0
- package/dist/SlackChatAdapter.d.ts.map +1 -0
- package/dist/SlackChatAdapter.js +143 -0
- package/dist/SlackChatAdapter.js.map +1 -0
- package/dist/UserAccessControl.d.ts +69 -0
- package/dist/UserAccessControl.d.ts.map +1 -0
- package/dist/UserAccessControl.js +171 -0
- package/dist/UserAccessControl.js.map +1 -0
- package/dist/WorktreeIncludeService.d.ts +32 -0
- package/dist/WorktreeIncludeService.d.ts.map +1 -0
- package/dist/WorktreeIncludeService.js +123 -0
- package/dist/WorktreeIncludeService.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/label-prompt-template.md +27 -0
- package/dist/procedures/ProcedureAnalyzer.d.ts +69 -0
- package/dist/procedures/ProcedureAnalyzer.d.ts.map +1 -0
- package/dist/procedures/ProcedureAnalyzer.js +271 -0
- package/dist/procedures/ProcedureAnalyzer.js.map +1 -0
- package/dist/procedures/index.d.ts +7 -0
- package/dist/procedures/index.d.ts.map +1 -0
- package/dist/procedures/index.js +7 -0
- package/dist/procedures/index.js.map +1 -0
- package/dist/procedures/registry.d.ts +156 -0
- package/dist/procedures/registry.d.ts.map +1 -0
- package/dist/procedures/registry.js +240 -0
- package/dist/procedures/registry.js.map +1 -0
- package/dist/procedures/types.d.ts +103 -0
- package/dist/procedures/types.d.ts.map +1 -0
- package/dist/procedures/types.js +5 -0
- package/dist/procedures/types.js.map +1 -0
- package/dist/prompt-assembly/types.d.ts +80 -0
- package/dist/prompt-assembly/types.d.ts.map +1 -0
- package/dist/prompt-assembly/types.js +8 -0
- package/dist/prompt-assembly/types.js.map +1 -0
- package/dist/prompts/builder.md +191 -0
- package/dist/prompts/debugger.md +128 -0
- package/dist/prompts/graphite-orchestrator.md +362 -0
- package/dist/prompts/orchestrator.md +290 -0
- package/dist/prompts/scoper.md +95 -0
- package/dist/prompts/standard-issue-assigned-user-prompt.md +33 -0
- package/dist/prompts/subroutines/changelog-update.md +79 -0
- package/dist/prompts/subroutines/coding-activity.md +12 -0
- package/dist/prompts/subroutines/concise-summary.md +67 -0
- package/dist/prompts/subroutines/debugger-fix.md +92 -0
- package/dist/prompts/subroutines/debugger-reproduction.md +74 -0
- package/dist/prompts/subroutines/full-delegation.md +68 -0
- package/dist/prompts/subroutines/get-approval.md +175 -0
- package/dist/prompts/subroutines/gh-pr.md +80 -0
- package/dist/prompts/subroutines/git-commit.md +37 -0
- package/dist/prompts/subroutines/plan-summary.md +21 -0
- package/dist/prompts/subroutines/preparation.md +16 -0
- package/dist/prompts/subroutines/question-answer.md +8 -0
- package/dist/prompts/subroutines/question-investigation.md +8 -0
- package/dist/prompts/subroutines/release-execution.md +81 -0
- package/dist/prompts/subroutines/release-summary.md +60 -0
- package/dist/prompts/subroutines/user-testing-summary.md +87 -0
- package/dist/prompts/subroutines/user-testing.md +48 -0
- package/dist/prompts/subroutines/validation-fixer.md +56 -0
- package/dist/prompts/subroutines/verbose-summary.md +46 -0
- package/dist/prompts/subroutines/verifications.md +77 -0
- package/dist/prompts/todolist-system-prompt-extension.md +15 -0
- package/dist/sinks/IActivitySink.d.ts +60 -0
- package/dist/sinks/IActivitySink.d.ts.map +1 -0
- package/dist/sinks/IActivitySink.js +2 -0
- package/dist/sinks/IActivitySink.js.map +1 -0
- package/dist/sinks/LinearActivitySink.d.ts +69 -0
- package/dist/sinks/LinearActivitySink.d.ts.map +1 -0
- package/dist/sinks/LinearActivitySink.js +111 -0
- package/dist/sinks/LinearActivitySink.js.map +1 -0
- package/dist/sinks/NoopActivitySink.d.ts +13 -0
- package/dist/sinks/NoopActivitySink.d.ts.map +1 -0
- package/dist/sinks/NoopActivitySink.js +17 -0
- package/dist/sinks/NoopActivitySink.js.map +1 -0
- package/dist/sinks/index.d.ts +9 -0
- package/dist/sinks/index.d.ts.map +1 -0
- package/dist/sinks/index.js +8 -0
- package/dist/sinks/index.js.map +1 -0
- package/dist/types.d.ts +32 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validation/ValidationLoopController.d.ts +54 -0
- package/dist/validation/ValidationLoopController.d.ts.map +1 -0
- package/dist/validation/ValidationLoopController.js +242 -0
- package/dist/validation/ValidationLoopController.js.map +1 -0
- package/dist/validation/index.d.ts +7 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +7 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/types.d.ts +82 -0
- package/dist/validation/types.d.ts.map +1 -0
- package/dist/validation/types.js +29 -0
- package/dist/validation/types.js.map +1 -0
- package/label-prompt-template.md +27 -0
- package/package.json +56 -0
- package/prompt-template.md +116 -0
- package/prompts/builder.md +191 -0
- package/prompts/debugger.md +128 -0
- package/prompts/graphite-orchestrator.md +362 -0
- package/prompts/orchestrator.md +290 -0
- package/prompts/scoper.md +95 -0
- package/prompts/standard-issue-assigned-user-prompt.md +33 -0
- package/prompts/todolist-system-prompt-extension.md +15 -0
package/README.md
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# @sylas/edge-worker
|
|
2
|
+
|
|
3
|
+
Unified edge worker for processing Linear issues with Claude. Handles webhook events, manages Claude sessions, and posts comments back to Linear.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @sylas/edge-worker
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
The EdgeWorker supports multiple repository/Linear workspace pairs. Each repository configuration includes:
|
|
14
|
+
- Git repository path and branch
|
|
15
|
+
- Linear workspace ID and OAuth token
|
|
16
|
+
- Workspace directory for issue processing
|
|
17
|
+
|
|
18
|
+
### Single Repository Example (CLI)
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { EdgeWorker } from '@sylas/edge-worker'
|
|
22
|
+
|
|
23
|
+
const edgeWorker = new EdgeWorker({
|
|
24
|
+
// Connection
|
|
25
|
+
proxyUrl: 'https://edge-proxy.example.com',
|
|
26
|
+
|
|
27
|
+
// Claude
|
|
28
|
+
claudePath: '/usr/local/bin/claude',
|
|
29
|
+
defaultAllowedTools: ['bash', 'edit', 'read'],
|
|
30
|
+
|
|
31
|
+
// Single repository configuration
|
|
32
|
+
repositories: [{
|
|
33
|
+
id: 'main-repo',
|
|
34
|
+
name: 'Main Repository',
|
|
35
|
+
repositoryPath: '/home/user/projects/main',
|
|
36
|
+
baseBranch: 'main',
|
|
37
|
+
linearWorkspaceId: 'workspace-123',
|
|
38
|
+
linearToken: await oauthHelper.getAccessToken(),
|
|
39
|
+
workspaceBaseDir: '/home/user/.sylas/workspaces/main'
|
|
40
|
+
}],
|
|
41
|
+
|
|
42
|
+
// Optional handlers
|
|
43
|
+
handlers: {
|
|
44
|
+
// Custom workspace creation (e.g., git worktrees)
|
|
45
|
+
createWorkspace: async (issue, repository) => {
|
|
46
|
+
const path = await createGitWorktree(
|
|
47
|
+
repository.repositoryPath,
|
|
48
|
+
issue.identifier,
|
|
49
|
+
repository.baseBranch
|
|
50
|
+
)
|
|
51
|
+
return { path, isGitWorktree: true }
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
// Log errors
|
|
55
|
+
onError: (error) => {
|
|
56
|
+
console.error('EdgeWorker error:', error)
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
// Features
|
|
61
|
+
features: {
|
|
62
|
+
enableContinuation: true,
|
|
63
|
+
enableTokenLimitHandling: true
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
// Start processing
|
|
68
|
+
await edgeWorker.start()
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Multi-Repository Example (Electron)
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { EdgeWorker } from '@sylas/edge-worker'
|
|
75
|
+
|
|
76
|
+
// Load repository configurations from user settings
|
|
77
|
+
const repositories = userSettings.repositories.map(repo => ({
|
|
78
|
+
id: repo.id,
|
|
79
|
+
name: repo.name,
|
|
80
|
+
repositoryPath: repo.path,
|
|
81
|
+
baseBranch: repo.branch || 'main',
|
|
82
|
+
linearWorkspaceId: repo.linearWorkspaceId,
|
|
83
|
+
linearToken: repo.linearToken, // Each repo can have its own token
|
|
84
|
+
workspaceBaseDir: path.join(app.getPath('userData'), 'workspaces', repo.id),
|
|
85
|
+
isActive: repo.enabled
|
|
86
|
+
}))
|
|
87
|
+
|
|
88
|
+
const edgeWorker = new EdgeWorker({
|
|
89
|
+
proxyUrl: config.proxyUrl,
|
|
90
|
+
claudePath: getClaudePath(),
|
|
91
|
+
|
|
92
|
+
// Multiple repositories
|
|
93
|
+
repositories,
|
|
94
|
+
|
|
95
|
+
// UI updates with repository context
|
|
96
|
+
handlers: {
|
|
97
|
+
onClaudeEvent: (issueId, event, repositoryId) => {
|
|
98
|
+
// Update UI with Claude's progress
|
|
99
|
+
mainWindow.webContents.send('claude-event', {
|
|
100
|
+
issueId,
|
|
101
|
+
event,
|
|
102
|
+
repository: repositories.find(r => r.id === repositoryId)
|
|
103
|
+
})
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
onSessionStart: (issueId, issue, repositoryId) => {
|
|
107
|
+
const repo = repositories.find(r => r.id === repositoryId)
|
|
108
|
+
// Show notification
|
|
109
|
+
new Notification({
|
|
110
|
+
title: `Processing Issue in ${repo.name}`,
|
|
111
|
+
body: `Working on ${issue.identifier}: ${issue.title}`
|
|
112
|
+
}).show()
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
createWorkspace: async (issue, repository) => {
|
|
116
|
+
// Create git worktree for the specific repository
|
|
117
|
+
const worktreePath = await createWorktree(
|
|
118
|
+
repository.repositoryPath,
|
|
119
|
+
issue.identifier,
|
|
120
|
+
repository.baseBranch
|
|
121
|
+
)
|
|
122
|
+
return { path: worktreePath, isGitWorktree: true }
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
await edgeWorker.start()
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Configuration
|
|
131
|
+
|
|
132
|
+
### Required Config
|
|
133
|
+
|
|
134
|
+
- `proxyUrl`: URL of the edge proxy server
|
|
135
|
+
- `claudePath`: Path to Claude CLI executable
|
|
136
|
+
- `repositories`: Array of repository configurations
|
|
137
|
+
|
|
138
|
+
### Repository Configuration
|
|
139
|
+
|
|
140
|
+
Each repository in the `repositories` array requires:
|
|
141
|
+
|
|
142
|
+
- `id`: Unique identifier for the repository
|
|
143
|
+
- `name`: Display name for the repository
|
|
144
|
+
- `repositoryPath`: Local git repository path
|
|
145
|
+
- `baseBranch`: Branch to create worktrees from (e.g., 'main')
|
|
146
|
+
- `linearWorkspaceId`: Linear workspace/team ID
|
|
147
|
+
- `linearToken`: OAuth token for this Linear workspace
|
|
148
|
+
- `workspaceBaseDir`: Where to create issue workspaces
|
|
149
|
+
|
|
150
|
+
Optional per-repository settings:
|
|
151
|
+
- `isActive`: Whether to process webhooks (default: true)
|
|
152
|
+
- `promptTemplatePath`: Custom prompt template for this repo
|
|
153
|
+
|
|
154
|
+
### Optional Handlers
|
|
155
|
+
|
|
156
|
+
All handlers are optional and now include repository context:
|
|
157
|
+
|
|
158
|
+
- `createWorkspace(issue, repository)`: Custom workspace creation
|
|
159
|
+
- `onClaudeEvent(issueId, event, repositoryId)`: Claude event updates
|
|
160
|
+
- `onSessionStart(issueId, issue, repositoryId)`: Session started
|
|
161
|
+
- `onSessionEnd(issueId, exitCode, repositoryId)`: Session ended
|
|
162
|
+
- `onError(error, context)`: Error handling
|
|
163
|
+
|
|
164
|
+
### Features
|
|
165
|
+
|
|
166
|
+
- `enableContinuation`: Use `--continue` flag for follow-up comments (default: true)
|
|
167
|
+
- `enableTokenLimitHandling`: Auto-restart on token limits (default: true)
|
|
168
|
+
- `enableAttachmentDownload`: Download issue attachments (default: false)
|
|
169
|
+
|
|
170
|
+
## Events
|
|
171
|
+
|
|
172
|
+
The EdgeWorker extends EventEmitter and emits:
|
|
173
|
+
|
|
174
|
+
- `connected`: Connected to proxy (token)
|
|
175
|
+
- `disconnected`: Disconnected from proxy (token, reason)
|
|
176
|
+
- `session:started`: Claude session started (issueId, issue, repositoryId)
|
|
177
|
+
- `session:ended`: Claude session ended (issueId, exitCode, repositoryId)
|
|
178
|
+
- `claude:event`: Any Claude event (issueId, event, repositoryId)
|
|
179
|
+
- `claude:response`: Claude text response (issueId, text, repositoryId)
|
|
180
|
+
- `claude:tool-use`: Claude used a tool (issueId, tool, input, repositoryId)
|
|
181
|
+
- `error`: Error occurred (error, context)
|
|
182
|
+
|
|
183
|
+
## Architecture
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
Your App (CLI/Electron)
|
|
187
|
+
↓ provides repository configs
|
|
188
|
+
EdgeWorker
|
|
189
|
+
↓ manages multiple repositories
|
|
190
|
+
├─→ Repository 1 (token A) ─→ Linear Workspace 1
|
|
191
|
+
├─→ Repository 2 (token A) ─→ Linear Workspace 1
|
|
192
|
+
└─→ Repository 3 (token B) ─→ Linear Workspace 2
|
|
193
|
+
↓ connects to proxy (grouped by token)
|
|
194
|
+
Edge Proxy
|
|
195
|
+
↓ webhooks from all workspaces
|
|
196
|
+
Linear
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Key features:
|
|
200
|
+
- Multiple repositories can share the same Linear workspace/token
|
|
201
|
+
- Repositories with different tokens connect separately to minimize connections
|
|
202
|
+
- Each repository has its own workspace directory and configuration
|
|
203
|
+
- OAuth tokens serve dual purpose: proxy auth and Linear API calls
|
|
204
|
+
|
|
205
|
+
## Prompt Templates
|
|
206
|
+
|
|
207
|
+
The EdgeWorker supports customizable prompt templates to tailor Claude's behavior for different repositories or workflows.
|
|
208
|
+
|
|
209
|
+
### Default Template
|
|
210
|
+
|
|
211
|
+
If no custom template is specified, EdgeWorker uses a built-in template that helps Claude determine whether to:
|
|
212
|
+
1. **Execute** - When requirements are clear, implement the solution
|
|
213
|
+
2. **Clarify** - When requirements are vague, ask clarifying questions
|
|
214
|
+
|
|
215
|
+
### Custom Templates
|
|
216
|
+
|
|
217
|
+
You can provide custom templates at two levels:
|
|
218
|
+
- **Global**: Via `config.features.promptTemplatePath`
|
|
219
|
+
- **Per-repository**: Via `repository.promptTemplatePath` (takes precedence)
|
|
220
|
+
|
|
221
|
+
### Template Variables
|
|
222
|
+
|
|
223
|
+
Templates use Handlebars-style variables that are automatically replaced:
|
|
224
|
+
|
|
225
|
+
- `{{repository_name}}` - Name of the repository
|
|
226
|
+
- `{{issue_id}}` - Linear issue ID
|
|
227
|
+
- `{{issue_title}}` - Issue title
|
|
228
|
+
- `{{issue_description}}` - Full issue description
|
|
229
|
+
- `{{issue_state}}` - Current issue state
|
|
230
|
+
- `{{issue_priority}}` - Priority level (0-4)
|
|
231
|
+
- `{{issue_url}}` - Direct link to Linear issue
|
|
232
|
+
- `{{comment_history}}` - All previous comments formatted
|
|
233
|
+
- `{{latest_comment}}` - Most recent comment text
|
|
234
|
+
- `{{working_directory}}` - Current working directory
|
|
235
|
+
- `{{base_branch}}` - Base git branch (e.g., 'main')
|
|
236
|
+
- `{{branch_name}}` - Issue branch name
|
|
237
|
+
|
|
238
|
+
### Example Custom Template
|
|
239
|
+
|
|
240
|
+
```markdown
|
|
241
|
+
You are an expert {{repository_name}} developer.
|
|
242
|
+
|
|
243
|
+
## Current Task
|
|
244
|
+
**Issue**: {{issue_title}} (#{{issue_id}})
|
|
245
|
+
**Priority**: {{issue_priority}}
|
|
246
|
+
**Status**: {{issue_state}}
|
|
247
|
+
|
|
248
|
+
## Description
|
|
249
|
+
{{issue_description}}
|
|
250
|
+
|
|
251
|
+
## Previous Discussion
|
|
252
|
+
{{comment_history}}
|
|
253
|
+
|
|
254
|
+
## Technical Context
|
|
255
|
+
- Repository: {{repository_name}}
|
|
256
|
+
- Working Directory: {{working_directory}}
|
|
257
|
+
- Branch: {{branch_name}} (from {{base_branch}})
|
|
258
|
+
|
|
259
|
+
## Instructions
|
|
260
|
+
1. Review the issue requirements carefully
|
|
261
|
+
2. Check existing code patterns in the repository
|
|
262
|
+
3. Implement a solution following project conventions
|
|
263
|
+
4. Ensure all tests pass
|
|
264
|
+
5. Create a descriptive pull request
|
|
265
|
+
|
|
266
|
+
Remember to ask clarifying questions if requirements are unclear.
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Using Custom Templates
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
// Global template for all repositories
|
|
273
|
+
const edgeWorker = new EdgeWorker({
|
|
274
|
+
// ... other config
|
|
275
|
+
features: {
|
|
276
|
+
promptTemplatePath: './prompts/default.md'
|
|
277
|
+
}
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
// Per-repository templates
|
|
281
|
+
const edgeWorker = new EdgeWorker({
|
|
282
|
+
repositories: [{
|
|
283
|
+
id: 'frontend',
|
|
284
|
+
name: 'Frontend App',
|
|
285
|
+
// ... other config
|
|
286
|
+
promptTemplatePath: './prompts/frontend-specific.md'
|
|
287
|
+
}, {
|
|
288
|
+
id: 'backend',
|
|
289
|
+
name: 'Backend API',
|
|
290
|
+
// ... other config
|
|
291
|
+
promptTemplatePath: './prompts/backend-specific.md'
|
|
292
|
+
}]
|
|
293
|
+
})
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AgentActivityCreateInput, IIssueTrackerService, ILogger, RepositoryConfig } from "sylas-core";
|
|
2
|
+
export declare class ActivityPoster {
|
|
3
|
+
private issueTrackers;
|
|
4
|
+
private repositories;
|
|
5
|
+
private logger;
|
|
6
|
+
constructor(issueTrackers: Map<string, IIssueTrackerService>, repositories: Map<string, RepositoryConfig>, logger: ILogger);
|
|
7
|
+
postActivityDirect(issueTracker: IIssueTrackerService, input: AgentActivityCreateInput, label: string): Promise<string | null>;
|
|
8
|
+
postInstantAcknowledgment(sessionId: string, repositoryId: string): Promise<void>;
|
|
9
|
+
postParentResumeAcknowledgment(sessionId: string, repositoryId: string): Promise<void>;
|
|
10
|
+
postRepositorySelectionActivity(sessionId: string, repositoryId: string, repositoryName: string, selectionMethod: "description-tag" | "label-based" | "project-based" | "team-based" | "team-prefix" | "catch-all" | "workspace-fallback" | "user-selected"): Promise<void>;
|
|
11
|
+
postSystemPromptSelectionThought(sessionId: string, labels: string[], repositoryId: string): Promise<void>;
|
|
12
|
+
postInstantPromptedAcknowledgment(sessionId: string, repositoryId: string, isStreaming: boolean): Promise<void>;
|
|
13
|
+
postComment(issueId: string, body: string, repositoryId: string, parentId?: string): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=ActivityPoster.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActivityPoster.d.ts","sourceRoot":"","sources":["../src/ActivityPoster.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,wBAAwB,EACxB,oBAAoB,EACpB,OAAO,EACP,gBAAgB,EAChB,MAAM,YAAY,CAAC;AAEpB,qBAAa,cAAc;IAC1B,OAAO,CAAC,aAAa,CAAoC;IACzD,OAAO,CAAC,YAAY,CAAgC;IACpD,OAAO,CAAC,MAAM,CAAU;gBAGvB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,EAChD,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAC3C,MAAM,EAAE,OAAO;IAOV,kBAAkB,CACvB,YAAY,EAAE,oBAAoB,EAClC,KAAK,EAAE,wBAAwB,EAC/B,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAoBnB,yBAAyB,CAC9B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IAoBV,8BAA8B,CACnC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IAiBV,+BAA+B,CACpC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,EACtB,eAAe,EACZ,iBAAiB,GACjB,aAAa,GACb,eAAe,GACf,YAAY,GACZ,aAAa,GACb,WAAW,GACX,oBAAoB,GACpB,eAAe,GAChB,OAAO,CAAC,IAAI,CAAC;IAuCV,gCAAgC,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EAAE,EAChB,YAAY,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IAsFV,iCAAiC,CACtC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,OAAO,GAClB,OAAO,CAAC,IAAI,CAAC;IAqBV,WAAW,CAChB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;CAehB"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
export class ActivityPoster {
|
|
2
|
+
issueTrackers;
|
|
3
|
+
repositories;
|
|
4
|
+
logger;
|
|
5
|
+
constructor(issueTrackers, repositories, logger) {
|
|
6
|
+
this.issueTrackers = issueTrackers;
|
|
7
|
+
this.repositories = repositories;
|
|
8
|
+
this.logger = logger;
|
|
9
|
+
}
|
|
10
|
+
async postActivityDirect(issueTracker, input, label) {
|
|
11
|
+
try {
|
|
12
|
+
const result = await issueTracker.createAgentActivity(input);
|
|
13
|
+
if (result.success) {
|
|
14
|
+
if (result.agentActivity) {
|
|
15
|
+
const activity = await result.agentActivity;
|
|
16
|
+
this.logger.debug(`Created ${label} activity ${activity.id}`);
|
|
17
|
+
return activity.id;
|
|
18
|
+
}
|
|
19
|
+
this.logger.debug(`Created ${label}`);
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
this.logger.error(`Failed to create ${label}:`, result);
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
this.logger.error(`Error creating ${label}:`, error);
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async postInstantAcknowledgment(sessionId, repositoryId) {
|
|
31
|
+
const issueTracker = this.issueTrackers.get(repositoryId);
|
|
32
|
+
if (!issueTracker) {
|
|
33
|
+
this.logger.warn(`No issue tracker found for repository ${repositoryId}`);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
await this.postActivityDirect(issueTracker, {
|
|
37
|
+
agentSessionId: sessionId,
|
|
38
|
+
content: {
|
|
39
|
+
type: "thought",
|
|
40
|
+
body: "I've received your request and I'm starting to work on it. Let me analyze the issue and prepare my approach.",
|
|
41
|
+
},
|
|
42
|
+
}, "instant acknowledgment");
|
|
43
|
+
}
|
|
44
|
+
async postParentResumeAcknowledgment(sessionId, repositoryId) {
|
|
45
|
+
const issueTracker = this.issueTrackers.get(repositoryId);
|
|
46
|
+
if (!issueTracker) {
|
|
47
|
+
this.logger.warn(`No issue tracker found for repository ${repositoryId}`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
await this.postActivityDirect(issueTracker, {
|
|
51
|
+
agentSessionId: sessionId,
|
|
52
|
+
content: { type: "thought", body: "Resuming from child session" },
|
|
53
|
+
}, "parent resume acknowledgment");
|
|
54
|
+
}
|
|
55
|
+
async postRepositorySelectionActivity(sessionId, repositoryId, repositoryName, selectionMethod) {
|
|
56
|
+
const issueTracker = this.issueTrackers.get(repositoryId);
|
|
57
|
+
if (!issueTracker) {
|
|
58
|
+
this.logger.warn(`No issue tracker found for repository ${repositoryId}`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
let methodDisplay;
|
|
62
|
+
if (selectionMethod === "user-selected") {
|
|
63
|
+
methodDisplay = "selected by user";
|
|
64
|
+
}
|
|
65
|
+
else if (selectionMethod === "description-tag") {
|
|
66
|
+
methodDisplay = "matched via [repo=...] tag in issue description";
|
|
67
|
+
}
|
|
68
|
+
else if (selectionMethod === "label-based") {
|
|
69
|
+
methodDisplay = "matched via label-based routing";
|
|
70
|
+
}
|
|
71
|
+
else if (selectionMethod === "project-based") {
|
|
72
|
+
methodDisplay = "matched via project-based routing";
|
|
73
|
+
}
|
|
74
|
+
else if (selectionMethod === "team-based") {
|
|
75
|
+
methodDisplay = "matched via team-based routing";
|
|
76
|
+
}
|
|
77
|
+
else if (selectionMethod === "team-prefix") {
|
|
78
|
+
methodDisplay = "matched via team prefix routing";
|
|
79
|
+
}
|
|
80
|
+
else if (selectionMethod === "catch-all") {
|
|
81
|
+
methodDisplay = "matched via catch-all routing";
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
methodDisplay = "matched via workspace fallback";
|
|
85
|
+
}
|
|
86
|
+
await this.postActivityDirect(issueTracker, {
|
|
87
|
+
agentSessionId: sessionId,
|
|
88
|
+
content: {
|
|
89
|
+
type: "thought",
|
|
90
|
+
body: `Repository "${repositoryName}" has been ${methodDisplay}.`,
|
|
91
|
+
},
|
|
92
|
+
}, "repository selection");
|
|
93
|
+
}
|
|
94
|
+
async postSystemPromptSelectionThought(sessionId, labels, repositoryId) {
|
|
95
|
+
const issueTracker = this.issueTrackers.get(repositoryId);
|
|
96
|
+
if (!issueTracker) {
|
|
97
|
+
this.logger.warn(`No issue tracker found for repository ${repositoryId}`);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
// Determine which prompt type was selected and which label triggered it
|
|
101
|
+
let selectedPromptType = null;
|
|
102
|
+
let triggerLabel = null;
|
|
103
|
+
const repository = Array.from(this.repositories.values()).find((r) => r.id === repositoryId);
|
|
104
|
+
if (repository?.labelPrompts) {
|
|
105
|
+
// Check debugger labels
|
|
106
|
+
const debuggerConfig = repository.labelPrompts.debugger;
|
|
107
|
+
const debuggerLabels = Array.isArray(debuggerConfig)
|
|
108
|
+
? debuggerConfig
|
|
109
|
+
: debuggerConfig?.labels;
|
|
110
|
+
const debuggerLabel = debuggerLabels?.find((label) => labels.includes(label));
|
|
111
|
+
if (debuggerLabel) {
|
|
112
|
+
selectedPromptType = "debugger";
|
|
113
|
+
triggerLabel = debuggerLabel;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
// Check builder labels
|
|
117
|
+
const builderConfig = repository.labelPrompts.builder;
|
|
118
|
+
const builderLabels = Array.isArray(builderConfig)
|
|
119
|
+
? builderConfig
|
|
120
|
+
: builderConfig?.labels;
|
|
121
|
+
const builderLabel = builderLabels?.find((label) => labels.includes(label));
|
|
122
|
+
if (builderLabel) {
|
|
123
|
+
selectedPromptType = "builder";
|
|
124
|
+
triggerLabel = builderLabel;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
// Check scoper labels
|
|
128
|
+
const scoperConfig = repository.labelPrompts.scoper;
|
|
129
|
+
const scoperLabels = Array.isArray(scoperConfig)
|
|
130
|
+
? scoperConfig
|
|
131
|
+
: scoperConfig?.labels;
|
|
132
|
+
const scoperLabel = scoperLabels?.find((label) => labels.includes(label));
|
|
133
|
+
if (scoperLabel) {
|
|
134
|
+
selectedPromptType = "scoper";
|
|
135
|
+
triggerLabel = scoperLabel;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
// Check orchestrator labels
|
|
139
|
+
const orchestratorConfig = repository.labelPrompts.orchestrator;
|
|
140
|
+
const orchestratorLabels = Array.isArray(orchestratorConfig)
|
|
141
|
+
? orchestratorConfig
|
|
142
|
+
: (orchestratorConfig?.labels ?? ["orchestrator"]);
|
|
143
|
+
const orchestratorLabel = orchestratorLabels?.find((label) => labels.includes(label));
|
|
144
|
+
if (orchestratorLabel) {
|
|
145
|
+
selectedPromptType = "orchestrator";
|
|
146
|
+
triggerLabel = orchestratorLabel;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Only post if a role was actually triggered
|
|
153
|
+
if (!selectedPromptType || !triggerLabel) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
await this.postActivityDirect(issueTracker, {
|
|
157
|
+
agentSessionId: sessionId,
|
|
158
|
+
content: {
|
|
159
|
+
type: "thought",
|
|
160
|
+
body: `Entering '${selectedPromptType}' mode because of the '${triggerLabel}' label. I'll follow the ${selectedPromptType} process...`,
|
|
161
|
+
},
|
|
162
|
+
}, "system prompt selection");
|
|
163
|
+
}
|
|
164
|
+
async postInstantPromptedAcknowledgment(sessionId, repositoryId, isStreaming) {
|
|
165
|
+
const issueTracker = this.issueTrackers.get(repositoryId);
|
|
166
|
+
if (!issueTracker) {
|
|
167
|
+
this.logger.warn(`No issue tracker found for repository ${repositoryId}`);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const message = isStreaming
|
|
171
|
+
? "I've queued up your message as guidance"
|
|
172
|
+
: "Getting started on that...";
|
|
173
|
+
await this.postActivityDirect(issueTracker, {
|
|
174
|
+
agentSessionId: sessionId,
|
|
175
|
+
content: { type: "thought", body: message },
|
|
176
|
+
}, "prompted acknowledgment");
|
|
177
|
+
}
|
|
178
|
+
async postComment(issueId, body, repositoryId, parentId) {
|
|
179
|
+
// Get the issue tracker for this repository
|
|
180
|
+
const issueTracker = this.issueTrackers.get(repositoryId);
|
|
181
|
+
if (!issueTracker) {
|
|
182
|
+
throw new Error(`No issue tracker found for repository ${repositoryId}`);
|
|
183
|
+
}
|
|
184
|
+
const commentInput = {
|
|
185
|
+
body,
|
|
186
|
+
};
|
|
187
|
+
// Add parent ID if provided (for reply)
|
|
188
|
+
if (parentId) {
|
|
189
|
+
commentInput.parentId = parentId;
|
|
190
|
+
}
|
|
191
|
+
await issueTracker.createComment(issueId, commentInput);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=ActivityPoster.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActivityPoster.js","sourceRoot":"","sources":["../src/ActivityPoster.ts"],"names":[],"mappings":"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"}
|