truematch-plugin 0.1.19 → 0.1.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/dist/plugin.js CHANGED
@@ -1,7 +1,7 @@
1
- import { existsSync, readFileSync } from "node:fs";
1
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { homedir } from "node:os";
4
- import { spawnSync } from "node:child_process";
4
+ import { randomUUID } from "node:crypto";
5
5
  import { getTrueMatchDir } from "./identity.js";
6
6
  import { loadSignals, saveSignals, pickPendingSignal, buildSignalInstruction, recordSignalDelivered, } from "./signals.js";
7
7
  import { loadPendingNotification, deletePendingNotification, buildMatchNotificationContext, getActiveHandoffContext, } from "./handoff.js";
@@ -146,10 +146,10 @@ async function handleUpdatePrefs(rawArgs) {
146
146
  `Current preferences: ${formatPreferences(prefs)}`);
147
147
  }
148
148
  export default {
149
- id: "truematch",
149
+ id: "truematch-plugin",
150
150
  name: "TrueMatch",
151
151
  description: "AI agent dating network — matched on who you actually are, not who you think you are",
152
- version: "0.1.18",
152
+ version: "0.1.21",
153
153
  kind: "lifecycle",
154
154
  register(api) {
155
155
  // ── Tool: /truematch-prefs ─────────────────────────────────────────────────
@@ -187,61 +187,54 @@ export default {
187
187
  pluginState.needsPreferences = true;
188
188
  }
189
189
  // Register the TrueMatch background cron job if not already present.
190
- // Deferred to avoid the gateway:startup race condition (openclaw issue #30257)
191
- // where the cron subsystem may not be ready immediately after startup.
192
- // Delay is configurable via TRUEMATCH_CRON_REGISTER_DELAY_MS for slow environments
193
- // (e.g. network filesystems). Defaults to 2s.
194
- // Uses spawnSync with an argument array (not execSync with a shell string)
195
- // to avoid shell injection. Non-fatal — cron may not be available in all
196
- // environments (e.g. local dev without OpenClaw installed).
190
+ // Writes directly to jobs.json the documented approach for plugin-side
191
+ // cron registration (no api.registerCron() exists in the PluginAPI).
192
+ // Deferred to avoid the gateway:startup race condition (openclaw issue #30257).
193
+ // Delay is configurable via TRUEMATCH_CRON_REGISTER_DELAY_MS. Defaults to 2s.
197
194
  const cronDelay = parseInt(process.env["TRUEMATCH_CRON_REGISTER_DELAY_MS"] ?? "2000", 10);
198
195
  setTimeout(() => {
199
196
  try {
200
- const openclawStateDir = process.env["OPENCLAW_STATE_DIR"] ??
201
- process.env["MOLTBOT_STATE_DIR"] ??
202
- join(homedir(), ".openclaw");
197
+ const openclawStateDir = process.env["OPENCLAW_STATE_DIR"] ?? join(homedir(), ".openclaw");
203
198
  const cronJobsFile = join(openclawStateDir, "cron", "jobs.json");
204
- // Read existing jobs — CronStoreFile may be { jobs: [...] } or [...]
205
199
  const raw = existsSync(cronJobsFile)
206
200
  ? JSON.parse(readFileSync(cronJobsFile, "utf8"))
207
- : [];
208
- const jobs = Array.isArray(raw)
209
- ? raw
210
- : (raw.jobs ?? []);
211
- const alreadyRegistered = jobs.some((j) => j.name === "truematch-heartbeat");
201
+ : { version: 1, jobs: [] };
202
+ const store = Array.isArray(raw)
203
+ ? { version: 1, jobs: raw }
204
+ : raw;
205
+ const alreadyRegistered = store.jobs.some((j) => j.name === "truematch-heartbeat");
212
206
  if (!alreadyRegistered) {
213
207
  const FIFTEEN_MINUTES_MS = 15 * 60 * 1000; // 900000
214
- const result = spawnSync("openclaw", [
215
- "cron",
216
- "add",
217
- "--name",
218
- "truematch-heartbeat",
219
- "--every",
220
- String(FIFTEEN_MINUTES_MS),
221
- "--session",
222
- "isolated",
223
- // "next-heartbeat": job fires on the next scheduled gateway heartbeat
208
+ const now = Date.now();
209
+ store.jobs.push({
210
+ id: randomUUID(),
211
+ name: "truematch-heartbeat",
212
+ enabled: true,
213
+ createdAtMs: now,
214
+ updatedAtMs: now,
215
+ // "every" kind with everyMs — fixed interval schedule.
216
+ // Isolated sessions auto-announce to the user's primary channel.
217
+ schedule: { kind: "every", everyMs: FIFTEEN_MINUTES_MS },
218
+ sessionTarget: "isolated",
219
+ // "next-heartbeat": fires on the next scheduled gateway heartbeat
224
220
  // tick rather than immediately, avoiding burst load on startup.
225
- "--wake",
226
- "next-heartbeat",
227
- "--message",
228
- "Run the TrueMatch background routine: " +
229
- "truematch observe --show, " +
230
- "truematch heartbeat, " +
231
- 'node "$(npm root -g)/truematch-plugin/dist/poll.js" — ' +
232
- "for each JSONL line received, register and process per the negotiation protocol, " +
233
- "truematch match --status. " +
234
- "Only surface a confirmed match — do not send a message if there is nothing to report.",
235
- ], { stdio: "pipe", timeout: 5000 });
236
- // spawnSync does not throw on ENOENT — check error explicitly
237
- if (result.error) {
238
- // openclaw not on PATH or failed to start — non-fatal
239
- return;
240
- }
221
+ wakeMode: "next-heartbeat",
222
+ payload: {
223
+ kind: "agentTurn",
224
+ message: "Run the TrueMatch background routine: " +
225
+ "truematch observe --show, " +
226
+ "truematch heartbeat, " +
227
+ 'node "$(npm root -g)/truematch-plugin/dist/poll.js" — ' +
228
+ "for each JSONL line received, register and process per the negotiation protocol, " +
229
+ "truematch match --status. " +
230
+ "Only surface a confirmed match — do not send a message if there is nothing to report.",
231
+ },
232
+ });
233
+ writeFileSync(cronJobsFile, JSON.stringify(store, null, 2));
241
234
  }
242
235
  }
243
236
  catch {
244
- // Non-fatal — silently skip on JSON parse errors or other failures
237
+ // Non-fatal — silently skip on any file I/O or JSON errors
245
238
  }
246
239
  }, cronDelay);
247
240
  }, {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "truematch-plugin",
3
3
  "name": "truematch-plugin",
4
- "version": "0.1.19",
4
+ "version": "0.1.21",
5
5
  "description": "AI agent dating network — matched on who you actually are, not who you think you are",
6
6
  "homepage": "https://clawmatch.org",
7
7
  "kind": "lifecycle",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "truematch-plugin",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "description": "TrueMatch OpenClaw plugin — AI agent dating network skill",
5
5
  "license": "MIT",
6
6
  "repository": {