opengate 0.2.4 → 0.2.9

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.d.ts CHANGED
@@ -1,5 +1,12 @@
1
+ import * as openclaw_plugin_sdk from 'openclaw/plugin-sdk';
1
2
  import { OpenClawPluginApi } from 'openclaw/plugin-sdk';
2
3
 
3
- declare function register(api: OpenClawPluginApi): void;
4
+ declare const _default: {
5
+ id: string;
6
+ name: string;
7
+ description: string;
8
+ configSchema: openclaw_plugin_sdk.OpenClawPluginConfigSchema;
9
+ register(api: OpenClawPluginApi): void;
10
+ };
4
11
 
5
- export { register as default };
12
+ export { _default as default };
package/dist/index.js CHANGED
@@ -1,3 +1,6 @@
1
+ // src/index.ts
2
+ import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
3
+
1
4
  // src/config.ts
2
5
  function resolveConfig(raw) {
3
6
  const url = typeof raw.url === "string" ? raw.url.replace(/\/$/, "") : "";
@@ -263,7 +266,10 @@ async function fetchInbox(url, apiKey) {
263
266
  throw new Error(`OpenGate inbox returned HTTP ${resp.status}`);
264
267
  }
265
268
  const body = await resp.json();
266
- return body.todo_tasks ?? [];
269
+ return {
270
+ todoTasks: body.todo_tasks ?? [],
271
+ inProgressTasks: body.in_progress_tasks ?? []
272
+ };
267
273
  }
