opencode-heartbeat-approval 0.3.0 → 0.4.0

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 CHANGED
@@ -10,10 +10,6 @@ var __export = (target, all) => {
10
10
  });
11
11
  };
12
12
 
13
- // src/plugin.ts
14
- import { readFile } from "fs/promises";
15
- import { join } from "path";
16
-
17
13
  // node_modules/zod/v4/classic/external.js
18
14
  var exports_external = {};
19
15
  __export(exports_external, {
@@ -12337,26 +12333,6 @@ tool.schema = exports_external;
12337
12333
  // src/plugin.ts
12338
12334
  var POLL_INTERVAL_MS = 1e4;
12339
12335
  var JSON_HEADERS = { "Content-Type": "application/json" };
12340
- async function discoverRunnerUrl(directory) {
12341
- try {
12342
- const configPath = join(directory, "heartbeat.json");
12343
- const text = await readFile(configPath, "utf-8");
12344
- const config2 = JSON.parse(text);
12345
- const web = config2?.web;
12346
- const port = web?.port;
12347
- if (typeof port === "number" && Number.isInteger(port) && port > 0 && port < 65536) {
12348
- return `http://127.0.0.1:${port}`;
12349
- }
12350
- console.warn(`[heartbeat-approval] heartbeat.json found but web.port invalid: ${JSON.stringify(port)} in ${directory}`);
12351
- return null;
12352
- } catch (err) {
12353
- if (err && typeof err === "object" && "code" in err && err.code === "ENOENT") {
12354
- return null;
12355
- }
12356
- console.warn(`[heartbeat-approval] Failed to read heartbeat.json in ${directory}:`, err);
12357
- return null;
12358
- }
12359
- }
12360
12336
  async function createGate(runnerUrl, params) {
12361
12337
  const resp = await fetch(`${runnerUrl}/api/approval`, {
12362
12338
  method: "POST",
@@ -12425,12 +12401,16 @@ Returns: { status: "approved" | "rejected" | "expired" | "unavailable" | "cancel
12425
12401
  });
12426
12402
  }
12427
12403
  const requestType = args.type === "assistance" ? "assistance" : "approval";
12428
- const resolvedUrl = await discoverRunnerUrl(ctx.directory);
12404
+ const envPort = process.env.APPROVAL_PORT;
12405
+ let resolvedUrl = null;
12406
+ if (envPort && /^\d+$/.test(envPort)) {
12407
+ resolvedUrl = `http://127.0.0.1:${envPort}`;
12408
+ }
12429
12409
  if (!resolvedUrl) {
12430
12410
  return JSON.stringify({
12431
12411
  status: "unavailable",
12432
12412
  type: requestType,
12433
- error: `Cannot discover runner: no heartbeat.json with valid web.port in ${ctx.directory}`,
12413
+ error: "APPROVAL_PORT environment variable not set. Ensure this opencode serve instance has APPROVAL_PORT configured.",
12434
12414
  approval_id: null
12435
12415
  });
12436
12416
  }
package/dist/plugin.js CHANGED
@@ -10,10 +10,6 @@ var __export = (target, all) => {
10
10
  });
11
11
  };
12
12
 
13
- // src/plugin.ts
14
- import { readFile } from "fs/promises";
15
- import { join } from "path";
16
-
17
13
  // node_modules/zod/v4/classic/external.js
18
14
  var exports_external = {};
19
15
  __export(exports_external, {
@@ -12337,26 +12333,6 @@ tool.schema = exports_external;
12337
12333
  // src/plugin.ts
12338
12334
  var POLL_INTERVAL_MS = 1e4;
12339
12335
  var JSON_HEADERS = { "Content-Type": "application/json" };
12340
- async function discoverRunnerUrl(directory) {
12341
- try {
12342
- const configPath = join(directory, "heartbeat.json");
12343
- const text = await readFile(configPath, "utf-8");
12344
- const config2 = JSON.parse(text);
12345
- const web = config2?.web;
12346
- const port = web?.port;
12347
- if (typeof port === "number" && Number.isInteger(port) && port > 0 && port < 65536) {
12348
- return `http://127.0.0.1:${port}`;
12349
- }
12350
- console.warn(`[heartbeat-approval] heartbeat.json found but web.port invalid: ${JSON.stringify(port)} in ${directory}`);
12351
- return null;
12352
- } catch (err) {
12353
- if (err && typeof err === "object" && "code" in err && err.code === "ENOENT") {
12354
- return null;
12355
- }
12356
- console.warn(`[heartbeat-approval] Failed to read heartbeat.json in ${directory}:`, err);
12357
- return null;
12358
- }
12359
- }
12360
12336
  async function createGate(runnerUrl, params) {
12361
12337
  const resp = await fetch(`${runnerUrl}/api/approval`, {
12362
12338
  method: "POST",
@@ -12425,12 +12401,16 @@ Returns: { status: "approved" | "rejected" | "expired" | "unavailable" | "cancel
12425
12401
  });
12426
12402
  }
12427
12403
  const requestType = args.type === "assistance" ? "assistance" : "approval";
12428
- const resolvedUrl = await discoverRunnerUrl(ctx.directory);
12404
+ const envPort = process.env.APPROVAL_PORT;
12405
+ let resolvedUrl = null;
12406
+ if (envPort && /^\d+$/.test(envPort)) {
12407
+ resolvedUrl = `http://127.0.0.1:${envPort}`;
12408
+ }
12429
12409
  if (!resolvedUrl) {
12430
12410
  return JSON.stringify({
12431
12411
  status: "unavailable",
12432
12412
  type: requestType,
12433
- error: `Cannot discover runner: no heartbeat.json with valid web.port in ${ctx.directory}`,
12413
+ error: "APPROVAL_PORT environment variable not set. Ensure this opencode serve instance has APPROVAL_PORT configured.",
12434
12414
  approval_id: null
12435
12415
  });
12436
12416
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-heartbeat-approval",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "OpenCode plugin providing request_human_input MCP tool for Heartbeat pipeline (approval + assistance)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/plugin.ts CHANGED
@@ -1,5 +1,3 @@
1
- import { readFile } from "node:fs/promises";
2
- import { join } from "node:path";
3
1
  import { tool } from "@opencode-ai/plugin";
4
2
  import type { PluginInput } from "@opencode-ai/plugin";
5
3
 
@@ -26,32 +24,6 @@ interface ConflictResponse {
26
24
  existing_approval_id: string;
27
25
  }
28
26
 
29
- /**
30
- * Auto-discover runner URL from the session's directory.
31
- * Reads heartbeat.json in ctx.directory to find web.port.
32
- * Returns null if not found (ENOENT is expected — not a heartbeat dir).
33
- */
34
- async function discoverRunnerUrl(directory: string): Promise<string | null> {
35
- try {
36
- const configPath = join(directory, "heartbeat.json");
37
- const text = await readFile(configPath, "utf-8");
38
- const config = JSON.parse(text) as Record<string, unknown>;
39
- const web = config?.web as Record<string, unknown> | undefined;
40
- const port = web?.port;
41
- if (typeof port === "number" && Number.isInteger(port) && port > 0 && port < 65536) {
42
- return `http://127.0.0.1:${port}`;
43
- }
44
- console.warn(`[heartbeat-approval] heartbeat.json found but web.port invalid: ${JSON.stringify(port)} in ${directory}`);
45
- return null;
46
- } catch (err: unknown) {
47
- if (err && typeof err === "object" && "code" in err && (err as { code: string }).code === "ENOENT") {
48
- return null;
49
- }
50
- console.warn(`[heartbeat-approval] Failed to read heartbeat.json in ${directory}:`, err);
51
- return null;
52
- }
53
- }
54
-
55
27
  async function createGate(runnerUrl: string, params: {
56
28
  prompt: string;
57
29
  artifacts?: string[];
@@ -137,12 +109,16 @@ Returns: { status: "approved" | "rejected" | "expired" | "unavailable" | "cancel
137
109
  }
138
110
  const requestType = (args.type === "assistance" ? "assistance" : "approval") as "approval" | "assistance";
139
111
 
140
- const resolvedUrl = await discoverRunnerUrl(ctx.directory);
112
+ const envPort = process.env.APPROVAL_PORT;
113
+ let resolvedUrl: string | null = null;
114
+ if (envPort && /^\d+$/.test(envPort)) {
115
+ resolvedUrl = `http://127.0.0.1:${envPort}`;
116
+ }
141
117
  if (!resolvedUrl) {
142
118
  return JSON.stringify({
143
119
  status: "unavailable",
144
120
  type: requestType,
145
- error: `Cannot discover runner: no heartbeat.json with valid web.port in ${ctx.directory}`,
121
+ error: "APPROVAL_PORT environment variable not set. Ensure this opencode serve instance has APPROVAL_PORT configured.",
146
122
  approval_id: null,
147
123
  });
148
124
  }