@saleso.innovations/bridge 0.1.15 → 0.1.16

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/INTEGRATION.md CHANGED
@@ -109,6 +109,17 @@ Codes expire after 10 minutes. Each code links **one** Hermes instance to **one*
109
109
 
110
110
  After first pairing, credentials are saved to `~/.cleos/agent.json`. Delivered cron files are tracked in `~/.cleos/cron-delivered.json` so restarts do not duplicate Jobs. Use `reconnectHermesAgent()` on restart — no new pairing code required.
111
111
 
112
+ ### Recover missed cron results
113
+
114
+ If cron results reached Telegram but not Cleos (for example after a bridge restart), re-deliver pending output files:
115
+
116
+ ```bash
117
+ cleos-bridge cron-backfill --list # inspect pending files
118
+ cleos-bridge cron-backfill --reset # clear delivery index and re-send all output files
119
+ ```
120
+
121
+ Keep `cleos-bridge start` running so new cron runs are forwarded automatically.
122
+
112
123
  ## Self-hosting Cleos
113
124
 
114
125
  Set `CLEOS_CONVEX_SITE_URL` in the Hermes build to your Convex `.site` URL instead of the default.
package/README.md CHANGED
@@ -34,7 +34,7 @@ This installs the latest package, refreshes the CLI symlink, and restarts `cleos
34
34
  To pin a specific release (e.g. after a Cleos update):
35
35
 
36
36
  ```bash
37
- curl -fsSL https://amicable-elephant-407.convex.site/update-bridge.sh | bash -s -- 0.1.15
37
+ curl -fsSL https://amicable-elephant-407.convex.site/update-bridge.sh | bash -s -- 0.1.16
38
38
  ```
39
39
 
40
40
  ## Manual usage
@@ -58,6 +58,13 @@ Credentials are saved to `~/.cleos/agent.json`.
58
58
 
59
59
  The daemon watches `~/.hermes/cron/output/` and forwards new cron results to the Cleos Jobs tab automatically.
60
60
 
61
+ To recover missed cron output (for example after a bridge restart):
62
+
63
+ ```bash
64
+ cleos-bridge cron-backfill --list
65
+ cleos-bridge cron-backfill --reset
66
+ ```
67
+
61
68
  ## Hermes API
62
69
 
63
70
  By default the bridge forwards chat to Hermes at `http://127.0.0.1:8642/v1/chat/completions`.
package/dist/cli.js CHANGED
@@ -8,6 +8,7 @@ import { prepareHermesForBridge } from "./ensureHermesApi.js";
8
8
  import { createHermesMessageHandler } from "./hermesForwarder.js";
9
9
  import { convexSiteUrlFromEnv } from "./resolve.js";
10
10
  import { normalizePairingCode } from "./normalizePairingCode.js";
11
+ import { backfillCronDeliveries, describeCronDeliveryState } from "./cronBackfill.js";
11
12
  async function main() {
12
13
  const [, , command, codeArg] = process.argv;
13
14
  const onUserMessage = createHermesMessageHandler();
@@ -70,6 +71,28 @@ async function main() {
70
71
  runBridgeUpdate({ tag: codeArg || "latest" });
71
72
  return;
72
73
  }
74
+ if (command === "cron-backfill") {
75
+ const reset = process.argv.includes("--reset");
76
+ const listOnly = process.argv.includes("--list");
77
+ if (listOnly) {
78
+ const state = describeCronDeliveryState();
79
+ console.log(JSON.stringify({ event: "cleos-bridge.cron-backfill.list", ...state }, null, 2));
80
+ return;
81
+ }
82
+ const session = await reconnectHermesAgent({ onUserMessage });
83
+ try {
84
+ const summary = await backfillCronDeliveries(session, { reset });
85
+ console.log(JSON.stringify({ event: "cleos-bridge.cron-backfill.complete", ...summary }, null, 2));
86
+ if (summary.remainingCount > 0) {
87
+ console.error(`${summary.remainingCount} cron file(s) still pending. Keep cleos-bridge running or retry when relay is connected.`);
88
+ process.exitCode = 1;
89
+ }
90
+ }
91
+ finally {
92
+ session.close();
93
+ }
94
+ return;
95
+ }
73
96
  printUsage();
74
97
  process.exit(1);
75
98
  }
