sentinelayer-cli 0.18.1 → 0.18.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sentinelayer-cli",
3
- "version": "0.18.1",
3
+ "version": "0.18.2",
4
4
  "description": "Scaffold Sentinelayer spec/prompt/guide artifacts with secure browser auth and token bootstrap.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -39,8 +39,8 @@ import {
39
39
  DEFAULT_RECAP_INTERVAL_MS,
40
40
  emitPeriodicRecap,
41
41
  } from "./recap.js";
42
+ import { hydrateSessionFromRemote } from "./remote-hydrate.js";
42
43
  import { stopRuntimeRunsForSession } from "./runtime-bridge.js";
43
- import { pollHumanMessages } from "./sync.js";
44
44
  import { getSession, renewSession } from "./store.js";
45
45
  import { appendToStream, readStream, tailStream } from "./stream.js";
46
46
  import { handleTaskDirective } from "./tasks.js";
@@ -214,6 +214,7 @@ function createSentiState({
214
214
  checkpointCloseoutOnStop,
215
215
  helpResponder,
216
216
  llmInvoker,
217
+ remoteHydrator,
217
218
  telemetrySessionId,
218
219
  }) {
219
220
  return {
@@ -243,6 +244,7 @@ function createSentiState({
243
244
  lastCheckpointResult: null,
244
245
  helpResponder,
245
246
  llmInvoker,
247
+ remoteHydrator,
246
248
  telemetrySessionId,
247
249
  running: true,
248
250
  tickTimer: null,
@@ -255,6 +257,7 @@ function createSentiState({
255
257
  lastTickSummary: null,
256
258
  recapEmitter: null,
257
259
  humanMessageCursor: null,
260
+ sessionEventsCursor: null,
258
261
  humanMessagePollInFlight: false,
259
262
  };
260
263
  }
@@ -1055,6 +1058,9 @@ function createHealthSummaryBase(nowIso, session, agents) {
1055
1058
  relayed: 0,
1056
1059
  dropped: 0,
1057
1060
  cursor: null,
1061
+ sessionEventsRelayed: 0,
1062
+ sessionEventsCursor: null,
1063
+ eventsBackfillComplete: null,
1058
1064
  reason: "",
1059
1065
  },
1060
1066
  recap: {
@@ -1236,7 +1242,7 @@ async function maybeRenewActiveSession(
1236
1242
  };
1237
1243
  }
1238
1244
 
1239
- async function pollAndRelayHumanMessages(
1245
+ async function hydrateRemoteSessionEvents(
1240
1246
  daemonState,
1241
1247
  summary,
1242
1248
  nowIso = new Date().toISOString()
@@ -1248,37 +1254,44 @@ async function pollAndRelayHumanMessages(
1248
1254
 
1249
1255
  daemonState.humanMessagePollInFlight = true;
1250
1256
  try {
1251
- const polled = await pollHumanMessages(daemonState.sessionId, {
1257
+ const hydrated = await daemonState.remoteHydrator({
1258
+ sessionId: daemonState.sessionId,
1252
1259
  targetPath: daemonState.targetPath,
1253
- since: daemonState.humanMessageCursor,
1254
1260
  });
1255
- if (!polled.ok) {
1256
- summary.humanMessages.reason = normalizeString(polled.reason) || "poll_failed";
1261
+ if (!hydrated.ok) {
1262
+ summary.humanMessages.reason = normalizeString(hydrated.reason) || "poll_failed";
1257
1263
  summary.humanMessages.cursor = daemonState.humanMessageCursor;
1264
+ summary.humanMessages.sessionEventsCursor = daemonState.sessionEventsCursor;
1258
1265
  return;
1259
1266
  }
1260
1267
 
1261
- const relayedEvents = [];
1262
- for (const event of polled.events || []) {
1263
- const persisted = await appendToStream(daemonState.sessionId, event, {
1264
- targetPath: daemonState.targetPath,
1265
- });
1266
- relayedEvents.push(persisted);
1267
- }
1268
- daemonState.humanMessageCursor = normalizeString(polled.cursor) || daemonState.humanMessageCursor;
1268
+ const relayed = Math.max(0, Math.floor(Number(hydrated.relayed || 0)));
1269
+ const humanRelayed = Math.max(0, Math.floor(Number(hydrated.humanRelayed || 0)));
1270
+ const sessionEventsRelayed = Math.max(0, Math.floor(Number(hydrated.eventsRelayed || 0)));
1271
+ daemonState.humanMessageCursor = normalizeString(hydrated.cursor) || daemonState.humanMessageCursor;
1272
+ daemonState.sessionEventsCursor =
1273
+ normalizeString(hydrated.eventsCursor) || daemonState.sessionEventsCursor;
1269
1274
 
1270
- summary.humanMessages.relayed = relayedEvents.length;
1271
- summary.humanMessages.dropped = Array.isArray(polled.dropped) ? polled.dropped.length : 0;
1275
+ summary.humanMessages.relayed = relayed;
1276
+ summary.humanMessages.dropped = Math.max(0, Math.floor(Number(hydrated.dropped || 0)));
1272
1277
  summary.humanMessages.cursor = daemonState.humanMessageCursor;
1278
+ summary.humanMessages.sessionEventsRelayed = sessionEventsRelayed;
1279
+ summary.humanMessages.sessionEventsCursor = daemonState.sessionEventsCursor;
1280
+ summary.humanMessages.humanEventsRelayed = humanRelayed;
1281
+ summary.humanMessages.eventsBackfillComplete = Boolean(hydrated.eventsBackfillComplete);
1282
+ summary.humanMessages.eventsPageCount = Math.max(0, Math.floor(Number(hydrated.eventsPageCount || 0)));
1283
+ summary.humanMessages.localAppendComplete = hydrated.localAppendComplete !== false;
1273
1284
  summary.humanMessages.reason = "";
1274
1285
 
1275
- if (relayedEvents.length > 0) {
1286
+ if (humanRelayed > 0) {
1276
1287
  await emitSentiEvent(
1277
1288
  daemonState.sessionId,
1278
1289
  "daemon_alert",
1279
1290
  {
1280
1291
  alert: "human_directive_received",
1281
- relayedCount: relayedEvents.length,
1292
+ relayedCount: relayed,
1293
+ humanEventsRelayed: humanRelayed,
1294
+ sessionEventsRelayed,
1282
1295
  droppedCount: summary.humanMessages.dropped,
1283
1296
  },
1284
1297
  {
@@ -1291,6 +1304,7 @@ async function pollAndRelayHumanMessages(
1291
1304
  summary.humanMessages.reason =
1292
1305
  normalizeString(error?.message) || "poll_relay_failed";
1293
1306
  summary.humanMessages.cursor = daemonState.humanMessageCursor;
1307
+ summary.humanMessages.sessionEventsCursor = daemonState.sessionEventsCursor;
1294
1308
  } finally {
1295
1309
  daemonState.humanMessagePollInFlight = false;
1296
1310
  }
@@ -1466,6 +1480,7 @@ export async function runSentiHealthTick(
1466
1480
  checkpointCloseoutOnStop: true,
1467
1481
  helpResponder: null,
1468
1482
  llmInvoker: invokeViaProxy,
1483
+ remoteHydrator: hydrateSessionFromRemote,
1469
1484
  telemetrySessionId: null,
1470
1485
  });
1471
1486
  const normalizedNow = normalizeIsoTimestamp(nowIso, new Date().toISOString());
@@ -1486,7 +1501,7 @@ export async function runSentiHealthTick(
1486
1501
  await emitStaleAndRecoveryAlerts(resolvedDaemonState, summary, staleAgents, normalizedNow);
1487
1502
  await emitConflictAlerts(resolvedDaemonState, summary, filteredAgents, normalizedNow);
1488
1503
  await maybeRenewActiveSession(resolvedDaemonState, summary, session, normalizedNow);
1489
- await pollAndRelayHumanMessages(resolvedDaemonState, summary, normalizedNow);
1504
+ await hydrateRemoteSessionEvents(resolvedDaemonState, summary, normalizedNow);
1490
1505
  await maybeEmitPeriodicRecap(resolvedDaemonState, summary, normalizedNow);
1491
1506
  await maybeGenerateSessionCheckpoint(resolvedDaemonState, summary, normalizedNow);
1492
1507
  return summary;
@@ -1513,6 +1528,7 @@ export async function startSenti(
1513
1528
  checkpointCloseoutOnStop = true,
1514
1529
  helpResponder = null,
1515
1530
  llmInvoker = invokeViaProxy,
1531
+ remoteHydrator = hydrateSessionFromRemote,
1516
1532
  } = {}
1517
1533
  ) {
1518
1534
  const normalizedSessionId = normalizeString(sessionId);
@@ -1597,6 +1613,7 @@ export async function startSenti(
1597
1613
  checkpointCloseoutOnStop: checkpointCloseoutOnStop !== false,
1598
1614
  helpResponder,
1599
1615
  llmInvoker: typeof llmInvoker === "function" ? llmInvoker : invokeViaProxy,
1616
+ remoteHydrator: typeof remoteHydrator === "function" ? remoteHydrator : hydrateSessionFromRemote,
1600
1617
  telemetrySessionId: telemetrySession?.id || null,
1601
1618
  });
1602
1619
 
@@ -1792,6 +1809,7 @@ export async function startSenti(
1792
1809
  lastCheckpointSourceSequenceId: daemonState.lastCheckpointSourceSequenceId,
1793
1810
  lastCheckpointResult: daemonState.lastCheckpointResult,
1794
1811
  humanMessageCursor: daemonState.humanMessageCursor,
1812
+ sessionEventsCursor: daemonState.sessionEventsCursor,
1795
1813
  }),
1796
1814
  };
1797
1815