youiyoux 0.1.20 → 0.1.21

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.
@@ -3,7 +3,7 @@ import { createRequire as __youiRequire } from "node:module"; import { dirname a
3
3
  // src/hub-packages.js
4
4
  var PACKAGES = {
5
5
  core: () => import("./src-AXF5XUQE.js"),
6
- scanner: () => import("./src-CCB3D7EM.js"),
6
+ scanner: () => import("./src-DUBN6O7T.js"),
7
7
  discover: () => import("./src-ULAQV67E.js"),
8
8
  tokens: () => import("./src-HBKEBCH6.js")
9
9
  };
@@ -9,7 +9,7 @@ import {
9
9
  scanProject,
10
10
  screenSlug,
11
11
  tokenImpact
12
- } from "./chunk-3SXAQHHJ.js";
12
+ } from "./chunk-RQUTV7SO.js";
13
13
  import {
14
14
  buildTokens,
15
15
  contrastText,
@@ -9,7 +9,7 @@ import {
9
9
  startRuleEditor,
10
10
  style,
11
11
  truncate
12
- } from "./chunk-YQS2VF65.js";
12
+ } from "./chunk-ZXINIRJ5.js";
13
13
  import {
14
14
  BASELINE_FILE,
15
15
  DEFAULT_EXCLUDE,
@@ -64,7 +64,7 @@ import {
64
64
  vendoredPath,
65
65
  whereUsed,
66
66
  withFile
67
- } from "./chunk-3SXAQHHJ.js";
67
+ } from "./chunk-RQUTV7SO.js";
68
68
  import {
69
69
  escapingLinks,
70
70
  within
@@ -1736,7 +1736,7 @@ function renderDiffText(result) {
1736
1736
  lines.push("");
1737
1737
  if (diff.findings.length > 0) lines.push(style.error(`\u2716 ${plural(diff.findings.length, "finding")} in this change: apply each fix (\u2192), then run \`youiyoux check --diff\` again`));
1738
1738
  else if (gaps.length > 0) lines.push(style.warn("! Not a pass: parts of this change could not be checked (above). Fix what could not be read, then run `youiyoux check --diff` again"));
1739
- else if (diff.files.length === 0) lines.push(style.ok(`\u2713 No checked files changed against ${diff.base}: nothing to check. Compare with a branch: youiyoux check --diff main`));
1739
+ else if (diff.files.length === 0) lines.push(style.ok(`\u2713 No checked files changed against ${diff.base}: nothing to check${diff.base === "HEAD" ? ". Compare with a branch: youiyoux check --diff main" : ""}`));
1740
1740
  else lines.push(style.ok(`\u2713 No drift in this change: ${plural(diff.files.length, "file")} checked against ${diff.base}. Nothing to fix`));
1741
1741
  return lines.join("\n");
1742
1742
  }
@@ -1754,9 +1754,10 @@ function diffJson(result) {
1754
1754
  identity: result.identity
1755
1755
  };
1756
1756
  }