@@ -80,6 +103,8 @@ function printUsage() {
80
103
  console.error(" cleos-bridge start [CODE] Run as a reconnecting daemon (systemd)");
81
104
  console.error(" cleos-bridge reconnect Reconnect once using saved credentials");
82
105
  console.error(" cleos-bridge update [TAG] Update package and restart systemd service");
106
+ console.error(" cleos-bridge cron-backfill [--reset] [--list]");
107
+ console.error(" Re-deliver pending cron output files to Cleos");
83
108
  }
84
109
  async function waitForExit(session, onStart) {
85
110
  const stop = onStart?.();
@@ -0,0 +1,16 @@
1
+ import type { ConnectResult } from "./client.js";
2
+ export type CronBackfillSummary = {
3
+ clearedEntries: number;
4
+ pendingBefore: number;
5
+ deliveredCount: number;
6
+ remainingCount: number;
7
+ };
8
+ export declare function describeCronDeliveryState(): {
9
+ outputFileCount: number;
10
+ deliveredCount: number;
11
+ pendingFiles: string[];
12
+ };
13
+ export declare function backfillCronDeliveries(session: ConnectResult, options: {
14
+ reset: boolean;
15
+ }): Promise<CronBackfillSummary>;
16
+ //# sourceMappingURL=cronBackfill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cronBackfill.d.ts","sourceRoot":"","sources":["../src/cronBackfill.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AASjD,MAAM,MAAM,mBAAmB,GAAG;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,wBAAgB,yBAAyB,IAAI;IAC3C,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAUA;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAE9B"}
@@ -0,0 +1,14 @@
1
+ import { listCronOutputFiles, listPendingCronFiles, readDeliveredIndex, relativeOutputKey, runCronBackfill, } from "./cronWatcher.js";
2
+ export function describeCronDeliveryState() {
3
+ const delivered = readDeliveredIndex();
4
+ const outputFiles = listCronOutputFiles();
5
+ const pendingFiles = listPendingCronFiles(delivered);
6
+ return {
7
+ outputFileCount: outputFiles.length,
8
+ deliveredCount: delivered.size,
9
+ pendingFiles: pendingFiles.map(relativeOutputKey),
10
+ };
11
+ }
12
+ export async function backfillCronDeliveries(session, options) {
13
+ return runCronBackfill(session, options.reset);
14
+ }
@@ -1,4 +1,6 @@
1
1
  import type { ConnectResult } from "./client.js";
2
+ export declare const HERMES_CRON_OUTPUT_DIR: string;
3
+ export declare const DELIVERED_INDEX_PATH: string;
2
4
  type CronWatcherOptions = {
3
5
  session: ConnectResult;
4
6
  onDelivered?: (info: {
@@ -8,6 +10,18 @@ type CronWatcherOptions = {
8
10
  }) => void;
9
11
  onError?: (message: string) => void;
10
12
  };
13
+ export declare function readDeliveredIndex(): Set<string>;
14
+ export declare function writeDeliveredIndex(delivered: Set<string>): void;
15
+ export declare function clearDeliveredIndex(): number;
16
+ export declare function listCronOutputFiles(rootDir?: string): string[];
17
+ export declare function relativeOutputKey(filePath: string): string;
18
+ export declare function listPendingCronFiles(delivered?: Set<string>): string[];
11
19
  export declare function startCronWatcher(options: CronWatcherOptions): () => void;
20
+ export declare function runCronBackfill(session: ConnectResult, resetIndex: boolean): Promise<{
21
+ clearedEntries: number;
22
+ pendingBefore: number;
23
+ deliveredCount: number;
24
+ remainingCount: number;
25
+ }>;
12
26
  export {};
13
27
  //# sourceMappingURL=cronWatcher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cronWatcher.d.ts","sourceRoot":"","sources":["../src/cronWatcher.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAejD,KAAK,kBAAkB,GAAG;IACxB,OAAO,EAAE,aAAa,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACnF,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAAC;AAiGF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,IAAI,CAoExE"}
1
+ {"version":3,"file":"cronWatcher.d.ts","sourceRoot":"","sources":["../src/cronWatcher.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,eAAO,MAAM,sBAAsB,QAA+C,CAAC;AAEnF,eAAO,MAAM,oBAAoB,QAAmD,CAAC;AASrF,KAAK,kBAAkB,GAAG;IACxB,OAAO,EAAE,aAAa,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACnF,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF,wBAAgB,kBAAkB,IAAI,GAAG,CAAC,MAAM,CAAC,CAQhD;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAGhE;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAI5C;AAED,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,MAA+B,GAAG,MAAM,EAAE,CAoBtF;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,oBAAoB,CAAC,SAAS,GAAE,GAAG,CAAC,MAAM,CAAwB,GAAG,MAAM,EAAE,CAE5F;AAqHD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,IAAI,CA8BxE;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC;IAC1F,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC,CAsBD"}
@@ -3,12 +3,12 @@ import { homedir } from "node:os";
3
3
  import { dirname, join, relative } from "node:path";
4
4
  import { resolveActiveConversationId } from "./activeConversation.js";
5
5
  import { loadCredentials } from "./credentials.js";
6
- const HERMES_CRON_OUTPUT_DIR = join(homedir(), ".hermes", "cron", "output");
6
+ export const HERMES_CRON_OUTPUT_DIR = join(homedir(), ".hermes", "cron", "output");
7
7
  const HERMES_CRON_JOBS_FILE = join(homedir(), ".hermes", "cron", "jobs.json");
8
- const DELIVERED_INDEX_PATH = join(homedir(), ".cleos", "cron-delivered.json");
8
+ export const DELIVERED_INDEX_PATH = join(homedir(), ".cleos", "cron-delivered.json");
9
9
  const POLL_INTERVAL_MS = 5_000;
10
10
  const FILE_SETTLE_MS = 750;
11
- function readDeliveredIndex() {
11
+ export function readDeliveredIndex() {
12
12
  try {
13
13
  const parsed = JSON.parse(readFileSync(DELIVERED_INDEX_PATH, "utf8"));
14
14
  if (!Array.isArray(parsed))
@@ -19,11 +19,16 @@ function readDeliveredIndex() {
19
19
  return new Set();
20
20
  }
21
21
  }
22
- function writeDeliveredIndex(delivered) {
22
+ export function writeDeliveredIndex(delivered) {
23
23
  mkdirSync(dirname(DELIVERED_INDEX_PATH), { recursive: true });
24
24
  writeFileSync(DELIVERED_INDEX_PATH, JSON.stringify([...delivered].sort(), null, 2));
25
25
  }
26
- function listCronOutputFiles(rootDir) {
26
+ export function clearDeliveredIndex() {
27
+ const previous = readDeliveredIndex().size;
28
+ writeDeliveredIndex(new Set());
29
+ return previous;
30
+ }
31
+ export function listCronOutputFiles(rootDir = HERMES_CRON_OUTPUT_DIR) {
27
32
  if (!existsSync(rootDir))
28
33
  return [];
29
34
  const files = [];
@@ -46,6 +51,12 @@ function listCronOutputFiles(rootDir) {
46
51
  }
47
52
  return files.sort();
48
53
  }
54
+ export function relativeOutputKey(filePath) {
55
+ return relative(HERMES_CRON_OUTPUT_DIR, filePath).replace(/\\/g, "/");
56
+ }
57
+ export function listPendingCronFiles(delivered = readDeliveredIndex()) {
58
+ return listCronOutputFiles().filter((filePath) => !delivered.has(relativeOutputKey(filePath)));
59
+ }
49
60
  function loadHermesCronJobs() {
50
61
  const names = new Map();
51
62
  if (!existsSync(HERMES_CRON_JOBS_FILE))
@@ -68,9 +79,6 @@ function loadHermesCronJobs() {
68
79
  }
69
80
  return names;
70
81
  }
71
- function relativeOutputKey(filePath) {
72
- return relative(HERMES_CRON_OUTPUT_DIR, filePath).replace(/\\/g, "/");
73
- }
74
82
  function parseRunAtFromFileName(filePath) {
75
83
  const base = filePath.split("/").pop()?.replace(/\.md$/i, "") ?? "";
76
84
  if (!base)
@@ -103,14 +111,58 @@ async function readFileWhenStable(filePath) {
103
111
  function sleep(ms) {
104
112
  return new Promise((resolve) => setTimeout(resolve, ms));
105
113
  }
114
+ function isRelayNotOpenError(error) {
115
+ return error instanceof Error && error.message === "Cleos relay connection is not open";
116
+ }
117
+ async function deliverPendingFiles(session, delivered, conversationId, options) {
118
+ const jobNames = loadHermesCronJobs();
119
+ for (const filePath of listCronOutputFiles()) {
120
+ const key = relativeOutputKey(filePath);
121
+ if (delivered.has(key))
122
+ continue;
123
+ const parts = key.split("/");
124
+ const jobId = parts[0] ?? "unknown";
125
+ const jobName = jobNames.get(jobId) ?? jobId;
126
+ const content = await readFileWhenStable(filePath);
127
+ if (!content) {
128
+ delivered.add(key);
129
+ writeDeliveredIndex(delivered);
130
+ continue;
131
+ }
132
+ try {
133
+ session.deliverCronResult(content, {
134
+ conversationId,
135
+ jobId,
136
+ jobName,
137
+ runAt: parseRunAtFromFileName(filePath),
138
+ });
139
+ }
140
+ catch (error) {
141
+ if (isRelayNotOpenError(error)) {
142
+ console.log(JSON.stringify({
143
+ event: "cleos-bridge.cron-deferred",
144
+ file: key,
145
+ reason: "relay_not_open",
146
+ }));
147
+ return;
148
+ }
149
+ throw error;
150
+ }
151
+ delivered.add(key);
152
+ writeDeliveredIndex(delivered);
153
+ options.onDelivered?.({ jobId, jobName, filePath });
154
+ console.log(JSON.stringify({
155
+ event: "cleos-bridge.cron-delivered",
156
+ jobId,
157
+ jobName,
158
+ file: key,
159
+ }));
160
+ }
161
+ }
106
162
  export function startCronWatcher(options) {
107
163
  const delivered = readDeliveredIndex();
108
164
  let conversationId = loadCredentials()?.conversationId ?? null;
109
165
  let stopped = false;
110
- for (const filePath of listCronOutputFiles(HERMES_CRON_OUTPUT_DIR)) {
111
- delivered.add(relativeOutputKey(filePath));
112
- }
113
- writeDeliveredIndex(delivered);
114
166
  const tick = () => {
115
167
  void (async () => {
116
168
  if (stopped)
@@ -119,35 +171,7 @@ export function startCronWatcher(options) {
119
171
  if (!conversationId) {
120
172
  conversationId = await resolveActiveConversationId();
121
173
  }
122
- const jobNames = loadHermesCronJobs();
123
- for (const filePath of listCronOutputFiles(HERMES_CRON_OUTPUT_DIR)) {
124
- const key = relativeOutputKey(filePath);
125
- if (delivered.has(key))
126
- continue;
127
- const parts = key.split("/");
128
- const jobId = parts[0] ?? "unknown";
129
- const jobName = jobNames.get(jobId) ?? jobId;
130
- const content = await readFileWhenStable(filePath);
131
- if (!content) {
132
- delivered.add(key);
133
- continue;
134
- }
135
- options.session.deliverCronResult(content, {
136
- conversationId: conversationId,
137
- jobId,
138
- jobName,
139
- runAt: parseRunAtFromFileName(filePath),
140
- });
141
- delivered.add(key);
142
- writeDeliveredIndex(delivered);
143
- options.onDelivered?.({ jobId, jobName, filePath });
144
- console.log(JSON.stringify({
145
- event: "cleos-bridge.cron-delivered",
146
- jobId,
147
- jobName,
148
- file: key,
149
- }));
150
- }
174
+ await deliverPendingFiles(options.session, delivered, conversationId, options);
151
175
  }
152
176
  catch (error) {
153
177
  const message = error instanceof Error ? error.message : String(error);
@@ -163,3 +187,23 @@ export function startCronWatcher(options) {
163
187
  clearInterval(timer);
164
188
  };
165
189
  }
190
+ export async function runCronBackfill(session, resetIndex) {
191
+ const pendingBefore = listPendingCronFiles().length;
192
+ const clearedEntries = resetIndex ? clearDeliveredIndex() : 0;
193
+ const delivered = readDeliveredIndex();
194
+ const pendingAfterReset = listPendingCronFiles(delivered).length;
195
+ let conversationId = loadCredentials()?.conversationId ?? null;
196
+ if (!conversationId) {
197
+ conversationId = await resolveActiveConversationId();
198
+ }
199
+ const deliveredBefore = delivered.size;
200
+ await deliverPendingFiles(session, delivered, conversationId, {});
201
+ const deliveredCount = delivered.size - deliveredBefore;
202
+ const remainingCount = listPendingCronFiles(delivered).length;
203
+ return {
204
+ clearedEntries,
205
+ pendingBefore: resetIndex ? pendingAfterReset : pendingBefore,
206
+ deliveredCount,
207
+ remainingCount,
208
+ };
209
+ }
package/dist/index.d.ts CHANGED
@@ -9,7 +9,8 @@ export { createHermesMessageHandler, forwardToHermes, resolveHermesApiConfig } f
9
9
  export type { HermesForwarderOptions } from "./hermesForwarder.js";
10
10
  export { executeHermesCommand, HERMES_COMMAND_NAMES, isHermesCommandName, userSafeCommandError, } from "./hermesCommands.js";
11
11
  export type { HermesCommandErrorCode, HermesCommandName } from "./hermesCommands.js";
12
- export { startCronWatcher } from "./cronWatcher.js";
12
+ export { startCronWatcher, listPendingCronFiles, clearDeliveredIndex } from "./cronWatcher.js";
13
+ export { backfillCronDeliveries, describeCronDeliveryState } from "./cronBackfill.js";
13
14
  export { resolveActiveConversationId, rememberConversationId } from "./activeConversation.js";
14
15
  export { runBridgeDaemon } from "./daemon.js";
15
16
  export type { RunBridgeOptions } from "./daemon.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACvF,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,UAAU,EACV,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC/F,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACxE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC3G,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAC9F,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,6BAA6B,EAC7B,sBAAsB,EACtB,2BAA2B,EAC3B,0BAA0B,EAC1B,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACvF,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,UAAU,EACV,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC/F,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACxE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC3G,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AACtF,OAAO,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAC9F,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,6BAA6B,EAC7B,sBAAsB,EACtB,2BAA2B,EAC3B,0BAA0B,EAC1B,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -4,7 +4,8 @@ export { resolvePairingCode, convexSiteUrlFromEnv } from "./resolve.js";
4
4
  export { pairWithCleos } from "./pairWithCleos.js";
5
5
  export { createHermesMessageHandler, forwardToHermes, resolveHermesApiConfig } from "./hermesForwarder.js";
6
6
  export { executeHermesCommand, HERMES_COMMAND_NAMES, isHermesCommandName, userSafeCommandError, } from "./hermesCommands.js";
7
- export { startCronWatcher } from "./cronWatcher.js";
7
+ export { startCronWatcher, listPendingCronFiles, clearDeliveredIndex } from "./cronWatcher.js";
8
+ export { backfillCronDeliveries, describeCronDeliveryState } from "./cronBackfill.js";
8
9
  export { resolveActiveConversationId, rememberConversationId } from "./activeConversation.js";
9
10
  export { runBridgeDaemon } from "./daemon.js";
10
11
  export { DEFAULT_BRIDGE_INSTALL_URL, DEFAULT_BRIDGE_UPDATE_URL, DEFAULT_CLEOS_CONVEX_SITE_URL, DEFAULT_HERMES_API_URL, DEFAULT_BRIDGE_CAPABILITIES, HERMES_COMMANDS_CAPABILITY, bridgeInstallCommand, bridgeUpdateCommand, } from "./constants.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saleso.innovations/bridge",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "Connect your Hermes agent to the Cleos iOS app via pairing code.",
5
5
  "type": "module",
6
6
  "license": "MIT",