dotdog 0.7.1 → 0.8.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/dist/cli.js +63 -16
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3421,7 +3421,7 @@ function serve(dir = ".") {
|
|
|
3421
3421
|
project: P(dag),
|
|
3422
3422
|
nodes: N(dag).length,
|
|
3423
3423
|
edges: E(dag).length,
|
|
3424
|
-
version: dag.v || dag.version || "",
|
|
3424
|
+
version: dag.v || dag.version || (Array.isArray(dag) ? `${dag[0]}` : "unknown"),
|
|
3425
3425
|
order: dag.o || [],
|
|
3426
3426
|
cycles: dag.cy !== undefined ? dag.cy : null,
|
|
3427
3427
|
savings: tk.sv || tk.savings_pct || 0,
|
|
@@ -3464,6 +3464,18 @@ function serve(dir = ".") {
|
|
|
3464
3464
|
}
|
|
3465
3465
|
|
|
3466
3466
|
// src/cli.ts
|
|
3467
|
+
function normalizeDag(dag) {
|
|
3468
|
+
if (Array.isArray(dag)) {
|
|
3469
|
+
const v3Nodes = (dag[2] || []).map((n, i) => {
|
|
3470
|
+
const props = n[2] || [];
|
|
3471
|
+
const states = n[3] || [];
|
|
3472
|
+
const edges = n[4] || [];
|
|
3473
|
+
return [i, n[0], n[1] === "p" ? "prediction" : "entity", "", props, states, edges];
|
|
3474
|
+
});
|
|
3475
|
+
return { v: dag[0], p: dag[1], n: v3Nodes, tk: dag[3] };
|
|
3476
|
+
}
|
|
3477
|
+
return dag;
|
|
3478
|
+
}
|
|
3467
3479
|
function resolvePath2(p) {
|
|
3468
3480
|
if (p.startsWith("~"))
|
|
3469
3481
|
p = join3(homedir2(), p.slice(1));
|
|
@@ -3609,20 +3621,31 @@ program2.command("init <project>").option("-m, --minimal", "Only SPEC.dog + data
|
|
|
3609
3621
|
console.log(source_default.bold(`
|
|
3610
3622
|
Project "${p}" initialized. Fill in SPEC.dog then run spec validate.`));
|
|
3611
3623
|
});
|
|
3612
|
-
program2.command("list").action(() => {
|
|
3624
|
+
program2.command("list").option("--json", "Output project names as JSON").action((opts) => {
|
|
3625
|
+
const entries = [];
|
|
3613
3626
|
for (const d of ["projects", "specs"]) {
|
|
3614
3627
|
const dd = join3(process.cwd(), d);
|
|
3615
3628
|
if (!existsSync3(dd))
|
|
3616
3629
|
continue;
|
|
3617
3630
|
const projects = readdirSync3(dd, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
3631
|
+
for (const p of projects) {
|
|
3632
|
+
const sp = join3(dd, p);
|
|
3633
|
+
const n = existsSync3(sp) ? readdirSync3(sp).filter((f) => f.endsWith(".dog")).length : 0;
|
|
3634
|
+
entries.push({ root: d, name: p, dogFiles: n });
|
|
3635
|
+
}
|
|
3636
|
+
}
|
|
3637
|
+
if (opts.json) {
|
|
3638
|
+
console.log(JSON.stringify(entries.map((e) => e.name)));
|
|
3639
|
+
return;
|
|
3640
|
+
}
|
|
3641
|
+
for (const d of ["projects", "specs"]) {
|
|
3642
|
+
const projects = entries.filter((e) => e.root === d);
|
|
3618
3643
|
if (!projects.length)
|
|
3619
3644
|
continue;
|
|
3620
3645
|
console.log(source_default.bold(`
|
|
3621
3646
|
${d}/`));
|
|
3622
3647
|
for (const p of projects) {
|
|
3623
|
-
|
|
3624
|
-
const n = existsSync3(sp) ? readdirSync3(sp).filter((f) => f.endsWith(".dog")).length : 0;
|
|
3625
|
-
console.log(` ${source_default.cyan(p)} : ${n} .dog files`);
|
|
3648
|
+
console.log(` ${source_default.cyan(p.name)} : ${p.dogFiles} .dog files`);
|
|
3626
3649
|
}
|
|
3627
3650
|
}
|
|
3628
3651
|
});
|
|
@@ -3634,7 +3657,7 @@ ${s.length} sections`));
|
|
|
3634
3657
|
for (const sec of s)
|
|
3635
3658
|
console.log(` ${sec.heading.padEnd(30)} ${sec.content.length} chars`);
|
|
3636
3659
|
});
|
|
3637
|
-
program2.command("compile [dir]").option("-o, --output <file>").action((d = ".", opts) => {
|
|
3660
|
+
program2.command("compile [dir]").option("-o, --output <file>").option("--v3", "Ultra-compact v3 format (53% smaller than v2)").action((d = ".", opts) => {
|
|
3638
3661
|
const dir = resolvePath2(d);
|
|
3639
3662
|
const dirs = [join3(dir, "projects"), join3(dir, "specs"), dir];
|
|
3640
3663
|
let found = false;
|
|
@@ -3784,16 +3807,36 @@ program2.command("compile [dir]").option("-o, --output <file>").action((d = ".",
|
|
|
3784
3807
|
}
|
|
3785
3808
|
v2nodes.push(entry);
|
|
3786
3809
|
}
|
|
3787
|
-
const
|
|
3788
|
-
const
|
|
3789
|
-
const
|
|
3810
|
+
const outPath = opts.output || join3(pd, `${p}.dag`);
|
|
3811
|
+
const v2dag = { v: 2, p, n: v2nodes };
|
|
3812
|
+
const v2Json = JSON.stringify(v2dag);
|
|
3813
|
+
const dagTokens = Math.round(Buffer.byteLength(v2Json, "utf-8") / 4);
|
|
3790
3814
|
const allSavingsPct = sourceTokens > 0 ? Math.round((1 - dagTokens / sourceTokens) * 1000) / 10 : 0;
|
|
3791
3815
|
const contentSavingsPct = contentTokens > 0 ? Math.round((1 - dagTokens / contentTokens) * 1000) / 10 : 0;
|
|
3792
3816
|
const savingsTokens = sourceTokens - dagTokens;
|
|
3793
|
-
const outPath = opts.output || join3(pd, `${p}.dag`);
|
|
3794
3817
|
const tokens = { m: "chars/4", st: sourceTokens, ct: contentTokens, dt: dagTokens, sv: allSavingsPct, cs: contentSavingsPct, saved: savingsTokens };
|
|
3795
|
-
const
|
|
3796
|
-
|
|
3818
|
+
const v3dag = [3, p, v2nodes.map((n) => {
|
|
3819
|
+
const nd2 = nodes[n[0]];
|
|
3820
|
+
const tc = nd2.g === "prediction" ? "p" : "e";
|
|
3821
|
+
const st = nd2.s && nd2.s.length ? nd2.s : null;
|
|
3822
|
+
const ed = n[6] && n[6].length ? n[6] : null;
|
|
3823
|
+
const entry = [nd2.i, tc, n[4].length ? n[4] : null, st, ed];
|
|
3824
|
+
if (nd2.g === "prediction") {
|
|
3825
|
+
const f = [];
|
|
3826
|
+
if (nd2.cf != null)
|
|
3827
|
+
f.push(nd2.cf);
|
|
3828
|
+
if (nd2.tf)
|
|
3829
|
+
f.push(nd2.tf);
|
|
3830
|
+
if (f.length)
|
|
3831
|
+
entry.push(f);
|
|
3832
|
+
}
|
|
3833
|
+
return entry;
|
|
3834
|
+
}), tokens];
|
|
3835
|
+
const dag = opts.v3 ? v3dag : v2dag;
|
|
3836
|
+
const dagJson = JSON.stringify(dag);
|
|
3837
|
+
const report = opts.v3 ? [...dag, tokens] : { ...dag, tk: tokens };
|
|
3838
|
+
writeFileSync2(outPath, JSON.stringify(report, null, 2) + `
|
|
3839
|
+
`);
|
|
3797
3840
|
console.log(source_default.green(` ✓ ${outPath}`));
|
|
3798
3841
|
console.log(source_default.gray(` ${nodes.length} nodes, ${edges.length} edges, ${files.length} files`));
|
|
3799
3842
|
console.log(source_default.gray(` ${sourceTokens} → ${dagTokens} tokens (${allSavingsPct}% savings, ${contentSavingsPct}% content-only, ${savingsTokens} saved)`));
|
|
@@ -3858,7 +3901,8 @@ program2.command("visualize [dir]").option("-s, --save").action((d = ".", opts)
|
|
|
3858
3901
|
if (!existsSync3(dagFile))
|
|
3859
3902
|
continue;
|
|
3860
3903
|
const dag = JSON.parse(readFileSync3(dagFile, "utf-8"));
|
|
3861
|
-
const
|
|
3904
|
+
const d2 = normalizeDag(dag);
|
|
3905
|
+
const nodes = d2.n || dag.nodes || [];
|
|
3862
3906
|
const isV22 = (n) => Array.isArray(n) && typeof n[0] === "number";
|
|
3863
3907
|
const nodeName2 = (n) => isV22(n) ? nodes[n[0]] ? nodes[n[0]][1] || String(n[0]) : String(n[0]) : n.i || n.id || "";
|
|
3864
3908
|
const slug = (s) => s.replace(/\s+/g, "_").replace(/^[^a-zA-Z]+/, "n_");
|
|
@@ -4198,7 +4242,8 @@ program2.command("simulate <scenario>").description("Walk through a scenario, ch
|
|
|
4198
4242
|
let entities = [], relationships = [];
|
|
4199
4243
|
if (existsSync3(dagFile)) {
|
|
4200
4244
|
const dag = JSON.parse(readFileSync3(dagFile, "utf-8"));
|
|
4201
|
-
const
|
|
4245
|
+
const d2 = normalizeDag(dag);
|
|
4246
|
+
const simNodes = d2.n || dag.nodes || [];
|
|
4202
4247
|
const isV22 = (n) => Array.isArray(n) && typeof n[0] === "number";
|
|
4203
4248
|
entities = simNodes.map((n) => (isV22(n) ? n[1] || String(n[0]) : n.i || n.id || "").toLowerCase());
|
|
4204
4249
|
if (dag.e || dag.edges) {
|
|
@@ -4369,7 +4414,8 @@ program2.command("verify [dir]").description("Verify spec-code alignment. --init
|
|
|
4369
4414
|
if (opts.init) {
|
|
4370
4415
|
const entities = [];
|
|
4371
4416
|
const props = new Map;
|
|
4372
|
-
|
|
4417
|
+
const d3 = normalizeDag(dag);
|
|
4418
|
+
for (const node of d3.n || []) {
|
|
4373
4419
|
const name = node[1] || String(node[0]);
|
|
4374
4420
|
entities.push(name);
|
|
4375
4421
|
if (node[4])
|
|
@@ -4719,7 +4765,8 @@ program2.command("badge [dir]").description("Generate dotdog-badge.svg (shields.
|
|
|
4719
4765
|
console.log(source_default.red(` No .dag for ${p}. Run dotdog compile first.`));
|
|
4720
4766
|
continue;
|
|
4721
4767
|
}
|
|
4722
|
-
const
|
|
4768
|
+
const rawDag = JSON.parse(readFileSync3(dagFile, "utf-8"));
|
|
4769
|
+
const dag = normalizeDag(rawDag);
|
|
4723
4770
|
const saved = dag.tk && dag.tk.saved ? dag.tk.saved : 0;
|
|
4724
4771
|
const fmt = saved >= 1000 ? `${(saved / 1000).toFixed(1)}K` : `${saved}`;
|
|
4725
4772
|
const label = "dotdog";
|