pi-evalset-lab 0.1.0 → 0.2.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/CHANGELOG.md +11 -0
- package/README.md +59 -1
- package/examples/evalset-compare-sample-embedded.html +142 -0
- package/examples/evalset-compare-sample.png +0 -0
- package/package.json +38 -6
- package/scripts/export-evalset-report-html.mjs +356 -0
- package/.copier-answers.yml +0 -5
- package/.githooks/pre-commit +0 -12
- package/.github/CODEOWNERS +0 -12
- package/.github/ISSUE_TEMPLATE/bug-report.yml +0 -63
- package/.github/ISSUE_TEMPLATE/config.yml +0 -5
- package/.github/ISSUE_TEMPLATE/docs.yml +0 -39
- package/.github/ISSUE_TEMPLATE/feature-request.yml +0 -41
- package/.github/VOUCHED.td +0 -8
- package/.github/dependabot.yml +0 -13
- package/.github/pull_request_template.md +0 -34
- package/.github/workflows/ci.yml +0 -37
- package/.github/workflows/publish.yml +0 -60
- package/.github/workflows/release-please.yml +0 -25
- package/.github/workflows/vouch-check-pr.yml +0 -29
- package/.github/workflows/vouch-manage.yml +0 -34
- package/.pi/extensions/startup-intake-router.ts +0 -151
- package/.pi/prompts/init-project-docs.md +0 -32
- package/.release-please-config.json +0 -11
- package/.release-please-manifest.json +0 -3
- package/AGENTS.md +0 -39
- package/CODE_OF_CONDUCT.md +0 -50
- package/CONTRIBUTING.md +0 -28
- package/NEXT_SESSION_PROMPT.md +0 -14
- package/SECURITY.md +0 -34
- package/SUPPORT.md +0 -37
- package/docs/dev/CONTRIBUTING.md +0 -37
- package/docs/dev/EXTENSION_SOP.md +0 -43
- package/docs/dev/next_steps.md +0 -17
- package/docs/dev/plans/001-initial-plan.md +0 -24
- package/docs/dev/status.md +0 -21
- package/docs/org/operating_model.md +0 -39
- package/docs/org/project-docs-intake.questions.json +0 -60
- package/docs/project/foundation.md +0 -28
- package/docs/project/incentives.md +0 -17
- package/docs/project/resources.md +0 -26
- package/docs/project/skills.md +0 -17
- package/docs/project/strategic_goals.md +0 -18
- package/docs/project/tactical_goals.md +0 -39
- package/docs/project/vision.md +0 -21
- package/external/.gitkeep +0 -0
- package/ontology/.gitkeep +0 -0
- package/policy/security-policy.json +0 -10
- package/prek.toml +0 -15
- package/scripts/docs-list.sh +0 -50
- package/scripts/init-project-docs.sh +0 -56
- package/scripts/install-hooks.sh +0 -13
- package/scripts/sync-to-live.sh +0 -91
- package/scripts/validate-structure.sh +0 -325
- package/src/.gitkeep +0 -0
- package/tests/.gitkeep +0 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
4
|
+
import { dirname, resolve } from "node:path";
|
|
5
|
+
|
|
6
|
+
const HELP_TEXT = `Export evalset JSON report to a standalone HTML file.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
node ./scripts/export-evalset-report-html.mjs --in <report.json> [--out <report.html>] [--title <text>]
|
|
10
|
+
|
|
11
|
+
Options:
|
|
12
|
+
--in, -i Input report path (.json) [required]
|
|
13
|
+
--out, -o Output HTML path (default: input path with .html extension)
|
|
14
|
+
--title Custom report title
|
|
15
|
+
--help, -h Show this help
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
function parseArgs(argv) {
|
|
19
|
+
/** @type {{input?: string; output?: string; title?: string; help?: boolean}} */
|
|
20
|
+
const result = {};
|
|
21
|
+
|
|
22
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
23
|
+
const token = argv[i];
|
|
24
|
+
|
|
25
|
+
switch (token) {
|
|
26
|
+
case "--help":
|
|
27
|
+
case "-h":
|
|
28
|
+
result.help = true;
|
|
29
|
+
break;
|
|
30
|
+
case "--in":
|
|
31
|
+
case "--input":
|
|
32
|
+
case "-i":
|
|
33
|
+
result.input = argv[i + 1];
|
|
34
|
+
i += 1;
|
|
35
|
+
break;
|
|
36
|
+
case "--out":
|
|
37
|
+
case "--output":
|
|
38
|
+
case "-o":
|
|
39
|
+
result.output = argv[i + 1];
|
|
40
|
+
i += 1;
|
|
41
|
+
break;
|
|
42
|
+
case "--title":
|
|
43
|
+
result.title = argv[i + 1];
|
|
44
|
+
i += 1;
|
|
45
|
+
break;
|
|
46
|
+
default:
|
|
47
|
+
throw new Error(`Unknown option: ${token}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function requireValue(value, flag) {
|
|
55
|
+
if (!value || value.startsWith("-")) {
|
|
56
|
+
throw new Error(`Missing value for ${flag}`);
|
|
57
|
+
}
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function isRecord(value) {
|
|
62
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function toArray(value) {
|
|
66
|
+
return Array.isArray(value) ? value : [];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function esc(value) {
|
|
70
|
+
return String(value ?? "")
|
|
71
|
+
.replace(/&/g, "&")
|
|
72
|
+
.replace(/</g, "<")
|
|
73
|
+
.replace(/>/g, ">")
|
|
74
|
+
.replace(/\"/g, """)
|
|
75
|
+
.replace(/'/g, "'");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function pct(value) {
|
|
79
|
+
return typeof value === "number" ? `${(value * 100).toFixed(1)}%` : "n/a";
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function money(value) {
|
|
83
|
+
return `$${Number(value ?? 0).toFixed(6)}`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function ms(value) {
|
|
87
|
+
return `${Number(value ?? 0).toFixed(0)} ms`;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function passPill(pass) {
|
|
91
|
+
return pass ? '<span class="pill ok">PASS</span>' : '<span class="pill bad">FAIL</span>';
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function outcomePill(outcome) {
|
|
95
|
+
if (outcome === "improved") {
|
|
96
|
+
return '<span class="pill imp">Improved</span>';
|
|
97
|
+
}
|
|
98
|
+
if (outcome === "regressed") {
|
|
99
|
+
return '<span class="pill reg">Regressed</span>';
|
|
100
|
+
}
|
|
101
|
+
return '<span class="pill same">No change</span>';
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function checksText(entry) {
|
|
105
|
+
const lines = toArray(entry?.checks).map((check) => {
|
|
106
|
+
const marker = check?.pass ? "✅" : "❌";
|
|
107
|
+
return `${marker} ${check?.details ?? ""}`;
|
|
108
|
+
});
|
|
109
|
+
return lines.length > 0 ? lines.join("\n") : "None";
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function pageTemplate({ title, subtitle, summaryCards, tableHeader, tableRows }) {
|
|
113
|
+
return `<!doctype html>
|
|
114
|
+
<html lang="en">
|
|
115
|
+
<head>
|
|
116
|
+
<meta charset="utf-8" />
|
|
117
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
118
|
+
<title>${esc(title)}</title>
|
|
119
|
+
<style>
|
|
120
|
+
:root {
|
|
121
|
+
--bg: #0b1020;
|
|
122
|
+
--panel: #111a33;
|
|
123
|
+
--line: #24335f;
|
|
124
|
+
--txt: #e8eeff;
|
|
125
|
+
--muted: #9fb0d8;
|
|
126
|
+
--ok: #2ecc71;
|
|
127
|
+
--bad: #ff6b6b;
|
|
128
|
+
--same: #7f8ea3;
|
|
129
|
+
--imp: #49dcb1;
|
|
130
|
+
--reg: #ff8f70;
|
|
131
|
+
}
|
|
132
|
+
* { box-sizing: border-box; }
|
|
133
|
+
body { margin: 0; padding: 24px; font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Ubuntu; background: var(--bg); color: var(--txt); }
|
|
134
|
+
.wrap { max-width: 1240px; margin: 0 auto; }
|
|
135
|
+
.panel { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 14px; margin-bottom: 14px; }
|
|
136
|
+
.muted { color: var(--muted); font-size: 0.92rem; }
|
|
137
|
+
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px; }
|
|
138
|
+
.card { background: #0e1630; border: 1px solid #2a3a66; border-radius: 10px; padding: 10px; }
|
|
139
|
+
.label { color: var(--muted); text-transform: uppercase; letter-spacing: .04em; font-size: .75rem; }
|
|
140
|
+
.val { margin-top: 4px; font-size: 1.06rem; font-weight: 600; }
|
|
141
|
+
table { width: 100%; border-collapse: collapse; font-size: .91rem; }
|
|
142
|
+
th, td { text-align: left; padding: 10px 8px; border-bottom: 1px solid var(--line); vertical-align: top; }
|
|
143
|
+
th { color: var(--muted); }
|
|
144
|
+
.pill { display: inline-block; border-radius: 999px; padding: 2px 10px; font-size: .74rem; font-weight: 700; border: 1px solid transparent; }
|
|
145
|
+
.ok { background: rgba(46, 204, 113, .14); color: #9df7c5; border-color: rgba(46, 204, 113, .45); }
|
|
146
|
+
.bad { background: rgba(255, 107, 107, .14); color: #ffc2c2; border-color: rgba(255, 107, 107, .45); }
|
|
147
|
+
.same { background: rgba(127, 142, 163, .14); color: #d4dcf2; border-color: rgba(127, 142, 163, .45); }
|
|
148
|
+
.imp { background: rgba(73, 220, 177, .14); color: #abf6df; border-color: rgba(73, 220, 177, .45); }
|
|
149
|
+
.reg { background: rgba(255, 143, 112, .14); color: #ffd0c2; border-color: rgba(255, 143, 112, .45); }
|
|
150
|
+
.meta { color: var(--muted); font-size: .8rem; margin-top: 6px; }
|
|
151
|
+
pre { white-space: pre-wrap; background: #0d152b; border: 1px solid #2a3a66; border-radius: 8px; padding: 8px; max-height: 220px; overflow: auto; }
|
|
152
|
+
details summary { cursor: pointer; color: #9dc2ff; }
|
|
153
|
+
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
|
|
154
|
+
@media (max-width: 980px) { .split { grid-template-columns: 1fr; } }
|
|
155
|
+
</style>
|
|
156
|
+
</head>
|
|
157
|
+
<body>
|
|
158
|
+
<div class="wrap">
|
|
159
|
+
<div class="panel">
|
|
160
|
+
<h1 style="margin:0 0 8px; font-size:1.32rem;">${esc(title)}</h1>
|
|
161
|
+
<div class="muted">${esc(subtitle)}</div>
|
|
162
|
+
</div>
|
|
163
|
+
|
|
164
|
+
<div class="panel grid">
|
|
165
|
+
${summaryCards}
|
|
166
|
+
</div>
|
|
167
|
+
|
|
168
|
+
<div class="panel">
|
|
169
|
+
<table>
|
|
170
|
+
<thead>${tableHeader}</thead>
|
|
171
|
+
<tbody>${tableRows}</tbody>
|
|
172
|
+
</table>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
</body>
|
|
176
|
+
</html>`;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function summaryCard(label, value) {
|
|
180
|
+
return `<div class="card"><div class="label">${esc(label)}</div><div class="val">${esc(value)}</div></div>`;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function renderRun(report, options) {
|
|
184
|
+
const cases = toArray(report?.cases);
|
|
185
|
+
|
|
186
|
+
const summaryCards = [
|
|
187
|
+
summaryCard("Pass rate", `${pct(report?.totals?.passRate)} (${report?.totals?.passedCases ?? 0}/${report?.totals?.scoredCases ?? 0})`),
|
|
188
|
+
summaryCard("Avg latency", ms(report?.totals?.avgLatencyMs)),
|
|
189
|
+
summaryCard("Total cost", money(report?.totals?.usage?.cost?.total)),
|
|
190
|
+
summaryCard("Dataset", report?.dataset?.name ?? "n/a"),
|
|
191
|
+
summaryCard("Variant", report?.variant?.name ?? "n/a"),
|
|
192
|
+
summaryCard("Run ID", report?.run?.runId ?? "n/a"),
|
|
193
|
+
].join("\n");
|
|
194
|
+
|
|
195
|
+
const rows = cases
|
|
196
|
+
.map((entry, index) => {
|
|
197
|
+
const checks = checksText(entry);
|
|
198
|
+
return `<tr>
|
|
199
|
+
<td>${index + 1}</td>
|
|
200
|
+
<td><code>${esc(entry?.id ?? `case-${index + 1}`)}</code></td>
|
|
201
|
+
<td>${passPill(Boolean(entry?.pass))}<div class="meta">${ms(entry?.latencyMs)}</div></td>
|
|
202
|
+
<td><details><summary>checks + output</summary>
|
|
203
|
+
<h4 style="margin:8px 0 6px;">Checks</h4><pre>${esc(checks)}</pre>
|
|
204
|
+
<h4 style="margin:8px 0 6px;">Output preview</h4><pre>${esc(entry?.outputPreview ?? "")}</pre>
|
|
205
|
+
</details></td>
|
|
206
|
+
</tr>`;
|
|
207
|
+
})
|
|
208
|
+
.join("\n");
|
|
209
|
+
|
|
210
|
+
const title = options.title || `Evalset run report: ${report?.dataset?.name ?? "dataset"}`;
|
|
211
|
+
const subtitle = [
|
|
212
|
+
report?.dataset?.path,
|
|
213
|
+
`model ${report?.model?.provider ?? "unknown"}/${report?.model?.id ?? "unknown"}`,
|
|
214
|
+
`run ${report?.run?.runId ?? "n/a"}`,
|
|
215
|
+
]
|
|
216
|
+
.filter(Boolean)
|
|
217
|
+
.join(" · ");
|
|
218
|
+
|
|
219
|
+
return pageTemplate({
|
|
220
|
+
title,
|
|
221
|
+
subtitle,
|
|
222
|
+
summaryCards,
|
|
223
|
+
tableHeader: `<tr><th>#</th><th>Case</th><th>Result</th><th>Details</th></tr>`,
|
|
224
|
+
tableRows: rows,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function renderCompare(report, options) {
|
|
229
|
+
const baselineCases = toArray(report?.baseline?.cases);
|
|
230
|
+
const candidateById = new Map(toArray(report?.candidate?.cases).map((entry) => [String(entry?.id ?? ""), entry]));
|
|
231
|
+
|
|
232
|
+
const summaryCards = [
|
|
233
|
+
summaryCard(
|
|
234
|
+
"Baseline pass",
|
|
235
|
+
`${pct(report?.baseline?.totals?.passRate)} (${report?.baseline?.totals?.passedCases ?? 0}/${report?.baseline?.totals?.scoredCases ?? 0})`,
|
|
236
|
+
),
|
|
237
|
+
summaryCard(
|
|
238
|
+
"Candidate pass",
|
|
239
|
+
`${pct(report?.candidate?.totals?.passRate)} (${report?.candidate?.totals?.passedCases ?? 0}/${report?.candidate?.totals?.scoredCases ?? 0})`,
|
|
240
|
+
),
|
|
241
|
+
summaryCard("Δ pass rate", pct(report?.delta?.passRate)),
|
|
242
|
+
summaryCard("Δ avg latency", ms(report?.delta?.avgLatencyMs)),
|
|
243
|
+
summaryCard("Δ total cost", money(report?.delta?.totalCost)),
|
|
244
|
+
summaryCard("Dataset hash", (report?.run?.datasetHash ?? "n/a").slice(0, 12)),
|
|
245
|
+
].join("\n");
|
|
246
|
+
|
|
247
|
+
const rows = baselineCases
|
|
248
|
+
.map((baselineEntry, index) => {
|
|
249
|
+
const candidateEntry = candidateById.get(String(baselineEntry?.id ?? "")) ?? {};
|
|
250
|
+
|
|
251
|
+
let outcome = "same";
|
|
252
|
+
if (!baselineEntry?.pass && candidateEntry?.pass) {
|
|
253
|
+
outcome = "improved";
|
|
254
|
+
} else if (baselineEntry?.pass && !candidateEntry?.pass) {
|
|
255
|
+
outcome = "regressed";
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return `<tr>
|
|
259
|
+
<td>${index + 1}</td>
|
|
260
|
+
<td><code>${esc(baselineEntry?.id ?? `case-${index + 1}`)}</code></td>
|
|
261
|
+
<td>${passPill(Boolean(baselineEntry?.pass))}<div class="meta">${ms(baselineEntry?.latencyMs)}</div></td>
|
|
262
|
+
<td>${passPill(Boolean(candidateEntry?.pass))}<div class="meta">${ms(candidateEntry?.latencyMs)}</div></td>
|
|
263
|
+
<td>${outcomePill(outcome)}</td>
|
|
264
|
+
<td><details><summary>checks + output</summary>
|
|
265
|
+
<div class="split">
|
|
266
|
+
<div>
|
|
267
|
+
<h4 style="margin:8px 0 6px;">Baseline checks</h4><pre>${esc(checksText(baselineEntry))}</pre>
|
|
268
|
+
<h4 style="margin:8px 0 6px;">Baseline output</h4><pre>${esc(baselineEntry?.outputPreview ?? "")}</pre>
|
|
269
|
+
</div>
|
|
270
|
+
<div>
|
|
271
|
+
<h4 style="margin:8px 0 6px;">Candidate checks</h4><pre>${esc(checksText(candidateEntry))}</pre>
|
|
272
|
+
<h4 style="margin:8px 0 6px;">Candidate output</h4><pre>${esc(candidateEntry?.outputPreview ?? "")}</pre>
|
|
273
|
+
</div>
|
|
274
|
+
</div>
|
|
275
|
+
</details></td>
|
|
276
|
+
</tr>`;
|
|
277
|
+
})
|
|
278
|
+
.join("\n");
|
|
279
|
+
|
|
280
|
+
const title = options.title || `Evalset compare report: ${report?.dataset?.name ?? "dataset"}`;
|
|
281
|
+
const subtitle = [
|
|
282
|
+
report?.dataset?.path,
|
|
283
|
+
`model ${report?.model?.provider ?? "unknown"}/${report?.model?.id ?? "unknown"}`,
|
|
284
|
+
`run ${report?.run?.runId ?? "n/a"}`,
|
|
285
|
+
]
|
|
286
|
+
.filter(Boolean)
|
|
287
|
+
.join(" · ");
|
|
288
|
+
|
|
289
|
+
return pageTemplate({
|
|
290
|
+
title,
|
|
291
|
+
subtitle,
|
|
292
|
+
summaryCards,
|
|
293
|
+
tableHeader: `<tr><th>#</th><th>Case</th><th>Baseline</th><th>Candidate</th><th>Outcome</th><th>Details</th></tr>`,
|
|
294
|
+
tableRows: rows,
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function renderUnknown(report, options) {
|
|
299
|
+
const title = options.title || "Evalset report (raw JSON)";
|
|
300
|
+
const subtitle = `Unsupported report kind: ${report?.kind ?? "unknown"}`;
|
|
301
|
+
const summaryCards = summaryCard("Kind", report?.kind ?? "unknown");
|
|
302
|
+
const tableRows = `<tr><td><pre>${esc(JSON.stringify(report, null, 2))}</pre></td></tr>`;
|
|
303
|
+
return pageTemplate({
|
|
304
|
+
title,
|
|
305
|
+
subtitle,
|
|
306
|
+
summaryCards,
|
|
307
|
+
tableHeader: `<tr><th>Report JSON</th></tr>`,
|
|
308
|
+
tableRows,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function defaultOutputPath(inputPath) {
|
|
313
|
+
if (inputPath.toLowerCase().endsWith(".json")) {
|
|
314
|
+
return inputPath.replace(/\.json$/i, ".html");
|
|
315
|
+
}
|
|
316
|
+
return `${inputPath}.html`;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
async function main() {
|
|
320
|
+
const cli = parseArgs(process.argv.slice(2));
|
|
321
|
+
|
|
322
|
+
if (cli.help) {
|
|
323
|
+
console.log(HELP_TEXT.trimEnd());
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const input = resolve(process.cwd(), requireValue(cli.input, "--in"));
|
|
328
|
+
const output = resolve(process.cwd(), cli.output ? requireValue(cli.output, "--out") : defaultOutputPath(input));
|
|
329
|
+
|
|
330
|
+
const raw = await readFile(input, "utf8");
|
|
331
|
+
const parsed = JSON.parse(raw);
|
|
332
|
+
|
|
333
|
+
if (!isRecord(parsed)) {
|
|
334
|
+
throw new Error("Report JSON must be an object.");
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
let html;
|
|
338
|
+
if (parsed.kind === "evalset-run") {
|
|
339
|
+
html = renderRun(parsed, { title: cli.title });
|
|
340
|
+
} else if (parsed.kind === "evalset-compare") {
|
|
341
|
+
html = renderCompare(parsed, { title: cli.title });
|
|
342
|
+
} else {
|
|
343
|
+
html = renderUnknown(parsed, { title: cli.title });
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
await mkdir(dirname(output), { recursive: true });
|
|
347
|
+
await writeFile(output, `${html}\n`, "utf8");
|
|
348
|
+
|
|
349
|
+
console.log(`Exported HTML report: ${output}`);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
main().catch((error) => {
|
|
353
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
354
|
+
console.error(`export-evalset-report-html error: ${message}`);
|
|
355
|
+
process.exit(1);
|
|
356
|
+
});
|
package/.copier-answers.yml
DELETED
package/.githooks/pre-commit
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
set -euo pipefail
|
|
3
|
-
|
|
4
|
-
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
5
|
-
|
|
6
|
-
if command -v prek >/dev/null 2>&1; then
|
|
7
|
-
(cd "$ROOT_DIR" && prek run --hook-stage pre-commit)
|
|
8
|
-
elif [[ -x "$ROOT_DIR/node_modules/.bin/prek" ]]; then
|
|
9
|
-
(cd "$ROOT_DIR" && "$ROOT_DIR/node_modules/.bin/prek" run --hook-stage pre-commit)
|
|
10
|
-
else
|
|
11
|
-
"$ROOT_DIR/scripts/validate-structure.sh"
|
|
12
|
-
fi
|
package/.github/CODEOWNERS
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
# Default owner for generated repositories. Update if you use a different maintainer/team.
|
|
2
|
-
|
|
3
|
-
* @tryingET
|
|
4
|
-
|
|
5
|
-
/.github/workflows/* @tryingET
|
|
6
|
-
/.github/ISSUE_TEMPLATE/* @tryingET
|
|
7
|
-
/.github/VOUCHED.td @tryingET
|
|
8
|
-
/extensions/* @tryingET
|
|
9
|
-
/package.json @tryingET
|
|
10
|
-
/SECURITY.md @tryingET
|
|
11
|
-
/.release-please-config.json @tryingET
|
|
12
|
-
/.release-please-manifest.json @tryingET
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
name: Bug report
|
|
2
|
-
description: Report a reproducible defect.
|
|
3
|
-
labels: ["bug", "needs-triage"]
|
|
4
|
-
body:
|
|
5
|
-
- type: markdown
|
|
6
|
-
attributes:
|
|
7
|
-
value: |
|
|
8
|
-
Thanks for reporting a bug.
|
|
9
|
-
Please provide a minimal reproduction and include exact versions.
|
|
10
|
-
|
|
11
|
-
- type: checkboxes
|
|
12
|
-
id: preflight
|
|
13
|
-
attributes:
|
|
14
|
-
label: Preflight
|
|
15
|
-
options:
|
|
16
|
-
- label: I searched existing issues and did not find a duplicate.
|
|
17
|
-
required: true
|
|
18
|
-
- label: I can reproduce this on the latest release.
|
|
19
|
-
required: true
|
|
20
|
-
|
|
21
|
-
- type: textarea
|
|
22
|
-
id: expected
|
|
23
|
-
attributes:
|
|
24
|
-
label: Expected behavior
|
|
25
|
-
description: What should happen?
|
|
26
|
-
validations:
|
|
27
|
-
required: true
|
|
28
|
-
|
|
29
|
-
- type: textarea
|
|
30
|
-
id: actual
|
|
31
|
-
attributes:
|
|
32
|
-
label: Actual behavior
|
|
33
|
-
description: What happened instead?
|
|
34
|
-
validations:
|
|
35
|
-
required: true
|
|
36
|
-
|
|
37
|
-
- type: textarea
|
|
38
|
-
id: reproduce
|
|
39
|
-
attributes:
|
|
40
|
-
label: Steps to reproduce
|
|
41
|
-
description: Include exact commands, inputs, and files.
|
|
42
|
-
placeholder: |
|
|
43
|
-
1. Run ...
|
|
44
|
-
2. Execute ...
|
|
45
|
-
3. Observe ...
|
|
46
|
-
validations:
|
|
47
|
-
required: true
|
|
48
|
-
|
|
49
|
-
- type: textarea
|
|
50
|
-
id: logs
|
|
51
|
-
attributes:
|
|
52
|
-
label: Logs and screenshots
|
|
53
|
-
description: Paste relevant logs/errors. Remove secrets before posting.
|
|
54
|
-
render: shell
|
|
55
|
-
|
|
56
|
-
- type: input
|
|
57
|
-
id: environment
|
|
58
|
-
attributes:
|
|
59
|
-
label: Environment
|
|
60
|
-
description: OS, runtime version, package version.
|
|
61
|
-
placeholder: "ubuntu-24.04, node 20.x, package 0.1.0"
|
|
62
|
-
validations:
|
|
63
|
-
required: true
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
blank_issues_enabled: false
|
|
2
|
-
contact_links:
|
|
3
|
-
- name: Security vulnerability reporting
|
|
4
|
-
url: https://docs.github.com/en/code-security/security-advisories/repository-security-advisories/about-coordinated-disclosure-of-security-vulnerabilities
|
|
5
|
-
about: Follow SECURITY.md and use private vulnerability reporting. Do not post exploit details publicly.
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
name: Documentation improvement
|
|
2
|
-
description: Request a docs clarification, correction, or new guide.
|
|
3
|
-
labels: ["docs", "needs-triage"]
|
|
4
|
-
body:
|
|
5
|
-
- type: checkboxes
|
|
6
|
-
id: preflight
|
|
7
|
-
attributes:
|
|
8
|
-
label: Preflight
|
|
9
|
-
options:
|
|
10
|
-
- label: I searched existing issues and did not find a duplicate docs request.
|
|
11
|
-
required: true
|
|
12
|
-
|
|
13
|
-
- type: textarea
|
|
14
|
-
id: location
|
|
15
|
-
attributes:
|
|
16
|
-
label: Affected documentation
|
|
17
|
-
description: Link file/path/section that needs improvement.
|
|
18
|
-
validations:
|
|
19
|
-
required: true
|
|
20
|
-
|
|
21
|
-
- type: textarea
|
|
22
|
-
id: change
|
|
23
|
-
attributes:
|
|
24
|
-
label: Requested change
|
|
25
|
-
description: What should be clarified, corrected, or added?
|
|
26
|
-
validations:
|
|
27
|
-
required: true
|
|
28
|
-
|
|
29
|
-
- type: textarea
|
|
30
|
-
id: reason
|
|
31
|
-
attributes:
|
|
32
|
-
label: Why this matters
|
|
33
|
-
description: What confusion or failure does this currently cause?
|
|
34
|
-
|
|
35
|
-
- type: textarea
|
|
36
|
-
id: references
|
|
37
|
-
attributes:
|
|
38
|
-
label: Supporting references
|
|
39
|
-
description: Optional examples, screenshots, or related links.
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
name: Feature request
|
|
2
|
-
description: Suggest a new capability or improvement.
|
|
3
|
-
labels: ["enhancement", "needs-triage"]
|
|
4
|
-
body:
|
|
5
|
-
- type: checkboxes
|
|
6
|
-
id: preflight
|
|
7
|
-
attributes:
|
|
8
|
-
label: Preflight
|
|
9
|
-
options:
|
|
10
|
-
- label: I searched existing issues and did not find a duplicate request.
|
|
11
|
-
required: true
|
|
12
|
-
- label: This request describes one focused capability.
|
|
13
|
-
required: true
|
|
14
|
-
|
|
15
|
-
- type: textarea
|
|
16
|
-
id: problem
|
|
17
|
-
attributes:
|
|
18
|
-
label: Problem statement
|
|
19
|
-
description: What user or maintainer problem should be solved?
|
|
20
|
-
validations:
|
|
21
|
-
required: true
|
|
22
|
-
|
|
23
|
-
- type: textarea
|
|
24
|
-
id: proposal
|
|
25
|
-
attributes:
|
|
26
|
-
label: Proposed solution
|
|
27
|
-
description: Describe the desired behavior and expected outcome.
|
|
28
|
-
validations:
|
|
29
|
-
required: true
|
|
30
|
-
|
|
31
|
-
- type: textarea
|
|
32
|
-
id: alternatives
|
|
33
|
-
attributes:
|
|
34
|
-
label: Alternatives considered
|
|
35
|
-
description: What other options did you evaluate?
|
|
36
|
-
|
|
37
|
-
- type: textarea
|
|
38
|
-
id: additional
|
|
39
|
-
attributes:
|
|
40
|
-
label: Additional context
|
|
41
|
-
description: Links, examples, screenshots, or constraints.
|
package/.github/VOUCHED.td
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
# Vouched (trusted) contributors list for this repository.
|
|
2
|
-
#
|
|
3
|
-
# Keep one handle per line, sorted alphabetically.
|
|
4
|
-
# Prefix with '-' to denounce a user and block contribution.
|
|
5
|
-
#
|
|
6
|
-
# Default maintainer bootstrap (adjust to your owner/team policy).
|
|
7
|
-
github:tryingET Initial repository owner
|
|
8
|
-
# github:co-maintainer Optional second maintainer
|
package/.github/dependabot.yml
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
summary: "PR template for scoped changes with explicit validation."
|
|
3
|
-
read_when:
|
|
4
|
-
- "Opening a pull request for review."
|
|
5
|
-
system4d:
|
|
6
|
-
container: "Reviewer-ready pull request intake format."
|
|
7
|
-
compass: "Clarity, verification, and rollback awareness."
|
|
8
|
-
engine: "Summarize -> validate -> assess risk -> request review."
|
|
9
|
-
fog: "Integration side effects may appear after merge."
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## Summary
|
|
13
|
-
|
|
14
|
-
- What changed?
|
|
15
|
-
- Why now?
|
|
16
|
-
|
|
17
|
-
## Validation
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
npm run check
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
Paste relevant output (and any additional checks) below.
|
|
24
|
-
|
|
25
|
-
## Risk and rollback
|
|
26
|
-
|
|
27
|
-
- Risk level: low / medium / high
|
|
28
|
-
- Rollback plan if this regresses production behavior:
|
|
29
|
-
|
|
30
|
-
## Checklist
|
|
31
|
-
|
|
32
|
-
- [ ] Scope is focused and reviewable.
|
|
33
|
-
- [ ] Docs/changelog updated when behavior changed.
|
|
34
|
-
- [ ] No secrets or credentials added.
|
package/.github/workflows/ci.yml
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
name: ci
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
pull_request:
|
|
5
|
-
push:
|
|
6
|
-
branches:
|
|
7
|
-
- main
|
|
8
|
-
|
|
9
|
-
permissions:
|
|
10
|
-
contents: read
|
|
11
|
-
|
|
12
|
-
jobs:
|
|
13
|
-
check:
|
|
14
|
-
runs-on: ubuntu-latest
|
|
15
|
-
steps:
|
|
16
|
-
- name: Checkout
|
|
17
|
-
uses: actions/checkout@v6
|
|
18
|
-
|
|
19
|
-
- name: Setup Node.js
|
|
20
|
-
uses: actions/setup-node@v6
|
|
21
|
-
with:
|
|
22
|
-
node-version: "20"
|
|
23
|
-
|
|
24
|
-
- name: Install dependencies
|
|
25
|
-
run: |
|
|
26
|
-
if [[ -f package-lock.json ]]; then
|
|
27
|
-
npm ci
|
|
28
|
-
else
|
|
29
|
-
npm install --package-lock-only --ignore-scripts
|
|
30
|
-
npm ci
|
|
31
|
-
fi
|
|
32
|
-
|
|
33
|
-
- name: Validate structure
|
|
34
|
-
run: npm run check
|
|
35
|
-
|
|
36
|
-
- name: npm pack dry run
|
|
37
|
-
run: npm pack --dry-run
|