diff --git a/scripts/partition-test-shards.mjs b/scripts/partition-test-shards.mjs index 3c2f37e3764..d3757cbb9f4 100644 --- a/scripts/partition-test-shards.mjs +++ b/scripts/partition-test-shards.mjs @@ -157,14 +157,6 @@ const TIMINGS_PATH = path.join(REPO_ROOT, 'scripts', 'test-shard-timings.json'); // beside them. That last figure is the floor this count cannot move: a CLI // slice (~960-1010s measured) is serial, so past eight the slowest shard is // the slice and more shards only add runners. -// -// ⚠ The bins above were placed by their SUM. Since #25870 partition() places -// them by that same wall model (WHOLE_LEG_PARALLELISM), so a slice shard no -// longer carries a whole-package leg ahead of its slice; on the committed -// dataset's full list the predicted steps move from 1277s on the three slice -// shards (643s elsewhere) to 966s on the slice shards and 830s elsewhere. On -// the 2026-10-26 refresh, with the CLI cut into 4 slices (pin 3c, below), all -// eight read ~738s. export const SHARD_COUNT = 8; // The acceptance bound #10472 set: the slowest shard within ~1.3x the mean. @@ -362,23 +354,10 @@ export function timingModeNote(event) { // n = 2 869.44s 1.52x still the floor // n = 3 579.63s 1.01x meets -- spec's task is the floor // -// So n = 3, and pin 3c held it there. Slices were placed at their PLAIN weight -// (partition() unchanged), so every bin kept the density the whole-package +// So n = 3, and pin 3c holds it there. Slices are placed at their PLAIN weight +// (partition() is unchanged), so every bin keeps the density the whole-package // split had -- see densityCap() for the hard limit on that and its pin. // -// RE-DERIVED AT 4 (#25870), on the 14-run refresh of 2026-10-26 (newest run -// 40272142430): the CLI at 2697.45s. `@objectstack/spec` (1168.98s) and -// `@objectstack/runtime` (793.70s) each run as two tasks, so the heaviest -// other serial task is `@objectstack/metadata-protocol`'s 670.12s, and a slice -// must sit within 1.3 x 670.12 = 871.16s. -// -// n = 3 899.15s 1.34x still the floor -- pin 3c refused 3 -// n = 4 674.36s 1.01x meets -- metadata-protocol is the floor -// -// Since #25870 partition() places a slice at its wall share rather than its -// plain weight (WHOLE_LEG_PARALLELISM); `total`, and so the density cap, still -// reads plain sums. -// // ⛔ THE COUNT IS CONFIGURED; WHETHER A RUN SLICES IS DECIDED BY THAT RUN. A // pull_request or merge_group run splits its own affected set, so planShards() // asks, of the run's own list, whether a configured package is that run's @@ -399,7 +378,7 @@ export function timingModeNote(event) { // a change to what that generator can DECODE, which is why the map it replaced // is kept below. export const FILE_SHARDED_PACKAGES = Object.freeze({ - '@objectstack/cli': 4, + '@objectstack/cli': 3, }); // THE MAP AS IT STOOD BEFORE ITS LAST CHANGE, read only by the generator's @@ -427,10 +406,8 @@ export const FILE_SHARDED_PACKAGES = Object.freeze({ // `test-core-run-summary-*`, #25771), so four days after that PR lands no // retained summary predates the change and this map decodes nothing. // The outgoing map of #22075's third round was empty -- the runs before it -// carried no slice. #25870 raised the CLI from 3 slices to 4, so this holds 3. -export const PREVIOUS_FILE_SHARDED_PACKAGES = Object.freeze({ - '@objectstack/cli': 3, -}); +// carried no slice -- so this one is empty too. +export const PREVIOUS_FILE_SHARDED_PACKAGES = Object.freeze({}); // The item grammar. A shard item is a package (`@objectstack/cli`) or a SLICE // of one (`@objectstack/cli 1/2`), and this pair of functions is the only place @@ -905,58 +882,21 @@ function readManifest(dir) { } } -// ── A SLICE IS A SERIAL LEG: BINS ARE PLACED BY WALL, NOT BY SUM (#25870) ──── -// -// A shard's "Run this shard's tests" step runs its whole packages four at a -// time (`--concurrency=4`) and THEN each file-level slice as a turbo run of its -// own, alone on the runner (ci.yml). So a slice's seconds reach the wall one for -// one while a whole package's are shared about 2.9 ways -- the wall model the -// SHARD_COUNT header calibrated (#25376): step ~ wholeSum / 2.9 + slice. This -// constant is that 2.9, not a new measurement. -// -// Placing bins by their SUM of seconds treated a slice second like a whole -// second, so every slice shard was filled up to the mean with whole packages and -// then ran its slice after them. On the committed dataset's full list that put -// ~900s of whole packages in front of each 966s CLI slice: predicted step 1277s -// on the three slice shards against 643s on the other five, and measured the -// same way on the pull_request runs #25870 tabulates -- 3/8-5/8 at 25-29 min, -// the rest at 7-17, the gap being each slice shard's whole-package leg -// (`Run this shard's tests` minus the slice leg's own turbo `Time:`). -// -// So partition() places by LOAD -- a bin's predicted wall, kept in whole-package -// seconds (a slice counts WHOLE_LEG_PARALLELISM times its weight) so that a list -// with no slice is placed by exactly the same additions and comparisons as the -// plain-sum LPT it replaced, byte for byte. `total` stays the plain sum of -// predicted test windows: the density cap and the drift report are statements -// about that quantity, and neither changes meaning here. -export const WHOLE_LEG_PARALLELISM = 2.9; - -// One item's share of a bin's load, in whole-package seconds. -export function loadOf(item) { - return item.slice ? item.weight * WHOLE_LEG_PARALLELISM : item.weight; -} - -// A bin's predicted `Run this shard's tests` step under the wall model. -export function wallOf(bin) { - return bin.load / WHOLE_LEG_PARALLELISM; -} - -// LPT greedy on load (above): heaviest item into the currently lightest bin. -// Deterministic: input order never matters because both the item sort and the -// bin choice break ties explicitly (by name / by lowest bin index). +// LPT greedy: heaviest package into the currently lightest bin. Deterministic: +// input order never matters because both the package sort and the bin choice +// break ties explicitly (by name / by lowest bin index). export function partition(items, shardCount) { const sorted = [...items].sort( - (a, b) => loadOf(b) - loadOf(a) || a.name.localeCompare(b.name, 'en') + (a, b) => b.weight - a.weight || a.name.localeCompare(b.name, 'en') ); - const bins = Array.from({ length: shardCount }, () => ({ total: 0, load: 0, names: [] })); + const bins = Array.from({ length: shardCount }, () => ({ total: 0, names: [] })); for (const it of sorted) { let best = 0; for (let i = 1; i < bins.length; i++) { - if (bins[i].load < bins[best].load) best = i; + if (bins[i].total < bins[best].total) best = i; } bins[best].names.push(it.name); bins[best].total += it.weight; - bins[best].load += loadOf(it); } return bins; } @@ -965,34 +905,13 @@ export function partition(items, shardCount) { // `floor` is the heaviest single package: sharding is BY PACKAGE, so no split // at any shard count can put max below it, and comparing it to the mean says // whether the bound is even reachable before anyone tries to reach it. -// -// `walls` / `wallRatio` are the same statistic on what the bins were placed by -// (wallOf, #25870). With no slice in the split they are the totals scaled by -// one constant, so the two ratios agree; with a slice, only the wall ratio says -// whether the shards finish together. A bin built by hand (no `load`) is read -// as all whole packages. export function balanceOf(bins, items = null) { const totals = bins.map((b) => b.total); const sum = totals.reduce((a, b) => a + b, 0); const mean = sum / bins.length; const max = Math.max(...totals); const floor = items ? Math.max(0, ...items.map((i) => i.weight)) : null; - const walls = bins.map((b) => wallOf({ load: b.load ?? b.total })); - const wallMean = walls.reduce((a, b) => a + b, 0) / bins.length; - const wallMax = Math.max(...walls); - return { - totals, - sum, - mean, - max, - min: Math.min(...totals), - ratio: mean === 0 ? 1 : max / mean, - floor, - walls, - wallMean, - wallMax, - wallRatio: wallMean === 0 ? 1 : wallMax / wallMean, - }; + return { totals, sum, mean, max, min: Math.min(...totals), ratio: mean === 0 ? 1 : max / mean, floor }; } // ── THE DENSITY CAP: NO SHARD CARRIES MORE THAN THE SPLIT PROVEN GREEN (#22075) ─ @@ -1052,7 +971,7 @@ export function refineToCap(bins, items, cap) { const weightOf = new Map(items.map((i) => [i.name, i.weight])); const slices = new Set(items.filter((i) => i.slice).map((i) => i.name)); const movable = (name) => !slices.has(name); - const out = bins.map((b) => ({ total: b.total, load: b.load, names: [...b.names] })); + const out = bins.map((b) => ({ total: b.total, names: [...b.names] })); const EPSILON = 1e-9; for (let step = 0; step < 10_000; step++) { let h = 0; @@ -1079,21 +998,15 @@ export function refineToCap(bins, items, cap) { } if (best === null) break; const { to, give, take } = best; - // Only whole packages move, and a whole package's load is its weight, so - // `load` follows `total` move for move. out[h].names.splice(out[h].names.indexOf(give), 1); out[h].total -= weightOf.get(give); - out[h].load -= weightOf.get(give); out[to].names.push(give); out[to].total += weightOf.get(give); - out[to].load += weightOf.get(give); if (take !== null) { out[to].names.splice(out[to].names.indexOf(take), 1); out[to].total -= weightOf.get(take); - out[to].load -= weightOf.get(take); out[h].names.push(take); out[h].total += weightOf.get(take); - out[h].load += weightOf.get(take); } } return out; @@ -1571,9 +1484,7 @@ const SELF_TEST_BATTERIES = Object.freeze({ // 8 of these 25 are pins 3b and 3c, the file-level slicing's (#16173), and // every one of them runs unconditionally: 3c's fixtures and 3b's cut of the // heaviest package do not depend on what the live map slices. - // 2 of these 27 are pin 2b, the wall placement's (#25870): a fixture, so it - // runs whatever the dataset holds. - 'the balancing pins (#10472)': 27, + 'the balancing pins (#10472)': 25, 'predicted-vs-measured drift (#16173)': 9, 'drift warning tier under the red (#16465)': 12, 'file-level slice items (#16173)': 20, @@ -1820,55 +1731,16 @@ function selfTest() { }); const real = datasetPlan.bins; const balance = balanceOf(real, datasetItems); - // Graded on predicted WALL, the quantity the bins are placed by (#25870): with - // a slice in the split, the bin SUMS are deliberately unequal -- a slice shard - // carries its serial slice and little else -- and only the walls say whether - // the shards finish together. With no slice the two ratios are the same number. check(() => { - if (balance.wallRatio > MAX_SHARD_OVER_MEAN) { + if (balance.ratio > MAX_SHARD_OVER_MEAN) { throw new Error( - `balance: at ${SHARD_COUNT} shards the slowest predicted test step is ${balance.wallRatio.toFixed(2)}x the mean ` + - `(${balance.wallMax.toFixed(0)}s vs ${balance.wallMean.toFixed(0)}s), past the ${MAX_SHARD_OVER_MEAN}x bound. ` + - 'Walls: ' + balance.walls.map((t) => t.toFixed(0)).join('/') + 's; bins: ' + - balance.totals.map((t) => t.toFixed(0)).join('/') + 's.' + `balance: at ${SHARD_COUNT} shards the heaviest bin is ${balance.ratio.toFixed(2)}x the mean ` + + `(${balance.max.toFixed(0)}s vs ${balance.mean.toFixed(0)}s), past the ${MAX_SHARD_OVER_MEAN}x bound. ` + + 'Bins: ' + balance.totals.map((t) => t.toFixed(0)).join('/') + 's.' ); } }); - // 2b. A SLICE IS PLACED AS THE SERIAL LEG IT IS (#25870). Three shards, a - // package cut in two (100s a slice) and three whole packages (100s, 50s, - // 50s). Placed by SUM -- the LPT this replaced -- each slice shard also - // takes a 50s whole package, which runs four-wide BEFORE the slice and - // lengthens that shard's step to ~117s. Placed by wall, the slices run - // alone and the three whole packages share the third shard (~69s). The - // two placements differ, so a revert to the sum reds here. - const serial = partition( - [ - { name: 's 1/2', weight: 100, slice: { index: 1, count: 2 } }, - { name: 's 2/2', weight: 100, slice: { index: 2, count: 2 } }, - mk('x', 100), - mk('y', 50), - mk('z', 50), - ], - 3 - ); - check(() => { - const crowded = serial.filter((bin) => bin.names.some((n) => n.startsWith('s ')) && bin.names.length > 1); - if (crowded.length > 0) { - throw new Error( - `slice placement: a slice shard also carries whole packages (${crowded.map((b) => b.names.join('+')).join('; ')}) ` + - 'that run before its serial slice -- are the bins placed by their plain SUM again?' - ); - } - }); - check(() => { - const walls = serial.map(wallOf); - const expected = [100, 100, 200 / WHOLE_LEG_PARALLELISM]; - if (walls.some((w, i) => Math.abs(w - expected[i]) > 1e-9)) { - throw new Error(`slice placement: predicted walls ${walls.map((w) => w.toFixed(2)).join('/')}s, expected ${expected.map((w) => w.toFixed(2)).join('/')}s`); - } - }); - // 3. The bound is REACHABLE at this shard count -- the arithmetic #10472 // asked about when it floated 6 -> 8. No split can put the heaviest bin // below the heaviest single package, so once that package exceeds @@ -3142,8 +3014,7 @@ function selfTest() { console.log( `partition-test-shards: self-test OK (${datasetPackages.length} measured packages ` + `-> ${datasetItems.length} shard items, ${SHARD_COUNT} shards, ` + - `predicted test-step walls ${balance.walls.map((t) => t.toFixed(0)).join('/')}s, ` + - `max/mean ${balance.wallRatio.toFixed(2)}x <= ${MAX_SHARD_OVER_MEAN}x, floor ${balance.floor.toFixed(0)}s, ` + + `max/mean ${balance.ratio.toFixed(2)}x <= ${MAX_SHARD_OVER_MEAN}x, floor ${balance.floor.toFixed(0)}s, ` + `bins ${balance.totals.map((t) => t.toFixed(2)).join('/')}s within the ${datasetCap.toFixed(2)}s density cap, ` + `file-level slices: ` + `${datasetPlan.decisions.filter((d) => d.count > 1).map((d) => `${d.name} x${d.count}`).join(', ') || 'none'})` @@ -3266,7 +3137,7 @@ function main() { { excluded } ); const mine = bins[shardIndex - 1]; - const { max, mean, ratio, walls, wallRatio } = balanceOf(bins); + const { max, mean, ratio } = balanceOf(bins); // Printed on every shard, not just the imbalanced one, and printed as the // RATIO the acceptance bound is written in: the per-shard numbers alone never // said whether the split was balanced, which is why #10472's imbalance had to @@ -3280,13 +3151,6 @@ function main() { `density cap ${cap.toFixed(2)}s; ` + `${packages - estimated} measured, ${estimated} estimated from test-file count)` ); - // What the bins were placed by (wallOf, #25870): the test step each shard is - // predicted to take, a slice counted as the serial leg it runs as. - console.error( - ` predicted test-step walls (whole / ${WHOLE_LEG_PARALLELISM} + slice): ` + - `${walls.map((w) => w.toFixed(0)).join('/')}s, this shard ${wallOf(mine).toFixed(0)}s; ` + - `max/mean ${wallRatio.toFixed(2)}x` - ); // Only a document that states its own slicing prints this, so a Test Core // shard's log is unchanged; the nightly's says where its slice count came from. if (acrossShards !== null) { diff --git a/scripts/test-shard-timings.json b/scripts/test-shard-timings.json index e68f9b230d5..946dd83387d 100644 --- a/scripts/test-shard-timings.json +++ b/scripts/test-shard-timings.json @@ -1,291 +1,192 @@ { "note": "GENERATED by scripts/measure-test-shard-timings.mjs -- do not hand-edit. Per-package `turbo run test` durations in seconds, the balancing input for the Test Core shard split (scripts/partition-test-shards.mjs). See `provenance.refresh` to regenerate. Every weight is a real measurement: the ones in `carriedOver` were measured by an earlier refresh and re-confirmed unchanged by a turbo cache HIT in this one. A weight is the median of the executed runs that measured it; the ones in `provisional` rest on fewer than `provenance.minimumRuns` of them -- fit to balance on, NOT a baseline to set a ceiling from. `ceilings` is each package's suite-duration ceiling, graded by scripts/check-test-suite-ceilings.mjs: its slowest executed run in the refresh window that first set it, times `provenance.ceilingHeadroom`, then held by every later refresh -- raised only by a ruling, never by a refresh. `uncapped` names the packages with none, and why. `density` is the window's density reading: each run's count of executed packages (cache replays excluded) and each measured package's median share of its runs' executed seconds -- what the next refresh's diff judges a rise against.", "provenance": { - "measuredAt": "2026-10-26", + "measuredAt": "2026-10-23", "summaries": [ - "3LDaSZoydWFxKiH8lVKLKVxGaMJ.json", - "3LDaPIV2dIpgEvVGKFxYd6HvYkT.json", - "3LDaO15zRDYZSNL1mB4enxuV3pa.json", - "3LDaOA8UT8QuAmkEjdJ2ih9ciUl.json", - "3LDaO4ahLYajwSYg8Iy4e79uMZL.json", - "3LDaQTO1pa0xrf6skNVq1PTxAYj.json", - "3LDaQbbOFROA2if4SYKnPJnY8o6.json", - "3LDaNRvMdnlmDnRZo3E35ef7ks1.json", - "3LDaOeEKoicr9j7n9bhhFslV63z.json", - "3LDaRBIewlANXPlK3igFDETMWOI.json", - "3LDaRBTVuCafN7r6ZM5ZfFqjXx8.json", - "3LDUYCGqjs1sRzM1Hb1WD6PIwhN.json", - "3LDTsfHrAX3sOq0c6nnMHcuPx6Y.json", - "3LDTG0QWuTkpMMqTfVkFtgLyW0D.json", - "3LDTCt9nMnjs1OzDOslA4UsgCvu.json", - "3LDTD0OxpF7fQ5DdY8H1NtGZvFQ.json", - "3LDTbtbIiyRWaCz6X3v7kGwNVWQ.json", - "3LDVEm7r4dtDMAyjwMuVV0zmXc0.json", - "3LDTT8XKvxfOaZRj53OyH8xWSBF.json", - "3LDTFqIBMVBKsY28virwghMkFiL.json", - "3LDTKBXlf47dz3hfnKZMHkaTx9s.json", - "3LDTKLgrAjBCoXlvkdXVlk5d06g.json", - "3LDN6nIRzg0SK0Bfe5cFQYDpSGm.json", - "3LDMrn1JsFnStMbyMsWsjRCIppa.json", - "3LDM8vCv7eT8HJFiv6i1ba8F5C4.json", - "3LDM6YchNjUNnEX1mmCus3d5Lto.json", - "3LDM6XTlK0HzBh35UmBt3P9iTBG.json", - "3LDM5kcy0SUDC9jEeQmcPEihAji.json", - "3LDM5lyTXtiyMEprJRWvtNQhV6f.json", - "3LDMTBfery6kKunHMlt7Kd0szBw.json", - "3LDMAG5HG3glYUEjSdFbueF6BPE.json", - "3LDM7rqhvMfLuIe1brpwhqWirHV.json", - "3LDM7wRFUaB4zc3VwgshO1mBSCD.json", - "3LDGKabmuOiTpeutCfpQ8MCG3JL.json", - "3LDG0vuLgEd5aQwcBTlS0YBgnQp.json", - "3LDFJsWivFuJiiGHDEwILPwlcz4.json", - "3LDF8vkb02p6SNpuS4vKirjVwQ9.json", - "3LDF8xIQIUHmWeT9toL0o4jREsW.json", - "3LDFAqSn0y9wDS0lmJ1mYwamSPH.json", - "3LDFAs6AkJW4lWJOl3Pixh9EB4q.json", - "3LDFfH4jECaxoW15YV8XBjfpCwh.json", - "3LDFENmkz0oxlagjizS7tCB1mkd.json", - "3LDFGb6shtRRGKZE87sDkAOwhXb.json", - "3LDFGlhe5FUP6cAlO6a2rNhZ8Dv.json", - "3LCtwDL1RvwV3LsCCj5Pj7yN6Aj.json", - "3LCsVp9yNcuFTd4W1h2Uxny5Jpq.json", - "3LCsW62HFSmQutLoRc531TTmPmo.json", - "3LCv0vMFXsWiaOcjshFuUh0rweo.json", - "3LCtBosMSnAnSxYZxeaKp4puEo9.json", - "3LCsnLxYRS4BfVzGWACILMH0QlK.json", - "3LCtoOMEqIQZClJRjfIjl2WzvTV.json", - "3LCsTzeKKUrcWhmkhp5rXbFrmzq.json", - "3LCsSJDnOPW4vmOIKa580tpvczO.json", - "3LCv5DaXWaRqna0YqJzWSndYgGG.json", - "3LCsxEGt7TyrgdzwLBdNQnCj7ce.json", - "3LCmV3rMTs7wtFpTipqfnE0OTwk.json", - "3LClu2fJ5CL0KMrIF9NZxMsdHRA.json", - "3LClA8CyF7dJLIUAwrWJPMuolIP.json", - "3LCl9j2pcY0fUVyK6Mgwnt3B7v7.json", - "3LCl9deGxEkkmULZ5DvEM7f2dtP.json", - "3LClB22Q5pGTJNT4GhEhOfWBdNX.json", - "3LClB3eWfhAQUjsqZK8uibbrpyE.json", - "3LCl9LJwdmCIaWVwiKLHP7jtqMN.json", - "3LClHHXv8z3FYmPyqk1mKFNIXAg.json", - "3LCl8eYIdHlVT0ZItbe0UlbtmKO.json", - "3LCl8g0miILcr770UuUyGNaqfDw.json", - "3LCekjGcB6kfA0LBQVOtvZdyJwz.json", - "3LCeMJJubkzKlSLBUV4mhAw567n.json", - "3LCdsRub0h5xiZQTkx3HNCT1eqi.json", - "3LCdsCwP2A23ygiG4D3V2kJ9kAJ.json", - "3LCds6jOAUoZwUPIHDRnnmLkrBB.json", - "3LCdrA94CAIwysH3gLzmUkgtRah.json", - "3LCdrCFQYpMAaK0ABwdKmzlAQmt.json", - "3LCdteoI6PV9ApQpI9YjSyfPZQu.json", - "3LCdyf3bmXHqc8h0UPBDUd1LBem.json", - "3LCdw436KV0AeGSejShfHD60VZC.json", - "3LCdw6a1kqW9GzNKyNVvZI9rklg.json", - "3LCWX5J71I4rp7iKfQtsV5bOLx5.json", - "3LCWWsjoYHuNYKsj1F8SjA4HC9J.json", - "3LCWXBsBFOQkOVzU7fDlF49yEdg.json", - "3LCWX7QRGj9b82MbiyFv381x07W.json", - "3LCWXIsNky4qPD33mw15CaLU36t.json", - "3LCWYRaXK6Ypls3igfLhLxVp1hb.json", - "3LCWYKzowb5ktvobYfcml0W935G.json", - "3LCWYhVNJBuCoBVbca4apYB7XL8.json", - "3LCWY1xSWspaDuQAydMknIyP11C.json", - "3LCWW4w8notGugVkPyzBE8fDOUk.json", - "3LCWVzeqeINeG89tTqRZC0kEERu.json", - "3LCPFGjCJGDv96aKr0AsNKJS1ak.json", - "3LCPFUFYq2fszNDtFZn933fjTe8.json", - "3LCPFikJ4vlA9FrvABcM2utNGsq.json", - "3LCPFVLm15Tf6OeOwvceW9TLKA2.json", - "3LCPFPVv5NuabV7YPH5ZngI20ul.json", - "3LCPGsKYGTTKFwHqlRiNZtXDMxi.json", - "3LCPGv1syvP1CH86XNr33ZqPgpl.json", - "3LCPJvzLONBV1x8BfgA1YaLAVhw.json", - "3LCPFUCIBvdSaZ4qsQapAUMvKzF.json", - "3LCPEMxwnLKkKwpClLlXqmdrdiM.json", - "3LCPEO2ZWEPaxLnB4YUoHsdCUEx.json", - "3LCI0yuSEEwpDcv3mxTAabYsT74.json", - "3LCHzEibBmoaUQnasJ8dlmBXNAz.json", - "3LCI0Hyl8qxTnjCNL6h7ZVMlCeL.json", - "3LCHywitYKodFp5sSHabAXsUErB.json", - "3LCHz02JdnDgSLfiKj219achauU.json", - "3LCI1wF1e6DFIxxoIDxkGCMhjPm.json", - "3LCI225OECHtfdYnPG1stRhkS4A.json", - "3LCI1QxNYHbdkEVlUG1NauyzzdI.json", - "3LCI1euhgYjFncNbXEAZqLCJjbn.json", - "3LCI3DFmgnMsN5G68yfkOfWSZ0t.json", - "3LCI3CxQgQCISZCrV0Nn8ueHY5o.json", - "3LCC3rxx7LgNW7HKq0TrE4lZ3hI.json", - "3LCBbGH6vf6UKso8eF0icozaNYO.json", - "3LCAf6zNl797qrzrnaGUkv4tL7e.json", - "3LCBMyYBtLCSRYvfGYybeEZIkvw.json", - "3LCDD7DDnNUzbunqOjvBzfYzp5L.json", - "3LCAg06xKPufsgt8nyvIEo8DxlJ.json", - "3LCAg1BKIQRtwwOy5WWNJJ0UzVT.json", - "3LCAfNaWjSREo9QdnPSj2XBUUi9.json", - "3LCAftw6pqPiGQ2vIJPMyo1cofh.json", - "3LCAgTku9pHMsbPzXARi2V7Gx4E.json", - "3LCAgMRb0ZKJgXVwYr6hlUW0hi2.json", - "3LC4G3pPljtgnqvbMI7wHYweqU4.json", - "3LC42H4n3ghFeZGKSeBoXNEXeAC.json", - "3LC3LNHU6fXoQqP1Zrl9yWP3RvB.json", - "3LC409r9udvJ7ZqAjAe3rp1jfju.json", - "3LC5oojMAwIlwjm0nucDrW7IKOv.json", - "3LC3MIwksYBlx1BxAdaTMHrWb7E.json", - "3LC3MHdka4d4VTGwYcyF33J6EmL.json", - "3LC3LTCF4rRUyftjSLNmjjC3Bbd.json", - "3LC3M3tOMzsRJCJjXKKiXECiv29.json", - "3LC3KdDX3FsPzb5JXfKWmn49OuU.json", - "3LC3KgCkjiACXvOmaveS1ramgZH.json", - "3LBxXKoHflSvnVUxOGzmkfYAhxw.json", - "3LBxZjd6LkCX0hm3VHitN0bFbxh.json", - "3LBxQYi4KdBwoLjrfAW3Qc6sI9f.json", - "3LBxu3ApUnTrZtNTGTOrAYpgDgd.json", - "3LBwZxgStewMCWZB0DbJM5yDC97.json", - "3LByUkS0cMbQX3tuPekDh7yMrWX.json", - "3LBweyM37YiWR5BITbl8heAJ85y.json", - "3LBx52yfzG5egICSnFplmlhcos4.json", - "3LBxCCnd9t5oBDHOLDcuJPNgBsO.json", - "3LBwcOsrluJGy92YNKAfy93bM3N.json", - "3LByvd9eelZsmzimdQKpMx14Pjy.json", - "3LBpfnSHdoQPrufWbCIA3oYWMhQ.json", - "3LBpyRLEXr3FNvGPsV4K3NQi8ie.json", - "3LBq9Ly9kxM8spEL5Qpym9zUQqm.json", - "3LBrh12BGhRd1AdSpFfqp8sw995.json", - "3LBpdiEdj7OblBJgcg4Y4ZDIvCZ.json", - "3LBqeJD8XmRkGDPd746sMQZygSS.json", - "3LBpCjeKQnOUkJalK9527767wmB.json", - "3LBqAkoUaOrYcpfoMo2FCqzt9vK.json", - "3LBqehpRQHGFC6hD0t1tYbKjBAO.json", - "3LBpMqAuVndlJG2KRDjQN4Bv2WV.json", - "3LBrf9R97F4LvQJXKdxaKYDuLKM.json" + "3L5pkkPHrqIIhRQweIZni3Jx7aO.json", + "3L5pK0YguKIvCY56IGYC68ubcnZ.json", + "3L5r7HrLBpJw06Kn9XvmCJKAk2I.json", + "3L5qPyNpntYIVqHv5kttg7ouTyb.json", + "3L5orAUkQaLbM91Eomq4Lp41E2I.json", + "3L5or8L4X8hDTrlB8fFYvDl14Nr.json", + "3L5p97SK55GLiCOyNWcQ0KPPYny.json", + "3L5pYfbQZQq7z6GuC4x4NEro8nt.json", + "3L5pYgQhfn9F1YfZWcZs3m75wLJ.json", + "3L5if5AHrl7wQgsMo3ih11gEmqi.json", + "3L5hSfDHmwBh5GMQNMGeg3mgpBD.json", + "3L5jEVrlkZ9AUR9obG1RxghGaNO.json", + "3L5jKNwhp3zxrgEkAdOEMu7HJiz.json", + "3L5ix9jJ5LfgjPDCVM23vrGANPf.json", + "3L5hYzIHzYbTnqZthz4E8Acoey6.json", + "3L5iwScsRQslaZqoufX9q49Ca1Y.json", + "3L5kHHjXj3jd2ikEXJkYAr2qoNg.json", + "3L5iMqqYvLtphnuVU2790j4BcOs.json", + "3L5aYyVM6hDZDXM2wUgLAzVn1lK.json", + "3L5b8ackq0B6vLxB1gJvGHvPwm5.json", + "3L5cwiNtOq0V3rj8Y3t0cpp099W.json", + "3L5a8o5LwuAyjA4N4ZHocot55Y2.json", + "3L5bCbVihHlFDbW27FNwV44BRAx.json", + "3L5dT9aCViSVhEDNf1glxKoUaPK.json", + "3L5aFXABy8dYjmenqLEja1JVybr.json", + "3L5dJx1cAfph7mWxor3zJT2UYI1.json", + "3L5bG4aQQV63WVrO3IpmJSur08r.json", + "3L5V0fYBXrPNFbEUIfP6XZ35QDi.json", + "3L5VJjjOdLIiHZSNqsrkIyYU9xA.json", + "3L5TjnxBup2JEvkC531UdO5iWTj.json", + "3L5VB2bblXMBlcCEImC68dliybU.json", + "3L5WEzoPTRwkpRiFoQ32OVzqO1V.json", + "3L5TzKPzELsixHpzSjlTIHpoU6f.json", + "3L5V6en0ePK8VGrYZov45WkLSaL.json", + "3L5U2MRXW2XALPTb0VzKo6dNFJg.json", + "3L5W57i8V6y1S6QzwcVd0yPwR0G.json", + "3L5NBqXWi7RH6wc1MHy717jo4b0.json", + "3L5P0U39kjIKstpb6wjyOjtmH5I.json", + "3L5ND5kM4oQJOYTfUJpDjFQKWsx.json", + "3L5NPoU7qJwhN7znV0srql9bw4Q.json", + "3L5NAdhsrWpMHqrza9YUkmWhbPd.json", + "3L5PSHkSEL8Qg8Njjjsdw2pz0hN.json", + "3L5NuylkQZ95nfitetQsSE4hvkk.json", + "3L5PkJwVZ43AQr28FfYYXyszhwu.json", + "3L5NeKyqy7O5jwElRRKlNYSJQv5.json", + "3L5FxoGDDW0aAns2yrHnVBLzzHa.json", + "3L5GofvOX3G4fWKovi2RjHNWRaB.json", + "3L5F4WWgME9vI6HK7iu0GBEJ0U9.json", + "3L5GDreVG7PT584aKMhIoEKLJFY.json", + "3L5FFQAu9qmm3VTgQbMZlSVvMY9.json", + "3L5HUQ5lfq5ym4mVY13SNNnFZ74.json", + "3L5Fd18OtpYfA89sDRpunV8qEgS.json", + "3L5ExCnfNxu0b2zJMAlU1NcsUqE.json", + "3L5GFbyUvTxjQxh2EUvxBQMxhbp.json", + "3L58EQzDDayMHI3g6DkmeodxKy9.json", + "3L57uQhzTpHqcPBN54RDFEET4Uz.json", + "3L59kg4N8hqgKoxz9cma89rnsGs.json", + "3L58xrCgLhQ3w6qiwBcLJsL4Gvc.json", + "3L57ykdu32hsG0CEyrpXurC33qg.json", + "3L5AHpdhkBPonHmH3q7y1nRYPZf.json", + "3L58JpBeQnSkG3glDgcCgs1Xgdd.json", + "3L59O1y0GZpYg2ai5VcbUHzqtVI.json", + "3L57nHTeD92ORte7cpJ1OIMS1rD.json", + "3L51mYL41RY1q8Er1eXMCmPjT7Z.json", + "3L52WQJ80eyu4PyyCTF9xfXd151.json", + "3L50glJH53t1JTZIQkxQFF0QpGB.json", + "3L51gYDjx9oKOgRqr3VI7MNogrX.json", + "3L52xWsBkNA851yAh8q1iograbK.json", + "3L50i4R33lk0o6XZ82F7WzPeQt1.json", + "3L51qEQLz6BJ1d9zlYXzqvlpo0O.json", + "3L50ngZJEiGlvN8YX4FuuAENKoF.json", + "3L52nHJeQYh3sAmrzVfKtD1vZqj.json" ], "runs": [ - "40272142430", - "40266979145", - "40262173089", - "40257470166", - "40242835329", - "40238189261", - "40233481335", - "40228747755", - "40223991179", - "40219252911", - "40214410982", - "40209651657", - "40204927516", - "40200279306" + "39943147947", + "39936055900", + "39928834751", + "39921744055", + "39915751898", + "39909025131", + "39903431405", + "39898100438" ], "mergeRule": "median across runs; a file-sharded package is summed from its slices WITHIN one run first, and a run that cannot assemble every slice contributes no sample for it; a package not measured in this pass keeps its previous weight ONLY when a turbo cache HIT witnesses that its inputs are unchanged, and every such package is named in `carriedOver`", - "refresh": "node scripts/measure-test-shard-timings.mjs [--run ] ... --merge-into scripts/test-shard-timings.json --out scripts/test-shard-timings.json (summaries: the `test-core-run-summary--of-` artifacts of any green run, or a local `pnpm exec turbo run test --concurrency=4 --summarize`. ⚠ ONE RUN COVERS ONLY 2-52 of ~71 packages depending on cache warmth, so feed SEVERAL runs -- a `--run ` before each run's summaries is REQUIRED, so a sliced package is assembled per run and then medianed like every other package -- and `--merge-into` to carry the cache-hit remainder. A package measured by fewer than `minimumRuns` executed runs is named in `provisional`, so feed runs until that list is empty. `.github/workflows/shard-timings-refresh.yml` does all of this weekly.)", + "refresh": "node scripts/measure-test-shard-timings.mjs [--run ] ... --merge-into scripts/test-shard-timings.json --out scripts/test-shard-timings.json (summaries: the `test-core-run-summary--of-6` artifacts of any green run, or a local `pnpm exec turbo run test --concurrency=4 --summarize`. ⚠ ONE RUN COVERS ONLY 2-52 of ~71 packages depending on cache warmth, so feed SEVERAL runs -- a `--run ` before each run's summaries is REQUIRED, so a sliced package is assembled per run and then medianed like every other package -- and `--merge-into` to carry the cache-hit remainder. A package measured by fewer than `minimumRuns` executed runs is named in `provisional`, so feed runs until that list is empty. `.github/workflows/shard-timings-refresh.yml` does all of this weekly.)", "minimumRuns": 3, "ceilingHeadroom": 1.25 }, - "secondsPerTestFileFallback": 2.114, + "secondsPerTestFileFallback": 3.244, "packages": { - "@objectstack/cli": 2697.45, - "@objectstack/client": 81.49, - "@objectstack/client-react": 8.1, - "@objectstack/cloud-connection": 115.93, - "@objectstack/connector-imap": 3.55, - "@objectstack/connector-mcp": 29.9, - "@objectstack/connector-openapi": 24.54, - "@objectstack/connector-rest": 28.39, - "@objectstack/connector-slack": 23.67, - "@objectstack/core": 103.58, - "@objectstack/downstream-contract": 6.8, - "@objectstack/driver-memory": 103.22, - "@objectstack/driver-mongodb": 54.92, - "@objectstack/driver-sql": 241.07, - "@objectstack/driver-sqlite-wasm": 63.75, - "@objectstack/driver-turso": 129.29, - "@objectstack/embedder-openai": 5.22, - "@objectstack/example-crm": 23.11, - "@objectstack/example-embed-objectql": 7.86, - "@objectstack/example-showcase": 48.49, - "@objectstack/example-todo": 27.48, - "@objectstack/formula": 39.47, - "@objectstack/hono": 30.38, - "@objectstack/http-conformance": 155.47, - "@objectstack/knowledge-memory": 2.57, - "@objectstack/knowledge-ragflow": 4.29, - "@objectstack/lint": 141.56, - "@objectstack/mcp": 68.77, - "@objectstack/metadata": 142.75, - "@objectstack/metadata-core": 15.7, - "@objectstack/metadata-fs": 21.58, - "@objectstack/metadata-protocol": 670.12, - "@objectstack/objectql": 450.03, - "@objectstack/observability": 3.06, - "@objectstack/organizations": 99.66, - "@objectstack/platform-objects": 80.46, - "@objectstack/plugin-approvals": 254.27, - "@objectstack/plugin-audit": 255.86, - "@objectstack/plugin-auth": 283.83, - "@objectstack/plugin-dev": 48.97, - "@objectstack/plugin-email": 77.36, - "@objectstack/plugin-hono-server": 68.19, - "@objectstack/plugin-pinyin-search": 53.27, - "@objectstack/plugin-security": 245.56, - "@objectstack/plugin-sharing": 150.16, - "@objectstack/plugin-webhooks": 49.65, - "@objectstack/rest": 569.96, - "@objectstack/runtime": 793.7, - "@objectstack/sdui-parser": 3.68, - "@objectstack/service-analytics": 406.18, - "@objectstack/service-automation": 522.93, - "@objectstack/service-cache": 2.22, - "@objectstack/service-cluster": 11.41, - "@objectstack/service-cluster-redis": 12.79, - "@objectstack/service-datasource": 90.24, - "@objectstack/service-i18n": 7.81, - "@objectstack/service-job": 14.25, - "@objectstack/service-knowledge": 34.06, - "@objectstack/service-mailbox": 67.92, - "@objectstack/service-messaging": 120.65, - "@objectstack/service-package": 32.97, - "@objectstack/service-print": 29.92, - "@objectstack/service-queue": 33.57, - "@objectstack/service-realtime": 8.09, - "@objectstack/service-settings": 147.44, - "@objectstack/service-sms": 8.95, - "@objectstack/service-storage": 150.72, - "@objectstack/spec": 1168.98, - "@objectstack/trigger-api": 10.92, - "@objectstack/trigger-record-change": 56.43, - "@objectstack/trigger-schedule": 33.51, - "@objectstack/types": 19.54, - "@objectstack/verify": 376.32, - "@objectstack/vitest-filter-preflight": 13.41, - "create-objectstack": 13.77 + "@objectstack/cli": 2899.02, + "@objectstack/client": 147.21, + "@objectstack/client-react": 12.44, + "@objectstack/cloud-connection": 268.04, + "@objectstack/connector-imap": 3.67, + "@objectstack/connector-mcp": 43.15, + "@objectstack/connector-openapi": 33.96, + "@objectstack/connector-rest": 34.78, + "@objectstack/connector-slack": 34.99, + "@objectstack/core": 164.54, + "@objectstack/downstream-contract": 16.85, + "@objectstack/driver-memory": 141.51, + "@objectstack/driver-mongodb": 100, + "@objectstack/driver-sql": 384.28, + "@objectstack/driver-sqlite-wasm": 85.63, + "@objectstack/driver-turso": 189.07, + "@objectstack/embedder-openai": 5.56, + "@objectstack/example-crm": 41.32, + "@objectstack/example-embed-objectql": 28.22, + "@objectstack/example-showcase": 130.48, + "@objectstack/example-todo": 58.58, + "@objectstack/formula": 39.65, + "@objectstack/hono": 41.55, + "@objectstack/http-conformance": 125.37, + "@objectstack/knowledge-memory": 3.94, + "@objectstack/knowledge-ragflow": 4.23, + "@objectstack/lint": 200.52, + "@objectstack/mcp": 112.36, + "@objectstack/metadata": 119.96, + "@objectstack/metadata-core": 25.61, + "@objectstack/metadata-fs": 37.42, + "@objectstack/metadata-protocol": 629.62, + "@objectstack/objectql": 970.12, + "@objectstack/observability": 2.89, + "@objectstack/organizations": 73.2, + "@objectstack/platform-objects": 123.56, + "@objectstack/plugin-approvals": 360.06, + "@objectstack/plugin-audit": 249.24, + "@objectstack/plugin-auth": 405.25, + "@objectstack/plugin-dev": 50.78, + "@objectstack/plugin-email": 119.76, + "@objectstack/plugin-hono-server": 77.51, + "@objectstack/plugin-pinyin-search": 37.94, + "@objectstack/plugin-security": 360.02, + "@objectstack/plugin-sharing": 209.26, + "@objectstack/plugin-webhooks": 94.12, + "@objectstack/rest": 876.56, + "@objectstack/runtime": 848.96, + "@objectstack/sdui-parser": 4.23, + "@objectstack/service-analytics": 412.58, + "@objectstack/service-automation": 450.63, + "@objectstack/service-cache": 1.64, + "@objectstack/service-cluster": 21.59, + "@objectstack/service-cluster-redis": 22.41, + "@objectstack/service-datasource": 128.92, + "@objectstack/service-i18n": 17.69, + "@objectstack/service-job": 31.65, + "@objectstack/service-knowledge": 28.49, + "@objectstack/service-mailbox": 57.26, + "@objectstack/service-messaging": 158.74, + "@objectstack/service-package": 51.92, + "@objectstack/service-print": 32.82, + "@objectstack/service-queue": 36.08, + "@objectstack/service-realtime": 9.31, + "@objectstack/service-settings": 149.93, + "@objectstack/service-sms": 22.13, + "@objectstack/service-storage": 223.46, + "@objectstack/spec": 1606.55, + "@objectstack/trigger-api": 14.65, + "@objectstack/trigger-record-change": 81.69, + "@objectstack/trigger-schedule": 43.22, + "@objectstack/types": 23.67, + "@objectstack/verify": 220.52, + "@objectstack/vitest-filter-preflight": 28.34, + "create-objectstack": 26.36 }, "skippedAsCached": [ "@objectstack/cli", - "@objectstack/client", - "@objectstack/client-react", "@objectstack/cloud-connection", "@objectstack/connector-mcp", - "@objectstack/connector-openapi", "@objectstack/connector-rest", - "@objectstack/connector-slack", "@objectstack/core", "@objectstack/downstream-contract", - "@objectstack/driver-memory", - "@objectstack/driver-mongodb", - "@objectstack/driver-sql", "@objectstack/driver-sqlite-wasm", "@objectstack/driver-turso", - "@objectstack/embedder-openai", "@objectstack/example-crm", "@objectstack/example-embed-objectql", - "@objectstack/example-showcase", - "@objectstack/example-todo", "@objectstack/formula", - "@objectstack/hono", "@objectstack/http-conformance", - "@objectstack/knowledge-memory", "@objectstack/knowledge-ragflow", "@objectstack/lint", "@objectstack/mcp", "@objectstack/metadata", + "@objectstack/metadata-core", "@objectstack/metadata-fs", "@objectstack/metadata-protocol", "@objectstack/objectql", @@ -294,7 +195,6 @@ "@objectstack/platform-objects", "@objectstack/plugin-approvals", "@objectstack/plugin-audit", - "@objectstack/plugin-auth", "@objectstack/plugin-dev", "@objectstack/plugin-email", "@objectstack/plugin-hono-server", @@ -304,45 +204,31 @@ "@objectstack/plugin-webhooks", "@objectstack/rest", "@objectstack/runtime", - "@objectstack/sdui-parser", "@objectstack/service-analytics", "@objectstack/service-automation", "@objectstack/service-cache", - "@objectstack/service-datasource", - "@objectstack/service-i18n", + "@objectstack/service-cluster-redis", "@objectstack/service-job", "@objectstack/service-knowledge", "@objectstack/service-mailbox", "@objectstack/service-messaging", "@objectstack/service-package", - "@objectstack/service-print", - "@objectstack/service-queue", - "@objectstack/service-realtime", "@objectstack/service-settings", + "@objectstack/service-sms", "@objectstack/service-storage", "@objectstack/spec", "@objectstack/trigger-api", "@objectstack/trigger-record-change", "@objectstack/trigger-schedule", - "@objectstack/verify", - "@objectstack/vitest-filter-preflight" + "@objectstack/types", + "@objectstack/vitest-filter-preflight", + "create-objectstack" ], "skippedIncompleteSlices": [ - "@objectstack/cli in run 40209651657 (missing 1/3, 2/3)", - "@objectstack/cli in run 40214410982 (missing 1/3, 2/3)", - "@objectstack/cli in run 40266979145 (missing 2/3, 3/3)" + "@objectstack/cli in run 39943147947 (missing 2/3, 3/3)" ], "carriedOver": [], - "provisional": [ - "@objectstack/metadata-protocol", - "@objectstack/plugin-audit", - "@objectstack/plugin-sharing", - "@objectstack/rest", - "@objectstack/runtime", - "@objectstack/service-analytics", - "@objectstack/service-automation", - "@objectstack/verify" - ], + "provisional": [], "ceilings": { "@objectstack/cli": 2868.12, "@objectstack/client": 179.74, @@ -424,138 +310,114 @@ "density": { "runs": [ { - "run": "40272142430", - "executed": 20 + "run": "39943147947", + "executed": 49 }, { - "run": "40266979145", - "executed": 59 + "run": "39936055900", + "executed": 54 }, { - "run": "40262173089", - "executed": 58 + "run": "39928834751", + "executed": 43 }, { - "run": "40257470166", - "executed": 58 - }, - { - "run": "40242835329", - "executed": 32 - }, - { - "run": "40238189261", - "executed": 33 - }, - { - "run": "40233481335", - "executed": 29 - }, - { - "run": "40228747755", - "executed": 20 - }, - { - "run": "40223991179", - "executed": 20 - }, - { - "run": "40219252911", - "executed": 20 + "run": "39921744055", + "executed": 75 }, { - "run": "40214410982", - "executed": 40 + "run": "39915751898", + "executed": 69 }, { - "run": "40209651657", - "executed": 40 + "run": "39909025131", + "executed": 70 }, { - "run": "40204927516", + "run": "39903431405", "executed": 75 }, { - "run": "40200279306", - "executed": 73 + "run": "39898100438", + "executed": 72 } ], "shares": { - "@objectstack/cli": 0.2175, - "@objectstack/client": 0.01878, - "@objectstack/client-react": 0.002868, - "@objectstack/cloud-connection": 0.03284, - "@objectstack/connector-imap": 0.001097, - "@objectstack/connector-mcp": 0.007916, - "@objectstack/connector-openapi": 0.004374, - "@objectstack/connector-rest": 0.006797, - "@objectstack/connector-slack": 0.003776, - "@objectstack/core": 0.017, - "@objectstack/downstream-contract": 0.003234, - "@objectstack/driver-memory": 0.01712, - "@objectstack/driver-mongodb": 0.01244, - "@objectstack/driver-sql": 0.02573, - "@objectstack/driver-sqlite-wasm": 0.0106, - "@objectstack/driver-turso": 0.02147, - "@objectstack/embedder-openai": 0.001983, - "@objectstack/example-crm": 0.004883, - "@objectstack/example-embed-objectql": 0.003669, - "@objectstack/example-showcase": 0.01117, - "@objectstack/example-todo": 0.004618, - "@objectstack/formula": 0.01122, - "@objectstack/hono": 0.004841, - "@objectstack/http-conformance": 0.01206, - "@objectstack/knowledge-memory": 0.000795, - "@objectstack/knowledge-ragflow": 0.001635, - "@objectstack/lint": 0.0241, - "@objectstack/mcp": 0.011, - "@objectstack/metadata": 0.03279, - "@objectstack/metadata-core": 0.00486, - "@objectstack/metadata-fs": 0.003597, - "@objectstack/metadata-protocol": 0.05121, - "@objectstack/objectql": 0.1187, - "@objectstack/observability": 0.001056, - "@objectstack/organizations": 0.01782, - "@objectstack/platform-objects": 0.01368, - "@objectstack/plugin-approvals": 0.01971, - "@objectstack/plugin-audit": 0.01955, - "@objectstack/plugin-auth": 0.04246, - "@objectstack/plugin-dev": 0.008368, - "@objectstack/plugin-email": 0.02333, - "@objectstack/plugin-hono-server": 0.01322, - "@objectstack/plugin-pinyin-search": 0.009586, - "@objectstack/plugin-security": 0.04182, - "@objectstack/plugin-sharing": 0.01147, - "@objectstack/plugin-webhooks": 0.007615, - "@objectstack/rest": 0.04352, - "@objectstack/runtime": 0.06059, - "@objectstack/sdui-parser": 0.001406, - "@objectstack/service-analytics": 0.03101, - "@objectstack/service-automation": 0.03996, - "@objectstack/service-cache": 0.0006902, - "@objectstack/service-cluster": 0.003502, - "@objectstack/service-cluster-redis": 0.003888, - "@objectstack/service-datasource": 0.01368, - "@objectstack/service-i18n": 0.002411, - "@objectstack/service-job": 0.003756, - "@objectstack/service-knowledge": 0.005797, - "@objectstack/service-mailbox": 0.01569, - "@objectstack/service-messaging": 0.01734, - "@objectstack/service-package": 0.005475, - "@objectstack/service-print": 0.006634, - "@objectstack/service-queue": 0.006008, - "@objectstack/service-realtime": 0.002314, - "@objectstack/service-settings": 0.04004, - "@objectstack/service-sms": 0.003692, - "@objectstack/service-storage": 0.03974, - "@objectstack/spec": 0.2647, - "@objectstack/trigger-api": 0.00402, - "@objectstack/trigger-record-change": 0.009983, - "@objectstack/trigger-schedule": 0.007522, - "@objectstack/types": 0.005565, - "@objectstack/verify": 0.02873, - "@objectstack/vitest-filter-preflight": 0.005587, - "create-objectstack": 0.005706 + "@objectstack/cli": 0.2164, + "@objectstack/client": 0.01174, + "@objectstack/client-react": 0.0009241, + "@objectstack/cloud-connection": 0.01921, + "@objectstack/connector-imap": 0.0002767, + "@objectstack/connector-mcp": 0.002915, + "@objectstack/connector-openapi": 0.0026, + "@objectstack/connector-rest": 0.002878, + "@objectstack/connector-slack": 0.002672, + "@objectstack/core": 0.01031, + "@objectstack/downstream-contract": 0.001177, + "@objectstack/driver-memory": 0.01114, + "@objectstack/driver-mongodb": 0.007783, + "@objectstack/driver-sql": 0.03059, + "@objectstack/driver-sqlite-wasm": 0.007015, + "@objectstack/driver-turso": 0.01846, + "@objectstack/embedder-openai": 0.0004014, + "@objectstack/example-crm": 0.003057, + "@objectstack/example-embed-objectql": 0.002133, + "@objectstack/example-showcase": 0.01, + "@objectstack/example-todo": 0.004714, + "@objectstack/formula": 0.003693, + "@objectstack/hono": 0.003341, + "@objectstack/http-conformance": 0.0101, + "@objectstack/knowledge-memory": 0.0003478, + "@objectstack/knowledge-ragflow": 0.000354, + "@objectstack/lint": 0.01451, + "@objectstack/mcp": 0.008144, + "@objectstack/metadata": 0.01135, + "@objectstack/metadata-core": 0.001921, + "@objectstack/metadata-fs": 0.003133, + "@objectstack/metadata-protocol": 0.05059, + "@objectstack/objectql": 0.07109, + "@objectstack/observability": 0.0002716, + "@objectstack/organizations": 0.00686, + "@objectstack/platform-objects": 0.009257, + "@objectstack/plugin-approvals": 0.02386, + "@objectstack/plugin-audit": 0.01921, + "@objectstack/plugin-auth": 0.03314, + "@objectstack/plugin-dev": 0.00361, + "@objectstack/plugin-email": 0.009403, + "@objectstack/plugin-hono-server": 0.005618, + "@objectstack/plugin-pinyin-search": 0.002891, + "@objectstack/plugin-security": 0.03053, + "@objectstack/plugin-sharing": 0.01499, + "@objectstack/plugin-webhooks": 0.006986, + "@objectstack/rest": 0.06441, + "@objectstack/runtime": 0.06859, + "@objectstack/sdui-parser": 0.0003479, + "@objectstack/service-analytics": 0.03143, + "@objectstack/service-automation": 0.04294, + "@objectstack/service-cache": 0.000132, + "@objectstack/service-cluster": 0.001845, + "@objectstack/service-cluster-redis": 0.00155, + "@objectstack/service-datasource": 0.009756, + "@objectstack/service-i18n": 0.001535, + "@objectstack/service-job": 0.002369, + "@objectstack/service-knowledge": 0.002017, + "@objectstack/service-mailbox": 0.004452, + "@objectstack/service-messaging": 0.01318, + "@objectstack/service-package": 0.004403, + "@objectstack/service-print": 0.002653, + "@objectstack/service-queue": 0.003507, + "@objectstack/service-realtime": 0.00076, + "@objectstack/service-settings": 0.01091, + "@objectstack/service-sms": 0.001988, + "@objectstack/service-storage": 0.01645, + "@objectstack/spec": 0.09904, + "@objectstack/trigger-api": 0.001217, + "@objectstack/trigger-record-change": 0.006333, + "@objectstack/trigger-schedule": 0.003499, + "@objectstack/types": 0.001908, + "@objectstack/verify": 0.01721, + "@objectstack/vitest-filter-preflight": 0.00254, + "create-objectstack": 0.001995 } } }