@guyghost/swarm-dao-cli 0.4.5 → 0.6.0

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.
@@ -0,0 +1,28 @@
1
+ export declare const SERIES_ROOT_CANDIDATES: readonly [".dao/improvement-series", "evidence/improvement-series"];
2
+ export declare const CYCLE_ROOT_CANDIDATES: readonly [".dao/improvement-cycles", "evidence/improvement-cycles"];
3
+ export declare const GRAPH_ROOT_CANDIDATES: readonly [".dao/graph-runs", "evidence/graph-runs"];
4
+ export interface LocatedRoot {
5
+ /** Absolute resolved root — the flag when given, else the best hit. */
6
+ root: string;
7
+ /** True when <root>/<id>/snapshot.json exists. */
8
+ found: boolean;
9
+ /** Relative candidates tried (for "not found" messages). */
10
+ tried: readonly string[];
11
+ }
12
+ /**
13
+ * Locate an evidence object across candidate roots. When the same id exists
14
+ * in several roots, a series that has actually started beats a fresh idle
15
+ * snapshot (running `improve status` without a root flag materializes an idle
16
+ * series under .dao/ — the operator's real series usually lives elsewhere).
17
+ */
18
+ export declare function locateRoot(cwd: string, id: string, candidates: readonly string[], explicit?: string): Promise<LocatedRoot>;
19
+ /** Read and parse a JSON file, or null when absent/invalid. */
20
+ export declare function readJsonOrNull(file: string): Promise<unknown>;
21
+ /** First/last journal timestamps as cycle duration, or null when unknowable. */
22
+ export declare function readJournalDurationMs(cycleDir: string): Promise<number | null>;
23
+ /** All cycle directories <root>/<seriesId>-c<N>, sorted by N. */
24
+ export declare function listCycleDirs(cycleRoot: string, seriesId: string): Promise<Array<{
25
+ number: number;
26
+ dir: string;
27
+ }>>;
28
+ //# sourceMappingURL=roots.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roots.d.ts","sourceRoot":"","sources":["../src/roots.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,sBAAsB,qEAAsE,CAAC;AAC1G,eAAO,MAAM,qBAAqB,qEAAsE,CAAC;AACzG,eAAO,MAAM,qBAAqB,qDAAsD,CAAC;AAEzF,MAAM,WAAW,WAAW;IAC1B,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,KAAK,EAAE,OAAO,CAAC;IACf,4DAA4D;IAC5D,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,WAAW,CAAC,CActB;AAED,+DAA+D;AAC/D,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMnE;AAED,gFAAgF;AAChF,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYpF;AAED,iEAAiE;AACjE,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAYjD"}
package/dist/roots.js ADDED
@@ -0,0 +1,78 @@
1
+ // Swarm DAO CLI — evidence-root location.
2
+ //
3
+ // Reads (status, cycles, gates) resolve an existing series/run across the
4
+ // known roots (.dao/* default, evidence/* repo-dogfood convention) instead of
5
+ // silently answering from a fresh idle snapshot. Creation effects (init, once,
6
+ // submit) keep the strict explicit/default root: no silent resolution on
7
+ // writes.
8
+ import { readdir, readFile } from "node:fs/promises";
9
+ import path from "node:path";
10
+ export const SERIES_ROOT_CANDIDATES = [".dao/improvement-series", "evidence/improvement-series"];
11
+ export const CYCLE_ROOT_CANDIDATES = [".dao/improvement-cycles", "evidence/improvement-cycles"];
12
+ export const GRAPH_ROOT_CANDIDATES = [".dao/graph-runs", "evidence/graph-runs"];
13
+ /**
14
+ * Locate an evidence object across candidate roots. When the same id exists
15
+ * in several roots, a series that has actually started beats a fresh idle
16
+ * snapshot (running `improve status` without a root flag materializes an idle
17
+ * series under .dao/ — the operator's real series usually lives elsewhere).
18
+ */
19
+ export async function locateRoot(cwd, id, candidates, explicit) {
20
+ const list = explicit ? [explicit] : candidates;
21
+ let fallback = null;
22
+ for (const relative of list) {
23
+ const root = path.resolve(cwd, relative);
24
+ const parsed = await readJsonOrNull(path.join(root, id, "snapshot.json"));
25
+ if (parsed === null)
26
+ continue;
27
+ const located = { root, found: true, tried: list };
28
+ const started = parsed.context?.started;
29
+ if (started === true)
30
+ return located;
31
+ fallback ??= located;
32
+ }
33
+ if (fallback)
34
+ return fallback;
35
+ return { root: path.resolve(cwd, list[0] ?? "."), found: false, tried: list };
36
+ }
37
+ /** Read and parse a JSON file, or null when absent/invalid. */
38
+ export async function readJsonOrNull(file) {
39
+ try {
40
+ return JSON.parse(await readFile(file, "utf8"));
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }
46
+ /** First/last journal timestamps as cycle duration, or null when unknowable. */
47
+ export async function readJournalDurationMs(cycleDir) {
48
+ try {
49
+ const raw = await readFile(path.join(cycleDir, "journal.ndjson"), "utf8");
50
+ const lines = raw.split("\n").filter((l) => l.trim().length > 0);
51
+ if (lines.length === 0)
52
+ return null;
53
+ const first = Date.parse(JSON.parse(lines[0] ?? "").receivedAt ?? "");
54
+ const last = Date.parse(JSON.parse(lines[lines.length - 1] ?? "").receivedAt ?? "");
55
+ if (!Number.isFinite(first) || !Number.isFinite(last) || last < first)
56
+ return null;
57
+ return last - first;
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ }
63
+ /** All cycle directories <root>/<seriesId>-c<N>, sorted by N. */
64
+ export async function listCycleDirs(cycleRoot, seriesId) {
65
+ let entries = [];
66
+ try {
67
+ entries = await readdir(cycleRoot);
68
+ }
69
+ catch {
70
+ return [];
71
+ }
72
+ const prefix = `${seriesId}-c`;
73
+ return entries
74
+ .filter((name) => name.startsWith(prefix) && /^\d+$/.test(name.slice(prefix.length)))
75
+ .map((name) => ({ number: Number(name.slice(prefix.length)), dir: path.join(cycleRoot, name) }))
76
+ .sort((a, b) => a.number - b.number);
77
+ }
78
+ //# sourceMappingURL=roots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roots.js","sourceRoot":"","sources":["../src/roots.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,EAAE;AACF,0EAA0E;AAC1E,8EAA8E;AAC9E,+EAA+E;AAC/E,yEAAyE;AACzE,UAAU;AAEV,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,yBAAyB,EAAE,6BAA6B,CAAU,CAAC;AAC1G,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,yBAAyB,EAAE,6BAA6B,CAAU,CAAC;AACzG,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,iBAAiB,EAAE,qBAAqB,CAAU,CAAC;AAWzF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAW,EACX,EAAU,EACV,UAA6B,EAC7B,QAAiB;IAEjB,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IAChD,IAAI,QAAQ,GAAuB,IAAI,CAAC;IACxC,KAAK,MAAM,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;QAC1E,IAAI,MAAM,KAAK,IAAI;YAAE,SAAS;QAC9B,MAAM,OAAO,GAAgB,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QAChE,MAAM,OAAO,GAAI,MAA8C,CAAC,OAAO,EAAE,OAAO,CAAC;QACjF,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,OAAO,CAAC;QACrC,QAAQ,KAAK,OAAO,CAAC;IACvB,CAAC;IACD,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AAChF,CAAC;AAED,+DAA+D;AAC/D,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY;IAC/C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,QAAgB;IAC1D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC,CAAC;QAC1E,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACpC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAA6B,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;QACnG,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,CAA6B,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;QACjH,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,KAAK;YAAE,OAAO,IAAI,CAAC;QACnF,OAAO,IAAI,GAAG,KAAK,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,iEAAiE;AACjE,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,SAAiB,EACjB,QAAgB;IAEhB,IAAI,OAAO,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,QAAQ,IAAI,CAAC;IAC/B,OAAO,OAAO;SACX,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;SACpF,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;SAC/F,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;AACzC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guyghost/swarm-dao-cli",
3
- "version": "0.4.5",
3
+ "version": "0.6.0",
4
4
  "description": "Swarm DAO standalone CLI",
5
5
  "type": "module",
6
6
  "main": "./dist/cli.js",
@@ -25,7 +25,7 @@
25
25
  "prepublishOnly": "bun run build"
26
26
  },
27
27
  "dependencies": {
28
- "@guyghost/swarm-dao-core": "^0.12.0",
28
+ "@guyghost/swarm-dao-core": "^0.12.1",
29
29
  "@guyghost/swarm-dao-graph": "^0.3.1",
30
30
  "@guyghost/swarm-dao-improvement": "^0.5.3",
31
31
  "@guyghost/swarm-dao-product": "^0.3.1"