Spaces:
Running
Running
Commit ·
3dfe2ca
1
Parent(s): e0d4a65
fix: rename blocked sync reason to out-of-sync
Browse filesCo-Authored-By: Codex <noreply@anthropic.com>
.claude/skills/sync-nowai-leaderboard/SKILL.md
CHANGED
|
@@ -50,8 +50,8 @@ From the repo root:
|
|
| 50 |
`message/attachments` envelope that template expects — not a raw MessageCard.
|
| 51 |
- Cards: green ✅ success (with "Open staging" button), red ❌ failure, amber ⚠️
|
| 52 |
sanity-gate abort, amber ⚠️ blocked preflight warning (dirty worktree / wrong
|
| 53 |
-
branch / fetch failure / local main out
|
| 54 |
-
Friday heartbeat (no changes detected — shows last date
|
| 55 |
`data/leaderboard.json` actually changed). No card on "no changes" Mon–Thu.
|
| 56 |
- The daily 14:00 launchd job (`~/.nowai-sync/`) loads `TEAMS_WEBHOOK_URL` from
|
| 57 |
`.env`, posts blocked-preflight warnings through `notify-blocked.mjs`, and
|
|
|
|
| 50 |
`message/attachments` envelope that template expects — not a raw MessageCard.
|
| 51 |
- Cards: green ✅ success (with "Open staging" button), red ❌ failure, amber ⚠️
|
| 52 |
sanity-gate abort, amber ⚠️ blocked preflight warning (dirty worktree / wrong
|
| 53 |
+
branch / fetch failure / local main out-of-sync with `origin/main`), blue 📋
|
| 54 |
+
Friday heartbeat (no changes detected — shows the last date
|
| 55 |
`data/leaderboard.json` actually changed). No card on "no changes" Mon–Thu.
|
| 56 |
- The daily 14:00 launchd job (`~/.nowai-sync/`) loads `TEAMS_WEBHOOK_URL` from
|
| 57 |
`.env`, posts blocked-preflight warnings through `notify-blocked.mjs`, and
|
.claude/skills/sync-nowai-leaderboard/lib/blocked-notify.mjs
CHANGED
|
@@ -2,6 +2,8 @@ const REASON_LABELS = {
|
|
| 2 |
'dirty-worktree': 'Worktree has uncommitted files',
|
| 3 |
'wrong-branch': 'Current branch is not main',
|
| 4 |
'fetch-failed': 'git fetch origin main failed',
|
|
|
|
|
|
|
| 5 |
'behind-or-diverged': 'Local main is not exactly in sync with origin/main',
|
| 6 |
};
|
| 7 |
|
|
|
|
| 2 |
'dirty-worktree': 'Worktree has uncommitted files',
|
| 3 |
'wrong-branch': 'Current branch is not main',
|
| 4 |
'fetch-failed': 'git fetch origin main failed',
|
| 5 |
+
'out-of-sync': 'Local main is not exactly in sync with origin/main',
|
| 6 |
+
// Backward-compatible alias for older wrapper revisions.
|
| 7 |
'behind-or-diverged': 'Local main is not exactly in sync with origin/main',
|
| 8 |
};
|
| 9 |
|
.claude/skills/sync-nowai-leaderboard/test/blocked-notify.test.mjs
CHANGED
|
@@ -22,9 +22,9 @@ test('buildBlockedNotification maps dirty-worktree to a warning card payload', (
|
|
| 22 |
]);
|
| 23 |
});
|
| 24 |
|
| 25 |
-
test('buildBlockedNotification uses
|
| 26 |
const out = buildBlockedNotification({
|
| 27 |
-
reason: '
|
| 28 |
facts: [['Branch', 'main'], ['RemoteAhead', '0'], ['LocalAhead', '1']],
|
| 29 |
now: new Date('2026-07-01T21:00:00Z'),
|
| 30 |
});
|
|
@@ -39,13 +39,13 @@ test('buildBlockedNotification uses exact-sync wording for local-ahead blocked r
|
|
| 39 |
|
| 40 |
test('parseBlockedCliArgs accepts repeated --fact pairs', () => {
|
| 41 |
const out = parseBlockedCliArgs([
|
| 42 |
-
'--reason', '
|
| 43 |
'--fact', 'Branch=main',
|
| 44 |
'--fact', 'RemoteAhead=2',
|
| 45 |
'--fact', 'LocalAhead=0',
|
| 46 |
]);
|
| 47 |
|
| 48 |
-
assert.equal(out.reason, '
|
| 49 |
assert.deepEqual(out.facts, [
|
| 50 |
['Branch', 'main'],
|
| 51 |
['RemoteAhead', '2'],
|
|
@@ -53,6 +53,19 @@ test('parseBlockedCliArgs accepts repeated --fact pairs', () => {
|
|
| 53 |
]);
|
| 54 |
});
|
| 55 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
test('parseBlockedCliArgs normalizes lowercase fact keys for stable payload titles', () => {
|
| 57 |
const parsed = parseBlockedCliArgs([
|
| 58 |
'--reason', 'dirty-worktree',
|
|
|
|
| 22 |
]);
|
| 23 |
});
|
| 24 |
|
| 25 |
+
test('buildBlockedNotification uses out-of-sync as the primary exact-sync reason', () => {
|
| 26 |
const out = buildBlockedNotification({
|
| 27 |
+
reason: 'out-of-sync',
|
| 28 |
facts: [['Branch', 'main'], ['RemoteAhead', '0'], ['LocalAhead', '1']],
|
| 29 |
now: new Date('2026-07-01T21:00:00Z'),
|
| 30 |
});
|
|
|
|
| 39 |
|
| 40 |
test('parseBlockedCliArgs accepts repeated --fact pairs', () => {
|
| 41 |
const out = parseBlockedCliArgs([
|
| 42 |
+
'--reason', 'out-of-sync',
|
| 43 |
'--fact', 'Branch=main',
|
| 44 |
'--fact', 'RemoteAhead=2',
|
| 45 |
'--fact', 'LocalAhead=0',
|
| 46 |
]);
|
| 47 |
|
| 48 |
+
assert.equal(out.reason, 'out-of-sync');
|
| 49 |
assert.deepEqual(out.facts, [
|
| 50 |
['Branch', 'main'],
|
| 51 |
['RemoteAhead', '2'],
|
|
|
|
| 53 |
]);
|
| 54 |
});
|
| 55 |
|
| 56 |
+
test('buildBlockedNotification still accepts the legacy behind-or-diverged alias', () => {
|
| 57 |
+
const out = buildBlockedNotification({
|
| 58 |
+
reason: 'behind-or-diverged',
|
| 59 |
+
facts: [['Branch', 'main']],
|
| 60 |
+
now: new Date('2026-07-01T21:00:00Z'),
|
| 61 |
+
});
|
| 62 |
+
|
| 63 |
+
assert.deepEqual(out.facts, [
|
| 64 |
+
['Reason', 'Local main is not exactly in sync with origin/main'],
|
| 65 |
+
['Branch', 'main'],
|
| 66 |
+
]);
|
| 67 |
+
});
|
| 68 |
+
|
| 69 |
test('parseBlockedCliArgs normalizes lowercase fact keys for stable payload titles', () => {
|
| 70 |
const parsed = parseBlockedCliArgs([
|
| 71 |
'--reason', 'dirty-worktree',
|