youiyoux 0.1.15 → 0.1.17

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.
Files changed (27) hide show
  1. package/dist/chunks/{chunk-FTL53MU3.js → chunk-2HRV3FFX.js} +2 -2
  2. package/dist/chunks/{chunk-T4EHV4XY.js → chunk-BMBXZG7W.js} +65 -16
  3. package/dist/chunks/{chunk-HII2I2PI.js → chunk-CKH54UT6.js} +3 -3
  4. package/dist/chunks/{chunk-S7UN5KQK.js → chunk-CLYYS6VI.js} +2 -2
  5. package/dist/chunks/{chunk-MIUG2Z43.js → chunk-COJJZPVD.js} +3 -3
  6. package/dist/chunks/{chunk-A2IZOTJG.js → chunk-G5BKBWEQ.js} +1 -1
  7. package/dist/chunks/{chunk-ALQVHSF2.js → chunk-I6HDWG3U.js} +1 -1
  8. package/dist/chunks/{chunk-DAGYR4NV.js → chunk-Q77GHEZ5.js} +7 -4
  9. package/dist/chunks/{chunk-QEUZDGIF.js → chunk-TW24A5TT.js} +6 -6
  10. package/dist/chunks/{chunk-CZJFEND6.js → chunk-W3ZCAAXH.js} +4 -4
  11. package/dist/chunks/{chunk-HIXGUALJ.js → chunk-XHJQOWD4.js} +1 -1
  12. package/dist/chunks/figma-auth-O7YTQOAD.js +212 -0
  13. package/dist/chunks/{ingest-R2TM3QBM.js → ingest-XSUSELVB.js} +9 -9
  14. package/dist/chunks/{src-IMWXYWQK.js → src-3F2YGGDW.js} +3 -3
  15. package/dist/chunks/{src-7SHBAJEO.js → src-COKDT2AL.js} +2 -2
  16. package/dist/chunks/{src-WMGLZKYK.js → src-CWTSWOK4.js} +2 -2
  17. package/dist/chunks/{src-CCGTRT5J.js → src-HKWBBHA4.js} +4 -4
  18. package/dist/chunks/{src-LUPO3O76.js → src-O535ZT77.js} +2 -2
  19. package/dist/chunks/{src-6JO73FOS.js → src-RMQQPWAD.js} +3 -3
  20. package/dist/chunks/{src-OHHZY3TA.js → src-WSHA347Z.js} +7 -7
  21. package/dist/chunks/{src-4BOFDAZD.js → src-X34V5MHP.js} +1 -1
  22. package/dist/hub-previews.js +6 -6
  23. package/dist/hub-server.js +3 -3
  24. package/dist/hub-snapshot.js +1 -1
  25. package/dist/youi.js +8 -8
  26. package/dist/youiyoux.js +8 -8
  27. package/package.json +4 -4
@@ -4,10 +4,10 @@ import {
4
4
  loadPackage,
5
5
  readTryIndex,
6
6
  send
7
- } from "./chunk-CZJFEND6.js";
7
+ } from "./chunk-W3ZCAAXH.js";
8
8
  import {
9
9
  writeFileAtomic
10
- } from "./chunk-S7UN5KQK.js";
10
+ } from "./chunk-CLYYS6VI.js";
11
11
 
12
12
  // ../../apps/web/scripts/discover-thumbs.ts
13
13
  import { existsSync, readFileSync } from "node:fs";
@@ -9,7 +9,7 @@ import {
9
9
  startRuleEditor,
10
10
  style,
11
11
  truncate
12
- } from "./chunk-QEUZDGIF.js";
12
+ } from "./chunk-TW24A5TT.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-HII2I2PI.js";
67
+ } from "./chunk-CKH54UT6.js";
68
68
  import {
69
69
  escapingLinks,
70
70
  within
@@ -78,7 +78,7 @@ import {
78
78
  libraryOfPackage,
79
79
  packageOf,
80
80
  playwrightCli
81
- } from "./chunk-ALQVHSF2.js";
81
+ } from "./chunk-I6HDWG3U.js";
82
82
  import {
83
83
  MissingIndexError,
84
84
  buildGaps,
@@ -96,7 +96,7 @@ import {
96
96
  sharedStore,
97
97
  showFromCatalog,
98
98
  syncIndex
99
- } from "./chunk-DAGYR4NV.js";
99
+ } from "./chunk-Q77GHEZ5.js";
100
100
  import {
101
101
  checkpointSqlite,
102
102
  indexHome,
@@ -104,7 +104,7 @@ import {
104
104
  openSqlite,
105
105
  projectGraph,
106
106
  storeLocation
107
- } from "./chunk-A2IZOTJG.js";
107
+ } from "./chunk-G5BKBWEQ.js";
108
108
  import {
109
109
  DL_EXT,
110
110
  buildTokens,
@@ -114,7 +114,7 @@ import {
114
114
  parseCssColor,
115
115
  parseDimension,
116
116
  readRules
117
- } from "./chunk-HIXGUALJ.js";
117
+ } from "./chunk-XHJQOWD4.js";
118
118
  import {
119
119
  Baseline,
120
120
  CiRecord,
@@ -153,7 +153,7 @@ import {
153
153
  toPosix,
154
154
  unifiedDiff,
155
155
  writeFileAtomic
156
- } from "./chunk-S7UN5KQK.js";
156
+ } from "./chunk-CLYYS6VI.js";
157
157
  import {
158
158
  __toESM
159
159
  } from "./chunk-WNTS7ZO4.js";
@@ -182,7 +182,7 @@ import { join as join2, relative, resolve } from "node:path";
182
182
 
183
183
  // ../cli/src/command.ts
184
184
  var COMMAND = "youiyoux";
185
- var SUBCOMMANDS = ["show", "where", "bom", "check", "baseline", "rules", "plan", "migrate", "upgrade", "record", "hub", "init", "adopt", "status", "system", "sync", "link", "unlink", "scan", "watch", "hooks", "agents", "mcp", "ui", "library", "discover", "index", "report", "render", "screens", "requests", "detect", "build", "parity", "schema", "inventory", "gaps", "help"];
185
+ var SUBCOMMANDS = ["show", "where", "bom", "check", "baseline", "rules", "plan", "migrate", "upgrade", "record", "hub", "figma", "init", "adopt", "status", "system", "sync", "link", "unlink", "scan", "watch", "hooks", "agents", "mcp", "ui", "library", "discover", "index", "report", "render", "screens", "requests", "detect", "build", "parity", "schema", "inventory", "gaps", "help"];
186
186
 
187
187
  // ../cli/src/agents.ts
188
188
  var import_yaml = __toESM(require_dist(), 1);
