@stupify/cli 0.0.11 → 0.0.12
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/analysis.js +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/render.js +32 -6
- package/package.json +1 -1
- package/src/analysis.ts +1 -1
- package/src/constants.ts +1 -1
- package/src/render.ts +34 -6
package/dist/analysis.js
CHANGED
|
@@ -101,7 +101,7 @@ function stringSnapshot(value) {
|
|
|
101
101
|
}
|
|
102
102
|
function limitSnapshot(value) {
|
|
103
103
|
const lines = value.split(/\r?\n/);
|
|
104
|
-
const limit =
|
|
104
|
+
const limit = 12;
|
|
105
105
|
if (lines.length <= limit)
|
|
106
106
|
return value;
|
|
107
107
|
return `${lines.slice(0, limit).join("\n")}
|
package/dist/constants.d.ts
CHANGED
package/dist/constants.js
CHANGED
package/dist/render.js
CHANGED
|
@@ -25,9 +25,9 @@ ${format.label("Patterns:")} ${run.patterns.join(", ")}
|
|
|
25
25
|
${format.success("No judgment-offload signals found.")}`;
|
|
26
26
|
}
|
|
27
27
|
return `${slopHeading()}
|
|
28
|
-
${run.matches.map((match, index) => `${index + 1}. ${format.label(match.patternId)}
|
|
29
28
|
${committerLabel(run)} (${sourceLabel(command)})
|
|
30
29
|
|
|
30
|
+
${run.matches.map((match, index) => `${index + 1}. ${format.label(match.patternId)}
|
|
31
31
|
${match.reason}
|
|
32
32
|
|
|
33
33
|
\`\`\`
|
|
@@ -36,7 +36,7 @@ ${match.snapshot ?? match.proof}
|
|
|
36
36
|
${format.muted(match.proof)}
|
|
37
37
|
|
|
38
38
|
${match.checkWhy ?? "This pattern may indicate judgment-offload."}`).join("\n\n")}
|
|
39
|
-
${format.muted(
|
|
39
|
+
${format.muted(summaryLine(run))}`;
|
|
40
40
|
}
|
|
41
41
|
export function helpText() {
|
|
42
42
|
return `Stupify ${VERSION}
|
|
@@ -98,23 +98,32 @@ function sourceHint(command) {
|
|
|
98
98
|
}
|
|
99
99
|
function sourceLabel(command) {
|
|
100
100
|
if (command.kind === "staged")
|
|
101
|
-
return "staged
|
|
101
|
+
return "staged";
|
|
102
102
|
if (command.kind === "since")
|
|
103
|
-
return
|
|
103
|
+
return sinceLabel(command.since);
|
|
104
104
|
if (command.kind === "commit")
|
|
105
105
|
return `commit ${command.commit}`;
|
|
106
106
|
if (command.kind === "commits")
|
|
107
107
|
return `last ${command.count} commits`;
|
|
108
|
-
return "stdin
|
|
108
|
+
return "stdin";
|
|
109
109
|
}
|
|
110
110
|
function committerLabel(run) {
|
|
111
|
-
const committers = (run.stats.committers ?? []).
|
|
111
|
+
const committers = humanCommitters(run.stats.committers ?? []).map(committerDisplayName);
|
|
112
112
|
if (committers.length === 0)
|
|
113
113
|
return "unknown committer";
|
|
114
114
|
if (committers.length <= 3)
|
|
115
115
|
return committers.join(", ");
|
|
116
116
|
return `${committers.slice(0, 3).join(", ")} +${committers.length - 3} more`;
|
|
117
117
|
}
|
|
118
|
+
function humanCommitters(committers) {
|
|
119
|
+
const nonEmpty = committers.filter(Boolean);
|
|
120
|
+
const humans = nonEmpty.filter((committer) => !isBotCommitter(committer));
|
|
121
|
+
return humans.length > 0 ? humans : nonEmpty;
|
|
122
|
+
}
|
|
123
|
+
function isBotCommitter(value) {
|
|
124
|
+
return /(?:^|<)(?:github|dependabot|renovate)(?:\s|@|>)/i.test(value) ||
|
|
125
|
+
/(?:noreply@github\.com|bot@)/i.test(value);
|
|
126
|
+
}
|
|
118
127
|
function committerDisplayName(value) {
|
|
119
128
|
return value.replace(/\s*<[^>]+>\s*$/, "").trim() || value;
|
|
120
129
|
}
|
|
@@ -123,3 +132,20 @@ function slopHeading() {
|
|
|
123
132
|
return `${format.warn(format.heading(heading))}
|
|
124
133
|
${format.warn("=".repeat(heading.length))}`;
|
|
125
134
|
}
|
|
135
|
+
function sinceLabel(since) {
|
|
136
|
+
const value = since.trim().toLowerCase();
|
|
137
|
+
if (value === "yesterday" || value === "1 day ago")
|
|
138
|
+
return "yesterday";
|
|
139
|
+
const match = /^(\d+)\s+(day|week|month|year)s?\s+ago$/.exec(value);
|
|
140
|
+
if (!match)
|
|
141
|
+
return `since ${since}`;
|
|
142
|
+
const count = Number(match[1]);
|
|
143
|
+
const unit = match[2];
|
|
144
|
+
if (count === 1)
|
|
145
|
+
return `last ${unit}`;
|
|
146
|
+
return `last ${count} ${unit}s`;
|
|
147
|
+
}
|
|
148
|
+
function summaryLine(run) {
|
|
149
|
+
const noun = run.matches.length === 1 ? "signal" : "signals";
|
|
150
|
+
return `${run.matches.length} ${noun}. Warn-only. Nothing blocked.`;
|
|
151
|
+
}
|
package/package.json
CHANGED
package/src/analysis.ts
CHANGED
|
@@ -135,7 +135,7 @@ function stringSnapshot(value: unknown): string | undefined {
|
|
|
135
135
|
|
|
136
136
|
function limitSnapshot(value: string): string {
|
|
137
137
|
const lines = value.split(/\r?\n/);
|
|
138
|
-
const limit =
|
|
138
|
+
const limit = 12;
|
|
139
139
|
if (lines.length <= limit) return value;
|
|
140
140
|
return `${lines.slice(0, limit).join("\n")}
|
|
141
141
|
[stupify: snapshot shortened after ${limit} lines]`;
|
package/src/constants.ts
CHANGED
package/src/render.ts
CHANGED
|
@@ -30,9 +30,9 @@ ${format.success("No judgment-offload signals found.")}`;
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
return `${slopHeading()}
|
|
33
|
-
${run.matches.map((match, index) => `${index + 1}. ${format.label(match.patternId)}
|
|
34
33
|
${committerLabel(run)} (${sourceLabel(command)})
|
|
35
34
|
|
|
35
|
+
${run.matches.map((match, index) => `${index + 1}. ${format.label(match.patternId)}
|
|
36
36
|
${match.reason}
|
|
37
37
|
|
|
38
38
|
\`\`\`
|
|
@@ -41,7 +41,7 @@ ${match.snapshot ?? match.proof}
|
|
|
41
41
|
${format.muted(match.proof)}
|
|
42
42
|
|
|
43
43
|
${match.checkWhy ?? "This pattern may indicate judgment-offload."}`).join("\n\n")}
|
|
44
|
-
${format.muted(
|
|
44
|
+
${format.muted(summaryLine(run))}`;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
export function helpText(): string {
|
|
@@ -101,20 +101,31 @@ function sourceHint(command: SearchCommand): string {
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
function sourceLabel(command: SearchCommand): string {
|
|
104
|
-
if (command.kind === "staged") return "staged
|
|
105
|
-
if (command.kind === "since") return
|
|
104
|
+
if (command.kind === "staged") return "staged";
|
|
105
|
+
if (command.kind === "since") return sinceLabel(command.since);
|
|
106
106
|
if (command.kind === "commit") return `commit ${command.commit}`;
|
|
107
107
|
if (command.kind === "commits") return `last ${command.count} commits`;
|
|
108
|
-
return "stdin
|
|
108
|
+
return "stdin";
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
function committerLabel(run: SearchRunJson): string {
|
|
112
|
-
const committers = (run.stats.committers ?? []).
|
|
112
|
+
const committers = humanCommitters(run.stats.committers ?? []).map(committerDisplayName);
|
|
113
113
|
if (committers.length === 0) return "unknown committer";
|
|
114
114
|
if (committers.length <= 3) return committers.join(", ");
|
|
115
115
|
return `${committers.slice(0, 3).join(", ")} +${committers.length - 3} more`;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
function humanCommitters(committers: readonly string[]): readonly string[] {
|
|
119
|
+
const nonEmpty = committers.filter(Boolean);
|
|
120
|
+
const humans = nonEmpty.filter((committer) => !isBotCommitter(committer));
|
|
121
|
+
return humans.length > 0 ? humans : nonEmpty;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function isBotCommitter(value: string): boolean {
|
|
125
|
+
return /(?:^|<)(?:github|dependabot|renovate)(?:\s|@|>)/i.test(value) ||
|
|
126
|
+
/(?:noreply@github\.com|bot@)/i.test(value);
|
|
127
|
+
}
|
|
128
|
+
|
|
118
129
|
function committerDisplayName(value: string): string {
|
|
119
130
|
return value.replace(/\s*<[^>]+>\s*$/, "").trim() || value;
|
|
120
131
|
}
|
|
@@ -124,3 +135,20 @@ function slopHeading(): string {
|
|
|
124
135
|
return `${format.warn(format.heading(heading))}
|
|
125
136
|
${format.warn("=".repeat(heading.length))}`;
|
|
126
137
|
}
|
|
138
|
+
|
|
139
|
+
function sinceLabel(since: string): string {
|
|
140
|
+
const value = since.trim().toLowerCase();
|
|
141
|
+
if (value === "yesterday" || value === "1 day ago") return "yesterday";
|
|
142
|
+
const match = /^(\d+)\s+(day|week|month|year)s?\s+ago$/.exec(value);
|
|
143
|
+
if (!match) return `since ${since}`;
|
|
144
|
+
|
|
145
|
+
const count = Number(match[1]);
|
|
146
|
+
const unit = match[2];
|
|
147
|
+
if (count === 1) return `last ${unit}`;
|
|
148
|
+
return `last ${count} ${unit}s`;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function summaryLine(run: SearchRunJson): string {
|
|
152
|
+
const noun = run.matches.length === 1 ? "signal" : "signals";
|
|
153
|
+
return `${run.matches.length} ${noun}. Warn-only. Nothing blocked.`;
|
|
154
|
+
}
|