@hilbras/omninode 1.0.0 → 2.0.0-alpha.1

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/README.md CHANGED
@@ -18,13 +18,24 @@ existing intelligence; it does not try to become another model.
18
18
 
19
19
  ## Status
20
20
 
21
- **v1.0.0 — Phases 10 + 11: Production Release.** The plan is complete: the
21
+ **v2.0.0-alpha.1 — v2 Phase 1: Architecture & API Stabilization** (the v2
22
+ roadmap is [docs/ROADMAP_V2.md](docs/ROADMAP_V2.md); the v1 plan is complete:
23
+ the
22
24
  full loop from §28 runs in one command —
23
25
  `User → project context → memory → research agents → reports → aggregation →
24
26
  planner → plan → execution → result` — with audit logging, error recovery and
25
27
  production hardening (see [docs/DEVELOPMENT_PLAN.md](docs/DEVELOPMENT_PLAN.md)
26
28
  for the plan and [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the design).
27
29
 
30
+ ### What changed in v2 Phase 1
31
+
32
+ - All local stores now build on one shared `JsonFileStore` (atomic writes,
33
+ serialized read-modify-write, schema-versioned files, corruption tolerance)
34
+ with a `ProjectStores` facade.
35
+ - Dependency direction corrected (adapters no longer import engine modules).
36
+ - API surface stabilized and guarded: [API_STABILITY.md](docs/API_STABILITY.md),
37
+ [API.md](docs/API.md), [DEPRECATIONS.md](docs/DEPRECATIONS.md).
38
+
28
39
  ### What's in v1.0
29
40
 
30
41
  | Capability | Where |
@@ -284,6 +295,8 @@ required for the core engine.
284
295
  - [Development plan](docs/DEVELOPMENT_PLAN.md) — the full 12-phase roadmap
285
296
  - [Architecture](docs/ARCHITECTURE.md) — module map, workflow, local state
286
297
  - [Security model](docs/SECURITY.md) — secrets, process execution, env isolation, audit log
298
+ - [API stability policy](docs/API_STABILITY.md) and [public API inventory](docs/API.md)
299
+ - [Deprecations](docs/DEPRECATIONS.md) · [Changelog](CHANGELOG.md) · [v2 roadmap](docs/ROADMAP_V2.md)
287
300
  - [Example project](examples/demo/) — a runnable end-to-end demo (`./demo.sh`)
288
301
 
289
302
  Prefer a container? `docker build -t omninode .` then
package/dist/cli/index.js CHANGED
@@ -6,7 +6,7 @@ import { realpathSync } from "fs";
6
6
  import { Command } from "commander";
7
7
 
8
8
  // src/version.ts
9
- var OMNINODE_VERSION = "1.0.0";
9
+ var OMNINODE_VERSION = "2.0.0-alpha.1";
10
10
 
11
11
  // src/errors/index.ts
12
12
  var OmniNodeError = class extends Error {
@@ -1302,40 +1302,54 @@ function registerRoleCommands(program) {
1302
1302
  });
1303
1303
  }
1304
1304
 
1305
- // src/tasks/store.ts
1305
+ // src/persistence/json-file-store.ts
1306
1306
  import { mkdir, readFile, rename, writeFile } from "fs/promises";
1307
1307
  import { dirname } from "path";
1308
- var FileTaskStore = class {
1308
+ var JsonFileStore = class {
1309
1309
  filePath;
1310
- /**
1311
- * Read-modify-write operations are serialized: parallel pipeline tasks
1312
- * would otherwise race on the JSON file (last writer wins).
1313
- */
1310
+ schemaVersion;
1311
+ onCorrupt;
1312
+ log;
1314
1313
  queue = Promise.resolve();
1315
- constructor(directory = `${process.cwd()}/.omninode`) {
1316
- this.filePath = `${directory}/tasks.json`;
1314
+ constructor(options) {
1315
+ this.filePath = `${options.directory ?? `${process.cwd()}/.omninode`}/${options.fileName}`;
1316
+ this.schemaVersion = options.schemaVersion ?? 1;
1317
+ this.onCorrupt = options.onCorrupt;
1318
+ this.log = logger.child({ component: "persistence", file: options.fileName });
1317
1319
  }
1318
- async save(task) {
1319
- return this.synchronized(async () => {
1320
- const tasks = await this.load();
1321
- const index = tasks.findIndex((t) => t.id === task.id);
1322
- if (index >= 0) tasks[index] = task;
1323
- else tasks.push(task);
1324
- await this.write(tasks);
1325
- });
1320
+ get path() {
1321
+ return this.filePath;
1326
1322
  }
1327
- async get(id) {
1328
- return this.synchronized(async () => {
1329
- const tasks = await this.load();
1330
- return tasks.find((t) => t.id === id);
1331
- });
1323
+ /** All items, or [] when missing/corrupt. */
1324
+ async readAll() {
1325
+ let raw;
1326
+ try {
1327
+ raw = await readFile(this.filePath, "utf8");
1328
+ } catch {
1329
+ return [];
1330
+ }
1331
+ try {
1332
+ const parsed = JSON.parse(raw);
1333
+ if (Array.isArray(parsed)) return parsed;
1334
+ if (parsed !== null && typeof parsed === "object" && Array.isArray(parsed.items)) {
1335
+ return parsed.items;
1336
+ }
1337
+ throw new Error("persisted file has an unrecognized shape");
1338
+ } catch (error) {
1339
+ this.log.warn(`Treating ${this.filePath} as empty \u2014 it could not be parsed.`);
1340
+ this.onCorrupt?.(this.filePath, error);
1341
+ return [];
1342
+ }
1332
1343
  }
1333
- async list(filter = {}) {
1334
- return this.synchronized(async () => {
1335
- const tasks = await this.load();
1336
- return tasks.filter((task) => filter.status ? task.status === filter.status : true).filter((task) => filter.project ? task.project === filter.project : true).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
1337
- });
1344
+ async writeAll(items) {
1345
+ const document = { schemaVersion: this.schemaVersion, items };
1346
+ const tmp = `${this.filePath}.tmp`;
1347
+ await mkdir(dirname(this.filePath), { recursive: true });
1348
+ await writeFile(tmp, `${JSON.stringify(document, null, 2)}
1349
+ `, "utf8");
1350
+ await rename(tmp, this.filePath);
1338
1351
  }
1352
+ /** Serializes an async operation against this file. */
1339
1353
  synchronized(operation) {
1340
1354
  const result = this.queue.then(operation, operation);
1341
1355
  this.queue = result.then(
@@ -1344,21 +1358,37 @@ var FileTaskStore = class {
1344
1358
  );
1345
1359
  return result;
1346
1360
  }
1347
- async load() {
1348
- try {
1349
- const raw = await readFile(this.filePath, "utf8");
1350
- const parsed = JSON.parse(raw);
1351
- return Array.isArray(parsed) ? parsed : [];
1352
- } catch {
1353
- return [];
1354
- }
1361
+ /** Read-modify-write helper: applies `mutate` to the current items. */
1362
+ async mutate(mutate) {
1363
+ return this.synchronized(async () => {
1364
+ const items = await this.readAll();
1365
+ const [next, result] = await mutate(items);
1366
+ await this.writeAll(next);
1367
+ return result;
1368
+ });
1355
1369
  }
1356
- async write(tasks) {
1357
- const tmp = `${this.filePath}.tmp`;
1358
- await mkdir(dirname(this.filePath), { recursive: true });
1359
- await writeFile(tmp, `${JSON.stringify(tasks, null, 2)}
1360
- `, "utf8");
1361
- await rename(tmp, this.filePath);
1370
+ };
1371
+
1372
+ // src/tasks/store.ts
1373
+ var FileTaskStore = class extends JsonFileStore {
1374
+ constructor(directory) {
1375
+ super({ ...directory !== void 0 ? { directory } : {}, fileName: "tasks.json" });
1376
+ }
1377
+ save(task) {
1378
+ return this.mutate((tasks) => {
1379
+ const index = tasks.findIndex((t) => t.id === task.id);
1380
+ if (index >= 0) tasks[index] = task;
1381
+ else tasks.push(task);
1382
+ return [tasks, void 0];
1383
+ });
1384
+ }
1385
+ async get(id) {
1386
+ const tasks = await this.readAll();
1387
+ return tasks.find((t) => t.id === id);
1388
+ }
1389
+ async list(filter = {}) {
1390
+ const tasks = await this.readAll();
1391
+ return tasks.filter((task) => filter.status ? task.status === filter.status : true).filter((task) => filter.project ? task.project === filter.project : true).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
1362
1392
  }
1363
1393
  };
1364
1394
 
@@ -1575,10 +1605,10 @@ var FileAuditLog = class {
1575
1605
  }
1576
1606
  /** Recent events, oldest first; used by the CLI. */
1577
1607
  async recent(limit = 20) {
1578
- const { readFile: readFile6 } = await import("fs/promises");
1608
+ const { readFile: readFile2 } = await import("fs/promises");
1579
1609
  let raw;
1580
1610
  try {
1581
- raw = await readFile6(this.filePath, "utf8");
1611
+ raw = await readFile2(this.filePath, "utf8");
1582
1612
  } catch {
1583
1613
  return [];
1584
1614
  }
@@ -1594,8 +1624,6 @@ var FileAuditLog = class {
1594
1624
  };
1595
1625
 
1596
1626
  // src/memory/local.ts
1597
- import { mkdir as mkdir3, readFile as readFile2, rename as rename2, writeFile as writeFile2 } from "fs/promises";
1598
- import { dirname as dirname3 } from "path";
1599
1627
  var STOPWORDS = /* @__PURE__ */ new Set([
1600
1628
  "the",
1601
1629
  "and",
@@ -1652,29 +1680,24 @@ function relevanceScore(queryKeywords, entry2) {
1652
1680
  }
1653
1681
  return overlap * 2 + tagMatches * 1.5;
1654
1682
  }
1655
- var LocalMemoryProvider = class {
1683
+ var LocalMemoryProvider = class extends JsonFileStore {
1656
1684
  name = "local";
1657
- filePath;
1658
- queue = Promise.resolve();
1659
- constructor(directory = `${process.cwd()}/.omninode`) {
1660
- this.filePath = `${directory}/memory.json`;
1685
+ constructor(directory) {
1686
+ super({ ...directory !== void 0 ? { directory } : {}, fileName: "memory.json" });
1661
1687
  }
1662
1688
  async query(query) {
1663
- return this.synchronized(async () => {
1664
- const entries = await this.load();
1665
- const filtered = entries.filter((entry2) => query.scope ? entry2.scope === query.scope : true).filter(
1666
- (entry2) => query.tags && query.tags.length > 0 ? query.tags.every((tag) => (entry2.tags ?? []).includes(tag)) : true
1667
- );
1668
- if (!query.text || query.text.trim().length === 0) {
1669
- return filtered.sort((a, b) => (b.updatedAt ?? b.createdAt ?? "").localeCompare(a.updatedAt ?? a.createdAt ?? "")).slice(0, query.limit ?? 10);
1670
- }
1671
- const queryKeywords = keywords(query.text);
1672
- return filtered.map((entry2) => ({ entry: entry2, score: relevanceScore(queryKeywords, entry2) })).filter(({ score }) => score > 0).sort((a, b) => b.score - a.score).slice(0, query.limit ?? 10).map(({ entry: entry2 }) => entry2);
1673
- });
1689
+ const entries = await this.readAll();
1690
+ const filtered = entries.filter((entry2) => query.scope ? entry2.scope === query.scope : true).filter(
1691
+ (entry2) => query.tags && query.tags.length > 0 ? query.tags.every((tag) => (entry2.tags ?? []).includes(tag)) : true
1692
+ );
1693
+ if (!query.text || query.text.trim().length === 0) {
1694
+ return filtered.sort((a, b) => (b.updatedAt ?? b.createdAt ?? "").localeCompare(a.updatedAt ?? a.createdAt ?? "")).slice(0, query.limit ?? 10);
1695
+ }
1696
+ const queryKeywords = keywords(query.text);
1697
+ return filtered.map((entry2) => ({ entry: entry2, score: relevanceScore(queryKeywords, entry2) })).filter(({ score }) => score > 0).sort((a, b) => b.score - a.score).slice(0, query.limit ?? 10).map(({ entry: entry2 }) => entry2);
1674
1698
  }
1675
- async write(entry2) {
1676
- return this.synchronized(async () => {
1677
- const entries = await this.load();
1699
+ write(entry2) {
1700
+ return this.mutate((entries) => {
1678
1701
  const index = entries.findIndex((e) => e.key === entry2.key);
1679
1702
  const stamped = {
1680
1703
  ...entry2,
@@ -1683,35 +1706,11 @@ var LocalMemoryProvider = class {
1683
1706
  };
1684
1707
  if (index >= 0) entries[index] = stamped;
1685
1708
  else entries.push(stamped);
1686
- await this.saveAll(entries);
1709
+ return [entries, void 0];
1687
1710
  });
1688
1711
  }
1689
1712
  async count() {
1690
- return (await this.load()).length;
1691
- }
1692
- synchronized(operation) {
1693
- const result = this.queue.then(operation, operation);
1694
- this.queue = result.then(
1695
- () => void 0,
1696
- () => void 0
1697
- );
1698
- return result;
1699
- }
1700
- async load() {
1701
- try {
1702
- const raw = await readFile2(this.filePath, "utf8");
1703
- const parsed = JSON.parse(raw);
1704
- return Array.isArray(parsed) ? parsed : [];
1705
- } catch {
1706
- return [];
1707
- }
1708
- }
1709
- async saveAll(entries) {
1710
- const tmp = `${this.filePath}.tmp`;
1711
- await mkdir3(dirname3(this.filePath), { recursive: true });
1712
- await writeFile2(tmp, `${JSON.stringify(entries, null, 2)}
1713
- `, "utf8");
1714
- await rename2(tmp, this.filePath);
1713
+ return (await this.readAll()).length;
1715
1714
  }
1716
1715
  };
1717
1716
 
@@ -2228,84 +2227,39 @@ var ReportService = class {
2228
2227
  };
2229
2228
 
2230
2229
  // src/reports/store.ts
2231
- import { mkdir as mkdir4, readFile as readFile3, rename as rename3, writeFile as writeFile3 } from "fs/promises";
2232
- import { dirname as dirname4 } from "path";
2233
- var FileReportStore = class {
2234
- filePath;
2235
- queue = Promise.resolve();
2236
- constructor(directory = `${process.cwd()}/.omninode`) {
2237
- this.filePath = `${directory}/reports.json`;
2230
+ var FileReportStore = class extends JsonFileStore {
2231
+ constructor(directory) {
2232
+ super({ ...directory !== void 0 ? { directory } : {}, fileName: "reports.json" });
2238
2233
  }
2239
2234
  async saveReports(reports) {
2240
- return this.synchronized(async () => {
2241
- const entries = await this.load();
2235
+ await this.mutate((entries) => {
2242
2236
  for (const report of reports) {
2243
- const index = entries.findIndex(
2244
- (e) => e.kind === "report" && e.report.id === report.id
2245
- );
2237
+ const index = entries.findIndex((e) => e.kind === "report" && e.report.id === report.id);
2246
2238
  const entry2 = { kind: "report", report };
2247
2239
  if (index >= 0) entries[index] = entry2;
2248
2240
  else entries.push(entry2);
2249
2241
  }
2250
- await this.write(entries);
2242
+ return [entries, void 0];
2251
2243
  });
2252
2244
  }
2253
2245
  async listReports(filter = {}) {
2254
- return this.synchronized(async () => {
2255
- const entries = await this.load();
2256
- return entries.filter((e) => e.kind === "report").map((e) => e.report).filter((report) => filter.taskId ? report.taskId === filter.taskId : true).filter((report) => filter.agent ? report.agent === filter.agent : true).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
2257
- });
2246
+ return (await this.readAll()).filter((e) => e.kind === "report").map((e) => e.report).filter((report) => filter.taskId ? report.taskId === filter.taskId : true).filter((report) => filter.agent ? report.agent === filter.agent : true).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
2258
2247
  }
2259
2248
  async saveCombined(combined) {
2260
- return this.synchronized(async () => {
2261
- const entries = await this.load();
2262
- const index = entries.findIndex(
2263
- (e) => e.kind === "combined" && e.combined.id === combined.id
2264
- );
2249
+ await this.mutate((entries) => {
2250
+ const index = entries.findIndex((e) => e.kind === "combined" && e.combined.id === combined.id);
2265
2251
  const entry2 = { kind: "combined", combined };
2266
2252
  if (index >= 0) entries[index] = entry2;
2267
2253
  else entries.push(entry2);
2268
- await this.write(entries);
2254
+ return [entries, void 0];
2269
2255
  });
2270
2256
  }
2271
2257
  async getCombined(id) {
2272
- return this.synchronized(async () => {
2273
- const entries = await this.load();
2274
- const found = entries.find((e) => e.kind === "combined" && e.combined.id === id);
2275
- return found?.kind === "combined" ? found.combined : void 0;
2276
- });
2258
+ const found = (await this.readAll()).find((e) => e.kind === "combined" && e.combined.id === id);
2259
+ return found?.kind === "combined" ? found.combined : void 0;
2277
2260
  }
2278
2261
  async listCombined(filter = {}) {
2279
- return this.synchronized(async () => {
2280
- const entries = await this.load();
2281
- return entries.filter((e) => e.kind === "combined").map((e) => e.combined).filter(
2282
- (combined) => filter.pipelineRunId ? combined.pipelineRunId === filter.pipelineRunId : true
2283
- ).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
2284
- });
2285
- }
2286
- synchronized(operation) {
2287
- const result = this.queue.then(operation, operation);
2288
- this.queue = result.then(
2289
- () => void 0,
2290
- () => void 0
2291
- );
2292
- return result;
2293
- }
2294
- async load() {
2295
- try {
2296
- const raw = await readFile3(this.filePath, "utf8");
2297
- const parsed = JSON.parse(raw);
2298
- return Array.isArray(parsed) ? parsed : [];
2299
- } catch {
2300
- return [];
2301
- }
2302
- }
2303
- async write(entries) {
2304
- const tmp = `${this.filePath}.tmp`;
2305
- await mkdir4(dirname4(this.filePath), { recursive: true });
2306
- await writeFile3(tmp, `${JSON.stringify(entries, null, 2)}
2307
- `, "utf8");
2308
- await rename3(tmp, this.filePath);
2262
+ return (await this.readAll()).filter((e) => e.kind === "combined").map((e) => e.combined).filter((combined) => filter.pipelineRunId ? combined.pipelineRunId === filter.pipelineRunId : true).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
2309
2263
  }
2310
2264
  };
2311
2265
 
@@ -3053,114 +3007,44 @@ function createDefaultChatFn(providers) {
3053
3007
  }
3054
3008
 
3055
3009
  // src/pipelines/store.ts
3056
- import { mkdir as mkdir5, readFile as readFile4, rename as rename4, writeFile as writeFile4 } from "fs/promises";
3057
- import { dirname as dirname5 } from "path";
3058
- var FilePipelineRunStore = class {
3059
- filePath;
3060
- queue = Promise.resolve();
3061
- constructor(directory = `${process.cwd()}/.omninode`) {
3062
- this.filePath = `${directory}/pipelines.json`;
3010
+ var FilePipelineRunStore = class extends JsonFileStore {
3011
+ constructor(directory) {
3012
+ super({ ...directory !== void 0 ? { directory } : {}, fileName: "pipelines.json" });
3063
3013
  }
3064
- async save(run2) {
3065
- return this.synchronized(async () => {
3066
- const runs = await this.load();
3014
+ save(run2) {
3015
+ return this.mutate((runs) => {
3067
3016
  const index = runs.findIndex((r) => r.id === run2.id);
3068
3017
  if (index >= 0) runs[index] = run2;
3069
3018
  else runs.push(run2);
3070
- await this.write(runs);
3019
+ return [runs, void 0];
3071
3020
  });
3072
3021
  }
3073
3022
  async get(id) {
3074
- return this.synchronized(async () => {
3075
- const runs = await this.load();
3076
- return runs.find((r) => r.id === id);
3077
- });
3023
+ return (await this.readAll()).find((r) => r.id === id);
3078
3024
  }
3079
3025
  async list(filter = {}) {
3080
- return this.synchronized(async () => {
3081
- const runs = await this.load();
3082
- return runs.filter((run2) => filter.pipelineId ? run2.pipelineId === filter.pipelineId : true).filter((run2) => filter.status ? run2.status === filter.status : true).sort((a, b) => (a.startedAt ?? "").localeCompare(b.startedAt ?? ""));
3083
- });
3084
- }
3085
- synchronized(operation) {
3086
- const result = this.queue.then(operation, operation);
3087
- this.queue = result.then(
3088
- () => void 0,
3089
- () => void 0
3090
- );
3091
- return result;
3092
- }
3093
- async load() {
3094
- try {
3095
- const raw = await readFile4(this.filePath, "utf8");
3096
- const parsed = JSON.parse(raw);
3097
- return Array.isArray(parsed) ? parsed : [];
3098
- } catch {
3099
- return [];
3100
- }
3101
- }
3102
- async write(runs) {
3103
- const tmp = `${this.filePath}.tmp`;
3104
- await mkdir5(dirname5(this.filePath), { recursive: true });
3105
- await writeFile4(tmp, `${JSON.stringify(runs, null, 2)}
3106
- `, "utf8");
3107
- await rename4(tmp, this.filePath);
3026
+ return (await this.readAll()).filter((run2) => filter.pipelineId ? run2.pipelineId === filter.pipelineId : true).filter((run2) => filter.status ? run2.status === filter.status : true).sort((a, b) => (a.startedAt ?? "").localeCompare(b.startedAt ?? ""));
3108
3027
  }
3109
3028
  };
3110
3029
 
3111
3030
  // src/planner/store.ts
3112
- import { mkdir as mkdir6, readFile as readFile5, rename as rename5, writeFile as writeFile5 } from "fs/promises";
3113
- import { dirname as dirname6 } from "path";
3114
- var FilePlanStore = class {
3115
- filePath;
3116
- queue = Promise.resolve();
3117
- constructor(directory = `${process.cwd()}/.omninode`) {
3118
- this.filePath = `${directory}/plans.json`;
3031
+ var FilePlanStore = class extends JsonFileStore {
3032
+ constructor(directory) {
3033
+ super({ ...directory !== void 0 ? { directory } : {}, fileName: "plans.json" });
3119
3034
  }
3120
- async save(plan) {
3121
- return this.synchronized(async () => {
3122
- const plans = await this.load();
3035
+ save(plan) {
3036
+ return this.mutate((plans) => {
3123
3037
  const index = plans.findIndex((p) => p.id === plan.id);
3124
3038
  if (index >= 0) plans[index] = plan;
3125
3039
  else plans.push(plan);
3126
- await this.write(plans);
3040
+ return [plans, void 0];
3127
3041
  });
3128
3042
  }
3129
3043
  async get(id) {
3130
- return this.synchronized(async () => {
3131
- const plans = await this.load();
3132
- return plans.find((p) => p.id === id);
3133
- });
3044
+ return (await this.readAll()).find((p) => p.id === id);
3134
3045
  }
3135
3046
  async list(filter = {}) {
3136
- return this.synchronized(async () => {
3137
- const plans = await this.load();
3138
- return plans.filter((plan) => filter.pipelineRunId ? plan.pipelineRunId === filter.pipelineRunId : true).filter((plan) => filter.taskId ? plan.taskId === filter.taskId : true).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
3139
- });
3140
- }
3141
- synchronized(operation) {
3142
- const result = this.queue.then(operation, operation);
3143
- this.queue = result.then(
3144
- () => void 0,
3145
- () => void 0
3146
- );
3147
- return result;
3148
- }
3149
- async load() {
3150
- try {
3151
- const raw = await readFile5(this.filePath, "utf8");
3152
- const parsed = JSON.parse(raw);
3153
- return Array.isArray(parsed) ? parsed : [];
3154
- } catch {
3155
- return [];
3156
- }
3157
- }
3158
- async write(plans) {
3159
- const tmp = `${this.filePath}.tmp`;
3160
- await mkdir6(dirname6(this.filePath), { recursive: true });
3161
- await writeFile5(tmp, `${JSON.stringify(plans, null, 2)}
3162
- `, "utf8");
3163
- await rename5(tmp, this.filePath);
3047
+ return (await this.readAll()).filter((plan) => filter.pipelineRunId ? plan.pipelineRunId === filter.pipelineRunId : true).filter((plan) => filter.taskId ? plan.taskId === filter.taskId : true).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
3164
3048
  }
3165
3049
  };
3166
3050