opengate 0.2.8 → 0.2.11
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/dist/index.js +96 -21
- package/package.json +1 -1
- package/skills/opengate/SKILL.md +54 -14
package/dist/index.js
CHANGED
|
@@ -95,9 +95,11 @@ Before writing any code, gather all available context:
|
|
|
95
95
|
- Read any returned entries \u2014 they contain architecture decisions, patterns, gotchas, and conventions for this project
|
|
96
96
|
- Follow these conventions in your implementation
|
|
97
97
|
|
|
98
|
-
### Phase 3: Plan & Announce
|
|
98
|
+
### Phase 3: Plan & Announce (REQUIRED)
|
|
99
99
|
4. **Post starting comment** \u2014 \`POST /api/tasks/${task.id}/activity\`
|
|
100
|
-
Body: \`{"content": "Starting
|
|
100
|
+
Body: \`{"content": "## Starting Work\\n\\n**Plan:**\\n- <step 1>\\n- <step 2>\\n\\n**Context from KB:** <what you learned>\\n\\n**Concerns:** <any blockers or risks>"}\`
|
|
101
|
+
|
|
102
|
+
This comment is REQUIRED. Do not skip it.
|
|
101
103
|
- Your plan should reflect what you learned from the knowledge base, existing comments, and dependencies
|
|
102
104
|
|
|
103
105
|
${workspaceBlock}
|
|
@@ -109,15 +111,32 @@ ${workspaceBlock}
|
|
|
109
111
|
- Run the project's test suite and fix any failures
|
|
110
112
|
- Commit your changes with a descriptive message referencing the task
|
|
111
113
|
|
|
112
|
-
### Phase
|
|
114
|
+
### Phase 5.5: Knowledge Review (MANDATORY)
|
|
115
|
+
Before completing the task, review your work and ask yourself:
|
|
116
|
+
- Did I make an architecture or design decision? \u2192 Write it (category: "decision" or "architecture")
|
|
117
|
+
- Did I encounter a non-obvious gotcha or bug? \u2192 Write it (category: "gotcha")
|
|
118
|
+
- Did I establish or follow a pattern others should know? \u2192 Write it (category: "pattern")
|
|
119
|
+
- Did I discover project structure or conventions? \u2192 Write it (category: "reference")
|
|
120
|
+
|
|
121
|
+
If ANY of the above apply, write knowledge entries BEFORE completing:
|
|
122
|
+
\`PUT /api/projects/${projectId}/knowledge/<descriptive-key>\`
|
|
123
|
+
Body: \`{"title": "...", "content": "...", "tags": [...], "category": "..."}\`
|
|
124
|
+
|
|
125
|
+
Key naming: use kebab-case descriptors, e.g. "auth-middleware-pattern", "db-migration-gotcha"
|
|
126
|
+
|
|
127
|
+
IMPORTANT: Only write PROJECT-SCOPED knowledge. Do NOT write task-specific details.
|
|
128
|
+
Good: "The API uses tower middleware for auth, not axum extractors"
|
|
129
|
+
Bad: "Task T-123 required adding a new endpoint"
|
|
130
|
+
|
|
131
|
+
If nothing new was discovered, that's fine \u2014 skip this phase.
|
|
132
|
+
|
|
133
|
+
### Phase 6: Report & Complete (REQUIRED)
|
|
113
134
|
8. **Post results comment** \u2014 \`POST /api/tasks/${task.id}/activity\`
|
|
114
|
-
Body: \`{"content": "<
|
|
135
|
+
Body: \`{"content": "## Results\\n\\n**Changes:**\\n- <file1>: <what changed>\\n- <file2>: <what changed>\\n\\n**Approach:** <brief explanation>\\n\\n**Tests:** <pass/fail status>\\n\\n**Commits:** <hash(es)>"}\`
|
|
115
136
|
|
|
116
|
-
|
|
117
|
-
Body: \`{"title": "...", "content": "...", "tags": [...], "category": "<architecture|pattern|gotcha|decision|reference>"}\`
|
|
118
|
-
- Write entries for: architectural decisions you made, gotchas you encountered, patterns you established
|
|
137
|
+
This comment is REQUIRED. Do not skip it.
|
|
119
138
|
|
|
120
|
-
|
|
139
|
+
9. **Complete the task** \u2014 \`POST /api/tasks/${task.id}/complete\`
|
|
121
140
|
Body: \`{"summary": "<what was done>", "output": {"branch": "<branch-name>", "commits": ["<hash>"]}}\`
|
|
122
141
|
|
|
123
142
|
## Handling Blockers
|
|
@@ -137,6 +156,16 @@ If a dependency is not yet done:
|
|
|
137
156
|
- Respect existing patterns found in the knowledge base
|
|
138
157
|
- Keep commits atomic and descriptive
|
|
139
158
|
|
|
159
|
+
## Handling @-Mentions
|
|
160
|
+
If you receive a \`task.comment_mention\` notification:
|
|
161
|
+
1. Read the comment content from the notification body
|
|
162
|
+
2. Fetch the full task context: \`GET /api/tasks/{taskId}\`
|
|
163
|
+
3. Reason about what's being asked:
|
|
164
|
+
- If it's a question \u2192 post a reply comment with your answer
|
|
165
|
+
- If it's a request for changes \u2192 update task status to in_progress, make the changes, then re-complete
|
|
166
|
+
- If it's a simple acknowledgment \u2192 post a brief confirmation comment
|
|
167
|
+
4. Always reply with a comment so the human knows you've seen it
|
|
168
|
+
|
|
140
169
|
Now begin. Start with Phase 1: claim the task.`;
|
|
141
170
|
}
|
|
142
171
|
|
|
@@ -241,6 +270,10 @@ var TaskState = class {
|
|
|
241
270
|
activeCount() {
|
|
242
271
|
return Object.keys(this.data.spawned).length;
|
|
243
272
|
}
|
|
273
|
+
/** Returns all task IDs currently in the spawned set. */
|
|
274
|
+
spawnedIds() {
|
|
275
|
+
return Object.keys(this.data.spawned);
|
|
276
|
+
}
|
|
244
277
|
};
|
|
245
278
|
|
|
246
279
|
// src/poller.ts
|
|
@@ -266,7 +299,10 @@ async function fetchInbox(url, apiKey) {
|
|
|
266
299
|
throw new Error(`OpenGate inbox returned HTTP ${resp.status}`);
|
|
267
300
|
}
|
|
268
301
|
const body = await resp.json();
|
|
269
|
-
return
|
|
302
|
+
return {
|
|
303
|
+
todoTasks: body.todo_tasks ?? [],
|
|
304
|
+
inProgressTasks: body.in_progress_tasks ?? []
|
|
305
|
+
};
|
|
270
306
|
}
|
|
271
307
|
var OpenGatePoller = class {
|
|
272
308
|
constructor(pluginCfg, openclawCfg, logger, stateDir) {
|
|
@@ -297,6 +333,35 @@ var OpenGatePoller = class {
|
|
|
297
333
|
}
|
|
298
334
|
async poll() {
|
|
299
335
|
if (!this.running) return;
|
|
336
|
+
let inbox;
|
|
337
|
+
try {
|
|
338
|
+
inbox = await fetchInbox(this.pluginCfg.url, this.pluginCfg.apiKey);
|
|
339
|
+
} catch (e) {
|
|
340
|
+
this.logger.warn(
|
|
341
|
+
`[opengate] Failed to fetch inbox: ${e instanceof Error ? e.message : String(e)}`
|
|
342
|
+
);
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
const inboxTaskIds = /* @__PURE__ */ new Set([
|
|
346
|
+
...inbox.todoTasks.map((t) => t.id),
|
|
347
|
+
...inbox.inProgressTasks.map((t) => t.id)
|
|
348
|
+
]);
|
|
349
|
+
for (const spawnedId of this.state.spawnedIds()) {
|
|
350
|
+
if (!inboxTaskIds.has(spawnedId)) {
|
|
351
|
+
this.logger.info(
|
|
352
|
+
`[opengate] Task ${spawnedId} no longer in inbox (completed/cancelled) \u2014 freeing slot`
|
|
353
|
+
);
|
|
354
|
+
this.state.remove(spawnedId);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
for (const task of inbox.inProgressTasks) {
|
|
358
|
+
if (!this.state.isSpawned(task.id)) {
|
|
359
|
+
this.logger.warn(
|
|
360
|
+
`[opengate] Orphaned in_progress task "${task.title}" (${task.id}) \u2014 releasing back to todo`
|
|
361
|
+
);
|
|
362
|
+
await this.releaseTask(task.id);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
300
365
|
const maxConcurrent = this.pluginCfg.maxConcurrent ?? 3;
|
|
301
366
|
const active = this.state.activeCount();
|
|
302
367
|
if (active >= maxConcurrent) {
|
|
@@ -305,18 +370,9 @@ var OpenGatePoller = class {
|
|
|
305
370
|
);
|
|
306
371
|
return;
|
|
307
372
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
} catch (e) {
|
|
312
|
-
this.logger.warn(
|
|
313
|
-
`[opengate] Failed to fetch inbox: ${e instanceof Error ? e.message : String(e)}`
|
|
314
|
-
);
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
if (tasks.length === 0) return;
|
|
318
|
-
this.logger.info(`[opengate] Found ${tasks.length} todo task(s)`);
|
|
319
|
-
for (const task of tasks) {
|
|
373
|
+
if (inbox.todoTasks.length === 0) return;
|
|
374
|
+
this.logger.info(`[opengate] Found ${inbox.todoTasks.length} todo task(s)`);
|
|
375
|
+
for (const task of inbox.todoTasks) {
|
|
320
376
|
if (!this.running) break;
|
|
321
377
|
const currentActive = this.state.activeCount();
|
|
322
378
|
if (currentActive >= maxConcurrent) {
|
|
@@ -339,6 +395,25 @@ var OpenGatePoller = class {
|
|
|
339
395
|
if (project) this.projectCache.set(projectId, project);
|
|
340
396
|
return project;
|
|
341
397
|
}
|
|
398
|
+
async releaseTask(taskId) {
|
|
399
|
+
try {
|
|
400
|
+
const resp = await fetch(
|
|
401
|
+
`${this.pluginCfg.url}/api/tasks/${taskId}/release`,
|
|
402
|
+
{
|
|
403
|
+
method: "POST",
|
|
404
|
+
headers: { Authorization: `Bearer ${this.pluginCfg.apiKey}` },
|
|
405
|
+
signal: AbortSignal.timeout(1e4)
|
|
406
|
+
}
|
|
407
|
+
);
|
|
408
|
+
if (!resp.ok) {
|
|
409
|
+
this.logger.warn(`[opengate] Failed to release task ${taskId}: HTTP ${resp.status}`);
|
|
410
|
+
}
|
|
411
|
+
} catch (e) {
|
|
412
|
+
this.logger.warn(
|
|
413
|
+
`[opengate] Failed to release task ${taskId}: ${e instanceof Error ? e.message : String(e)}`
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
342
417
|
async spawnTask(task) {
|
|
343
418
|
this.logger.info(`[opengate] Spawning session for task: "${task.title}" (${task.id})`);
|
|
344
419
|
let project = null;
|
package/package.json
CHANGED
package/skills/opengate/SKILL.md
CHANGED
|
@@ -95,14 +95,24 @@ Specifically look for:
|
|
|
95
95
|
|
|
96
96
|
This enforces capacity limits and dependency checks. If claiming fails, read the error — you may have too many tasks in progress or a dependency is incomplete.
|
|
97
97
|
|
|
98
|
-
### 5. Comment: Starting Work
|
|
98
|
+
### 5. Comment: Starting Work (REQUIRED)
|
|
99
99
|
|
|
100
100
|
`post_comment(task_id, content)` → Post a comment before you start
|
|
101
101
|
|
|
102
|
-
Your starting comment
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
102
|
+
Your starting comment MUST use this structure:
|
|
103
|
+
```
|
|
104
|
+
## Starting Work
|
|
105
|
+
|
|
106
|
+
**Plan:**
|
|
107
|
+
- <step 1>
|
|
108
|
+
- <step 2>
|
|
109
|
+
|
|
110
|
+
**Context from KB:** <what you learned>
|
|
111
|
+
|
|
112
|
+
**Concerns:** <any blockers or risks>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Do NOT skip this comment. It is how the team tracks work and maintains visibility.
|
|
106
116
|
|
|
107
117
|
### 6. Do the Work
|
|
108
118
|
|
|
@@ -125,7 +135,28 @@ Store useful artifacts like:
|
|
|
125
135
|
- Links to PRs, commits, or external resources
|
|
126
136
|
- Feature branch name (e.g. `task/<task_id_short>`) for workspace continuity
|
|
127
137
|
|
|
128
|
-
### 9.
|
|
138
|
+
### 9. Post Results Comment (REQUIRED)
|
|
139
|
+
|
|
140
|
+
`post_comment(task_id, content)` → Post a final results comment
|
|
141
|
+
|
|
142
|
+
Your results comment MUST use this structure:
|
|
143
|
+
```
|
|
144
|
+
## Results
|
|
145
|
+
|
|
146
|
+
**Changes:**
|
|
147
|
+
- <file1>: <what changed>
|
|
148
|
+
- <file2>: <what changed>
|
|
149
|
+
|
|
150
|
+
**Approach:** <brief explanation>
|
|
151
|
+
|
|
152
|
+
**Tests:** <pass/fail status>
|
|
153
|
+
|
|
154
|
+
**Commits:** <hash(es)>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Do NOT skip this comment. It is critical for reviewers and future reference.
|
|
158
|
+
|
|
159
|
+
### 10. Complete the Task
|
|
129
160
|
|
|
130
161
|
`complete_task(task_id, summary, output)` → Finish the task with a summary and structured output
|
|
131
162
|
|
|
@@ -181,19 +212,28 @@ If a dependency is no longer needed:
|
|
|
181
212
|
- **References** — links, docs, external resources
|
|
182
213
|
- **General** — anything else worth knowing
|
|
183
214
|
|
|
184
|
-
### Writing Knowledge
|
|
215
|
+
### Writing Knowledge (MANDATORY Review)
|
|
185
216
|
|
|
186
|
-
|
|
217
|
+
Before completing any task, review your work with this checklist:
|
|
218
|
+
|
|
219
|
+
- [ ] Did I make an architecture or design decision? → Write it (category: `decision` or `architecture`)
|
|
220
|
+
- [ ] Did I encounter a non-obvious gotcha or bug? → Write it (category: `gotcha`)
|
|
221
|
+
- [ ] Did I establish or follow a pattern others should know? → Write it (category: `pattern`)
|
|
222
|
+
- [ ] Did I discover project structure or conventions? → Write it (category: `reference`)
|
|
223
|
+
|
|
224
|
+
If ANY apply, write knowledge entries BEFORE completing:
|
|
187
225
|
|
|
188
226
|
`set_knowledge(project_id, key, title, content, tags, category)`
|
|
189
227
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
-
|
|
194
|
-
-
|
|
228
|
+
Key naming: use kebab-case descriptors, e.g. `auth-middleware-pattern`, `db-migration-gotcha`
|
|
229
|
+
|
|
230
|
+
**IMPORTANT: Only write PROJECT-SCOPED knowledge.** Do NOT write task-specific details.
|
|
231
|
+
- Good: "The API uses tower middleware for auth, not axum extractors"
|
|
232
|
+
- Bad: "Task T-123 required adding a new endpoint"
|
|
233
|
+
|
|
234
|
+
If nothing new was discovered, that's fine — skip writing.
|
|
195
235
|
|
|
196
|
-
Categories: `architecture`, `
|
|
236
|
+
Categories: `architecture`, `pattern`, `gotcha`, `decision`, `reference`
|
|
197
237
|
|
|
198
238
|
## Agent Profile
|
|
199
239
|
|