@motivation-labs/crosscheck 0.13.1-beta.6 → 0.14.0-beta.15
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/assets/screenshot-watch-timing.png +0 -0
- package/assets/screenshot-watch-timing.svg +1 -0
- package/dist/__tests__/diff-hash.test.d.ts +2 -0
- package/dist/__tests__/diff-hash.test.d.ts.map +1 -0
- package/dist/__tests__/diff-hash.test.js +126 -0
- package/dist/__tests__/diff-hash.test.js.map +1 -0
- package/dist/__tests__/scopes.test.d.ts +2 -0
- package/dist/__tests__/scopes.test.d.ts.map +1 -0
- package/dist/__tests__/scopes.test.js +101 -0
- package/dist/__tests__/scopes.test.js.map +1 -0
- package/dist/commands/watch.d.ts.map +1 -1
- package/dist/commands/watch.js +175 -30
- package/dist/commands/watch.js.map +1 -1
- package/dist/github/client.d.ts.map +1 -1
- package/dist/github/client.js +3 -2
- package/dist/github/client.js.map +1 -1
- package/dist/lib/board.d.ts.map +1 -1
- package/dist/lib/board.js +25 -6
- package/dist/lib/board.js.map +1 -1
- package/dist/lib/diff-hash.d.ts +16 -0
- package/dist/lib/diff-hash.d.ts.map +1 -0
- package/dist/lib/diff-hash.js +71 -0
- package/dist/lib/diff-hash.js.map +1 -0
- package/dist/lib/scopes.d.ts +16 -0
- package/dist/lib/scopes.d.ts.map +1 -0
- package/dist/lib/scopes.js +37 -0
- package/dist/lib/scopes.js.map +1 -0
- package/package.json +1 -1
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="940" height="494.2"><rect width="940" height="494.2" rx="5" ry="5" class="a"/><svg y="0%" x="0%"><circle cx="20" cy="20" r="6" fill="#ff5f58"/><circle cx="40" cy="20" r="6" fill="#ffbd2e"/><circle cx="60" cy="20" r="6" fill="#18c132"/></svg><svg height="434.2" viewBox="0 0 90 43.42" width="900" x="15" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="50"><style>@keyframes o{0%{transform:translateX(-90px)}5.3%{transform:translateX(-180px)}10.5%{transform:translateX(-270px)}15.8%{transform:translateX(-360px)}21.1%{transform:translateX(-450px)}26.3%{transform:translateX(-540px)}31.6%{transform:translateX(-630px)}36.8%{transform:translateX(-720px)}42.1%{transform:translateX(-810px)}47.4%{transform:translateX(-900px)}52.6%{transform:translateX(-990px)}57.9%{transform:translateX(-1080px)}63.2%{transform:translateX(-1170px)}68.4%{transform:translateX(-1260px)}73.7%{transform:translateX(-1350px)}78.9%{transform:translateX(-1440px)}84.2%{transform:translateX(-1530px)}89.5%{transform:translateX(-1620px)}94.7%{transform:translateX(-1710px)}to{transform:translateX(-1800px)}}.a{fill:#282d35}.f,.g,.h{fill:#b9c0cb;white-space:pre}.g,.h{fill:#a8cc8c}.h{fill:#b9c0cb;font-weight:700}.i,.j,.k,.l{fill:#b9bfca;white-space:pre}.j,.k,.l{fill:#dbab79}.k,.l{fill:#66c2cd}.l{fill:#71bef2}</style><g font-family="Monaco,Consolas,Menlo,'Bitstream Vera Sans Mono','Powerline Symbols',monospace" font-size="1.67"><defs><symbol id="1"><text y="1.67" class="f">────────────────────────────────────────────────────────────────────────────────────────</text></symbol><symbol id="2"><text y="1.67" class="g">●</text><text x="2.004" y="1.67" class="h">crosscheck</text><text x="14.028" y="1.67" class="f">cross-vendor</text><text x="27.054" y="1.67" class="f">·</text><text x="29.058" y="1.67" class="f">thorough</text></symbol><symbol id="3"><text x="39.078" y="1.67" class="f">workflow:</text><text x="49.098" y="1.67" class="f">review</text><text x="56.112" y="1.67" class="f">→</text><text x="58.116" y="1.67" class="f">fix</text><text x="62.124" y="1.67" class="f">→</text><text x="64.128" y="1.67" class="f">recheck</text></symbol><symbol id="4"><text x="73.146" y="1.67" class="f">vendors:</text><text x="83.166" y="1.67" class="f">claude</text></symbol><symbol id="5"><text y="1.67" class="f">·</text><text x="2.004" y="1.67" class="f">codex</text></symbol><symbol id="6"><text x="7.014" y="1.67" class="f">───────────────────────────────────────────────────────────────────────────────────</text></symbol><symbol id="7"><text y="1.67" class="f">─────</text></symbol><symbol id="8"><text x="7.014" y="1.67" class="f">PRs:</text><text x="12.024" y="1.67" class="f">4</text><text x="14.028" y="1.67" class="f">·</text><text x="16.032" y="1.67" class="f">CRs:</text><text x="21.042" y="1.67" class="f">3</text><text x="23.046" y="1.67" class="f">·</text><text x="25.05" y="1.67" class="f">fixes:</text><text x="32.064" y="1.67" class="f">2</text><text x="35.07" y="1.67" class="f">│</text><text x="38.076" y="1.67" class="f">avg</text><text x="42.084" y="1.67" class="f">CR:</text><text x="46.092" y="1.67" class="i">1m34s</text><text x="53.106" y="1.67" class="f">│</text><text x="56.112" y="1.67" class="f">↑</text><text x="58.116" y="1.67" class="f">18:42</text></symbol><symbol id="9"><text x="65.13" y="1.67" class="f">tunnel:</text><text x="75.15" y="1.67" class="f">e3f9a1.smee.io</text></symbol><symbol id="10"><text y="1.67" class="g">✓</text></symbol><symbol id="11"><text x="3.006" y="1.67" class="f">10:17</text><text x="9.018" y="1.67" class="f">PM</text><text x="13.026" y="1.67" class="f">PR</text><text x="16.032" y="1.67" class="f">#111</text><text x="21.042" y="1.67" class="f">opened</text><text x="29.058" y="1.67" class="f">feat/login</text><text x="43.086" y="1.67" class="f">origin=</text><text x="50.1" y="1.67" class="j">claude</text><text x="58.116" y="1.67" class="f">via=body</text><text x="68.136" y="1.67" class="f">reviewer=</text><text x="77.154" y="1.67" class="k">codex</text></symbol><symbol id="12"><text x="84.168" y="1.67" class="f">10:22</text></symbol><symbol id="13"><text y="1.67" class="f">PM</text><text x="4.008" y="1.67" class="f">PR</text><text x="7.014" y="1.67" class="f">#112</text><text x="12.024" y="1.67" class="f">opened</text><text x="20.04" y="1.67" class="f">fix/null-ptr</text><text x="34.068" y="1.67" class="f">origin=</text><text x="41.082" y="1.67" class="j">codex</text><text x="49.098" y="1.67" class="f">via=commits</text><text x="62.124" y="1.67" class="f">reviewer=</text><text x="71.142" y="1.67" class="k">claude</text></symbol><symbol id="14"><text x="77.154" y="1.67" class="f">─────────────</text></symbol><symbol id="15"><text y="1.67" class="f">───────────────────────────────────────────────────────────────────────────</text></symbol><symbol id="16"><text x="77.154" y="1.67" class="g">✓</text><text x="79.158" y="1.67" class="f">#109</text><text x="85.17" y="1.67" class="f">org/r</text></symbol><symbol id="17"><text y="1.67" class="f">epo</text><text x="5.01" y="1.67" class="f">feat/auth</text><text x="18.036" y="1.67" class="f">CR:</text><text x="22.044" y="1.67" class="g">APPROVE</text><text x="31.062" y="1.67" class="f">(43s)</text><text x="38.076" y="1.67" class="f">→</text><text x="40.08" y="1.67" class="k">https://github.com/org/repo/pull/109</text></symbol><symbol id="18"><text x="78.156" y="1.67" class="g">✓</text><text x="80.16" y="1.67" class="f">#110</text><text x="86.172" y="1.67" class="f">org/</text></symbol><symbol id="19"><text y="1.67" class="f">repo</text><text x="6.012" y="1.67" class="f">fix/crash</text><text x="19.038" y="1.67" class="f">CR:</text><text x="23.046" y="1.67" class="j">NEEDS</text><text x="29.058" y="1.67" class="j">WORK</text><text x="34.068" y="1.67" class="f">·</text><text x="36.072" y="1.67" class="f">fix</text><text x="40.08" y="1.67" class="f">2</text><text x="43.086" y="1.67" class="f">(2m08s)</text><text x="52.104" y="1.67" class="f">→</text><text x="54.108" y="1.67" class="k">https://github.com/org/repo/pull/110</text></symbol><symbol id="20"><text x="2.004" y="1.67" class="g">⠋</text><text x="4.008" y="1.67" class="h">#111</text><text x="10.02" y="1.67" class="i">org/repo</text><text x="20.04" y="1.67" class="f">feat/login</text><text x="46.092" y="1.67" class="f">started</text><text x="54.108" y="1.67" class="f">10:17</text><text x="60.12" y="1.67" class="f">PM</text><text x="64.128" y="1.67" class="f">4m05s</text><text x="71.142" y="1.67" class="g">⠋</text><text x="73.146" y="1.67" class="f">rechecking…</text></symbol><symbol id="21"><text x="86.172" y="1.67" class="f">PR</text><text x="89.178" y="1.67" class="l">█</text></symbol><symbol id="22"><text y="1.67" class="l">█████████</text><text x="10.02" y="1.67" class="f">711loc</text><text x="17.034" y="1.67" class="f">|</text><text x="19.038" y="1.67" class="f">CR</text><text x="22.044" y="1.67" class="j">████████</text><text x="31.062" y="1.67" class="j">2</text><text x="33.066" y="1.67" class="j">issues</text><text x="40.08" y="1.67" class="j">(NEEDS</text><text x="47.094" y="1.67" class="j">WORK,</text><text x="53.106" y="1.67" class="j">3.2K)</text><text x="59.118" y="1.67" class="f">codex</text><text x="65.13" y="1.67" class="f">·</text><text x="67.134" y="1.67" class="f">thorough</text><text x="76.152" y="1.67" class="f">|</text><text x="78.156" y="1.67" class="f">Fix</text><text x="82.164" y="1.67" class="k">███</text><text x="85.17" y="1.67" class="f">░░░</text><text x="89.178" y="1.67" class="k">✓</text></symbol><symbol id="23"><text x="1.002" y="1.67" class="k">1</text><text x="3.006" y="1.67" class="k">applied</text><text x="11.022" y="1.67" class="f">(2K)</text><text x="16.032" y="1.67" class="f">|</text><text x="18.036" y="1.67" class="f">Recheck</text><text x="26.052" y="1.67" class="f">░░░░░</text></symbol><symbol id="24"><text x="33.066" y="1.67" class="g">⠋</text><text x="35.07" y="1.67" class="h">#112</text><text x="41.082" y="1.67" class="i">org/repo</text><text x="51.102" y="1.67" class="f">fix/null-ptr</text><text x="83.166" y="1.67" class="f">started</text></symbol><symbol id="25"><text x="1.002" y="1.67" class="f">10:22</text><text x="7.014" y="1.67" class="f">PM</text><text x="11.022" y="1.67" class="f">8s</text><text x="15.03" y="1.67" class="g">⠋</text><text x="17.034" y="1.67" class="f">reviewing…</text></symbol><symbol id="26"><text x="29.058" y="1.67" class="f">PR</text><text x="32.064" y="1.67" class="l">███</text><text x="35.07" y="1.67" class="f">░░░░░░░</text><text x="43.086" y="1.67" class="f">42loc</text><text x="49.098" y="1.67" class="f">|</text><text x="51.102" y="1.67" class="f">CR</text><text x="54.108" y="1.67" class="f">░░░░░░░░</text><text x="63.126" y="1.67" class="f">queued</text><text x="70.14" y="1.67" class="f">|</text><text x="72.144" y="1.67" class="f">Fix</text><text x="76.152" y="1.67" class="f">░░░░░░</text><text x="83.166" y="1.67" class="f">queued</text></symbol><symbol id="27"><text x="89.178" y="1.67" class="f">─</text></symbol><symbol id="28"><text y="1.67" class="f">───────────────────────────────────────────────────────────────────────────────────────</text></symbol><symbol id="a"><path fill="transparent" d="M0 0h90v20H0z"/></symbol><symbol id="b"><path fill="#6f7683" d="M0 0h1.102v2.171H0z"/></symbol></defs><path class="a" d="M0 0h90v43.42H0z"/><g style="animation-duration:.9500000000000003s;animation-iteration-count:infinite;animation-name:o;animation-timing-function:steps(1,end)"><svg width="1890"><svg><use xlink:href="#a"/><use xlink:href="#b" x="-.004"/></svg><svg x="90"><use xlink:href="#a"/><use xlink:href="#b" x="87.996" y="2.146"/><use xlink:href="#1"/></svg><svg x="180"><use xlink:href="#a"/><use xlink:href="#b" x="36.996" y="6.488"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/></svg><svg x="270"><use xlink:href="#a"/><use xlink:href="#b" x="70.996" y="8.659"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/></svg><svg x="360"><use xlink:href="#a"/><use xlink:href="#b" x="6.996" y="13.001"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/><use xlink:href="#4" y="8.684"/><use xlink:href="#5" y="10.855"/></svg><svg x="450"><use xlink:href="#a"/><use xlink:href="#b" x="4.996" y="17.343"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/><use xlink:href="#4" y="8.684"/><use xlink:href="#5" y="10.855"/><use xlink:href="#6" y="13.026"/><use xlink:href="#7" y="15.197"/></svg><svg x="540"><use xlink:href="#a"/><use xlink:href="#b" x="62.996" y="19.514"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/><use xlink:href="#4" y="8.684"/><use xlink:href="#5" y="10.855"/><use xlink:href="#6" y="13.026"/><use xlink:href="#7" y="15.197"/><use xlink:href="#8" y="17.368"/></svg><svg x="630"><use xlink:href="#a"/><use xlink:href="#b" x=".996" y="23.856"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/><use xlink:href="#4" y="8.684"/><use xlink:href="#5" y="10.855"/><use xlink:href="#6" y="13.026"/><use xlink:href="#7" y="15.197"/><use xlink:href="#8" y="17.368"/><use xlink:href="#9" y="19.539"/><use xlink:href="#10" y="21.71"/></svg><svg x="720"><use xlink:href="#a"/><use xlink:href="#b" x="81.996" y="26.027"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/><use xlink:href="#4" y="8.684"/><use xlink:href="#5" y="10.855"/><use xlink:href="#6" y="13.026"/><use xlink:href="#7" y="15.197"/><use xlink:href="#8" y="17.368"/><use xlink:href="#9" y="19.539"/><use xlink:href="#10" y="21.71"/><use xlink:href="#11" y="23.881"/></svg><svg x="810"><use xlink:href="#a"/><use xlink:href="#b" x="76.996" y="30.369"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/><use xlink:href="#4" y="8.684"/><use xlink:href="#5" y="10.855"/><use xlink:href="#6" y="13.026"/><use xlink:href="#7" y="15.197"/><use xlink:href="#8" y="17.368"/><use xlink:href="#9" y="19.539"/><use xlink:href="#10" y="21.71"/><use xlink:href="#11" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/></svg><svg x="900"><use xlink:href="#a"/><use xlink:href="#b" x="74.996" y="34.711"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/><use xlink:href="#4" y="8.684"/><use xlink:href="#5" y="10.855"/><use xlink:href="#6" y="13.026"/><use xlink:href="#7" y="15.197"/><use xlink:href="#8" y="17.368"/><use xlink:href="#9" y="19.539"/><use xlink:href="#10" y="21.71"/><use xlink:href="#11" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#15" y="32.565"/></svg><svg x="990"><use xlink:href="#a"/><use xlink:href="#b" x="75.996" y="39.053"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/><use xlink:href="#4" y="8.684"/><use xlink:href="#5" y="10.855"/><use xlink:href="#6" y="13.026"/><use xlink:href="#7" y="15.197"/><use xlink:href="#8" y="17.368"/><use xlink:href="#9" y="19.539"/><use xlink:href="#10" y="21.71"/><use xlink:href="#11" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#15" y="32.565"/><use xlink:href="#16" y="34.736"/><use xlink:href="#17" y="36.907"/></svg><svg x="1080"><use xlink:href="#a"/><use xlink:href="#b" x="89.996" y="41.224"/><use xlink:href="#2" y="2.171"/><use xlink:href="#3" y="4.342"/><use xlink:href="#4" y="6.513"/><use xlink:href="#5" y="8.684"/><use xlink:href="#6" y="10.855"/><use xlink:href="#7" y="13.026"/><use xlink:href="#8" y="15.197"/><use xlink:href="#9" y="17.368"/><use xlink:href="#10" y="19.539"/><use xlink:href="#11" y="21.71"/><use xlink:href="#12" y="23.881"/><use xlink:href="#13" y="26.052"/><use xlink:href="#14" y="28.223"/><use xlink:href="#15" y="30.394"/><use xlink:href="#16" y="32.565"/><use xlink:href="#17" y="34.736"/><use xlink:href="#18" y="36.907"/><use xlink:href="#19" y="39.078"/></svg><svg x="1170"><use xlink:href="#a"/><use xlink:href="#b" x="89.996" y="41.224"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#9" y="15.197"/><use xlink:href="#10" y="17.368"/><use xlink:href="#11" y="19.539"/><use xlink:href="#12" y="21.71"/><use xlink:href="#13" y="23.881"/><use xlink:href="#14" y="26.052"/><use xlink:href="#15" y="28.223"/><use xlink:href="#16" y="30.394"/><use xlink:href="#17" y="32.565"/><use xlink:href="#18" y="34.736"/><use xlink:href="#19" y="36.907"/></svg><svg x="1260"><use xlink:href="#a"/><use xlink:href="#b" x="83.996" y="41.224"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/><use xlink:href="#11" y="15.197"/><use xlink:href="#12" y="17.368"/><use xlink:href="#13" y="19.539"/><use xlink:href="#14" y="21.71"/><use xlink:href="#15" y="23.881"/><use xlink:href="#16" y="26.052"/><use xlink:href="#17" y="28.223"/><use xlink:href="#18" y="30.394"/><use xlink:href="#19" y="32.565"/><use xlink:href="#20" y="39.078"/></svg><svg x="1350"><use xlink:href="#a"/><use xlink:href="#b" x="30.996" y="41.224"/><use xlink:href="#7"/><use xlink:href="#8" y="2.171"/><use xlink:href="#9" y="4.342"/><use xlink:href="#10" y="6.513"/><use xlink:href="#11" y="8.684"/><use xlink:href="#12" y="10.855"/><use xlink:href="#13" y="13.026"/><use xlink:href="#14" y="15.197"/><use xlink:href="#15" y="17.368"/><use xlink:href="#16" y="19.539"/><use xlink:href="#17" y="21.71"/><use xlink:href="#18" y="23.881"/><use xlink:href="#19" y="26.052"/><use xlink:href="#20" y="32.565"/><use xlink:href="#21" y="34.736"/><use xlink:href="#22" y="36.907"/><use xlink:href="#23" y="39.078"/></svg><svg x="1440"><use xlink:href="#a"/><use xlink:href="#b" x="30.996" y="41.224"/><use xlink:href="#8"/><use xlink:href="#9" y="2.171"/><use xlink:href="#10" y="4.342"/><use xlink:href="#11" y="6.513"/><use xlink:href="#12" y="8.684"/><use xlink:href="#13" y="10.855"/><use xlink:href="#14" y="13.026"/><use xlink:href="#15" y="15.197"/><use xlink:href="#16" y="17.368"/><use xlink:href="#17" y="19.539"/><use xlink:href="#18" y="21.71"/><use xlink:href="#19" y="23.881"/><use xlink:href="#20" y="30.394"/><use xlink:href="#21" y="32.565"/><use xlink:href="#22" y="34.736"/><use xlink:href="#23" y="36.907"/></svg><svg x="1530"><use xlink:href="#a"/><use xlink:href="#b" x="26.996" y="41.224"/><use xlink:href="#10"/><use xlink:href="#11" y="2.171"/><use xlink:href="#12" y="4.342"/><use xlink:href="#13" y="6.513"/><use xlink:href="#14" y="8.684"/><use xlink:href="#15" y="10.855"/><use xlink:href="#16" y="13.026"/><use xlink:href="#17" y="15.197"/><use xlink:href="#18" y="17.368"/><use xlink:href="#19" y="19.539"/><use xlink:href="#20" y="26.052"/><use xlink:href="#21" y="28.223"/><use xlink:href="#22" y="30.394"/><use xlink:href="#23" y="32.565"/><use xlink:href="#24" y="36.907"/><use xlink:href="#25" y="39.078"/></svg><svg x="1620"><use xlink:href="#a"/><use xlink:href="#b" x="88.996" y="41.224"/><use xlink:href="#11"/><use xlink:href="#12" y="2.171"/><use xlink:href="#13" y="4.342"/><use xlink:href="#14" y="6.513"/><use xlink:href="#15" y="8.684"/><use xlink:href="#16" y="10.855"/><use xlink:href="#17" y="13.026"/><use xlink:href="#18" y="15.197"/><use xlink:href="#19" y="17.368"/><use xlink:href="#20" y="23.881"/><use xlink:href="#21" y="26.052"/><use xlink:href="#22" y="28.223"/><use xlink:href="#23" y="30.394"/><use xlink:href="#24" y="34.736"/><use xlink:href="#25" y="36.907"/><use xlink:href="#26" y="39.078"/></svg><svg x="1710"><use xlink:href="#a"/><use xlink:href="#b" x="86.996" y="41.224"/><use xlink:href="#13"/><use xlink:href="#14" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#20" y="19.539"/><use xlink:href="#21" y="21.71"/><use xlink:href="#22" y="23.881"/><use xlink:href="#23" y="26.052"/><use xlink:href="#24" y="30.394"/><use xlink:href="#25" y="32.565"/><use xlink:href="#26" y="34.736"/><use xlink:href="#27" y="36.907"/><use xlink:href="#28" y="39.078"/></svg><svg x="1800"><use xlink:href="#a"/><use xlink:href="#b" x="86.996" y="41.224"/><use xlink:href="#14"/><use xlink:href="#15" y="2.171"/><use xlink:href="#16" y="4.342"/><use xlink:href="#17" y="6.513"/><use xlink:href="#18" y="8.684"/><use xlink:href="#19" y="10.855"/><use xlink:href="#20" y="17.368"/><use xlink:href="#21" y="19.539"/><use xlink:href="#22" y="21.71"/><use xlink:href="#23" y="23.881"/><use xlink:href="#24" y="28.223"/><use xlink:href="#25" y="30.394"/><use xlink:href="#26" y="32.565"/><use xlink:href="#27" y="34.736"/><use xlink:href="#28" y="36.907"/></svg></svg></g></g></svg></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-hash.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/diff-hash.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { execSync } from 'child_process';
|
|
3
|
+
import { mkdtempSync, rmSync, writeFileSync, readFileSync, existsSync } from 'fs';
|
|
4
|
+
import { tmpdir } from 'os';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import { computeDiffHash, PersistentDiffHashMap } from '../lib/diff-hash.js';
|
|
7
|
+
function git(args, cwd) {
|
|
8
|
+
return execSync(`git ${args}`, { cwd, stdio: ['ignore', 'pipe', 'pipe'], encoding: 'utf8' });
|
|
9
|
+
}
|
|
10
|
+
function setupRepo() {
|
|
11
|
+
const dir = mkdtempSync(join(tmpdir(), 'crosscheck-diff-test-'));
|
|
12
|
+
git('init --quiet -b main', dir);
|
|
13
|
+
git('config user.email test@test.local', dir);
|
|
14
|
+
git('config user.name Test', dir);
|
|
15
|
+
writeFileSync(join(dir, 'file.txt'), 'base content\n');
|
|
16
|
+
git('add .', dir);
|
|
17
|
+
git('commit --quiet -m base', dir);
|
|
18
|
+
// Create the "origin/main" remote-tracking ref that computeDiffHash expects
|
|
19
|
+
git('update-ref refs/remotes/origin/main HEAD', dir);
|
|
20
|
+
return { dir, baseRef: 'main' };
|
|
21
|
+
}
|
|
22
|
+
describe('computeDiffHash', () => {
|
|
23
|
+
let dir;
|
|
24
|
+
let baseRef;
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
;
|
|
27
|
+
({ dir, baseRef } = setupRepo());
|
|
28
|
+
});
|
|
29
|
+
afterEach(() => {
|
|
30
|
+
rmSync(dir, { recursive: true, force: true });
|
|
31
|
+
});
|
|
32
|
+
it('returns a stable hex digest for a given patch', () => {
|
|
33
|
+
writeFileSync(join(dir, 'file.txt'), 'modified content\n');
|
|
34
|
+
git('commit --quiet -am edit', dir);
|
|
35
|
+
const h1 = computeDiffHash(dir, baseRef);
|
|
36
|
+
const h2 = computeDiffHash(dir, baseRef);
|
|
37
|
+
expect(h1).toBe(h2);
|
|
38
|
+
expect(h1).toMatch(/^[0-9a-f]{64}$/);
|
|
39
|
+
});
|
|
40
|
+
it('returns identical hash when an amend produces the same patch under a new SHA', () => {
|
|
41
|
+
writeFileSync(join(dir, 'file.txt'), 'modified content\n');
|
|
42
|
+
git('commit --quiet -am edit', dir);
|
|
43
|
+
const shaBefore = git('rev-parse HEAD', dir).trim();
|
|
44
|
+
const hashBefore = computeDiffHash(dir, baseRef);
|
|
45
|
+
// Amend the commit message only — same tree, new SHA
|
|
46
|
+
git('commit --quiet --amend -m "edit (reworded)"', dir);
|
|
47
|
+
const shaAfter = git('rev-parse HEAD', dir).trim();
|
|
48
|
+
const hashAfter = computeDiffHash(dir, baseRef);
|
|
49
|
+
expect(shaAfter).not.toBe(shaBefore);
|
|
50
|
+
expect(hashAfter).toBe(hashBefore);
|
|
51
|
+
});
|
|
52
|
+
it('returns different hash when the diff content changes', () => {
|
|
53
|
+
writeFileSync(join(dir, 'file.txt'), 'first change\n');
|
|
54
|
+
git('commit --quiet -am one', dir);
|
|
55
|
+
const h1 = computeDiffHash(dir, baseRef);
|
|
56
|
+
writeFileSync(join(dir, 'file.txt'), 'second change\n');
|
|
57
|
+
git('commit --quiet -am two', dir);
|
|
58
|
+
const h2 = computeDiffHash(dir, baseRef);
|
|
59
|
+
expect(h1).not.toBe(h2);
|
|
60
|
+
});
|
|
61
|
+
it('returns the empty-diff hash when HEAD equals base', () => {
|
|
62
|
+
const h = computeDiffHash(dir, baseRef);
|
|
63
|
+
expect(h).toMatch(/^[0-9a-f]{64}$/);
|
|
64
|
+
// Hash of empty string sha256 — stable sentinel
|
|
65
|
+
expect(h).toBe('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855');
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe('PersistentDiffHashMap', () => {
|
|
69
|
+
let cacheFile;
|
|
70
|
+
beforeEach(() => {
|
|
71
|
+
cacheFile = join(mkdtempSync(join(tmpdir(), 'crosscheck-dhm-')), 'diff-hashes.json');
|
|
72
|
+
});
|
|
73
|
+
afterEach(() => {
|
|
74
|
+
if (existsSync(cacheFile))
|
|
75
|
+
rmSync(cacheFile);
|
|
76
|
+
});
|
|
77
|
+
it('upserts and reads back an entry', () => {
|
|
78
|
+
const m = new PersistentDiffHashMap(cacheFile);
|
|
79
|
+
m.upsert('owner/repo#1', { sha: 'abc123', hash: 'h1' });
|
|
80
|
+
expect(m.get('owner/repo#1')).toEqual({ sha: 'abc123', hash: 'h1' });
|
|
81
|
+
});
|
|
82
|
+
it('overwrites an existing entry for the same key', () => {
|
|
83
|
+
const m = new PersistentDiffHashMap(cacheFile);
|
|
84
|
+
m.upsert('owner/repo#1', { sha: 'abc', hash: 'h1' });
|
|
85
|
+
m.upsert('owner/repo#1', { sha: 'def', hash: 'h2' });
|
|
86
|
+
expect(m.get('owner/repo#1')).toEqual({ sha: 'def', hash: 'h2' });
|
|
87
|
+
});
|
|
88
|
+
it('persists across instances backed by the same file', () => {
|
|
89
|
+
const a = new PersistentDiffHashMap(cacheFile);
|
|
90
|
+
a.upsert('owner/repo#42', { sha: 'aaa', hash: 'hash-x' });
|
|
91
|
+
const b = new PersistentDiffHashMap(cacheFile);
|
|
92
|
+
expect(b.get('owner/repo#42')).toEqual({ sha: 'aaa', hash: 'hash-x' });
|
|
93
|
+
});
|
|
94
|
+
it('returns undefined for missing keys', () => {
|
|
95
|
+
const m = new PersistentDiffHashMap(cacheFile);
|
|
96
|
+
expect(m.get('nope')).toBeUndefined();
|
|
97
|
+
});
|
|
98
|
+
it('evicts oldest entries when exceeding the cap (FIFO)', () => {
|
|
99
|
+
const m = new PersistentDiffHashMap(cacheFile, /*maxEntries*/ 3);
|
|
100
|
+
m.upsert('a', { sha: '1', hash: 'h1' });
|
|
101
|
+
m.upsert('b', { sha: '2', hash: 'h2' });
|
|
102
|
+
m.upsert('c', { sha: '3', hash: 'h3' });
|
|
103
|
+
m.upsert('d', { sha: '4', hash: 'h4' }); // evicts 'a'
|
|
104
|
+
expect(m.get('a')).toBeUndefined();
|
|
105
|
+
expect(m.get('b')).toEqual({ sha: '2', hash: 'h2' });
|
|
106
|
+
expect(m.get('d')).toEqual({ sha: '4', hash: 'h4' });
|
|
107
|
+
});
|
|
108
|
+
it('upsert that overwrites does not count toward the cap', () => {
|
|
109
|
+
const m = new PersistentDiffHashMap(cacheFile, 2);
|
|
110
|
+
m.upsert('a', { sha: '1', hash: 'h1' });
|
|
111
|
+
m.upsert('b', { sha: '2', hash: 'h2' });
|
|
112
|
+
m.upsert('a', { sha: '1b', hash: 'h1b' }); // overwrite, not insert
|
|
113
|
+
expect(m.get('a')).toEqual({ sha: '1b', hash: 'h1b' });
|
|
114
|
+
expect(m.get('b')).toEqual({ sha: '2', hash: 'h2' });
|
|
115
|
+
});
|
|
116
|
+
it('tolerates a missing or malformed cache file', () => {
|
|
117
|
+
writeFileSync(cacheFile, 'not json');
|
|
118
|
+
const m = new PersistentDiffHashMap(cacheFile);
|
|
119
|
+
expect(m.get('any')).toBeUndefined();
|
|
120
|
+
m.upsert('x', { sha: '9', hash: 'h9' });
|
|
121
|
+
// Should have rewritten the file to valid JSON
|
|
122
|
+
const parsed = JSON.parse(readFileSync(cacheFile, 'utf8'));
|
|
123
|
+
expect(parsed['x']).toEqual({ sha: '9', hash: 'h9' });
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
//# sourceMappingURL=diff-hash.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-hash.test.js","sourceRoot":"","sources":["../../src/__tests__/diff-hash.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scopes.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/scopes.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { dedupScopes } from '../lib/scopes.js';
|
|
3
|
+
describe('dedupScopes', () => {
|
|
4
|
+
it('drops repo scope when its owner is in orgs', () => {
|
|
5
|
+
const input = [
|
|
6
|
+
{ org: 'codatta' },
|
|
7
|
+
{ owner: 'codatta', repo: 'humanbased-monorepo' },
|
|
8
|
+
];
|
|
9
|
+
const { scopes, dropped, fallbackRepos } = dedupScopes(input);
|
|
10
|
+
expect(scopes).toEqual([{ org: 'codatta' }]);
|
|
11
|
+
expect(dropped.get('codatta')).toEqual(['humanbased-monorepo']);
|
|
12
|
+
expect(fallbackRepos.get('codatta')).toEqual([
|
|
13
|
+
{ owner: 'codatta', repo: 'humanbased-monorepo' },
|
|
14
|
+
]);
|
|
15
|
+
});
|
|
16
|
+
it('keeps repo scope when its owner is not in orgs', () => {
|
|
17
|
+
const input = [
|
|
18
|
+
{ org: 'codatta' },
|
|
19
|
+
{ owner: 'beingzy', repo: 'founder-dashboard' },
|
|
20
|
+
];
|
|
21
|
+
const { scopes, dropped, fallbackRepos } = dedupScopes(input);
|
|
22
|
+
expect(scopes).toEqual(input);
|
|
23
|
+
expect(dropped.size).toBe(0);
|
|
24
|
+
expect(fallbackRepos.size).toBe(0);
|
|
25
|
+
});
|
|
26
|
+
it('matches org and owner names case-insensitively while preserving display values', () => {
|
|
27
|
+
const input = [
|
|
28
|
+
{ org: 'motivation-labs' },
|
|
29
|
+
{ owner: 'Motivation-Labs', repo: 'crosscheck' },
|
|
30
|
+
];
|
|
31
|
+
const { scopes, dropped, fallbackRepos } = dedupScopes(input);
|
|
32
|
+
expect(scopes).toEqual([{ org: 'motivation-labs' }]);
|
|
33
|
+
expect([...dropped.entries()]).toEqual([
|
|
34
|
+
['motivation-labs', ['crosscheck']],
|
|
35
|
+
]);
|
|
36
|
+
expect(fallbackRepos.get('motivation-labs')).toEqual([
|
|
37
|
+
{ owner: 'Motivation-Labs', repo: 'crosscheck' },
|
|
38
|
+
]);
|
|
39
|
+
});
|
|
40
|
+
it('preserves order: orgs first, then surviving repos in original order', () => {
|
|
41
|
+
const input = [
|
|
42
|
+
{ org: 'Motivation-Labs' },
|
|
43
|
+
{ owner: 'beingzy', repo: 'a' },
|
|
44
|
+
{ owner: 'Motivation-Labs', repo: 'monorepo' },
|
|
45
|
+
{ owner: 'beingzy', repo: 'b' },
|
|
46
|
+
{ org: 'codatta' },
|
|
47
|
+
{ owner: 'codatta', repo: 'symphony' },
|
|
48
|
+
];
|
|
49
|
+
const { scopes, dropped, fallbackRepos } = dedupScopes(input);
|
|
50
|
+
expect(scopes).toEqual([
|
|
51
|
+
{ org: 'Motivation-Labs' },
|
|
52
|
+
{ owner: 'beingzy', repo: 'a' },
|
|
53
|
+
{ owner: 'beingzy', repo: 'b' },
|
|
54
|
+
{ org: 'codatta' },
|
|
55
|
+
]);
|
|
56
|
+
expect([...dropped.entries()]).toEqual([
|
|
57
|
+
['Motivation-Labs', ['monorepo']],
|
|
58
|
+
['codatta', ['symphony']],
|
|
59
|
+
]);
|
|
60
|
+
expect([...fallbackRepos.entries()]).toEqual([
|
|
61
|
+
['Motivation-Labs', [{ owner: 'Motivation-Labs', repo: 'monorepo' }]],
|
|
62
|
+
['codatta', [{ owner: 'codatta', repo: 'symphony' }]],
|
|
63
|
+
]);
|
|
64
|
+
});
|
|
65
|
+
it('aggregates multiple drops per org', () => {
|
|
66
|
+
const input = [
|
|
67
|
+
{ org: 'codatta' },
|
|
68
|
+
{ owner: 'codatta', repo: 'a' },
|
|
69
|
+
{ owner: 'codatta', repo: 'b' },
|
|
70
|
+
{ owner: 'codatta', repo: 'c' },
|
|
71
|
+
];
|
|
72
|
+
const { scopes, dropped } = dedupScopes(input);
|
|
73
|
+
expect(scopes).toEqual([{ org: 'codatta' }]);
|
|
74
|
+
expect(dropped.get('codatta')).toEqual(['a', 'b', 'c']);
|
|
75
|
+
});
|
|
76
|
+
it('returns empty dropped map and unchanged scopes when no orgs configured', () => {
|
|
77
|
+
const input = [
|
|
78
|
+
{ owner: 'a', repo: 'x' },
|
|
79
|
+
{ owner: 'b', repo: 'y' },
|
|
80
|
+
];
|
|
81
|
+
const { scopes, dropped } = dedupScopes(input);
|
|
82
|
+
expect(scopes).toEqual(input);
|
|
83
|
+
expect(dropped.size).toBe(0);
|
|
84
|
+
});
|
|
85
|
+
it('handles empty input', () => {
|
|
86
|
+
const { scopes, dropped } = dedupScopes([]);
|
|
87
|
+
expect(scopes).toEqual([]);
|
|
88
|
+
expect(dropped.size).toBe(0);
|
|
89
|
+
});
|
|
90
|
+
it('does not drop org scopes themselves even when duplicated (no-op for duplicate orgs)', () => {
|
|
91
|
+
const input = [
|
|
92
|
+
{ org: 'codatta' },
|
|
93
|
+
{ org: 'codatta' },
|
|
94
|
+
];
|
|
95
|
+
const { scopes, dropped } = dedupScopes(input);
|
|
96
|
+
// duplicate org scopes are out of dedupScopes' contract; only repo-vs-org collapse is in scope
|
|
97
|
+
expect(scopes).toEqual(input);
|
|
98
|
+
expect(dropped.size).toBe(0);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
//# sourceMappingURL=scopes.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scopes.test.js","sourceRoot":"","sources":["../../src/__tests__/scopes.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AA6JA,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,wBAAsB,QAAQ,CAAC,IAAI,GAAE,SAAc,iBA4zBlD"}
|