getadvantage 0.1.0 → 0.3.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/README.md +7 -0
- package/brief.mjs +634 -634
- package/checks-runner.mjs +136 -136
- package/checks.mjs +327 -327
- package/deploy.mjs +203 -203
- package/gauge.mjs +95 -0
- package/handoff.mjs +10 -3
- package/index.mjs +223 -181
- package/init.mjs +81 -0
- package/ledger.mjs +110 -0
- package/models.mjs +40 -0
- package/overviews.mjs +536 -536
- package/package.json +1 -1
- package/switch.mjs +60 -0
- package/util.mjs +142 -142
package/checks-runner.mjs
CHANGED
|
@@ -1,136 +1,136 @@
|
|
|
1
|
-
// Ship-Safe — runs the full check suite and renders the per-check + overall
|
|
2
|
-
// verdict. Shared by both `ship-safe check` and `ship-safe deploy` so the gate
|
|
3
|
-
// is identical in both paths.
|
|
4
|
-
|
|
5
|
-
import { c, GLYPH, printResult, section } from "./util.mjs";
|
|
6
|
-
import {
|
|
7
|
-
checkDirtyTree,
|
|
8
|
-
checkSecrets,
|
|
9
|
-
checkTypecheck,
|
|
10
|
-
checkBuild,
|
|
11
|
-
checkSchemaBump,
|
|
12
|
-
} from "./checks.mjs";
|
|
13
|
-
import {
|
|
14
|
-
overviewApiSurface,
|
|
15
|
-
overviewIntegrations,
|
|
16
|
-
overviewSchedules,
|
|
17
|
-
} from "./overviews.mjs";
|
|
18
|
-
import { briefStaleness } from "./brief.mjs";
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Run every check and print a clean summary.
|
|
22
|
-
* @param {object} o
|
|
23
|
-
* @param {string} o.cwd repo root
|
|
24
|
-
* @param {boolean} o.runBuild also run a full `npm run build` (slower)
|
|
25
|
-
* @param {string} [o.baseRef] merge-base ref for the schema diff (default main)
|
|
26
|
-
* @param {boolean} [o.overview] run the v1.1 read-only overview scanners
|
|
27
|
-
* (API surface · integrations · schedules).
|
|
28
|
-
* Defaults to ON — they're fast, read-only maps.
|
|
29
|
-
* @param {boolean} [o.briefCheck] emit a NON-BLOCKING staleness warning if the
|
|
30
|
-
* PROJECT BRAIN (PROJECT-BRIEF.md) is missing or
|
|
31
|
-
* out of date. Defaults to ON. Never a fail.
|
|
32
|
-
* @returns {Promise<{ exitCode: number, results: any[] }>} exitCode 0=GO, 1=NO-GO
|
|
33
|
-
*/
|
|
34
|
-
export async function runChecks(o) {
|
|
35
|
-
const cwd = o.cwd;
|
|
36
|
-
const results = [];
|
|
37
|
-
|
|
38
|
-
section("Checks");
|
|
39
|
-
|
|
40
|
-
// a. Dirty-tree guard
|
|
41
|
-
results.push(safe(() => checkDirtyTree(cwd), "Dirty-tree guard"));
|
|
42
|
-
printResult(results[results.length - 1]);
|
|
43
|
-
|
|
44
|
-
// b. Secret scan
|
|
45
|
-
results.push(safe(() => checkSecrets(cwd), "Secret scan"));
|
|
46
|
-
printResult(results[results.length - 1]);
|
|
47
|
-
|
|
48
|
-
// c. Typecheck (always) + optional full build
|
|
49
|
-
results.push(safe(() => checkTypecheck(cwd), "Typecheck (tsc --noEmit)"));
|
|
50
|
-
printResult(results[results.length - 1]);
|
|
51
|
-
if (o.runBuild) {
|
|
52
|
-
results.push(safe(() => checkBuild(cwd), "Production build (npm run build)"));
|
|
53
|
-
printResult(results[results.length - 1]);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// d. Schema-bump check
|
|
57
|
-
results.push(safe(() => checkSchemaBump(cwd, o.baseRef || "main"), "Schema-bump check"));
|
|
58
|
-
printResult(results[results.length - 1]);
|
|
59
|
-
|
|
60
|
-
// ---- v1.1 OVERVIEW SCANNERS (read-only maps) ----------------------------
|
|
61
|
-
// Default-on: three fast, read-only repo scans that give the builder a map of
|
|
62
|
-
// what their app actually has. They emit pass/warn only (never a blocking
|
|
63
|
-
// fail) — a surprising map is informational, the v1 safety checks own NO-GO.
|
|
64
|
-
// Disable with `--no-overview`.
|
|
65
|
-
const runOverview = o.overview !== false;
|
|
66
|
-
if (runOverview) {
|
|
67
|
-
section("Overview — what your app has (read-only)");
|
|
68
|
-
|
|
69
|
-
results.push(safe(() => overviewApiSurface(cwd), "API surface map"));
|
|
70
|
-
printResult(results[results.length - 1]);
|
|
71
|
-
|
|
72
|
-
results.push(safe(() => overviewIntegrations(cwd), "Agents & integrations map"));
|
|
73
|
-
printResult(results[results.length - 1]);
|
|
74
|
-
|
|
75
|
-
results.push(safe(() => overviewSchedules(cwd), "Schedules & jobs map"));
|
|
76
|
-
printResult(results[results.length - 1]);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// ---- PROJECT BRAIN staleness (non-blocking) -----------------------------
|
|
80
|
-
// Warn (never fail) if the repo-resident project brief is missing or stale,
|
|
81
|
-
// so the portable context any model/tool reads on start doesn't silently rot.
|
|
82
|
-
if (o.briefCheck !== false) {
|
|
83
|
-
results.push(
|
|
84
|
-
safe(() => {
|
|
85
|
-
const s = briefStaleness(cwd);
|
|
86
|
-
if (s.status === "ok") {
|
|
87
|
-
return { status: "pass", label: "Project brief", detail: s.reason, extra: [] };
|
|
88
|
-
}
|
|
89
|
-
return {
|
|
90
|
-
status: "warn",
|
|
91
|
-
label: "Project brief",
|
|
92
|
-
detail: s.reason,
|
|
93
|
-
extra: ["project brief is stale, run `ship-safe brief` to refresh."],
|
|
94
|
-
};
|
|
95
|
-
}, "Project brief"),
|
|
96
|
-
);
|
|
97
|
-
printResult(results[results.length - 1]);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// ---- Overall verdict ----------------------------------------------------
|
|
101
|
-
const fails = results.filter((r) => r.status === "fail").length;
|
|
102
|
-
const warns = results.filter((r) => r.status === "warn").length;
|
|
103
|
-
const passes = results.filter((r) => r.status === "pass").length;
|
|
104
|
-
|
|
105
|
-
section("Verdict");
|
|
106
|
-
console.log(` ${GLYPH.pass} ${passes} ${GLYPH.warn} ${warns} ${GLYPH.fail} ${fails}`);
|
|
107
|
-
|
|
108
|
-
if (fails > 0) {
|
|
109
|
-
console.log(
|
|
110
|
-
"\n" + c.red(c.bold(" NO-GO")) + c.red(` — ${fails} blocking issue(s). Do not ship until these are clear.`),
|
|
111
|
-
);
|
|
112
|
-
return { exitCode: 1, results };
|
|
113
|
-
}
|
|
114
|
-
if (warns > 0) {
|
|
115
|
-
console.log(
|
|
116
|
-
"\n" + c.green(c.bold(" GO")) + c.yellow(` — with ${warns} warning(s) to eyeball first.`),
|
|
117
|
-
);
|
|
118
|
-
return { exitCode: 0, results };
|
|
119
|
-
}
|
|
120
|
-
console.log("\n" + c.green(c.bold(" GO")) + c.green(" — all checks clear. Safe to ship."));
|
|
121
|
-
return { exitCode: 0, results };
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/** Never let one check throwing crash the whole gate — surface it as a fail. */
|
|
125
|
-
function safe(fn, label) {
|
|
126
|
-
try {
|
|
127
|
-
return fn();
|
|
128
|
-
} catch (e) {
|
|
129
|
-
return {
|
|
130
|
-
status: "fail",
|
|
131
|
-
label,
|
|
132
|
-
detail: `Check errored: ${e.message || e}`,
|
|
133
|
-
extra: [],
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
}
|
|
1
|
+
// Ship-Safe — runs the full check suite and renders the per-check + overall
|
|
2
|
+
// verdict. Shared by both `ship-safe check` and `ship-safe deploy` so the gate
|
|
3
|
+
// is identical in both paths.
|
|
4
|
+
|
|
5
|
+
import { c, GLYPH, printResult, section } from "./util.mjs";
|
|
6
|
+
import {
|
|
7
|
+
checkDirtyTree,
|
|
8
|
+
checkSecrets,
|
|
9
|
+
checkTypecheck,
|
|
10
|
+
checkBuild,
|
|
11
|
+
checkSchemaBump,
|
|
12
|
+
} from "./checks.mjs";
|
|
13
|
+
import {
|
|
14
|
+
overviewApiSurface,
|
|
15
|
+
overviewIntegrations,
|
|
16
|
+
overviewSchedules,
|
|
17
|
+
} from "./overviews.mjs";
|
|
18
|
+
import { briefStaleness } from "./brief.mjs";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Run every check and print a clean summary.
|
|
22
|
+
* @param {object} o
|
|
23
|
+
* @param {string} o.cwd repo root
|
|
24
|
+
* @param {boolean} o.runBuild also run a full `npm run build` (slower)
|
|
25
|
+
* @param {string} [o.baseRef] merge-base ref for the schema diff (default main)
|
|
26
|
+
* @param {boolean} [o.overview] run the v1.1 read-only overview scanners
|
|
27
|
+
* (API surface · integrations · schedules).
|
|
28
|
+
* Defaults to ON — they're fast, read-only maps.
|
|
29
|
+
* @param {boolean} [o.briefCheck] emit a NON-BLOCKING staleness warning if the
|
|
30
|
+
* PROJECT BRAIN (PROJECT-BRIEF.md) is missing or
|
|
31
|
+
* out of date. Defaults to ON. Never a fail.
|
|
32
|
+
* @returns {Promise<{ exitCode: number, results: any[] }>} exitCode 0=GO, 1=NO-GO
|
|
33
|
+
*/
|
|
34
|
+
export async function runChecks(o) {
|
|
35
|
+
const cwd = o.cwd;
|
|
36
|
+
const results = [];
|
|
37
|
+
|
|
38
|
+
section("Checks");
|
|
39
|
+
|
|
40
|
+
// a. Dirty-tree guard
|
|
41
|
+
results.push(safe(() => checkDirtyTree(cwd), "Dirty-tree guard"));
|
|
42
|
+
printResult(results[results.length - 1]);
|
|
43
|
+
|
|
44
|
+
// b. Secret scan
|
|
45
|
+
results.push(safe(() => checkSecrets(cwd), "Secret scan"));
|
|
46
|
+
printResult(results[results.length - 1]);
|
|
47
|
+
|
|
48
|
+
// c. Typecheck (always) + optional full build
|
|
49
|
+
results.push(safe(() => checkTypecheck(cwd), "Typecheck (tsc --noEmit)"));
|
|
50
|
+
printResult(results[results.length - 1]);
|
|
51
|
+
if (o.runBuild) {
|
|
52
|
+
results.push(safe(() => checkBuild(cwd), "Production build (npm run build)"));
|
|
53
|
+
printResult(results[results.length - 1]);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// d. Schema-bump check
|
|
57
|
+
results.push(safe(() => checkSchemaBump(cwd, o.baseRef || "main"), "Schema-bump check"));
|
|
58
|
+
printResult(results[results.length - 1]);
|
|
59
|
+
|
|
60
|
+
// ---- v1.1 OVERVIEW SCANNERS (read-only maps) ----------------------------
|
|
61
|
+
// Default-on: three fast, read-only repo scans that give the builder a map of
|
|
62
|
+
// what their app actually has. They emit pass/warn only (never a blocking
|
|
63
|
+
// fail) — a surprising map is informational, the v1 safety checks own NO-GO.
|
|
64
|
+
// Disable with `--no-overview`.
|
|
65
|
+
const runOverview = o.overview !== false;
|
|
66
|
+
if (runOverview) {
|
|
67
|
+
section("Overview — what your app has (read-only)");
|
|
68
|
+
|
|
69
|
+
results.push(safe(() => overviewApiSurface(cwd), "API surface map"));
|
|
70
|
+
printResult(results[results.length - 1]);
|
|
71
|
+
|
|
72
|
+
results.push(safe(() => overviewIntegrations(cwd), "Agents & integrations map"));
|
|
73
|
+
printResult(results[results.length - 1]);
|
|
74
|
+
|
|
75
|
+
results.push(safe(() => overviewSchedules(cwd), "Schedules & jobs map"));
|
|
76
|
+
printResult(results[results.length - 1]);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ---- PROJECT BRAIN staleness (non-blocking) -----------------------------
|
|
80
|
+
// Warn (never fail) if the repo-resident project brief is missing or stale,
|
|
81
|
+
// so the portable context any model/tool reads on start doesn't silently rot.
|
|
82
|
+
if (o.briefCheck !== false) {
|
|
83
|
+
results.push(
|
|
84
|
+
safe(() => {
|
|
85
|
+
const s = briefStaleness(cwd);
|
|
86
|
+
if (s.status === "ok") {
|
|
87
|
+
return { status: "pass", label: "Project brief", detail: s.reason, extra: [] };
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
status: "warn",
|
|
91
|
+
label: "Project brief",
|
|
92
|
+
detail: s.reason,
|
|
93
|
+
extra: ["project brief is stale, run `ship-safe brief` to refresh."],
|
|
94
|
+
};
|
|
95
|
+
}, "Project brief"),
|
|
96
|
+
);
|
|
97
|
+
printResult(results[results.length - 1]);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ---- Overall verdict ----------------------------------------------------
|
|
101
|
+
const fails = results.filter((r) => r.status === "fail").length;
|
|
102
|
+
const warns = results.filter((r) => r.status === "warn").length;
|
|
103
|
+
const passes = results.filter((r) => r.status === "pass").length;
|
|
104
|
+
|
|
105
|
+
section("Verdict");
|
|
106
|
+
console.log(` ${GLYPH.pass} ${passes} ${GLYPH.warn} ${warns} ${GLYPH.fail} ${fails}`);
|
|
107
|
+
|
|
108
|
+
if (fails > 0) {
|
|
109
|
+
console.log(
|
|
110
|
+
"\n" + c.red(c.bold(" NO-GO")) + c.red(` — ${fails} blocking issue(s). Do not ship until these are clear.`),
|
|
111
|
+
);
|
|
112
|
+
return { exitCode: 1, results };
|
|
113
|
+
}
|
|
114
|
+
if (warns > 0) {
|
|
115
|
+
console.log(
|
|
116
|
+
"\n" + c.green(c.bold(" GO")) + c.yellow(` — with ${warns} warning(s) to eyeball first.`),
|
|
117
|
+
);
|
|
118
|
+
return { exitCode: 0, results };
|
|
119
|
+
}
|
|
120
|
+
console.log("\n" + c.green(c.bold(" GO")) + c.green(" — all checks clear. Safe to ship."));
|
|
121
|
+
return { exitCode: 0, results };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Never let one check throwing crash the whole gate — surface it as a fail. */
|
|
125
|
+
function safe(fn, label) {
|
|
126
|
+
try {
|
|
127
|
+
return fn();
|
|
128
|
+
} catch (e) {
|
|
129
|
+
return {
|
|
130
|
+
status: "fail",
|
|
131
|
+
label,
|
|
132
|
+
detail: `Check errored: ${e.message || e}`,
|
|
133
|
+
extra: [],
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|