@@ -3405,7 +3405,7 @@ async function projectStatus(project2, cwd = process.cwd()) {
3405
3405
  const comparison = check.baseline?.comparison;
3406
3406
  const counted = comparison ? [...comparison.new, ...comparison.regressed] : check.violations;
3407
3407
  const usages = check.scan.report.usages;
3408
- const { RequestStore } = await import("./src-CCGTRT5J.js");
3408
+ const { RequestStore } = await import("./src-HKWBBHA4.js");
3409
3409
  const requests = await new RequestStore(project2.root, project2.config.id).list();
3410
3410
  const status = {
3411
3411
  id: project2.config.id,
@@ -5598,8 +5598,13 @@ ${style.bold("System")} ${style.dim("approved elements: build only with these")
5598
5598
  ${style.bold("Library")} ${style.dim("ingested references: browse and request adoption, never build with")}
5599
5599
  library search <query> Library items (lib: ids) and the System elements each could swap in for
5600
5600
  library request <id> --reason <text> draft an adoption request for a person to approve
5601
+ figma login [--paste] [--port n] | logout | status
5602
+ sign in to Figma once, for Figma links: through the browser with your team's
5603
+ private Figma app (FIGMA_CLIENT_ID, FIGMA_CLIENT_SECRET), else with a personal
5604
+ access token you paste; kept in the macOS Keychain (else a file only you can
5605
+ read). FIGMA_TOKEN still wins
5601
5606
  library ingest <link> [--draft] [--json]
5602
- read what a GitHub repository, a Storybook, a Figma file (FIGMA_TOKEN) or a
5607
+ read what a GitHub repository, a Storybook, a Figma file (youiyoux figma login) or a
5603
5608
  DESIGN.md holds into Library items, each sorted into a role, and show them;
5604
5609
  --draft files them as one draft in the changes queue, where a person keeps or
5605
5610
  drops each and approves the rest (youiyoux ui > Changes). GITHUB_TOKEN raises
@@ -5720,6 +5725,7 @@ var OPTIONS = {
5720
5725
  db: { type: "string" },
5721
5726
  record: { type: "boolean", default: false },
5722
5727
  draft: { type: "boolean", default: false },
5728
+ paste: { type: "boolean", default: false },
5723
5729
  cache: { type: "string" },
5724
5730
  role: { type: "string" },
5725
5731
  license: { type: "string" },
@@ -6001,7 +6007,7 @@ async function cmdLibrary(values, positionals) {
6001
6007
  return 0;
6002
6008
  }
6003
6009
  if (action === "ingest" && query && positionals.length === 2) {
6004
- const { fileIngestDraft, readLink, renderIngest } = await import("./ingest-R2TM3QBM.js");
6010
+ const { fileIngestDraft, readLink, renderIngest } = await import("./ingest-XSUSELVB.js");
6005
6011
  const p = values.draft ? await project(values) : null;
6006
6012
  const reading = await readLink(query, { allowLocal: true });
6007
6013
  const filed = p ? await fileIngestDraft(p, reading, values.state) : null;
@@ -6040,6 +6046,48 @@ async function cmdRecord(values) {
6040
6046
  else print([renderRecord(record, sentTo), ...values.out ? [style.dim(` written to ${values.out}`)] : [], ...!values.send && !values.out ? [style.dim(` youiyoux record --send posts it to the hub in ${HUB_URL_ENV}; --out <file> writes it; --json prints it`)] : []].join("\n"));
6041
6047
  return 0;
6042
6048
  }
6049
+ async function cmdFigma(values, positionals) {
6050
+ const [action, ...extra] = positionals;
6051
+ const auth = await import("./figma-auth-O7YTQOAD.js");
6052
+ const store = auth.credentialStore();
6053
+ if (extra.length > 0 || !["login", "logout", "status"].includes(action ?? "")) throw new UsageError("youiyoux figma login [--paste] [--port n] or youiyoux figma logout or youiyoux figma status");
6054
+ if (action === "status") {
6055
+ const stored = await store.get();
6056
+ const lines = process.env.FIGMA_TOKEN ? [`${style.ok("FIGMA_TOKEN")} is set: it is used, before any sign-in`] : [];
6057
+ if (!stored) lines.push(process.env.FIGMA_TOKEN ? style.dim("no sign-in kept") : `${style.warn("not signed in")} to Figma: youiyoux figma login`);
6058
+ else if (stored.kind === "token") lines.push(`${style.ok("signed in")}${stored.handle ? ` as ${stored.handle}` : ""} with a personal access token, kept in ${store.where} since ${stored.savedAt.slice(0, 10)}`);
6059
+ else lines.push(`${style.ok("signed in")}${stored.handle ? ` as ${stored.handle}` : ""} through your team's Figma app, kept in ${store.where}; renewed before ${stored.expiresAt.slice(0, 10)}${auth.oauthAppOf(process.env) ? "" : style.warn(" (renewing needs FIGMA_CLIENT_ID and FIGMA_CLIENT_SECRET)")}`);
6060
+ print(lines.join("\n"));
6061
+ return stored || process.env.FIGMA_TOKEN ? 0 : 1;
6062
+ }
6063
+ if (action === "logout") {
6064
+ const removed = await store.delete();
6065
+ print(removed ? `${style.ok("signed out")}: the Figma sign-in is removed from ${store.where}. To end it in Figma as well, remove the token or the app in Figma > Settings > Security` : style.dim("not signed in: nothing to remove"));
6066
+ return 0;
6067
+ }
6068
+ const app = values.paste ? null : auth.oauthAppOf(process.env);
6069
+ if (app) {
6070
+ const port = values.port ? Number(values.port) : auth.DEFAULT_CALLBACK_PORT;
6071
+ if (!Number.isInteger(port) || port < 1024 || port > 65535) throw new UsageError(`--port ${JSON.stringify(values.port)}: expected a port from 1024 to 65535`);
6072
+ const credential2 = await auth.browserLogin({ app, port, say: (line) => print(style.dim(line)) });
6073
+ await store.set(credential2);
6074
+ print(`${style.ok("signed in")} to Figma${credential2.handle ? ` as ${credential2.handle}` : ""} through your team's app; kept in ${store.where}, renewed by itself`);
6075
+ return 0;
6076
+ }
6077
+ print([
6078
+ "Sign in with a Figma personal access token:",
6079
+ " 1. Figma > Settings > Security > Personal access tokens > Generate new token (opening it now)",
6080
+ " 2. Give it an expiry, and these scopes, read-only: File content, Library content, and Current user (to check it)",
6081
+ " 3. Paste it here; it is not shown",
6082
+ style.dim(` (A team can sign in through the browser instead: register a private Figma OAuth app with the redirect URL ${auth.callbackUrl(auth.DEFAULT_CALLBACK_PORT)}, then set FIGMA_CLIENT_ID and FIGMA_CLIENT_SECRET.)`)
6083
+ ].join("\n"));
6084
+ if (process.stdin.isTTY) auth.openBrowser("https://www.figma.com/settings");
6085
+ const token = await auth.readSecret("Token: ");
6086
+ const { credential, checked } = await auth.tokenLogin(token);
6087
+ await store.set(credential);
6088
+ print(`${style.ok("signed in")} to Figma${credential.handle ? ` as ${credential.handle}` : ""}; kept in ${store.where}${checked ? "" : style.warn(" (not checked: give the token Current user: Read to let youiyoux check it)")}`);
6089
+ return 0;
6090
+ }
6043
6091
  function builtHub() {
6044
6092
  for (const dir of [join27(TOOL_ROOT, "hub"), join27(TOOL_ROOT, "apps/web/dist")]) if (existsSync4(join27(dir, "index.html"))) return dir;
6045
6093
  return null;
@@ -6055,7 +6103,7 @@ async function cmdHubServe(values, positionals) {
6055
6103
  if (problem) throw new UsageError(problem);
6056
6104
  const port = Number(values.port ?? process.env.PORT ?? 8080);
6057
6105
  if (!Number.isInteger(port) || port < 0 || port > 65535) throw new UsageError(`--port ${JSON.stringify(values.port ?? process.env.PORT)}: expected a port number`);
6058
- const { openStore, storeLocation: where2 } = await import("./src-LUPO3O76.js");
6106
+ const { openStore, storeLocation: where2 } = await import("./src-O535ZT77.js");
6059
6107
  const path = resolve14(values.db ?? process.env.YOUI_HUB_DB ?? join27(process.env.XDG_DATA_HOME || join27(homedir3(), ".local/share"), "youiyoux/hub.db"));
6060
6108
  const store = await openStore({ path });
6061
6109
  const dist = builtHub();
@@ -6384,7 +6432,7 @@ async function cmdUi(values) {
6384
6432
  async function cmdDetect(values, positionals) {
6385
6433
  const target = detectTarget(positionals);
6386
6434
  if (!target) throw new UsageError("youiyoux detect <repo-path> or youiyoux detect <url\u2026> [--expose] (one repo, or one or more URLs; not both)");
6387
- const { repoReport, siteReport, writeReport } = await import("./src-7SHBAJEO.js");
6435
+ const { repoReport, siteReport, writeReport } = await import("./src-COKDT2AL.js");
6388
6436
  const out = resolve14(values.out ?? ".youi/detect");
6389
6437
  const report = target.kind === "repo" ? await repoReport(target.path) : await siteReport(target.urls, { out, expose: values.expose, ...process.env.YOUI_CHROMIUM ? { executablePath: process.env.YOUI_CHROMIUM } : {} });
6390
6438
  const file = await writeReport(report, out);
@@ -6418,7 +6466,7 @@ async function cmdRequests(values, positionals) {
6418
6466
  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>";
6419
6467
  const [action, id, ...rest] = positionals;
6420
6468
  if (rest.length > 0) throw new UsageError(usage);
6421
- const { RequestStore, requestBrief } = await import("./src-CCGTRT5J.js");
6469
+ const { RequestStore, requestBrief } = await import("./src-HKWBBHA4.js");
6422
6470
  const { project: project2, root } = await product(values);
6423
6471
  const store = new RequestStore(root, project2?.config.id ?? basename5(root));
6424
6472
  const agent = { kind: "agent", name: "youiyoux CLI" };
@@ -6460,7 +6508,7 @@ async function cmdScreens(values, positionals, io) {
6460
6508
  const session = chosenSession(root, values["storage-state"] ? resolve14(values["storage-state"]) : void 0);
6461
6509
  if (session?.saved) process.stderr.write(`${style.dim(`signed in with the session youiyoux screens login saved (${session.file}); delete it to capture signed out`)}
6462
6510
  `);
6463
- const { launchBrowser } = await import("./src-7SHBAJEO.js");
6511
+ const { launchBrowser } = await import("./src-COKDT2AL.js");
6464
6512
  const browser = await launchBrowser(process.env.YOUI_CHROMIUM, { purpose: { what: "youiyoux screens capture", command: "youiyoux screens capture" } });
6465
6513
  try {
6466
6514
  const report = await captureScreens(dir, { base: values.base, root, browser, ...values.route ? { routes: [values.route] } : {}, ...session ? { storageState: session.file } : {}, log: (line) => process.stderr.write(`${style.dim(line)}
@@ -6517,7 +6565,7 @@ async function cmdReport(values, positionals, io) {
6517
6565
  return result.code;
6518
6566
  }
6519
6567
  async function cmdMcp(values) {
6520
- const { startStdioServer } = await import("./src-OHHZY3TA.js");
6568
+ const { startStdioServer } = await import("./src-WSHA347Z.js");
6521
6569
  await startStdioServer({ projectRoot: values.project ?? process.cwd(), ...loadOptions(values), ...values.cache ? { discoverCache: values.cache } : {} });
6522
6570
  return -1;
6523
6571
  }
@@ -6595,6 +6643,7 @@ var COMMANDS = {
6595
6643
  upgrade: cmdUpgrade,
6596
6644
  record: cmdRecord,
6597
6645
  hub: cmdHubServe,
6646
+ figma: cmdFigma,
6598
6647
  init: cmdInit,
6599
6648
  sync: cmdSync,
6600
6649
  scan: cmdScan,
@@ -18,7 +18,7 @@ import {
18
18
  sameColor,
19
19
  splitTopLevel,
20
20
  tailwindTheme
21
- } from "./chunk-HIXGUALJ.js";
21
+ } from "./chunk-XHJQOWD4.js";
22
22
  import {
23
23
  AST_GREP_LANGUAGES,
24
24
  BUILT_IN_CHECKS,
@@ -51,7 +51,7 @@ import {
51
51
  toPosix,
52
52
  unifiedDiff,
53
53
  writeFileAtomic
54
- } from "./chunk-S7UN5KQK.js";
54
+ } from "./chunk-CLYYS6VI.js";
55
55
 
56
56
  // ../scanner/src/parse.ts
57
57
  import { Lang, parseAsync } from "@ast-grep/napi";
@@ -7928,7 +7928,7 @@ var Eyes = class {
7928
7928
  }
7929
7929
  async open() {
7930
7930
  if (this.browser) return this.browser;
7931
- const { launchBrowser } = await import("./src-7SHBAJEO.js");
7931
+ const { launchBrowser } = await import("./src-COKDT2AL.js");
7932
7932
  try {
7933
7933
  this.browser = await launchBrowser(this.options.executablePath, { purpose: { what: "youiyoux render", command: "youiyoux render" }, ...this.options.download === false ? { download: false } : {}, ...this.options.log ? { log: this.options.log } : {} });
7934
7934
  } catch (error) {
@@ -27305,10 +27305,10 @@ function findUp(start, file2, owner = process.getuid?.()) {
27305
27305
  if (dirname(dir) === dir) return null;
27306
27306
  }
27307
27307
  }
27308
- async function writeFileAtomic(file2, content) {
27308
+ async function writeFileAtomic(file2, content, options = {}) {
27309
27309
  await mkdir(dirname(file2), { recursive: true });
27310
27310
  const temp = join(dirname(file2), `.${process.pid}.${randomBytes(6).toString("hex")}.tmp`);
27311
- await writeFile(temp, content, "utf8");
27311
+ await writeFile(temp, content, { encoding: "utf8", flag: "wx", ...options.mode !== void 0 ? { mode: options.mode } : {} });
27312
27312
  await rename(temp, file2);
27313
27313
  }
27314
27314
  async function readTextOrNull(file2) {
@@ -9,7 +9,7 @@ import {
9
9
  scanProject,
10
10
  screenSlug,
11
11
  tokenImpact
12
- } from "./chunk-HII2I2PI.js";
12
+ } from "./chunk-CKH54UT6.js";
13
13
  import {
14
14
  buildTokens,
15
15
  contrastText,
@@ -18,7 +18,7 @@ import {
18
18
  resolverLayout,
19
19
  ringOffset,
20
20
  systemPairs
21
- } from "./chunk-HIXGUALJ.js";
21
+ } from "./chunk-XHJQOWD4.js";
22
22
  import {
23
23
  BUILT_IN_CHECKS,
24
24
  COMPONENT_STATES,
@@ -45,7 +45,7 @@ import {
45
45
  toPosix,
46
46
  tokenValueProblems,
47
47
  writeFileAtomic
48
- } from "./chunk-S7UN5KQK.js";
48
+ } from "./chunk-CLYYS6VI.js";
49
49
  import {
50
50
  __toESM
51
51
  } from "./chunk-WNTS7ZO4.js";
@@ -2,7 +2,7 @@ import { createRequire as __youiRequire } from "node:module"; import { dirname a
2
2
  import {
3
3
  SHAPE_DIMENSIONS,
4
4
  shortHash
5
- } from "./chunk-S7UN5KQK.js";
5
+ } from "./chunk-CLYYS6VI.js";
6
6
 
7
7
  // ../store/src/driver.ts
8
8
  function searchTerms(words2) {
@@ -4,7 +4,7 @@ import {
4
4
  findFiles,
5
5
  require_dist,
6
6
  writeFileAtomic
7
- } from "./chunk-S7UN5KQK.js";
7
+ } from "./chunk-CLYYS6VI.js";
8
8
  import {
9
9
  __toESM
10
10
  } from "./chunk-WNTS7ZO4.js";
@@ -6,7 +6,7 @@ import {
6
6
  openStore,
7
7
  pageInteger,
8
8
  searchTerms
9
- } from "./chunk-A2IZOTJG.js";
9
+ } from "./chunk-G5BKBWEQ.js";
10
10
  import {
11
11
  LIBRARY_SOURCE_KINDS,
12
12
  LibraryEntry,
@@ -15,7 +15,7 @@ import {
15
15
  require_dist,
16
16
  sha256,
17
17
  writeFileAtomic
18
- } from "./chunk-S7UN5KQK.js";
18
+ } from "./chunk-CLYYS6VI.js";
19
19
  import {
20
20
  __toESM
21
21
  } from "./chunk-WNTS7ZO4.js";
@@ -700,7 +700,10 @@ var PoliteClient = class {
700
700
  if (cached?.etag) headers["if-none-match"] = cached.etag;
701
701
  if (cached?.lastModified) headers["if-modified-since"] = cached.lastModified;
702
702
  if (this.options.token && parsed.hostname === "api.github.com") headers.authorization = `Bearer ${this.options.token}`;
703
- if (this.options.figmaToken && parsed.hostname === "api.figma.com") headers["x-figma-token"] = this.options.figmaToken;
703
+ if (this.options.figmaToken && parsed.hostname === "api.figma.com") {
704
+ if (this.options.figmaBearer) headers.authorization = `Bearer ${this.options.figmaToken}`;
705
+ else headers["x-figma-token"] = this.options.figmaToken;
706
+ }
704
707
  this.stats.sent++;
705
708
  this.inFlight++;
706
709
  this.stats.maxInFlight = Math.max(this.stats.maxInFlight, this.inFlight);
@@ -2354,7 +2357,7 @@ async function ingestLink(link, options) {
2354
2357
  const now = options.now ?? (() => /* @__PURE__ */ new Date());
2355
2358
  const target = classifyLink(link, options);
2356
2359
  const fetchedAt = now().toISOString();
2357
- const result = await (target.kind === "github" ? readGithub(target, options.client, fetchedAt) : target.kind === "storybook" ? readStorybook(target, options.client, fetchedAt) : target.kind === "figma" ? options.figma ? readFigma(target, options.client, fetchedAt) : Promise.reject(new IngestError("a Figma file is read through Figma's API: set FIGMA_TOKEN to a personal access token that can read the file (Figma > Settings > Security > Personal access tokens)")) : readDesignMd(target, options.client, fetchedAt, (path) => readFile3(path, "utf8")));
2360
+ const result = await (target.kind === "github" ? readGithub(target, options.client, fetchedAt) : target.kind === "storybook" ? readStorybook(target, options.client, fetchedAt) : target.kind === "figma" ? options.figma ? readFigma(target, options.client, fetchedAt) : Promise.reject(new IngestError("a Figma file is read through Figma's API: sign in with youiyoux figma login (or set FIGMA_TOKEN)")) : readDesignMd(target, options.client, fetchedAt, (path) => readFile3(path, "utf8")));
2358
2361
  const over = result.entries.length - INGEST_CAP;
2359
2362
  return cleanData({
2360
2363
  ...result,
@@ -1,10 +1,10 @@
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-HII2I2PI.js";
4
+ } from "./chunk-CKH54UT6.js";
5
5
  import {
6
6
  shortHash
7
- } from "./chunk-S7UN5KQK.js";
7
+ } from "./chunk-CLYYS6VI.js";
8
8
 
9
9
  // ../cli/src/ui.ts
10
10
  import * as util from "node:util";
@@ -57,7 +57,7 @@ import { homedir, userInfo } from "node:os";
57
57
  import { join, resolve } from "node:path";
58
58
  async function swapImpact(candidate, family) {
59
59
  try {
60
- const { discoverIndexPath, sharedStore } = await import("./src-IMWXYWQK.js");
60
+ const { discoverIndexPath, sharedStore } = await import("./src-3F2YGGDW.js");
61
61
  const path = discoverIndexPath();
62
62
  if (!process.env.DATABASE_URL && !existsSync(path)) return null;
63
63
  const impact = await (await sharedStore(path, process.env, { readOnly: true })).swapImpact(candidate, family);
@@ -68,7 +68,7 @@ async function swapImpact(candidate, family) {
68
68
  }
69
69
  async function libraryLicence(id) {
70
70
  try {
71
- const { discoverCacheDir, findListing } = await import("./src-IMWXYWQK.js");
71
+ const { discoverCacheDir, findListing } = await import("./src-3F2YGGDW.js");
72
72
  const { entry } = await findListing(discoverCacheDir(void 0, process.env), id);
73
73
  return entry.id === id ? entry.license : null;
74
74
  } catch {
@@ -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-R2TM3QBM.js");
82
+ const { readLink } = await import("./ingest-XSUSELVB.js");
83
83
  return readLink(link, { allowLocal: false });
84
84
  }
85
85
  async function startRuleEditor(options) {
86
- const { FileStore, RuleWorkflow, serveWorkflow } = await import("./src-CCGTRT5J.js");
86
+ const { FileStore, RuleWorkflow, serveWorkflow } = await import("./src-HKWBBHA4.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);
@@ -2,10 +2,10 @@ import { createRequire as __youiRequire } from "node:module"; import { dirname a
2
2
 
3
3
  // src/hub-packages.js
4
4
  var PACKAGES = {
5
- core: () => import("./src-4BOFDAZD.js"),
6
- scanner: () => import("./src-6JO73FOS.js"),
7
- discover: () => import("./src-IMWXYWQK.js"),
8
- tokens: () => import("./src-WMGLZKYK.js")
5
+ core: () => import("./src-X34V5MHP.js"),
6
+ scanner: () => import("./src-RMQQPWAD.js"),
7
+ discover: () => import("./src-3F2YGGDW.js"),
8
+ tokens: () => import("./src-CWTSWOK4.js")
9
9
  };
10
10
  var loadPackage = (name) => PACKAGES[name]();
11
11
 
@@ -6,7 +6,7 @@ import {
6
6
  require_dist,
7
7
  toPosix,
8
8
  validateTokenSets
9
- } from "./chunk-S7UN5KQK.js";
9
+ } from "./chunk-CLYYS6VI.js";
10
10
  import {
11
11
  __commonJS,
12
12
  __toESM
@@ -0,0 +1,212 @@
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
+ import {
3
+ writeFileAtomic
4
+ } from "./chunk-CLYYS6VI.js";
5
+ import "./chunk-WNTS7ZO4.js";
6
+
7
+ // ../cli/src/figma-auth.ts
8
+ import { execFile, spawn } from "node:child_process";
9
+ import { createHash, randomBytes } from "node:crypto";
10
+ import { chmod, mkdir, readFile, rm } from "node:fs/promises";
11
+ import { createServer } from "node:http";
12
+ import { homedir } from "node:os";
13
+ import { dirname, join } from "node:path";
14
+ import { promisify } from "node:util";
15
+ var run = promisify(execFile);
16
+ var API = "https://api.figma.com/v1";
17
+ var FIGMA_SCOPES = ["file_content:read", "library_content:read", "current_user:read"];
18
+ var DEFAULT_CALLBACK_PORT = 47823;
19
+ var RENEW_MS = 24 * 60 * 60 * 1e3;
20
+ var KEYCHAIN = { account: "youiyoux", service: "youiyoux-figma" };
21
+ var parse = (text) => {
22
+ if (!text) return null;
23
+ try {
24
+ const value = JSON.parse(text);
25
+ return value && (value.kind === "token" || value.kind === "oauth") ? value : null;
26
+ } catch {
27
+ return null;
28
+ }
29
+ };
30
+ function fileStore(path) {
31
+ return {
32
+ where: path,
33
+ get: async () => parse(await readFile(path, "utf8").catch(() => null)),
34
+ set: async (credential) => {
35
+ await mkdir(dirname(path), { recursive: true, mode: 448 });
36
+ await chmod(dirname(path), 448);
37
+ await writeFileAtomic(path, `${JSON.stringify(credential)}
38
+ `, { mode: 384 });
39
+ },
40
+ delete: async () => rm(path).then(() => true, () => false)
41
+ };
42
+ }
43
+ function keychainStore() {
44
+ const { account, service } = KEYCHAIN;
45
+ return {
46
+ where: "the macOS Keychain (youiyoux-figma)",
47
+ get: async () => parse(await run("security", ["find-generic-password", "-a", account, "-s", service, "-w"]).then((r) => Buffer.from(r.stdout.trim(), "base64").toString("utf8"), () => null)),
48
+ set: (credential) => new Promise((done, fail) => {
49
+ const child = spawn("security", ["-i"], { stdio: ["pipe", "ignore", "pipe"] });
50
+ let err = "";
51
+ child.stderr.on("data", (c) => err += String(c));
52
+ child.on("error", fail);
53
+ child.on("exit", (code) => code === 0 && !err.trim() ? done() : fail(new Error(`the Keychain refused the credential${err.trim() ? `: ${err.trim()}` : ""}`)));
54
+ child.stdin.end(`add-generic-password -a ${account} -s ${service} -U -w ${Buffer.from(JSON.stringify(credential)).toString("base64")}
55
+ `);
56
+ }),
57
+ delete: async () => run("security", ["delete-generic-password", "-a", account, "-s", service]).then(() => true, () => false)
58
+ };
59
+ }
60
+ function credentialStore(env = process.env, platform = process.platform) {
61
+ if (env.YOUI_FIGMA_CREDENTIALS) return fileStore(env.YOUI_FIGMA_CREDENTIALS);
62
+ if (platform === "darwin") return keychainStore();
63
+ return fileStore(join(env.XDG_CONFIG_HOME || join(homedir(), ".config"), "youiyoux", "figma.json"));
64
+ }
65
+ var basic = (id, secret) => `Basic ${Buffer.from(`${id}:${secret}`).toString("base64")}`;
66
+ async function postForm(fetcher, url, auth, form) {
67
+ const response = await fetcher(url, { method: "POST", headers: { authorization: auth, "content-type": "application/x-www-form-urlencoded" }, body: new URLSearchParams(form).toString(), signal: AbortSignal.timeout(15e3) });
68
+ const body = await response.json().catch(() => ({}));
69
+ const said = [body.message, body.err, body.error].find((v) => typeof v === "string");
70
+ if (!response.ok) throw new Error(`Figma refused (${response.status}): ${said ?? response.statusText}`);
71
+ return body;
72
+ }
73
+ async function whoAmI(token, bearer, fetcher = fetch) {
74
+ const response = await fetcher(`${API}/me`, { headers: bearer ? { authorization: `Bearer ${token}` } : { "x-figma-token": token }, signal: AbortSignal.timeout(15e3) });
75
+ if (!response.ok) return { ok: false, handle: null, status: response.status };
76
+ const me = await response.json().catch(() => ({}));
77
+ return { ok: true, handle: typeof me.handle === "string" ? me.handle : null, status: response.status };
78
+ }
79
+ var oauthAppOf = (env) => env.FIGMA_CLIENT_ID && env.FIGMA_CLIENT_SECRET ? { clientId: env.FIGMA_CLIENT_ID, clientSecret: env.FIGMA_CLIENT_SECRET } : null;
80
+ var callbackUrl = (port) => `http://127.0.0.1:${port}/callback`;
81
+ function openBrowser(url) {
82
+ const [command, args] = process.platform === "darwin" ? ["open", [url]] : process.platform === "win32" ? ["rundll32", ["url.dll,FileProtocolHandler", url]] : ["xdg-open", [url]];
83
+ spawn(command, args, { stdio: "ignore", detached: true }).on("error", () => {
84
+ }).unref();
85
+ }
86
+ var page = (title, text) => `<!doctype html><meta charset="utf-8"><title>${title}</title><body style="font:16px system-ui;margin:3rem;max-width:32rem"><h1 style="font-size:1.25rem">${title}</h1><p>${text}</p></body>`;
87
+ async function browserLogin(options) {
88
+ const fetcher = options.fetcher ?? fetch;
89
+ const now = options.now ?? (() => /* @__PURE__ */ new Date());
90
+ const port = options.port ?? DEFAULT_CALLBACK_PORT;
91
+ const redirect = callbackUrl(port);
92
+ const state = randomBytes(24).toString("base64url");
93
+ const verifier = randomBytes(48).toString("base64url");
94
+ const challenge = createHash("sha256").update(verifier).digest("base64url");
95
+ const authorize = new URL("https://www.figma.com/oauth");
96
+ for (const [key, value] of Object.entries({ client_id: options.app.clientId, redirect_uri: redirect, scope: FIGMA_SCOPES.join(","), state, response_type: "code", code_challenge: challenge, code_challenge_method: "S256" })) authorize.searchParams.set(key, value);
97
+ const code = await new Promise((done, fail) => {
98
+ const server = createServer((req, res) => {
99
+ const url = new URL(req.url ?? "/", redirect);
100
+ if (url.pathname !== "/callback") {
101
+ res.writeHead(404).end();
102
+ return;
103
+ }
104
+ const finish = (status, title, text, outcome) => {
105
+ res.writeHead(status, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store" }).end(page(title, text));
106
+ clearTimeout(timer);
107
+ server.close();
108
+ outcome();
109
+ };
110
+ if (url.searchParams.get("state") !== state) return finish(400, "Not this sign-in", "This answer is not for the sign-in youiyoux started. Run youiyoux figma login again.", () => fail(new Error("the answer came with another sign-in's state; nothing was kept")));
111
+ const error = url.searchParams.get("error");
112
+ if (error) return finish(400, "Not signed in", "Figma did not sign you in. You can close this tab.", () => fail(new Error(`Figma did not sign you in: ${error}`)));
113
+ const given = url.searchParams.get("code");
114
+ if (!given) return finish(400, "Not signed in", "Figma sent no code. Run youiyoux figma login again.", () => fail(new Error("Figma sent no code")));
115
+ finish(200, "Signed in to Figma", "youiyoux can read your Figma files now. You can close this tab.", () => done(given));
116
+ });
117
+ const timer = setTimeout(() => {
118
+ server.close();
119
+ fail(new Error("no answer from Figma within five minutes; run youiyoux figma login again"));
120
+ }, options.timeoutMs ?? 5 * 6e4);
121
+ server.once("error", (error) => {
122
+ clearTimeout(timer);
123
+ fail(new Error(error.code === "EADDRINUSE" ? `port ${port} is taken: pass --port <n>, and register ${callbackUrl(port).replace(String(port), "<n>")} in the Figma app` : error.message));
124
+ });
125
+ server.listen(port, "127.0.0.1", () => {
126
+ options.say?.(`Opening Figma to sign in. If no browser opens, visit:
127
+ ${authorize.href}`);
128
+ (options.open ?? openBrowser)(authorize.href);
129
+ });
130
+ });
131
+ const tokens = await postForm(fetcher, `${API}/oauth/token`, basic(options.app.clientId, options.app.clientSecret), { redirect_uri: redirect, code, grant_type: "authorization_code", code_verifier: verifier });
132
+ const accessToken = tokens.access_token;
133
+ const refreshToken = tokens.refresh_token;
134
+ if (typeof accessToken !== "string" || typeof refreshToken !== "string") throw new Error("Figma's answer had no tokens");
135
+ const seconds = typeof tokens.expires_in === "number" ? tokens.expires_in : 90 * 86400;
136
+ const me = await whoAmI(accessToken, true, fetcher).catch(() => ({ ok: false, handle: null, status: 0 }));
137
+ return { kind: "oauth", accessToken, refreshToken, expiresAt: new Date(now().getTime() + seconds * 1e3).toISOString(), clientId: options.app.clientId, savedAt: now().toISOString(), handle: me.handle };
138
+ }
139
+ async function tokenLogin(token, options = {}) {
140
+ const clean = token.trim();
141
+ if (!/^[\w-]{20,200}$/.test(clean)) throw new Error("that does not look like a Figma personal access token (figd_\u2026)");
142
+ const me = await whoAmI(clean, false, options.fetcher);
143
+ if (!me.ok && me.status !== 403) throw new Error(`Figma does not accept that token (${me.status}): make a new one`);
144
+ return { credential: { kind: "token", token: clean, savedAt: (options.now ?? (() => /* @__PURE__ */ new Date()))().toISOString(), handle: me.handle }, checked: me.ok };
145
+ }
146
+ async function figmaAccess(options = {}) {
147
+ const env = options.env ?? process.env;
148
+ if (env.FIGMA_TOKEN) return { token: env.FIGMA_TOKEN, bearer: false, from: "env" };
149
+ const store = options.store ?? credentialStore(env);
150
+ const stored = await store.get();
151
+ if (!stored) return null;
152
+ if (stored.kind === "token") return { token: stored.token, bearer: false, from: "token" };
153
+ const now = (options.now ?? (() => /* @__PURE__ */ new Date()))();
154
+ if (Date.parse(stored.expiresAt) - now.getTime() > RENEW_MS) return { token: stored.accessToken, bearer: true, from: "oauth" };
155
+ const app = oauthAppOf(env);
156
+ if (!app || app.clientId !== stored.clientId) {
157
+ if (Date.parse(stored.expiresAt) > now.getTime()) return { token: stored.accessToken, bearer: true, from: "oauth" };
158
+ throw new Error("your Figma sign-in has lapsed, and renewing it needs your team's Figma app (FIGMA_CLIENT_ID and FIGMA_CLIENT_SECRET): set them and run youiyoux figma login");
159
+ }
160
+ const renewed = await postForm(options.fetcher ?? fetch, `${API}/oauth/refresh`, basic(app.clientId, app.clientSecret), { refresh_token: stored.refreshToken });
161
+ if (typeof renewed.access_token !== "string") throw new Error("Figma did not renew the sign-in: run youiyoux figma login");
162
+ const seconds = typeof renewed.expires_in === "number" ? renewed.expires_in : 90 * 86400;
163
+ await store.set({ ...stored, accessToken: renewed.access_token, expiresAt: new Date(now.getTime() + seconds * 1e3).toISOString() });
164
+ return { token: renewed.access_token, bearer: true, from: "oauth" };
165
+ }
166
+ async function readSecret(prompt, input = process.stdin, output = process.stderr) {
167
+ if (!input.isTTY) {
168
+ let text = "";
169
+ for await (const chunk of input) {
170
+ text += String(chunk);
171
+ if (text.includes("\n")) break;
172
+ }
173
+ return text.split(/\r?\n/)[0] ?? "";
174
+ }
175
+ output.write(prompt);
176
+ input.setRawMode(true);
177
+ input.resume();
178
+ return new Promise((done, fail) => {
179
+ let value = "";
180
+ const onData = (chunk) => {
181
+ for (const char of chunk.toString("utf8")) {
182
+ if (char === "\r" || char === "\n") return finish(() => done(value));
183
+ if (char === "") return finish(() => fail(new Error("cancelled")));
184
+ if (char === "\x7F" || char === "\b") value = value.slice(0, -1);
185
+ else if (char >= " ") value += char;
186
+ }
187
+ };
188
+ const finish = (then) => {
189
+ input.off("data", onData);
190
+ input.setRawMode(false);
191
+ input.pause();
192
+ output.write("\n");
193
+ then();
194
+ };
195
+ input.on("data", onData);
196
+ });
197
+ }
198
+ export {
199
+ DEFAULT_CALLBACK_PORT,
200
+ FIGMA_SCOPES,
201
+ browserLogin,
202
+ callbackUrl,
203
+ credentialStore,
204
+ figmaAccess,
205
+ fileStore,
206
+ keychainStore,
207
+ oauthAppOf,
208
+ openBrowser,
209
+ readSecret,
210
+ tokenLogin,
211
+ whoAmI
212
+ };
@@ -4,26 +4,26 @@ import {
4
4
  plural,
5
5
  style,
6
6
  workflowStateDir
7
- } from "./chunk-QEUZDGIF.js";
8
- import "./chunk-HII2I2PI.js";
7
+ } from "./chunk-TW24A5TT.js";
8
+ import "./chunk-CKH54UT6.js";
9
9
  import "./chunk-42YJX3W5.js";
10
- import "./chunk-HIXGUALJ.js";
11
- import "./chunk-S7UN5KQK.js";
10
+ import "./chunk-XHJQOWD4.js";
11
+ import "./chunk-CLYYS6VI.js";
12
12
  import "./chunk-WNTS7ZO4.js";
13
13
 
14
14
  // ../cli/src/ingest.ts
15
15
  import { userInfo } from "node:os";
16
16
  async function readLink(link, options) {
17
- const { githubBuckets, ingestLink, PoliteClient } = await import("./src-IMWXYWQK.js");
17
+ const { githubBuckets, ingestLink, PoliteClient } = await import("./src-3F2YGGDW.js");
18
18
  const env = options.env ?? process.env;
19
19
  const token = env.GITHUB_TOKEN || void 0;
20
- const figmaToken = env.FIGMA_TOKEN || void 0;
21
- const client = new PoliteClient({ buckets: githubBuckets(token), ...token ? { token } : {}, ...figmaToken ? { figmaToken } : {} });
22
- const result = await ingestLink(link, { client, allowLocal: options.allowLocal, figma: Boolean(figmaToken) });
20
+ const figma = /figma\.com\//i.test(link) ? await (await import("./figma-auth-O7YTQOAD.js")).figmaAccess({ env }) : null;
21
+ const client = new PoliteClient({ buckets: githubBuckets(token), ...token ? { token } : {}, ...figma ? { figmaToken: figma.token, figmaBearer: figma.bearer } : {} });
22
+ const result = await ingestLink(link, { client, allowLocal: options.allowLocal, figma: Boolean(figma) });
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-CCGTRT5J.js");
26
+ const { FileStore, RuleWorkflow } = await import("./src-HKWBBHA4.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 };
@@ -127,9 +127,9 @@ import {
127
127
  writeHttpCache,
128
128
  writeJson,
129
129
  writeSources
130
- } from "./chunk-DAGYR4NV.js";
131
- import "./chunk-A2IZOTJG.js";
132
- import "./chunk-S7UN5KQK.js";
130
+ } from "./chunk-Q77GHEZ5.js";
131
+ import "./chunk-G5BKBWEQ.js";
132
+ import "./chunk-CLYYS6VI.js";
133
133
  import "./chunk-WNTS7ZO4.js";
134
134
  export {
135
135
  ALL_INDEX_FILE,
@@ -36,8 +36,8 @@ import {
36
36
  siteReport,
37
37
  siteSignals,
38
38
  writeReport
39
- } from "./chunk-ALQVHSF2.js";
40
- import "./chunk-S7UN5KQK.js";
39
+ } from "./chunk-I6HDWG3U.js";
40
+ import "./chunk-CLYYS6VI.js";
41
41
  import "./chunk-WNTS7ZO4.js";
42
42
  export {
43
43
  BrowserMissingError,
@@ -56,8 +56,8 @@ import {
56
56
  tokenVariables,
57
57
  variableSuffixes,
58
58
  youiTypeVariables
59
- } from "./chunk-HIXGUALJ.js";
60
- import "./chunk-S7UN5KQK.js";
59
+ } from "./chunk-XHJQOWD4.js";
60
+ import "./chunk-CLYYS6VI.js";
61
61
  import "./chunk-WNTS7ZO4.js";
62
62
  export {
63
63
  AAA_TEXT,
@@ -64,11 +64,11 @@ import {
64
64
  validateIngestContent,
65
65
  validateLibraryContent,
66
66
  validateStyleContent
67
- } from "./chunk-MIUG2Z43.js";
68
- import "./chunk-HII2I2PI.js";
67
+ } from "./chunk-COJJZPVD.js";
68
+ import "./chunk-CKH54UT6.js";
69
69
  import "./chunk-42YJX3W5.js";
70
- import "./chunk-HIXGUALJ.js";
71
- import "./chunk-S7UN5KQK.js";
70
+ import "./chunk-XHJQOWD4.js";
71
+ import "./chunk-CLYYS6VI.js";
72
72
  import "./chunk-WNTS7ZO4.js";
73
73
  export {
74
74
  DesignFiles,
@@ -24,8 +24,8 @@ import {
24
24
  searchTerms,
25
25
  sqliteAdapter,
26
26
  storeLocation
27
- } from "./chunk-A2IZOTJG.js";
28
- import "./chunk-S7UN5KQK.js";
27
+ } from "./chunk-G5BKBWEQ.js";
28
+ import "./chunk-CLYYS6VI.js";
29
29
  import "./chunk-WNTS7ZO4.js";
30
30
  export {
31
31
  INDEX_FILE,
@@ -188,14 +188,14 @@ import {
188
188
  whyNoLines,
189
189
  withFile,
190
190
  withoutCredentials
191
- } from "./chunk-HII2I2PI.js";
191
+ } from "./chunk-CKH54UT6.js";
192
192
  import {
193
193
  escapingLinks,
194
194
  relativeInside,
195
195
  within
196
196
  } from "./chunk-42YJX3W5.js";
197
- import "./chunk-HIXGUALJ.js";
198
- import "./chunk-S7UN5KQK.js";
197
+ import "./chunk-XHJQOWD4.js";
198
+ import "./chunk-CLYYS6VI.js";
199
199
  import "./chunk-WNTS7ZO4.js";
200
200
  export {
201
201
  ARBITRARY,
@@ -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-MIUG2Z43.js";
5
+ } from "./chunk-COJJZPVD.js";
6
6
  import {
7
7
  PROJECT_FILE,
8
8
  ScanCache,
@@ -30,13 +30,13 @@ import {
30
30
  shotsText,
31
31
  tokenRows,
32
32
  whereUsed
33
- } from "./chunk-HII2I2PI.js";
33
+ } from "./chunk-CKH54UT6.js";
34
34
  import "./chunk-42YJX3W5.js";
35
35
  import {
36
36
  SHADCN_SLOTS,
37
37
  launchBrowser,
38
38
  libraryOfPackage
39
- } from "./chunk-ALQVHSF2.js";
39
+ } from "./chunk-I6HDWG3U.js";
40
40
  import {
41
41
  DISCOVER_RULE,
42
42
  DiscoverConstraints,
@@ -51,11 +51,11 @@ import {
51
51
  searchCatalog,
52
52
  sharedStore,
53
53
  showFromCatalog
54
- } from "./chunk-DAGYR4NV.js";
54
+ } from "./chunk-Q77GHEZ5.js";
55
55
  import {
56
56
  storeLocation
57
- } from "./chunk-A2IZOTJG.js";
58
- import "./chunk-HIXGUALJ.js";
57
+ } from "./chunk-G5BKBWEQ.js";
58
+ import "./chunk-XHJQOWD4.js";
59
59
  import {
60
60
  $ZodObject,
61
61
  $ZodType,
@@ -95,7 +95,7 @@ import {
95
95
  toJSONSchema,
96
96
  union,
97
97
  unknown
98
- } from "./chunk-S7UN5KQK.js";
98
+ } from "./chunk-CLYYS6VI.js";
99
99
  import {
100
100
  __commonJS,
101
101
  __toESM
@@ -162,7 +162,7 @@ import {
162
162
  validateTokenSets,
163
163
  walkGlob,
164
164
  writeFileAtomic
165
- } from "./chunk-S7UN5KQK.js";
165
+ } from "./chunk-CLYYS6VI.js";
166
166
  import "./chunk-WNTS7ZO4.js";
167
167
  export {
168
168
  AST_GREP_LANGUAGES,
@@ -2,12 +2,12 @@
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
  launchBrowser
5
- } from "./chunks/chunk-ALQVHSF2.js";
5
+ } from "./chunks/chunk-I6HDWG3U.js";
6
6
  import {
7
7
  discoverCacheDir,
8
8
  loadIndex
9
- } from "./chunks/chunk-DAGYR4NV.js";
10
- import "./chunks/chunk-A2IZOTJG.js";
9
+ } from "./chunks/chunk-Q77GHEZ5.js";
10
+ import "./chunks/chunk-G5BKBWEQ.js";
11
11
  import {
12
12
  THUMBS_PATH,
13
13
  THUMB_SCHEMES,
@@ -17,10 +17,10 @@ import {
17
17
  selectCandidates,
18
18
  thumbsDir,
19
19
  writeThumbIndex
20
- } from "./chunks/chunk-FTL53MU3.js";
21
- import "./chunks/chunk-CZJFEND6.js";
20
+ } from "./chunks/chunk-2HRV3FFX.js";
21
+ import "./chunks/chunk-W3ZCAAXH.js";
22
22
  import "./chunks/chunk-FVVL5JCY.js";
23
- import "./chunks/chunk-S7UN5KQK.js";
23
+ import "./chunks/chunk-CLYYS6VI.js";
24
24
  import "./chunks/chunk-WNTS7ZO4.js";
25
25
 
26
26
  // ../../apps/web/scripts/capture-discover-thumbs.ts
@@ -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-FTL53MU3.js";
5
+ } from "./chunks/chunk-2HRV3FFX.js";
6
6
  import {
7
7
  isLocalHost,
8
8
  loadPackage,
@@ -10,9 +10,9 @@ import {
10
10
  readTryIndex,
11
11
  send,
12
12
  tryMiddleware
13
- } from "./chunks/chunk-CZJFEND6.js";
13
+ } from "./chunks/chunk-W3ZCAAXH.js";
14
14
  import "./chunks/chunk-FVVL5JCY.js";
15
- import "./chunks/chunk-S7UN5KQK.js";
15
+ import "./chunks/chunk-CLYYS6VI.js";
16
16
  import "./chunks/chunk-WNTS7ZO4.js";
17
17
 
18
18
  // ../../apps/web/scripts/hub-server.ts
@@ -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-CZJFEND6.js";
6
+ } from "./chunks/chunk-W3ZCAAXH.js";
7
7
  import "./chunks/chunk-FVVL5JCY.js";
8
8
  import "./chunks/chunk-WNTS7ZO4.js";
9
9
 
package/dist/youi.js CHANGED
@@ -2,16 +2,16 @@
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-T4EHV4XY.js";
6
- import "./chunks/chunk-QEUZDGIF.js";
7
- import "./chunks/chunk-HII2I2PI.js";
5
+ } from "./chunks/chunk-BMBXZG7W.js";
6
+ import "./chunks/chunk-TW24A5TT.js";
7
+ import "./chunks/chunk-CKH54UT6.js";
8
8
  import "./chunks/chunk-42YJX3W5.js";
9
- import "./chunks/chunk-ALQVHSF2.js";
10
- import "./chunks/chunk-DAGYR4NV.js";
11
- import "./chunks/chunk-A2IZOTJG.js";
9
+ import "./chunks/chunk-I6HDWG3U.js";
10
+ import "./chunks/chunk-Q77GHEZ5.js";
11
+ import "./chunks/chunk-G5BKBWEQ.js";
12
12
  import "./chunks/chunk-FVVL5JCY.js";
13
- import "./chunks/chunk-HIXGUALJ.js";
14
- import "./chunks/chunk-S7UN5KQK.js";
13
+ import "./chunks/chunk-XHJQOWD4.js";
14
+ import "./chunks/chunk-CLYYS6VI.js";
15
15
  import "./chunks/chunk-WNTS7ZO4.js";
16
16
 
17
17
  // src/youi.js
package/dist/youiyoux.js CHANGED
@@ -3,16 +3,16 @@ import { createRequire as __youiRequire } from "node:module"; import { dirname a
3
3
  import {
4
4
  COMMAND_NAMES,
5
5
  main
6
- } from "./chunks/chunk-T4EHV4XY.js";
7
- import "./chunks/chunk-QEUZDGIF.js";
8
- import "./chunks/chunk-HII2I2PI.js";
6
+ } from "./chunks/chunk-BMBXZG7W.js";
7
+ import "./chunks/chunk-TW24A5TT.js";
8
+ import "./chunks/chunk-CKH54UT6.js";
9
9
  import "./chunks/chunk-42YJX3W5.js";
10
- import "./chunks/chunk-ALQVHSF2.js";
11
- import "./chunks/chunk-DAGYR4NV.js";
12
- import "./chunks/chunk-A2IZOTJG.js";
10
+ import "./chunks/chunk-I6HDWG3U.js";
11
+ import "./chunks/chunk-Q77GHEZ5.js";
12
+ import "./chunks/chunk-G5BKBWEQ.js";
13
13
  import "./chunks/chunk-FVVL5JCY.js";
14
- import "./chunks/chunk-HIXGUALJ.js";
15
- import "./chunks/chunk-S7UN5KQK.js";
14
+ import "./chunks/chunk-XHJQOWD4.js";
15
+ import "./chunks/chunk-CLYYS6VI.js";
16
16
  import "./chunks/chunk-WNTS7ZO4.js";
17
17
 
18
18
  // src/youiyoux.js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "youiyoux",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
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.15",
50
- "@youiyoux/core": "0.1.15",
51
- "@youiyoux/scanner": "0.1.15"
49
+ "@youiyoux/cli": "0.1.17",
50
+ "@youiyoux/scanner": "0.1.17",
51
+ "@youiyoux/core": "0.1.17"
52
52
  },
53
53
  "exports": {
54
54
  "./package.json": "./package.json"