agentready-design-cli 0.1.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.
- package/CRITERIA.md +57 -0
- package/README.md +51 -0
- package/dist/chunk-GWF7PSLR.js +1207 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +97 -0
- package/dist/index.d.ts +103 -0
- package/dist/index.js +19 -0
- package/package.json +61 -0
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
TIER_LABELS,
|
|
4
|
+
renderMarkdown,
|
|
5
|
+
runAssessment
|
|
6
|
+
} from "./chunk-GWF7PSLR.js";
|
|
7
|
+
|
|
8
|
+
// src/cli.ts
|
|
9
|
+
import { writeFile, mkdir } from "fs/promises";
|
|
10
|
+
import { dirname, resolve } from "path";
|
|
11
|
+
import { existsSync } from "fs";
|
|
12
|
+
import kleur from "kleur";
|
|
13
|
+
function parseArgs(argv) {
|
|
14
|
+
const args = argv.slice(2);
|
|
15
|
+
let target = ".";
|
|
16
|
+
let format = "both";
|
|
17
|
+
let out = ".";
|
|
18
|
+
let name;
|
|
19
|
+
let merge;
|
|
20
|
+
let help = false;
|
|
21
|
+
for (let i = 0; i < args.length; i++) {
|
|
22
|
+
const a = args[i];
|
|
23
|
+
if (a === "-h" || a === "--help") help = true;
|
|
24
|
+
else if (a === "--format") format = args[++i] ?? "both";
|
|
25
|
+
else if (a === "--out") out = args[++i] ?? ".";
|
|
26
|
+
else if (a === "--target") name = args[++i];
|
|
27
|
+
else if (a === "--merge") merge = args[++i];
|
|
28
|
+
else if (!a.startsWith("-")) target = a;
|
|
29
|
+
}
|
|
30
|
+
return { target, format, out, name, merge, help };
|
|
31
|
+
}
|
|
32
|
+
var HELP = `
|
|
33
|
+
${kleur.bold("agent-ready")} \u2014 score a design system against the Agent-Ready Design rubric.
|
|
34
|
+
|
|
35
|
+
${kleur.bold("Usage")}
|
|
36
|
+
npx agentready-design-cli [path] [options]
|
|
37
|
+
|
|
38
|
+
${kleur.bold("Options")}
|
|
39
|
+
--format <markdown|json|both> Output format. Default: both.
|
|
40
|
+
--out <dir> Directory to write reports into. Default: <path>.
|
|
41
|
+
--target <name> Friendly name for the report header.
|
|
42
|
+
--merge <file.json> Existing agent-ready-report.json to merge into (re-runs only pending rows).
|
|
43
|
+
-h, --help Show this help.
|
|
44
|
+
|
|
45
|
+
${kleur.bold("Examples")}
|
|
46
|
+
npx agentready-design-cli ./packages/ui
|
|
47
|
+
npx agentready-design-cli ./ds --format markdown --target "Acme UI"
|
|
48
|
+
npx agentready-design-cli ./ds --merge ./ds/agent-ready-report.json
|
|
49
|
+
`;
|
|
50
|
+
async function main() {
|
|
51
|
+
const opts = parseArgs(process.argv);
|
|
52
|
+
if (opts.help) {
|
|
53
|
+
console.log(HELP);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const target = resolve(opts.target);
|
|
57
|
+
if (!existsSync(target)) {
|
|
58
|
+
console.error(kleur.red(`\u2716 Target path does not exist: ${target}`));
|
|
59
|
+
process.exitCode = 1;
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
console.log(kleur.dim(`Scoring ${target} against Agent-Ready Design v0.1...`));
|
|
63
|
+
const report = await runAssessment({ target, name: opts.name, merge: opts.merge });
|
|
64
|
+
const outDir = resolve(opts.out);
|
|
65
|
+
await mkdir(outDir, { recursive: true });
|
|
66
|
+
if (opts.format === "json" || opts.format === "both") {
|
|
67
|
+
const p = resolve(outDir, "agent-ready-report.json");
|
|
68
|
+
await mkdir(dirname(p), { recursive: true });
|
|
69
|
+
await writeFile(p, JSON.stringify(report, null, 2) + "\n", "utf8");
|
|
70
|
+
console.log(kleur.green(`\u2713 ${p}`));
|
|
71
|
+
}
|
|
72
|
+
if (opts.format === "markdown" || opts.format === "both") {
|
|
73
|
+
const p = resolve(outDir, "agent-ready-report.md");
|
|
74
|
+
await writeFile(p, renderMarkdown(report) + "\n", "utf8");
|
|
75
|
+
console.log(kleur.green(`\u2713 ${p}`));
|
|
76
|
+
}
|
|
77
|
+
const r = report.rollup;
|
|
78
|
+
console.log("");
|
|
79
|
+
console.log(
|
|
80
|
+
kleur.bold(
|
|
81
|
+
`Tier ${r.tier} \u2014 ${TIER_LABELS[r.tier]} \xB7 floor ${r.foundationalFloor}/4 \xB7 retrieval ${r.retrievalLevel}/4 \xB7 median ${r.overallMedian.toFixed(1)}/4`
|
|
82
|
+
)
|
|
83
|
+
);
|
|
84
|
+
const pendingCount = report.criteria.filter((c) => c.status === "pending").length;
|
|
85
|
+
if (pendingCount > 0) {
|
|
86
|
+
console.log(
|
|
87
|
+
kleur.yellow(
|
|
88
|
+
`
|
|
89
|
+
${pendingCount} criteria require an agent. Paste prompts/self-assessment.md from the rubric repo to complete the report.`
|
|
90
|
+
)
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
main().catch((err) => {
|
|
95
|
+
console.error(kleur.red("\u2716 "), err);
|
|
96
|
+
process.exitCode = 1;
|
|
97
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mirror of report.schema.json for TypeScript consumers.
|
|
3
|
+
* Keep in sync — the JSON Schema is authoritative.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
type CriterionId =
|
|
7
|
+
| `1.${1 | 2 | 3 | 4}`
|
|
8
|
+
| `2.${1 | 2 | 3 | 4 | 5}`
|
|
9
|
+
| `3.${1 | 2 | 3 | 4}`
|
|
10
|
+
| `4.${1 | 2 | 3}`
|
|
11
|
+
| `5.${1 | 2 | 3 | 4}`
|
|
12
|
+
| `6.${1 | 2 | 3}`
|
|
13
|
+
| `7.${1 | 2 | 3 | 4}`
|
|
14
|
+
| `8.${1 | 2 | 3 | 4}`;
|
|
15
|
+
|
|
16
|
+
type Score = 0 | 1 | 2 | 3 | 4;
|
|
17
|
+
type Category = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
|
|
18
|
+
type CriterionStatus = "scored" | "pending" | "skipped" | "error";
|
|
19
|
+
type PendingReason = "requires-agent" | "requires-human";
|
|
20
|
+
type ProducerKind = "cli" | "prompt" | "skill" | "merged";
|
|
21
|
+
type EvidenceKind = "file" | "glob" | "command" | "url" | "note";
|
|
22
|
+
type EffortBucket = "hours" | "days" | "weeks" | "months";
|
|
23
|
+
|
|
24
|
+
interface Evidence {
|
|
25
|
+
kind: EvidenceKind;
|
|
26
|
+
path?: string;
|
|
27
|
+
line?: number;
|
|
28
|
+
snippet?: string;
|
|
29
|
+
detail?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface Criterion {
|
|
33
|
+
id: CriterionId;
|
|
34
|
+
category: Category;
|
|
35
|
+
title: string;
|
|
36
|
+
score: Score | null;
|
|
37
|
+
status?: CriterionStatus;
|
|
38
|
+
pending?: PendingReason;
|
|
39
|
+
rationale?: string;
|
|
40
|
+
evidence: Evidence[];
|
|
41
|
+
suggestion?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface BacklogItem {
|
|
45
|
+
title: string;
|
|
46
|
+
rationale?: string;
|
|
47
|
+
criteria: CriterionId[];
|
|
48
|
+
priority: number;
|
|
49
|
+
estimatedEffort?: EffortBucket;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
interface Rollup {
|
|
53
|
+
foundationalFloor: Score;
|
|
54
|
+
retrievalLevel: Score;
|
|
55
|
+
overallMedian: number;
|
|
56
|
+
tier: 0 | 1 | 2 | 3 | 4;
|
|
57
|
+
categoryFloors: Partial<Record<`${Category}`, Score>>;
|
|
58
|
+
categoryMedians: Partial<Record<`${Category}`, number>>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface Report {
|
|
62
|
+
schemaVersion: "0.1.0";
|
|
63
|
+
rubricVersion: "0.1.0";
|
|
64
|
+
generatedAt: string;
|
|
65
|
+
target: { path: string; name?: string; repository?: string };
|
|
66
|
+
producer: { kind: ProducerKind; name?: string; version?: string };
|
|
67
|
+
criteria: Criterion[];
|
|
68
|
+
rollup: Rollup;
|
|
69
|
+
backlog: BacklogItem[];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
type CheckResult = {
|
|
73
|
+
score: Score | null;
|
|
74
|
+
status?: CriterionStatus;
|
|
75
|
+
pending?: PendingReason;
|
|
76
|
+
rationale?: string;
|
|
77
|
+
evidence?: Evidence[];
|
|
78
|
+
suggestion?: string;
|
|
79
|
+
};
|
|
80
|
+
type RubricEntry = {
|
|
81
|
+
id: CriterionId;
|
|
82
|
+
category: Category;
|
|
83
|
+
title: string;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
type RunnerOptions = {
|
|
87
|
+
target: string;
|
|
88
|
+
name?: string;
|
|
89
|
+
/** Path to an existing report.json to merge into. If provided, the runner only re-runs checks for criteria the existing report marked `status: "pending"`. */
|
|
90
|
+
merge?: string;
|
|
91
|
+
};
|
|
92
|
+
declare function runAssessment(opts: RunnerOptions): Promise<Report>;
|
|
93
|
+
|
|
94
|
+
declare function computeRollup(criteria: Criterion[]): Rollup;
|
|
95
|
+
declare const TIER_LABELS: Record<number, string>;
|
|
96
|
+
declare function generateBacklog(criteria: Criterion[]): BacklogItem[];
|
|
97
|
+
|
|
98
|
+
declare function renderMarkdown(report: Report): string;
|
|
99
|
+
|
|
100
|
+
declare const RUBRIC: RubricEntry[];
|
|
101
|
+
declare const TOTAL_CRITERIA: number;
|
|
102
|
+
|
|
103
|
+
export { type BacklogItem, type Category, type CheckResult, type Criterion, type CriterionId, type CriterionStatus, type EffortBucket, type Evidence, type EvidenceKind, type PendingReason, type ProducerKind, RUBRIC, type Report, type Rollup, type RubricEntry, type Score, TIER_LABELS, TOTAL_CRITERIA, computeRollup, generateBacklog, renderMarkdown, runAssessment };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
RUBRIC,
|
|
4
|
+
TIER_LABELS,
|
|
5
|
+
TOTAL_CRITERIA,
|
|
6
|
+
computeRollup,
|
|
7
|
+
generateBacklog,
|
|
8
|
+
renderMarkdown,
|
|
9
|
+
runAssessment
|
|
10
|
+
} from "./chunk-GWF7PSLR.js";
|
|
11
|
+
export {
|
|
12
|
+
RUBRIC,
|
|
13
|
+
TIER_LABELS,
|
|
14
|
+
TOTAL_CRITERIA,
|
|
15
|
+
computeRollup,
|
|
16
|
+
generateBacklog,
|
|
17
|
+
renderMarkdown,
|
|
18
|
+
runAssessment
|
|
19
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agentready-design-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Deterministic checks for the Agent-Ready Design rubric. Run against a design-system repo to score what can be scored without an LLM.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Hunter Gillispie <hunter@builder.io>",
|
|
7
|
+
"homepage": "https://github.com/hgillispie/Agent-Ready-Design",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/hgillispie/Agent-Ready-Design.git",
|
|
11
|
+
"directory": "packages/cli"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"design-system",
|
|
15
|
+
"ai",
|
|
16
|
+
"llm",
|
|
17
|
+
"agent",
|
|
18
|
+
"rubric",
|
|
19
|
+
"audit"
|
|
20
|
+
],
|
|
21
|
+
"type": "module",
|
|
22
|
+
"bin": {
|
|
23
|
+
"agentready-design-cli": "dist/cli.js",
|
|
24
|
+
"agent-ready": "dist/cli.js"
|
|
25
|
+
},
|
|
26
|
+
"main": "./dist/index.js",
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"CRITERIA.md",
|
|
37
|
+
"README.md"
|
|
38
|
+
],
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsup",
|
|
41
|
+
"dev": "tsup --watch",
|
|
42
|
+
"test": "vitest run",
|
|
43
|
+
"test:watch": "vitest",
|
|
44
|
+
"typecheck": "tsc --noEmit",
|
|
45
|
+
"start": "node dist/cli.js",
|
|
46
|
+
"prepublishOnly": "pnpm typecheck && pnpm test && pnpm build"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"fast-glob": "^3.3.2",
|
|
53
|
+
"kleur": "^4.1.5"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/node": "^22.10.1",
|
|
57
|
+
"tsup": "^8.3.5",
|
|
58
|
+
"typescript": "^5.6.3",
|
|
59
|
+
"vitest": "^2.1.8"
|
|
60
|
+
}
|
|
61
|
+
}
|