268
274
  var OpenGatePoller = class {
269
275
  constructor(pluginCfg, openclawCfg, logger, stateDir) {
@@ -302,18 +308,26 @@ var OpenGatePoller = class {
302
308
  );
303
309
  return;
304
310
  }
305
- let tasks;
311
+ let inbox;
306
312
  try {
307
- tasks = await fetchInbox(this.pluginCfg.url, this.pluginCfg.apiKey);
313
+ inbox = await fetchInbox(this.pluginCfg.url, this.pluginCfg.apiKey);
308
314
  } catch (e) {
309
315
  this.logger.warn(
310
316
  `[opengate] Failed to fetch inbox: ${e instanceof Error ? e.message : String(e)}`
311
317
  );
312
318
  return;
313
319
  }
314
- if (tasks.length === 0) return;
315
- this.logger.info(`[opengate] Found ${tasks.length} todo task(s)`);
316
- for (const task of tasks) {
320
+ for (const task of inbox.inProgressTasks) {
321
+ if (!this.state.isSpawned(task.id)) {
322
+ this.logger.warn(
323
+ `[opengate] Orphaned in_progress task "${task.title}" (${task.id}) \u2014 releasing back to todo`
324
+ );
325
+ await this.releaseTask(task.id);
326
+ }
327
+ }
328
+ if (inbox.todoTasks.length === 0) return;
329
+ this.logger.info(`[opengate] Found ${inbox.todoTasks.length} todo task(s)`);
330
+ for (const task of inbox.todoTasks) {
317
331
  if (!this.running) break;
318
332
  const currentActive = this.state.activeCount();
319
333
  if (currentActive >= maxConcurrent) {
@@ -336,6 +350,25 @@ var OpenGatePoller = class {
336
350
  if (project) this.projectCache.set(projectId, project);
337
351
  return project;
338
352
  }
353
+ async releaseTask(taskId) {
354
+ try {
355
+ const resp = await fetch(
356
+ `${this.pluginCfg.url}/api/tasks/${taskId}/release`,
357
+ {
358
+ method: "POST",
359
+ headers: { Authorization: `Bearer ${this.pluginCfg.apiKey}` },
360
+ signal: AbortSignal.timeout(1e4)
361
+ }
362
+ );
363
+ if (!resp.ok) {
364
+ this.logger.warn(`[opengate] Failed to release task ${taskId}: HTTP ${resp.status}`);
365
+ }
366
+ } catch (e) {
367
+ this.logger.warn(
368
+ `[opengate] Failed to release task ${taskId}: ${e instanceof Error ? e.message : String(e)}`
369
+ );
370
+ }
371
+ }
339
372
  async spawnTask(task) {
340
373
  this.logger.info(`[opengate] Spawning session for task: "${task.title}" (${task.id})`);
341
374
  let project = null;
@@ -367,34 +400,40 @@ var OpenGatePoller = class {
367
400
  };
368
401
 
369
402
  // src/index.ts
370
- function register(api) {
371
- let poller = null;
372
- let pluginCfg;
373
- try {
374
- pluginCfg = resolveConfig(api.pluginConfig ?? {});
375
- } catch (e) {
376
- api.logger.error(e instanceof Error ? e.message : String(e));
377
- return;
378
- }
379
- const hooksToken = api.config?.hooks?.token;
380
- if (!hooksToken) {
381
- api.logger.error(
382
- '[opengate] hooks.token is not configured. Add the following to your OpenClaw config to enable task spawning:\n "hooks": { "enabled": true, "token": "<your-secret>", "allowRequestSessionKey": true, "allowedSessionKeyPrefixes": ["opengate-task:"] }'
383
- );
384
- return;
385
- }
386
- api.registerService({
387
- id: "opengate-poller",
388
- start(ctx) {
389
- poller = new OpenGatePoller(pluginCfg, api.config, ctx.logger, ctx.stateDir);
390
- poller.start();
391
- },
392
- stop(ctx) {
393
- poller?.stop();
394
- poller = null;
403
+ var index_default = {
404
+ id: "opengate",
405
+ name: "OpenGate",
406
+ description: "Polls OpenGate for assigned tasks and spawns isolated OpenClaw sessions to execute them. Turns OpenGate into the orchestrator.",
407
+ configSchema: emptyPluginConfigSchema(),
408
+ register(api) {
409
+ let poller = null;
410
+ let pluginCfg;
411
+ try {
412
+ pluginCfg = resolveConfig(api.pluginConfig ?? {});
413
+ } catch (e) {
414
+ api.logger.error(e instanceof Error ? e.message : String(e));
415
+ return;
395
416
  }
396
- });
397
- }
417
+ const hooksToken = api.config?.hooks?.token;
418
+ if (!hooksToken) {
419
+ api.logger.error(
420
+ '[opengate] hooks.token is not configured. Add the following to your OpenClaw config to enable task spawning:\n "hooks": { "enabled": true, "token": "<your-secret>", "allowRequestSessionKey": true, "allowedSessionKeyPrefixes": ["opengate-task:"] }'
421
+ );
422
+ return;
423
+ }
424
+ api.registerService({
425
+ id: "opengate-poller",
426
+ start(ctx) {
427
+ poller = new OpenGatePoller(pluginCfg, api.config, ctx.logger, ctx.stateDir);
428
+ poller.start();
429
+ },
430
+ stop(ctx) {
431
+ poller?.stop();
432
+ poller = null;
433
+ }
434
+ });
435
+ }
436
+ };
398
437
  export {
399
- register as default
438
+ index_default as default
400
439
  };
@@ -2,12 +2,11 @@
2
2
  "id": "opengate",
3
3
  "name": "OpenGate",
4
4
  "description": "Polls OpenGate for assigned tasks and spawns isolated OpenClaw sessions to execute them. Turns OpenGate into the orchestrator.",
5
- "version": "0.2.4",
5
+ "version": "0.2.8",
6
6
  "skills": ["./skills/opengate"],
7
7
  "configSchema": {
8
8
  "type": "object",
9
9
  "additionalProperties": false,
10
- "required": ["url", "apiKey"],
11
10
  "properties": {
12
11
  "url": {
13
12
  "type": "string",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opengate",
3
- "version": "0.2.4",
3
+ "version": "0.2.9",
4
4
  "description": "OpenGate task executor plugin for OpenClaw — polls assigned tasks and spawns isolated agent sessions",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -26,7 +26,11 @@
26
26
  "openclaw": {
27
27
  "extensions": [
28
28
  "./dist/index.js"
29
- ]
29
+ ],
30
+ "install": {
31
+ "npmSpec": "opengate",
32
+ "defaultChoice": "npm"
33
+ }
30
34
  },
31
35
  "publishConfig": {
32
36
  "access": "public"