@ouro.bot/cli 0.1.0-alpha.202 → 0.1.0-alpha.203

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/changelog.json CHANGED
@@ -1,6 +1,12 @@
1
1
  {
2
2
  "_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
3
3
  "versions": [
4
+ {
5
+ "version": "0.1.0-alpha.203",
6
+ "changes": [
7
+ "refactor: unify obligation systems — mind/obligations.ts merged into heart/obligations.ts with prefixed ReturnObligation API"
8
+ ]
9
+ },
4
10
  {
5
11
  "version": "0.1.0-alpha.202",
6
12
  "changes": [
@@ -3116,9 +3116,9 @@ async function runOuroCli(args, deps = createDefaultOuroCliDeps()) {
3116
3116
  if (command.kind === "attention.list" || command.kind === "attention.show" || command.kind === "attention.history") {
3117
3117
  try {
3118
3118
  const agentName = command.agent ?? (0, identity_1.getAgentName)();
3119
- const { listActiveObligations, readObligation } = await Promise.resolve().then(() => __importStar(require("../../mind/obligations")));
3119
+ const { listActiveReturnObligations, readReturnObligation } = await Promise.resolve().then(() => __importStar(require("../obligations")));
3120
3120
  if (command.kind === "attention.list") {
3121
- const obligations = listActiveObligations(agentName);
3121
+ const obligations = listActiveReturnObligations(agentName);
3122
3122
  if (obligations.length === 0) {
3123
3123
  const message = "nothing held — attention queue is empty";
3124
3124
  deps.writeStdout(message);
@@ -3130,7 +3130,7 @@ async function runOuroCli(args, deps = createDefaultOuroCliDeps()) {
3130
3130
  return message;
3131
3131
  }
3132
3132
  if (command.kind === "attention.show") {
3133
- const obligation = readObligation(agentName, command.id);
3133
+ const obligation = readReturnObligation(agentName, command.id);
3134
3134
  if (!obligation) {
3135
3135
  const message = `no obligation found with id ${command.id}`;
3136
3136
  deps.writeStdout(message);
@@ -3141,8 +3141,8 @@ async function runOuroCli(args, deps = createDefaultOuroCliDeps()) {
3141
3141
  return message;
3142
3142
  }
3143
3143
  // attention.history: show returned obligations
3144
- const { getObligationsDir } = await Promise.resolve().then(() => __importStar(require("../../mind/obligations")));
3145
- const obligationsDir = getObligationsDir(agentName);
3144
+ const { getReturnObligationsDir } = await Promise.resolve().then(() => __importStar(require("../obligations")));
3145
+ const obligationsDir = getReturnObligationsDir(agentName);
3146
3146
  let entries = [];
3147
3147
  try {
3148
3148
  entries = fs.readdirSync(obligationsDir);
@@ -3189,7 +3189,7 @@ async function runOuroCli(args, deps = createDefaultOuroCliDeps()) {
3189
3189
  const { sessionPath: getSessionPath } = await Promise.resolve().then(() => __importStar(require("../config")));
3190
3190
  const { parseCadenceToMs: parseCadenceMs, DEFAULT_CADENCE_MS } = await Promise.resolve().then(() => __importStar(require("./cadence")));
3191
3191
  const { parseFrontmatter } = await Promise.resolve().then(() => __importStar(require("../../repertoire/tasks/parser")));
3192
- const { listActiveObligations } = await Promise.resolve().then(() => __importStar(require("../../mind/obligations")));
3192
+ const { listActiveReturnObligations } = await Promise.resolve().then(() => __importStar(require("../obligations")));
3193
3193
  // Read runtime state
3194
3194
  const innerSessionPath = getSessionPath("inner-dialog", "inner", "session");
3195
3195
  const runtimeJsonPath = path.join(path.dirname(innerSessionPath), "runtime.json");
@@ -3242,7 +3242,7 @@ async function runOuroCli(args, deps = createDefaultOuroCliDeps()) {
3242
3242
  }
3243
3243
  catch { /* no habits — heartbeat unknown */ }
3244
3244
  // Attention count
3245
- const activeObligations = listActiveObligations(agentName);
3245
+ const activeObligations = listActiveReturnObligations(agentName);
3246
3246
  const message = buildInnerStatusOutput({
3247
3247
  agentName,
3248
3248
  runtimeState,
@@ -42,8 +42,15 @@ exports.advanceObligation = advanceObligation;
42
42
  exports.fulfillObligation = fulfillObligation;
43
43
  exports.findPendingObligationForOrigin = findPendingObligationForOrigin;
44
44
  exports.enrichObligation = enrichObligation;
45
+ exports.generateObligationId = generateObligationId;
46
+ exports.getReturnObligationsDir = getReturnObligationsDir;
47
+ exports.createReturnObligation = createReturnObligation;
48
+ exports.readReturnObligation = readReturnObligation;
49
+ exports.advanceReturnObligation = advanceReturnObligation;
50
+ exports.listActiveReturnObligations = listActiveReturnObligations;
45
51
  const fs = __importStar(require("fs"));
46
52
  const path = __importStar(require("path"));
53
+ const identity_1 = require("./identity");
47
54
  const runtime_1 = require("../nerves/runtime");
48
55
  const sync_1 = require("./sync");
49
56
  function obligationsDir(agentRoot) {
@@ -223,3 +230,92 @@ function enrichObligation(agentRoot, id, meaning) {
223
230
  });
224
231
  return obligation;
225
232
  }
233
+ function generateObligationId(timestamp) {
234
+ return `${timestamp}-${Math.random().toString(36).slice(2, 10)}`;
235
+ }
236
+ function getReturnObligationsDir(agentName) {
237
+ return path.join((0, identity_1.getAgentRoot)(agentName), "arc", "obligations", "inner");
238
+ }
239
+ function createReturnObligation(agentName, obligation) {
240
+ const dir = getReturnObligationsDir(agentName);
241
+ fs.mkdirSync(dir, { recursive: true });
242
+ const filePath = path.join(dir, `${obligation.id}.json`);
243
+ fs.writeFileSync(filePath, JSON.stringify(obligation, null, 2), "utf8");
244
+ (0, sync_1.trackSyncWrite)(filePath);
245
+ (0, runtime_1.emitNervesEvent)({
246
+ event: "mind.obligation_created",
247
+ component: "mind",
248
+ message: "return obligation created",
249
+ meta: {
250
+ obligationId: obligation.id,
251
+ origin: `${obligation.origin.friendId}/${obligation.origin.channel}/${obligation.origin.key}`,
252
+ status: obligation.status,
253
+ },
254
+ });
255
+ return filePath;
256
+ }
257
+ function readReturnObligation(agentName, obligationId) {
258
+ const dir = getReturnObligationsDir(agentName);
259
+ try {
260
+ const raw = fs.readFileSync(path.join(dir, `${obligationId}.json`), "utf-8");
261
+ return JSON.parse(raw);
262
+ }
263
+ catch {
264
+ return null;
265
+ }
266
+ }
267
+ function advanceReturnObligation(agentName, obligationId, update) {
268
+ const existing = readReturnObligation(agentName, obligationId);
269
+ if (!existing)
270
+ return null;
271
+ const updated = {
272
+ ...existing,
273
+ status: update.status,
274
+ ...(update.startedAt !== undefined ? { startedAt: update.startedAt } : {}),
275
+ ...(update.returnedAt !== undefined ? { returnedAt: update.returnedAt } : {}),
276
+ ...(update.returnTarget !== undefined ? { returnTarget: update.returnTarget } : {}),
277
+ };
278
+ const dir = getReturnObligationsDir(agentName);
279
+ const advancedFilePath = path.join(dir, `${obligationId}.json`);
280
+ fs.writeFileSync(advancedFilePath, JSON.stringify(updated, null, 2), "utf8");
281
+ (0, sync_1.trackSyncWrite)(advancedFilePath);
282
+ (0, runtime_1.emitNervesEvent)({
283
+ event: "mind.obligation_advanced",
284
+ component: "mind",
285
+ message: `obligation advanced to ${update.status}`,
286
+ meta: {
287
+ obligationId,
288
+ status: update.status,
289
+ ...(update.returnTarget ? { returnTarget: update.returnTarget } : {}),
290
+ },
291
+ });
292
+ return updated;
293
+ }
294
+ function listActiveReturnObligations(agentName) {
295
+ const dir = getReturnObligationsDir(agentName);
296
+ if (!fs.existsSync(dir))
297
+ return [];
298
+ let entries;
299
+ try {
300
+ entries = fs.readdirSync(dir);
301
+ }
302
+ catch {
303
+ return [];
304
+ }
305
+ const obligations = [];
306
+ for (const file of entries) {
307
+ if (!file.endsWith(".json"))
308
+ continue;
309
+ try {
310
+ const raw = fs.readFileSync(path.join(dir, file), "utf-8");
311
+ const parsed = JSON.parse(raw);
312
+ if (parsed.status === "queued" || parsed.status === "running") {
313
+ obligations.push(parsed);
314
+ }
315
+ }
316
+ catch {
317
+ // skip unparseable
318
+ }
319
+ }
320
+ return obligations.sort((a, b) => a.createdAt - b.createdAt);
321
+ }
@@ -58,10 +58,9 @@ const coding_1 = require("./coding");
58
58
  const diary_1 = require("../mind/diary");
59
59
  const tasks_1 = require("./tasks");
60
60
  const pending_1 = require("../mind/pending");
61
- const obligations_1 = require("../mind/obligations");
61
+ const obligations_1 = require("../heart/obligations");
62
62
  const progress_story_1 = require("../heart/progress-story");
63
63
  const cross_chat_delivery_1 = require("../heart/cross-chat-delivery");
64
- const obligations_2 = require("../heart/obligations");
65
64
  const episodes_1 = require("../mind/episodes");
66
65
  const cares_1 = require("../heart/cares");
67
66
  const presence_1 = require("../heart/presence");
@@ -220,7 +219,7 @@ function readActiveWorkInnerState() {
220
219
  const { pendingMessages, turns, runtimeState } = (0, thoughts_1.readInnerDialogRawData)(sessionPath, pendingDir);
221
220
  const dialogStatus = (0, thoughts_1.deriveInnerDialogStatus)(pendingMessages, turns, runtimeState);
222
221
  const job = (0, thoughts_1.deriveInnerJob)(pendingMessages, turns, runtimeState);
223
- const storeObligationPending = (0, obligations_2.readPendingObligations)(agentRoot).length > 0;
222
+ const storeObligationPending = (0, obligations_1.readPendingObligations)(agentRoot).length > 0;
224
223
  return {
225
224
  status: dialogStatus.processing === "started" ? "running" : "idle",
226
225
  hasPending: dialogStatus.queue !== "clear",
@@ -269,7 +268,7 @@ async function buildToolActiveWorkFrame(ctx) {
269
268
  }
270
269
  const pendingObligations = (() => {
271
270
  try {
272
- return (0, obligations_2.readPendingObligations)(agentRoot);
271
+ return (0, obligations_1.readPendingObligations)(agentRoot);
273
272
  }
274
273
  catch {
275
274
  return [];
@@ -1296,7 +1295,7 @@ exports.baseToolDefinitions = [
1296
1295
  writePendingEnvelope(pendingDir, envelope);
1297
1296
  if (delegatedFrom) {
1298
1297
  try {
1299
- (0, obligations_2.createObligation)((0, identity_1.getAgentRoot)(), {
1298
+ (0, obligations_1.createObligation)((0, identity_1.getAgentRoot)(), {
1300
1299
  origin: {
1301
1300
  friendId: delegatedFrom.friendId,
1302
1301
  channel: delegatedFrom.channel,
@@ -1311,7 +1310,7 @@ exports.baseToolDefinitions = [
1311
1310
  }
1312
1311
  /* v8 ignore next -- obligationId always set when delegatedFrom is set (see generateObligationId above) @preserve */
1313
1312
  if (obligationId) {
1314
- (0, obligations_1.createObligation)(agentName, {
1313
+ (0, obligations_1.createReturnObligation)(agentName, {
1315
1314
  id: obligationId,
1316
1315
  origin: delegatedFrom,
1317
1316
  status: "queued",
@@ -48,8 +48,7 @@ const runtime_1 = require("../nerves/runtime");
48
48
  const guardrails_1 = require("./guardrails");
49
49
  const identity_1 = require("../heart/identity");
50
50
  const surface_tool_1 = require("../senses/surface-tool");
51
- const obligations_1 = require("../mind/obligations");
52
- const obligations_2 = require("../heart/obligations");
51
+ const obligations_1 = require("../heart/obligations");
53
52
  const session_activity_1 = require("../heart/session-activity");
54
53
  const path = __importStar(require("path"));
55
54
  function safeGetAgentRoot() {
@@ -198,7 +197,7 @@ const surfaceToolDefinition = {
198
197
  catch {
199
198
  return "unknown";
200
199
  } })();
201
- (0, obligations_1.advanceObligation)(name, obligationId, {
200
+ (0, obligations_1.advanceReturnObligation)(name, obligationId, {
202
201
  status: update.status,
203
202
  ...(update.returnedAt !== undefined ? { returnedAt: update.returnedAt } : {}),
204
203
  ...(update.returnTarget !== undefined ? { returnTarget: update.returnTarget } : {}),
@@ -213,9 +212,9 @@ const surfaceToolDefinition = {
213
212
  /* v8 ignore start -- heart obligation fulfillment: tested via surface-tool.test.ts @preserve */
214
213
  try {
215
214
  const agentRoot = (0, identity_1.getAgentRoot)();
216
- const heartObligation = (0, obligations_2.findPendingObligationForOrigin)(agentRoot, origin);
215
+ const heartObligation = (0, obligations_1.findPendingObligationForOrigin)(agentRoot, origin);
217
216
  if (heartObligation) {
218
- (0, obligations_2.fulfillObligation)(agentRoot, heartObligation.id);
217
+ (0, obligations_1.fulfillObligation)(agentRoot, heartObligation.id);
219
218
  }
220
219
  }
221
220
  catch {
@@ -55,7 +55,7 @@ const prompt_1 = require("../mind/prompt");
55
55
  const mcp_manager_1 = require("../repertoire/mcp-manager");
56
56
  const bundle_manifest_1 = require("../mind/bundle-manifest");
57
57
  const pending_1 = require("../mind/pending");
58
- const obligations_1 = require("../mind/obligations");
58
+ const obligations_1 = require("../heart/obligations");
59
59
  const attention_queue_1 = require("./attention-queue");
60
60
  const channel_1 = require("../mind/friends/channel");
61
61
  const trust_gate_1 = require("./trust-gate");
@@ -66,7 +66,6 @@ const runtime_1 = require("../nerves/runtime");
66
66
  const manager_1 = require("../heart/bridges/manager");
67
67
  const session_activity_1 = require("../heart/session-activity");
68
68
  const bluebubbles_1 = require("./bluebubbles");
69
- const obligations_2 = require("../heart/obligations");
70
69
  const habit_turn_message_1 = require("./habit-turn-message");
71
70
  const journal_index_1 = require("../mind/journal-index");
72
71
  const habit_parser_1 = require("../heart/daemon/habit-parser");
@@ -324,7 +323,7 @@ function advanceObligationQuietly(agentName, obligationId, update) {
324
323
  if (!obligationId)
325
324
  return;
326
325
  try {
327
- (0, obligations_1.advanceObligation)(agentName, obligationId, update);
326
+ (0, obligations_1.advanceReturnObligation)(agentName, obligationId, update);
328
327
  /* v8 ignore start -- best-effort: obligation fs errors must never block return routing @preserve */
329
328
  }
330
329
  catch {
@@ -352,14 +351,14 @@ async function routeDelegatedCompletion(agentRoot, agentName, completion, draine
352
351
  if (delegated.obligationStatus === "pending") {
353
352
  // Fulfill the persistent obligation in the store
354
353
  try {
355
- const pending = (0, obligations_2.findPendingObligationForOrigin)(agentRoot, {
354
+ const pending = (0, obligations_1.findPendingObligationForOrigin)(agentRoot, {
356
355
  friendId: delegatedFrom.friendId,
357
356
  channel: delegatedFrom.channel,
358
357
  key: delegatedFrom.key,
359
358
  });
360
359
  /* v8 ignore next 2 -- obligation fulfillment tested via obligations.test.ts; integration requires real disk state @preserve */
361
360
  if (pending) {
362
- (0, obligations_2.fulfillObligation)(agentRoot, pending.id);
361
+ (0, obligations_1.fulfillObligation)(agentRoot, pending.id);
363
362
  }
364
363
  }
365
364
  catch {
@@ -577,7 +576,7 @@ async function runInnerDialogTurn(options) {
577
576
  }
578
577
  else {
579
578
  // Unified path: gather context for ALL habits (heartbeat included)
580
- const obligations = (0, obligations_1.listActiveObligations)(agentName);
579
+ const obligations = (0, obligations_1.listActiveReturnObligations)(agentName);
581
580
  const nowMs = now().getTime();
582
581
  const staleObligations = obligations.map((o) => ({
583
582
  friendName: o.origin.friendId,
@@ -670,7 +669,7 @@ async function runInnerDialogTurn(options) {
670
669
  signal: options?.signal,
671
670
  /* v8 ignore start -- attention queue: callback invoked by pipeline during pending drain; tested via attention-queue unit tests @preserve */
672
671
  onPendingDrained: (drained) => {
673
- const outstandingObligations = (0, obligations_1.listActiveObligations)(agentName);
672
+ const outstandingObligations = (0, obligations_1.listActiveReturnObligations)(agentName);
674
673
  attentionQueue = (0, attention_queue_1.buildAttentionQueue)({
675
674
  drainedPending: drained,
676
675
  outstandingObligations,
@@ -57,7 +57,6 @@ const target_resolution_1 = require("../heart/target-resolution");
57
57
  const thoughts_1 = require("../heart/daemon/thoughts");
58
58
  const pending_1 = require("../mind/pending");
59
59
  const obligations_1 = require("../heart/obligations");
60
- const obligations_2 = require("../mind/obligations");
61
60
  const provider_failover_1 = require("../heart/provider-failover");
62
61
  const provider_ping_1 = require("../heart/provider-ping");
63
62
  const auth_flow_1 = require("../heart/daemon/auth-flow");
@@ -466,7 +465,7 @@ async function handleInboundTurn(input) {
466
465
  targetCandidates,
467
466
  innerReturnObligations: (() => {
468
467
  try {
469
- return (0, obligations_2.listActiveObligations)((0, identity_1.getAgentName)());
468
+ return (0, obligations_1.listActiveReturnObligations)((0, identity_1.getAgentName)());
470
469
  }
471
470
  catch {
472
471
  return [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.202",
3
+ "version": "0.1.0-alpha.203",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",
@@ -1,138 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.getObligationsDir = getObligationsDir;
37
- exports.generateObligationId = generateObligationId;
38
- exports.createObligation = createObligation;
39
- exports.readObligation = readObligation;
40
- exports.advanceObligation = advanceObligation;
41
- exports.listActiveObligations = listActiveObligations;
42
- const fs = __importStar(require("fs"));
43
- const path = __importStar(require("path"));
44
- const identity_1 = require("../heart/identity");
45
- const runtime_1 = require("../nerves/runtime");
46
- const sync_1 = require("../heart/sync");
47
- // ── Paths ────────────────────────────────────────────────────────
48
- function getObligationsDir(agentName) {
49
- return path.join((0, identity_1.getAgentRoot)(agentName), "arc", "obligations", "inner");
50
- }
51
- // ── ID generation ────────────────────────────────────────────────
52
- function generateObligationId(timestamp) {
53
- return `${timestamp}-${Math.random().toString(36).slice(2, 10)}`;
54
- }
55
- // ── Store operations ─────────────────────────────────────────────
56
- function createObligation(agentName, obligation) {
57
- const dir = getObligationsDir(agentName);
58
- fs.mkdirSync(dir, { recursive: true });
59
- const filePath = path.join(dir, `${obligation.id}.json`);
60
- fs.writeFileSync(filePath, JSON.stringify(obligation, null, 2), "utf8");
61
- (0, sync_1.trackSyncWrite)(filePath);
62
- (0, runtime_1.emitNervesEvent)({
63
- event: "mind.obligation_created",
64
- component: "mind",
65
- message: "return obligation created",
66
- meta: {
67
- obligationId: obligation.id,
68
- origin: `${obligation.origin.friendId}/${obligation.origin.channel}/${obligation.origin.key}`,
69
- status: obligation.status,
70
- },
71
- });
72
- return filePath;
73
- }
74
- function readObligation(agentName, obligationId) {
75
- const dir = getObligationsDir(agentName);
76
- try {
77
- const raw = fs.readFileSync(path.join(dir, `${obligationId}.json`), "utf-8");
78
- return JSON.parse(raw);
79
- }
80
- catch {
81
- return null;
82
- }
83
- }
84
- function advanceObligation(agentName, obligationId, update) {
85
- const existing = readObligation(agentName, obligationId);
86
- if (!existing)
87
- return null;
88
- const updated = {
89
- ...existing,
90
- status: update.status,
91
- ...(update.startedAt !== undefined ? { startedAt: update.startedAt } : {}),
92
- ...(update.returnedAt !== undefined ? { returnedAt: update.returnedAt } : {}),
93
- ...(update.returnTarget !== undefined ? { returnTarget: update.returnTarget } : {}),
94
- };
95
- const dir = getObligationsDir(agentName);
96
- const advancedFilePath = path.join(dir, `${obligationId}.json`);
97
- fs.writeFileSync(advancedFilePath, JSON.stringify(updated, null, 2), "utf8");
98
- (0, sync_1.trackSyncWrite)(advancedFilePath);
99
- (0, runtime_1.emitNervesEvent)({
100
- event: "mind.obligation_advanced",
101
- component: "mind",
102
- message: `obligation advanced to ${update.status}`,
103
- meta: {
104
- obligationId,
105
- status: update.status,
106
- ...(update.returnTarget ? { returnTarget: update.returnTarget } : {}),
107
- },
108
- });
109
- return updated;
110
- }
111
- function listActiveObligations(agentName) {
112
- const dir = getObligationsDir(agentName);
113
- if (!fs.existsSync(dir))
114
- return [];
115
- let entries;
116
- try {
117
- entries = fs.readdirSync(dir);
118
- }
119
- catch {
120
- return [];
121
- }
122
- const obligations = [];
123
- for (const file of entries) {
124
- if (!file.endsWith(".json"))
125
- continue;
126
- try {
127
- const raw = fs.readFileSync(path.join(dir, file), "utf-8");
128
- const parsed = JSON.parse(raw);
129
- if (parsed.status === "queued" || parsed.status === "running") {
130
- obligations.push(parsed);
131
- }
132
- }
133
- catch {
134
- // skip unparseable
135
- }
136
- }
137
- return obligations.sort((a, b) => a.createdAt - b.createdAt);
138
- }