adsa-cli 0.1.1 → 0.1.2

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
@@ -58,6 +58,10 @@ the version checked out in front of them instead of reading files and guessing.
58
58
 
59
59
  `npx adsa-cli rubric` prints what 1, 3 and 5 mean for each.
60
60
 
61
+ `--out <dir>` puts every artifact of a run together somewhere else — the report, the
62
+ score, the badge and the history — and reads the previous score from there too, so a
63
+ repository can be audited without writing anything into it.
64
+
61
65
  ## Commands
62
66
 
63
67
  ```
package/bin/adsa.mjs CHANGED
@@ -11,14 +11,14 @@
11
11
  * adsa badge the README badge for the committed score
12
12
  */
13
13
  import { mkdirSync, realpathSync, writeFileSync } from "node:fs";
14
- import { join, resolve } from "node:path";
14
+ import { join, relative, resolve } from "node:path";
15
15
  import { pathToFileURL } from "node:url";
16
16
  import { loadConfig, resolveTarget } from "../lib/config.mjs";
17
17
  import { scan } from "../lib/scan.mjs";
18
18
  import { RUBRIC, score, scoreFile } from "../lib/score.mjs";
19
19
  import { buildTodo, html, markdown } from "../lib/report.mjs";
20
20
  import { badgeEndpoint, badgeMarkdown } from "../lib/badge.mjs";
21
- import { isDir } from "../lib/fsx.mjs";
21
+ import { exists, isDir } from "../lib/fsx.mjs";
22
22
  import { DIR, appendHistory, compare, readHistory, write } from "../lib/history.mjs";
23
23
  import { FIXES, applyFix } from "../lib/fix.mjs";
24
24
  import { evaluate, taskFile } from "../lib/eval.mjs";
@@ -47,7 +47,7 @@ Usage
47
47
 
48
48
  Options
49
49
  --json Machine-readable output
50
- --out <dir> Where to write the report (default: .adsa)
50
+ --out <dir> Write every artifact here instead of .adsa/
51
51
  --gate Exit non-zero if the score dropped, or is below --min
52
52
  --min <n> Minimum acceptable total for --gate
53
53
  --dry-run fix: show what would change, write nothing
@@ -157,9 +157,13 @@ function cmdAudit(dir, flags, out, json) {
157
157
  return 1;
158
158
  }
159
159
  const scored = score(facts, config);
160
- const outDir = flags.out || DIR;
160
+ // Everything one run writes lands together. --out is read from where the command
161
+ // was typed, so an absolute path is absolute and a relative one is relative to
162
+ // the reader, not to the repository being audited.
163
+ const artefacts = flags.out ? resolve(process.cwd(), flags.out) : join(root, DIR);
164
+ const fresh = !exists(join(artefacts, "score.json"));
161
165
  const file = scoreFile(facts, scored);
162
- const previous = readJson(join(root, DIR, "score.json"));
166
+ const previous = readJson(join(artefacts, "score.json"));
163
167
  const delta = compare(previous, file);
164
168
 
165
169
  if (flags.json) {
@@ -191,14 +195,25 @@ function cmdAudit(dir, flags, out, json) {
191
195
  }
192
196
  }
193
197
 
194
- const history = appendHistory(root, { date: file.generatedAt, total: file.total, max: file.max, dimensions: file.dimensions });
195
- write(join(root, DIR, "score.json"), file);
196
- write(join(root, DIR, "badge.json"), badgeEndpoint(file.total, file.max));
197
- const reportDir = join(root, outDir);
198
- mkdirSync(reportDir, { recursive: true });
199
- writeFileSync(join(reportDir, "report.html"), html(facts, scored, history));
200
- writeFileSync(join(reportDir, "report.md"), markdown(facts, scored));
201
- if (!flags.json && !flags.quiet) out(dim(`\nReport: ${join(outDir, "report.html")} · score: ${join(DIR, "score.json")}`));
198
+ const history = appendHistory(artefacts, { date: file.generatedAt, total: file.total, max: file.max, dimensions: file.dimensions });
199
+ write(join(artefacts, "score.json"), file);
200
+ write(join(artefacts, "badge.json"), badgeEndpoint(file.total, file.max));
201
+ mkdirSync(artefacts, { recursive: true });
202
+ writeFileSync(join(artefacts, "report.html"), html(facts, scored, history));
203
+ writeFileSync(join(artefacts, "report.md"), markdown(facts, scored));
204
+ // A path that climbs out of the current directory reads better absolute than as
205
+ // a ladder of "..".
206
+ const near = relative(process.cwd(), artefacts);
207
+ const shown = !near ? "." : near.startsWith("..") ? artefacts : near;
208
+ if (!flags.json && !flags.quiet) {
209
+ out(dim(`\nReport: ${join(shown, "report.html")} · score: ${join(shown, "score.json")}`));
210
+ // Say once what the directory is for, rather than leave someone to guess
211
+ // whether a new folder in their repository belongs in the commit.
212
+ if (fresh && !flags.out && exists(join(root, ".git"))) {
213
+ out(dim(" score.json, badge.json and history.json are meant to be committed — the badge and the gate read them."));
214
+ out(dim(" report.html and report.md are rewritten every run; ignore them if you would rather not carry them."));
215
+ }
216
+ }
202
217
 
203
218
  if (flags.gate) {
204
219
  const floor = flags.min ?? config.minScore ?? (previous ? previous.total : null);
package/lib/history.mjs CHANGED
@@ -5,22 +5,24 @@ import { readJson } from "./fsx.mjs";
5
5
 
6
6
  export const DIR = ".adsa";
7
7
 
8
- export function historyPath(root) {
9
- return join(root, DIR, "history.json");
8
+ /** Takes the directory the run writes into, not the repository root: with --out
9
+ * that is somewhere else entirely, and the history has to travel with the score. */
10
+ export function historyPath(dir) {
11
+ return join(dir, "history.json");
10
12
  }
11
13
 
12
- export function readHistory(root) {
13
- const json = readJson(historyPath(root));
14
+ export function readHistory(dir) {
15
+ const json = readJson(historyPath(dir));
14
16
  return Array.isArray(json) ? json : [];
15
17
  }
16
18
 
17
19
  /** Appends a run, collapsing same-day reruns so the file does not grow per invocation. */
18
- export function appendHistory(root, entry) {
19
- const history = readHistory(root);
20
+ export function appendHistory(dir, entry) {
21
+ const history = readHistory(dir);
20
22
  const day = entry.date.slice(0, 10);
21
23
  const filtered = history.filter((h) => h.date.slice(0, 10) !== day);
22
24
  filtered.push(entry);
23
- write(historyPath(root), filtered);
25
+ write(historyPath(dir), filtered);
24
26
  return filtered;
25
27
  }
26
28
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adsa-cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Score a design system on how well coding agents can use it, then fix what is missing.",
5
5
  "type": "module",
6
6
  "bin": {