commitshow 0.4.1 → 0.4.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/dist/lib/api.js +19 -7
- package/dist/lib/render.js +38 -13
- package/package.json +1 -1
package/dist/lib/api.js
CHANGED
|
@@ -161,13 +161,25 @@ export async function waitForPreviewSnapshot(projectId, since, timeoutMs = 180_0
|
|
|
161
161
|
// Otherwise require last_analysis_at to have advanced.
|
|
162
162
|
if (sinceMs === 0 || lastMs > sinceMs) {
|
|
163
163
|
const snapshot = await fetchLatestSnapshot(projectId);
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
164
|
+
// Race guard · analyze-project's concurrency claim-lock stamps
|
|
165
|
+
// projects.last_analysis_at = now() BEFORE the audit runs (see
|
|
166
|
+
// analyze-project line 4699+ · "datasette/2026-05-12 race"
|
|
167
|
+
// comment block · the lock serializes parallel audits). Without
|
|
168
|
+
// this guard the poll would return inside the claim-lock window
|
|
169
|
+
// with project.score_total = 0 (untouched initial) and
|
|
170
|
+
// snapshot = null · the user saw a 0/100 trophy on a fresh
|
|
171
|
+
// first-time audit. Wait for an actual snapshot whose
|
|
172
|
+
// created_at advances past the user's baseline.
|
|
173
|
+
const snapMs = snapshot?.created_at ? new Date(snapshot.created_at).getTime() : 0;
|
|
174
|
+
if (snapshot && snapMs > sinceMs) {
|
|
175
|
+
return {
|
|
176
|
+
project,
|
|
177
|
+
snapshot,
|
|
178
|
+
standing: null,
|
|
179
|
+
is_preview: project.status === 'preview',
|
|
180
|
+
cache_hit: false,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
171
183
|
}
|
|
172
184
|
}
|
|
173
185
|
await new Promise(r => setTimeout(r, intervalMs));
|
package/dist/lib/render.js
CHANGED
|
@@ -469,7 +469,15 @@ export function renderAudit(view) {
|
|
|
469
469
|
// the calibrated total.
|
|
470
470
|
const WALK_ON_AUDIT_MAX = 50;
|
|
471
471
|
const isWalkOn = p.status === 'preview';
|
|
472
|
-
|
|
472
|
+
// Prefer snapshot.score_total over project.score_total — defensive
|
|
473
|
+
// against the analyze-project claim-lock race (the lock stamps
|
|
474
|
+
// projects.last_analysis_at BEFORE the audit body runs · during that
|
|
475
|
+
// window project.score_total is still the 0 default while a freshly
|
|
476
|
+
// landed snapshot already carries the real number). The api.ts
|
|
477
|
+
// poller's race guard also ensures snapshot exists, but rendering
|
|
478
|
+
// also prefers snapshot here so any future call site that reads a
|
|
479
|
+
// fresh envelope without the guard still gets the truth.
|
|
480
|
+
const total = snapshot?.score_total ?? p.score_total ?? 0;
|
|
473
481
|
const lines = [];
|
|
474
482
|
// Big COMMIT.SHOW ANSI Shadow banner. Three-tier fallback by width:
|
|
475
483
|
// · cols ≥ 99 → single-line "COMMIT.SHOW"
|
|
@@ -728,7 +736,10 @@ export function renderAudit(view) {
|
|
|
728
736
|
// — same visual frame for share screenshots.
|
|
729
737
|
const lockedBar = '─ audition unlocks ─';
|
|
730
738
|
const auditDen = isWalkOn ? WALK_ON_AUDIT_MAX : 50;
|
|
731
|
-
|
|
739
|
+
// Prefer snapshot.score_auto over project.score_auto — same claim-lock
|
|
740
|
+
// race rationale as the `total` line above.
|
|
741
|
+
const auditScore = snapshot?.score_auto ?? p.score_auto ?? 0;
|
|
742
|
+
const auditScoreClamp = Math.min(auditScore, auditDen);
|
|
732
743
|
lines.push(' ' + ` Audit ${pad(`${auditScoreClamp}/${auditDen}`, 7)} ${scoreBar(auditScoreClamp, auditDen)}`);
|
|
733
744
|
if (isWalkOn) {
|
|
734
745
|
lines.push(' ' + ` Scout ${pad('—/30', 7)} ` + c.muted(lockedBar));
|
|
@@ -961,11 +972,18 @@ export function renderMarkdown(view) {
|
|
|
961
972
|
lines.push(`- ${s}`);
|
|
962
973
|
lines.push('');
|
|
963
974
|
}
|
|
964
|
-
|
|
975
|
+
// Prefer snapshot scores · race-safe vs analyze-project's claim-lock
|
|
976
|
+
// window where projects.score_* are still 0 while the snapshot already
|
|
977
|
+
// carries the real numbers. See renderAudit() comment block above.
|
|
978
|
+
const mdTotal = snapshot?.score_total ?? p.score_total;
|
|
979
|
+
const mdAudit = snapshot?.score_auto ?? p.score_auto;
|
|
980
|
+
const mdForecast = snapshot?.score_forecast ?? p.score_forecast;
|
|
981
|
+
const mdCommunity = snapshot?.score_community ?? p.score_community;
|
|
982
|
+
lines.push(`## Score · ${mdTotal} / 100`);
|
|
965
983
|
lines.push('');
|
|
966
|
-
lines.push(`- Audit: ${
|
|
967
|
-
lines.push(`- Scout: ${
|
|
968
|
-
lines.push(`- Community: ${
|
|
984
|
+
lines.push(`- Audit: ${mdAudit}/50`);
|
|
985
|
+
lines.push(`- Scout: ${mdForecast}/30`);
|
|
986
|
+
lines.push(`- Community: ${mdCommunity}/20`);
|
|
969
987
|
if (delta != null && delta !== 0) {
|
|
970
988
|
lines.push(`- **Δ ${delta > 0 ? '+' : ''}${delta}** since last audit`);
|
|
971
989
|
}
|
|
@@ -1025,9 +1043,16 @@ export function toAgentShape(view) {
|
|
|
1025
1043
|
// pillar-only fallback (Brief slot excluded · base /45).
|
|
1026
1044
|
const WALK_ON_AUDIT_MAX = 50;
|
|
1027
1045
|
const isWalkOn = p.status === 'preview';
|
|
1028
|
-
|
|
1046
|
+
// Prefer snapshot scores · race-safe vs analyze-project's claim-lock
|
|
1047
|
+
// window (see renderAudit comment). Snapshot carries the canonical
|
|
1048
|
+
// numbers for this run · projects.score_* are denormalized later.
|
|
1049
|
+
const jTotal = snapshot?.score_total ?? p.score_total;
|
|
1050
|
+
const jAudit = snapshot?.score_auto ?? p.score_auto;
|
|
1051
|
+
const jForecast = snapshot?.score_forecast ?? p.score_forecast;
|
|
1052
|
+
const jCommunity = snapshot?.score_community ?? p.score_community;
|
|
1053
|
+
const walkOnTotal = isWalkOn ? (jTotal ?? 0) : null;
|
|
1029
1054
|
const walkOnAuditNormalized = isWalkOn
|
|
1030
|
-
? Math.min(100, Math.round(((
|
|
1055
|
+
? Math.min(100, Math.round(((jAudit ?? 0) / WALK_ON_AUDIT_MAX) * 100))
|
|
1031
1056
|
: null;
|
|
1032
1057
|
return {
|
|
1033
1058
|
schema_version: '1',
|
|
@@ -1044,16 +1069,16 @@ export function toAgentShape(view) {
|
|
|
1044
1069
|
},
|
|
1045
1070
|
score: {
|
|
1046
1071
|
track: isWalkOn ? 'walk_on' : 'league',
|
|
1047
|
-
total:
|
|
1072
|
+
total: jTotal,
|
|
1048
1073
|
total_max: 100,
|
|
1049
|
-
audit:
|
|
1074
|
+
audit: jAudit,
|
|
1050
1075
|
audit_max: 50,
|
|
1051
|
-
scout:
|
|
1076
|
+
scout: jForecast,
|
|
1052
1077
|
scout_max: 30,
|
|
1053
|
-
community:
|
|
1078
|
+
community: jCommunity,
|
|
1054
1079
|
community_max: 20,
|
|
1055
1080
|
delta_since_last: snapshot?.score_total_delta ?? null,
|
|
1056
|
-
band: bandFor(
|
|
1081
|
+
band: bandFor(jTotal ?? 0),
|
|
1057
1082
|
walk_on_total: walkOnTotal,
|
|
1058
1083
|
walk_on_band: walkOnTotal != null ? bandFor(walkOnTotal) : null,
|
|
1059
1084
|
walk_on_audit_normalized: walkOnAuditNormalized,
|