kaloko 0.21.3 → 0.21.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kaloko",
3
- "version": "0.21.3",
3
+ "version": "0.21.4",
4
4
  "description": "Your AI agents build; Kaloko walks every screen, puts it on one canvas and records who approved what.",
5
5
  "keywords": [
6
6
  "qa",
package/src/cli.mjs CHANGED
@@ -33,7 +33,7 @@ import { detectProject, initScenario, skeletonScenario, scenarioHeader, formatDe
33
33
  import { checkSlug, checkName, setConfigKeys, createProject, renameProject, syncProject, shareProjectNote } from './lib/projects-cli.mjs'
34
34
  import { recheckCaptures } from './lib/recheck.mjs'
35
35
  import { runFindings, findingsText } from './lib/findings.mjs'
36
- import { resolveItems, fieldsOf, DEFAULT_LIMIT, timeLeft, rotationState, rotationCoverage, sourceLocaleOf, stackReader, readsOutside } from './lib/stack.mjs'
36
+ import { resolveItems, fieldsOf, DEFAULT_LIMIT, timeLeft, rotationState, rotationCoverage, rotationDate, sourceLocaleOf, stackReader, readsOutside } from './lib/stack.mjs'
37
37
  import { walkSiteChecks, siteChecksOn } from './lib/site.mjs'
38
38
  import { DEFAULTS as JEV_DEFAULTS } from './lib/jev.mjs'
39
39
  import { expandPacks } from './lib/packs.mjs'
@@ -823,7 +823,7 @@ async function walkStack ({ node, locale, page, env, run, scenario, scenarioDir,
823
823
  // gate and the walk's cookies on its own origins only
824
824
  const reader = readsOutside(node.items) ? await stackReader({ page, gate, origins: envOrigins(env, scenario, locale) }) : null
825
825
  let resolved
826
- try { resolved = await resolveItems({ node, base: baseUrl(env, locale), sourceBase: baseUrl(env, sourceLocale), page, scenarioDir, env, locale, scenario, limit: Number(args.limit) || undefined, rotation: { run: round }, checked: state?.checked || null, only: list(args.items), cache, readPage: reader?.read || null }) } finally { await reader?.dispose() }
826
+ try { resolved = await resolveItems({ node, base: baseUrl(env, locale), sourceBase: baseUrl(env, sourceLocale), page, scenarioDir, env, locale, scenario, limit: Number(args.limit) || undefined, rotation: { run: round, now: rotationDate(run.meta.started_at) }, checked: state?.checked || null, only: list(args.items), cache, readPage: reader?.read || null }) } finally { await reader?.dispose() }
827
827
  const { items, total, truncated, all, rotation, partial, variants, resolve_failed: unresolved, resolve_error: unresolvedWhy } = resolved
828
828
  if (unresolved) say(`! ${node.id} ${locale}${tag}: items.resolve failed for ${unresolved} page(s), walked without an edit link (${unresolvedWhy})`)
829
829
  if (variants) {
@@ -102,6 +102,15 @@ export function isoWeek (date = new Date()) {
102
102
  return { year, week, label: `${year}-W${String(week).padStart(2, '0')}`, index: Math.floor((monday - Date.UTC(1970, 0, 5)) / (7 * 86400000)) }
103
103
  }
104
104
 
105
+ /**
106
+ * The date that picks the window of `rotate: week`: the start of the run, so every locale and step of one run walks
107
+ * the same week even when the walk crosses midnight into a new week (a run started on Sunday night). Falls back to now.
108
+ */
109
+ export function rotationDate (startedAt) {
110
+ const d = startedAt ? new Date(startedAt) : null
111
+ return d && !Number.isNaN(d.getTime()) ? d : new Date()
112
+ }
113
+
105
114
  /**
106
115
  * The window of a rotating sample: `limit` entries of `list` starting at (round × limit) mod length, wrapping around,
107
116
  * so consecutive rounds cover the whole list in ceil(length / limit) rounds. Returns { slice, offset }.
package/src/lib/stack.mjs CHANGED
@@ -9,7 +9,7 @@ import { gunzipSync } from 'node:zlib'
9
9
  import { UserError, localized, readJson, writeJson } from './util.mjs'
10
10
  import { STACK_DEFAULT_FIELDS, STACK_SEMANTIC_SAMPLE, stackFieldsOf } from './manifest-core.mjs'
11
11
  import { variantItems, sitemapAlternates, pageAlternates, readHeadFrom } from './variants-core.mjs'
12
- import { DEFAULT_LIMIT, SITEMAP_MAX_BYTES, SITEMAP_MAX_CHILDREN, ROTATE_MODES, itemId, sitemapLocs, robotsSitemaps, sitemapsForLocale, handoffOf, isoWeek, rotateWindow, patternFor as corePatternFor, withLocale, sitemapPages, selectItems } from './stack-core.mjs'
12
+ import { DEFAULT_LIMIT, SITEMAP_MAX_BYTES, SITEMAP_MAX_CHILDREN, ROTATE_MODES, itemId, sitemapLocs, robotsSitemaps, sitemapsForLocale, handoffOf, isoWeek, rotateWindow, rotationDate, patternFor as corePatternFor, withLocale, sitemapPages, selectItems } from './stack-core.mjs'
13
13
 
14
14
  /** How long items.resolve may take for one page (ms) before the page is walked without its edit link. */
15
15
  export const RESOLVE_TIMEOUT = 15000
@@ -18,7 +18,7 @@ export const DEFAULT_SEMANTIC_SAMPLE = STACK_SEMANTIC_SAMPLE
18
18
  export const DEFAULT_FIELDS = STACK_DEFAULT_FIELDS
19
19
  export const fieldsOf = stackFieldsOf
20
20
  // sources, filters and the rotating window are pure (stack-core.mjs): hosted runs on the service pick the same pages
21
- export { DEFAULT_LIMIT, SITEMAP_MAX_BYTES, SITEMAP_MAX_CHILDREN, ROTATE_MODES, itemId, sitemapLocs, robotsSitemaps, sitemapsForLocale, handoffOf, isoWeek, rotateWindow }
21
+ export { DEFAULT_LIMIT, SITEMAP_MAX_BYTES, SITEMAP_MAX_CHILDREN, ROTATE_MODES, itemId, sitemapLocs, robotsSitemaps, sitemapsForLocale, handoffOf, isoWeek, rotateWindow, rotationDate }
22
22
 
23
23
  /** The text of a sitemap body: gzip (a .gz URL or the magic bytes 1f 8b) is unpacked, anything else read as UTF-8. */
24
24
  export function sitemapText (bytes, url = '') {