@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 +14 -1
- package/dist/cli/index.js +118 -234
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +148 -31
- package/dist/index.js +145 -234
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
**
|
|
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 = "
|
|
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/
|
|
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
|
|
1308
|
+
var JsonFileStore = class {
|
|
1309
1309
|
filePath;
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
*/
|
|
1310
|
+
schemaVersion;
|
|
1311
|
+
onCorrupt;
|
|
1312
|
+
log;
|
|
1314
1313
|
queue = Promise.resolve();
|
|
1315
|
-
constructor(
|
|
1316
|
-
this.filePath = `${directory}
|
|
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
|
-
|
|
1319
|
-
return this.
|
|
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
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
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
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
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
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
const
|
|
1351
|
-
|
|
1352
|
-
|
|
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
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
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:
|
|
1608
|
+
const { readFile: readFile2 } = await import("fs/promises");
|
|
1579
1609
|
let raw;
|
|
1580
1610
|
try {
|
|
1581
|
-
raw = await
|
|
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
|
-
|
|
1658
|
-
|
|
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
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
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
|
-
|
|
1676
|
-
return this.
|
|
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
|
-
|
|
1709
|
+
return [entries, void 0];
|
|
1687
1710
|
});
|
|
1688
1711
|
}
|
|
1689
1712
|
async count() {
|
|
1690
|
-
return (await this.
|
|
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
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2242
|
+
return [entries, void 0];
|
|
2251
2243
|
});
|
|
2252
2244
|
}
|
|
2253
2245
|
async listReports(filter = {}) {
|
|
2254
|
-
return this.
|
|
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
|
-
|
|
2261
|
-
const
|
|
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
|
-
|
|
2254
|
+
return [entries, void 0];
|
|
2269
2255
|
});
|
|
2270
2256
|
}
|
|
2271
2257
|
async getCombined(id) {
|
|
2272
|
-
|
|
2273
|
-
|
|
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.
|
|
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
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
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
|
-
|
|
3065
|
-
return this.
|
|
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
|
-
|
|
3019
|
+
return [runs, void 0];
|
|
3071
3020
|
});
|
|
3072
3021
|
}
|
|
3073
3022
|
async get(id) {
|
|
3074
|
-
return this.
|
|
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.
|
|
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
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
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
|
-
|
|
3121
|
-
return this.
|
|
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
|
-
|
|
3040
|
+
return [plans, void 0];
|
|
3127
3041
|
});
|
|
3128
3042
|
}
|
|
3129
3043
|
async get(id) {
|
|
3130
|
-
return this.
|
|
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.
|
|
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
|
|