1757
- function githubDiffAnnotations(result, prefix) {
1758
- const lines = (result.diff?.findings ?? []).map((f) => command(f.severity === "error" ? "error" : "warning", `${f.message} Fix: ${f.fix}`, { file: `${prefix}${f.file}`, line: f.line, col: f.column, title: `youi ${kindOf(f)}` }));
1759
- for (const gap of diffGaps(result)) lines.push(command("error", `${gap}; a clean result here is not a pass`, { title: "youi incomplete" }));
1757
+ function githubDiffAnnotations(result, prefix, strict) {
1758
+ const level = (severity) => strict && severity === "error" ? "error" : "warning";
1759
+ const lines = (result.diff?.findings ?? []).map((f) => command(level(f.severity), `${f.message} Fix: ${f.fix}`, { file: `${prefix}${f.file}`, line: f.line, col: f.column, title: `youi ${kindOf(f)}` }));
1760
+ for (const gap of diffGaps(result)) lines.push(command(level("error"), `${gap}; a clean result here is not a pass`, { title: "youi incomplete" }));
1760
1761
  return lines;
1761
1762
  }
1762
1763
  function githubDiffSummary(result) {
@@ -3416,7 +3417,7 @@ async function projectStatus(project2, cwd = process.cwd()) {
3416
3417
  const comparison = check.baseline?.comparison;
3417
3418
  const counted = comparison ? [...comparison.new, ...comparison.regressed] : check.violations;
3418
3419
  const usages = check.scan.report.usages;
3419
- const { RequestStore } = await import("./src-LESGEHOC.js");
3420
+ const { RequestStore } = await import("./src-LP3MFGA4.js");
3420
3421
  const requests = await new RequestStore(project2.root, project2.config.id).list();
3421
3422
  const status = {
3422
3423
  id: project2.config.id,
@@ -5983,7 +5984,7 @@ async function cmdCheckDiff(values, positionals, p, format) {
5983
5984
  const result = configured(p) ? await runCheck(p, { ...checkScope(values, positionals), diff: change }) : await runRepoCheck(p, change);
5984
5985
  if (format === "json") json3(diffJson(result));
5985
5986
  else if (format === "github") {
5986
- for (const line of githubDiffAnnotations(result, await repoPrefix(p.root))) print(line);
5987
+ for (const line of githubDiffAnnotations(result, await repoPrefix(p.root), values.strict)) print(line);
5987
5988
  print(renderDiffText(result));
5988
5989
  if (process.env.GITHUB_STEP_SUMMARY) await appendFile2(process.env.GITHUB_STEP_SUMMARY, githubDiffSummary(result));
5989
5990
  } else print(renderDiffText(result));
@@ -6066,7 +6067,7 @@ async function cmdLibrary(values, positionals) {
6066
6067
  return 0;
6067
6068
  }
6068
6069
  if (action === "ingest" && query && positionals.length === 2) {
6069
- const { fileIngestDraft, readLink, renderIngest } = await import("./ingest-IOFHL5VG.js");
6070
+ const { fileIngestDraft, readLink, renderIngest } = await import("./ingest-4C3TRSBA.js");
6070
6071
  const p = values.draft ? await project(values) : null;
6071
6072
  const reading = await readLink(query, { allowLocal: true });
6072
6073
  const filed = p ? await fileIngestDraft(p, reading, values.state) : null;
@@ -6525,7 +6526,7 @@ async function cmdRequests(values, positionals) {
6525
6526
  const usage = "youiyoux requests [--status open|addressed|closed|all] [--route r] or youiyoux requests show <id> | reply <id> --message <text> | addressed <id> --message <what you changed>";
6526
6527
  const [action, id, ...rest] = positionals;
6527
6528
  if (rest.length > 0) throw new UsageError(usage);
6528
- const { RequestStore, requestBrief } = await import("./src-LESGEHOC.js");
6529
+ const { RequestStore, requestBrief } = await import("./src-LP3MFGA4.js");
6529
6530
  const { project: project2, root } = await product(values);
6530
6531
  const store = new RequestStore(root, project2?.config.id ?? basename5(root));
6531
6532
  const agent = { kind: "agent", name: "youiyoux CLI" };
@@ -6624,7 +6625,7 @@ async function cmdReport(values, positionals, io) {
6624
6625
  return result.code;
6625
6626
  }
6626
6627
  async function cmdMcp(values) {
6627
- const { startStdioServer } = await import("./src-Z3LZMTHC.js");
6628
+ const { startStdioServer } = await import("./src-JTMKM6KB.js");
6628
6629
  await startStdioServer({ projectRoot: values.project ?? process.cwd(), ...loadOptions(values), ...values.cache ? { discoverCache: values.cache } : {} });
6629
6630
  return -1;
6630
6631
  }
@@ -4,7 +4,7 @@ import {
4
4
  loadPackage,
5
5
  readTryIndex,
6
6
  send
7
- } from "./chunk-WBU7YJGZ.js";
7
+ } from "./chunk-55I4SXOA.js";
8
8
  import {
9
9
  writeFileAtomic
10
10
  } from "./chunk-M56633DV.js";
@@ -1799,6 +1799,35 @@ function resolveClasses(classes, tag, theme, rules) {
1799
1799
  // ../scanner/src/drift.ts
1800
1800
  var cssVar = (token, index) => `var(${[...index.byVar].find(([, t]) => t === token)?.[0] ?? cssVariable(index.prefix, token.cssName)})`;
1801
1801
  var tokenList = (tokens) => tokens.slice(0, 3).map((t) => t.id).join(" or ");
1802
+ var viewportOfWord = (word) => /^(phone|mobile|handset)$/.test(word) ? "narrow" : /^(tablet|desktop)$/.test(word) ? "wide" : null;
1803
+ var tokenViewport = (token) => token.id.split(/[.-]/).map(viewportOfWord).find((v) => v !== null) ?? null;
1804
+ function preludeViewports(preludes) {
1805
+ const found = /* @__PURE__ */ new Set();
1806
+ for (const prelude of preludes) {
1807
+ if (/^@media\b/.test(prelude) && /max-width|width\s*<=?/.test(prelude)) found.add("narrow");
1808
+ if (/^@media\b/.test(prelude) && /min-width|width\s*>=?/.test(prelude)) found.add("wide");
1809
+ for (const word of prelude.toLowerCase().match(/[a-z]+/g) ?? []) {
1810
+ const viewport = viewportOfWord(word);
1811
+ if (viewport) found.add(viewport);
1812
+ }
1813
+ }
1814
+ return found;
1815
+ }
1816
+ function variantViewports(variants) {
1817
+ const found = /* @__PURE__ */ new Set();
1818
+ for (const variant of variants) {
1819
+ const viewport = viewportOfWord(variant) ?? (/^max-/.test(variant) ? "narrow" : /^(min-|@)?(sm|md|lg|xl|[2-9]xl)$/.test(variant) ? "wide" : null);
1820
+ if (viewport) found.add(viewport);
1821
+ }
1822
+ return found;
1823
+ }
1824
+ function fitting(tokens, viewports) {
1825
+ const own = tokens.filter((t) => {
1826
+ const v = tokenViewport(t);
1827
+ return v !== null && viewports.has(v);
1828
+ });
1829
+ return [...own, ...tokens.filter((t) => tokenViewport(t) === null)];
1830
+ }
1802
1831
  function utilityBefore(lineText, column) {
1803
1832
  return /(?:^|[\s"'`:])!?(-?[a-z][a-z0-9]*(?:-[a-z][a-z0-9]*)*)-\[$/.exec(lineText.slice(0, column - 1))?.[1] ?? null;
1804
1833
  }
@@ -1829,11 +1858,12 @@ function arbitraryFindings(module, index, added) {
1829
1858
  const offset = match.index + whole.indexOf(`${utility}-[`);
1830
1859
  const at = offsetToPosition(text, offset, start);
1831
1860
  if (!added(module.file, at.line)) continue;
1832
- const tokens = arbitraryTokens(utility, value, index);
1861
+ const variants = whole.slice(0, whole.indexOf(`${utility}-[`));
1862
+ const tokens = fitting(arbitraryTokens(utility, value, index), variantViewports(variants.split(":")));
1833
1863
  if (tokens.length === 0) continue;
1834
- const utilities = tokenUtilities(utility, tokens, index);
1864
+ const utilities = tokenUtilities(utility, tokens, index).map((u) => `${variants}${u}`);
1835
1865
  const kind = /^-?rounded/.test(utility) ? "radius" : utility === "text" ? "type" : "spacing";
1836
- const fix = utilities.length > 0 ? `use ${utilities.slice(0, 2).join(" or ")} (${tokenList(tokens)}, ${cssVar(tokens[0], index)})` : `use ${utility}-[${cssVar(tokens[0], index)}] (${tokenList(tokens)})`;
1866
+ const fix = utilities.length > 0 ? `use ${utilities.slice(0, 2).join(" or ")} (${tokenList(tokens)}, ${cssVar(tokens[0], index)})` : `use ${variants}${utility}-[${cssVar(tokens[0], index)}] (${tokenList(tokens)})`;
1837
1867
  findings.push({ kind: "hardcoded-value", file: module.file, ...at, text: `${utility}-[${value}]`, message: `Hardcoded ${kind} ${utility}-[${value}]: the token ${tokenList(tokens)} has this value.`, fix });
1838
1868
  }
1839
1869
  }
@@ -1851,9 +1881,10 @@ function cssDimensionFindings(module, index, isTokenSource, added) {
1851
1881
  if (!added(module.file, declaration.line) || isTokenSource && declaration.property.startsWith("--")) continue;
1852
1882
  const kind = CSS_DIMENSIONS.find(([pattern]) => pattern.test(declaration.property))?.[1];
1853
1883
  if (!kind) continue;
1884
+ const viewports = preludeViewports(rule.preludes);
1854
1885
  const matched = [];
1855
1886
  const value = declaration.value.replace(/(^|[\s(,])(-?)(\d*\.?\d+)px\b/g, (whole, lead, sign, n) => {
1856
- const token = dimensionTokens(kind, Number(n), index)[0];
1887
+ const token = fitting(dimensionTokens(kind, Number(n), index), viewports)[0];
1857
1888
  if (!token || Number(n) === 0) return whole;
1858
1889
  matched.push(token);
1859
1890
  return `${lead}${sign ? `calc(-1 * ${cssVar(token, index)})` : cssVar(token, index)}`;
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __youiRequire } from "node:module"; import { dirname as __youiDir } from "node:path"; import { fileURLToPath as __youiPath } from "node:url"; const require = __youiRequire(import.meta.url); const __youiDirname = __youiDir(__youiPath(import.meta.url));
2
2
  import {
3
3
  loadProject
4
- } from "./chunk-3SXAQHHJ.js";
4
+ } from "./chunk-RQUTV7SO.js";
5
5
  import {
6
6
  shortHash
7
7
  } from "./chunk-M56633DV.js";
@@ -79,11 +79,11 @@ function workflowStateDir(project, state) {
79
79
  return resolve(state ?? join(homedir(), ".youi", "workflow", shortHash(`${project.repo.root}\0${project.root}`)));
80
80
  }
81
81
  async function ingest(link) {
82
- const { readLink } = await import("./ingest-IOFHL5VG.js");
82
+ const { readLink } = await import("./ingest-4C3TRSBA.js");
83
83
  return readLink(link, { allowLocal: false });
84
84
  }
85
85
  async function startRuleEditor(options) {
86
- const { FileStore, RuleWorkflow, serveWorkflow } = await import("./src-LESGEHOC.js");
86
+ const { FileStore, RuleWorkflow, serveWorkflow } = await import("./src-LP3MFGA4.js");
87
87
  const projectRoot = resolve(options.project);
88
88
  const load = { ...options.config ? { configPath: resolve(options.config) } : {}, ...options.design ? { designRoot: resolve(options.design) } : {}, ...options.root ? { productRoot: resolve(options.root) } : {} };
89
89
  const project = await loadProject(projectRoot, load);
@@ -4,8 +4,8 @@ import {
4
4
  plural,
5
5
  style,
6
6
  workflowStateDir
7
- } from "./chunk-YQS2VF65.js";
8
- import "./chunk-3SXAQHHJ.js";
7
+ } from "./chunk-ZXINIRJ5.js";
8
+ import "./chunk-RQUTV7SO.js";
9
9
  import "./chunk-42YJX3W5.js";
10
10
  import "./chunk-4BQPCZLL.js";
11
11
  import "./chunk-M56633DV.js";
@@ -23,7 +23,7 @@ async function readLink(link, options) {
23
23
  return { link: result.link, source: result.source, license: result.license, fetchedAt: result.fetchedAt, entries: result.entries, skipped: result.skipped, notes: result.notes };
24
24
  }
25
25
  async function fileIngestDraft(project, reading, state) {
26
- const { FileStore, RuleWorkflow } = await import("./src-LESGEHOC.js");
26
+ const { FileStore, RuleWorkflow } = await import("./src-LP3MFGA4.js");
27
27
  const workflow = new RuleWorkflow({ projectRoot: project.root, store: new FileStore(workflowStateDir(project, state)), ...project.configFile ? { configPath: project.configFile } : {}, ...project.designOverride ? { designRoot: project.repo.root } : {}, ...project.rootOverride ? { productRoot: project.root } : {}, ingest: async () => reading });
28
28
  const draft = await workflow.create({ kind: "person", name: userInfo().username }, { kind: "ingest", link: reading.link });
29
29
  return { id: draft.id, problems: draft.problems };
@@ -188,7 +188,7 @@ import {
188
188
  whyNoLines,
189
189
  withFile,
190
190
  withoutCredentials
191
- } from "./chunk-3SXAQHHJ.js";
191
+ } from "./chunk-RQUTV7SO.js";
192
192
  import {
193
193
  escapingLinks,
194
194
  relativeInside,
@@ -2,7 +2,7 @@ import { createRequire as __youiRequire } from "node:module"; import { dirname a
2
2
  import {
3
3
  RequestStore,
4
4
  requestBrief
5
- } from "./chunk-TI3G57PX.js";
5
+ } from "./chunk-ALD2RX3X.js";
6
6
  import {
7
7
  PROJECT_FILE,
8
8
  ScanCache,
@@ -30,7 +30,7 @@ import {
30
30
  shotsText,
31
31
  tokenRows,
32
32
  whereUsed
33
- } from "./chunk-3SXAQHHJ.js";
33
+ } from "./chunk-RQUTV7SO.js";
34
34
  import "./chunk-42YJX3W5.js";
35
35
  import {
36
36
  SHADCN_SLOTS,
@@ -64,8 +64,8 @@ import {
64
64
  validateIngestContent,
65
65
  validateLibraryContent,
66
66
  validateStyleContent
67
- } from "./chunk-TI3G57PX.js";
68
- import "./chunk-3SXAQHHJ.js";
67
+ } from "./chunk-ALD2RX3X.js";
68
+ import "./chunk-RQUTV7SO.js";
69
69
  import "./chunk-42YJX3W5.js";
70
70
  import "./chunk-4BQPCZLL.js";
71
71
  import "./chunk-M56633DV.js";
@@ -17,8 +17,8 @@ import {
17
17
  selectCandidates,
18
18
  thumbsDir,
19
19
  writeThumbIndex
20
- } from "./chunks/chunk-6UHSXSS6.js";
21
- import "./chunks/chunk-WBU7YJGZ.js";
20
+ } from "./chunks/chunk-O77MKELR.js";
21
+ import "./chunks/chunk-55I4SXOA.js";
22
22
  import "./chunks/chunk-FVVL5JCY.js";
23
23
  import "./chunks/chunk-M56633DV.js";
24
24
  import "./chunks/chunk-WNTS7ZO4.js";
@@ -2,7 +2,7 @@
2
2
  import { createRequire as __youiRequire } from "node:module"; import { dirname as __youiDir } from "node:path"; import { fileURLToPath as __youiPath } from "node:url"; const require = __youiRequire(import.meta.url); const __youiDirname = __youiDir(__youiPath(import.meta.url));
3
3
  import {
4
4
  discoverThumbsMiddleware
5
- } from "./chunks/chunk-6UHSXSS6.js";
5
+ } from "./chunks/chunk-O77MKELR.js";
6
6
  import {
7
7
  isLocalHost,
8
8
  loadPackage,
@@ -10,7 +10,7 @@ import {
10
10
  readTryIndex,
11
11
  send,
12
12
  tryMiddleware
13
- } from "./chunks/chunk-WBU7YJGZ.js";
13
+ } from "./chunks/chunk-55I4SXOA.js";
14
14
  import "./chunks/chunk-FVVL5JCY.js";
15
15
  import "./chunks/chunk-M56633DV.js";
16
16
  import "./chunks/chunk-WNTS7ZO4.js";
@@ -3,7 +3,7 @@ import { createRequire as __youiRequire } from "node:module"; import { dirname a
3
3
  import {
4
4
  loadPackage,
5
5
  tryProject
6
- } from "./chunks/chunk-WBU7YJGZ.js";
6
+ } from "./chunks/chunk-55I4SXOA.js";
7
7
  import "./chunks/chunk-FVVL5JCY.js";
8
8
  import "./chunks/chunk-WNTS7ZO4.js";
9
9
 
package/dist/youi.js CHANGED
@@ -2,9 +2,9 @@
2
2
  import { createRequire as __youiRequire } from "node:module"; import { dirname as __youiDir } from "node:path"; import { fileURLToPath as __youiPath } from "node:url"; const require = __youiRequire(import.meta.url); const __youiDirname = __youiDir(__youiPath(import.meta.url));
3
3
  import {
4
4
  main
5
- } from "./chunks/chunk-K2W23VI3.js";
6
- import "./chunks/chunk-YQS2VF65.js";
7
- import "./chunks/chunk-3SXAQHHJ.js";
5
+ } from "./chunks/chunk-FYG6USCG.js";
6
+ import "./chunks/chunk-ZXINIRJ5.js";
7
+ import "./chunks/chunk-RQUTV7SO.js";
8
8
  import "./chunks/chunk-42YJX3W5.js";
9
9
  import "./chunks/chunk-5D7PLY7A.js";
10
10
  import "./chunks/chunk-UJMXSTUF.js";
package/dist/youiyoux.js CHANGED
@@ -3,9 +3,9 @@ import { createRequire as __youiRequire } from "node:module"; import { dirname a
3
3
  import {
4
4
  COMMAND_NAMES,
5
5
  main
6
- } from "./chunks/chunk-K2W23VI3.js";
7
- import "./chunks/chunk-YQS2VF65.js";
8
- import "./chunks/chunk-3SXAQHHJ.js";
6
+ } from "./chunks/chunk-FYG6USCG.js";
7
+ import "./chunks/chunk-ZXINIRJ5.js";
8
+ import "./chunks/chunk-RQUTV7SO.js";
9
9
  import "./chunks/chunk-42YJX3W5.js";
10
10
  import "./chunks/chunk-5D7PLY7A.js";
11
11
  import "./chunks/chunk-UJMXSTUF.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "youiyoux",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "Your agent rebuilds components you already have. youiyoux catches it: npx youiyoux turns any repo into a shareable report of near-duplicate components, hardcoded token values and off-library imports, with the fixes.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -46,9 +46,9 @@
46
46
  "typescript": "6.0.3"
47
47
  },
48
48
  "devDependencies": {
49
- "@youiyoux/cli": "0.1.20",
50
- "@youiyoux/core": "0.1.20",
51
- "@youiyoux/scanner": "0.1.20"
49
+ "@youiyoux/cli": "0.1.21",
50
+ "@youiyoux/scanner": "0.1.21",
51
+ "@youiyoux/core": "0.1.21"
52
52
  },
53
53
  "exports": {
54
54
  "./package.json": "./package.json"