jig-ui 0.6.0 → 0.7.0

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 (2) hide show
  1. package/dist/index.js +60 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2975,7 +2975,7 @@ function check(opts) {
2975
2975
  }
2976
2976
 
2977
2977
  // src/commands/init.ts
2978
- import { existsSync as existsSync13, mkdirSync as mkdirSync5, readdirSync as readdirSync9, readFileSync as readFileSync18, writeFileSync as writeFileSync4 } from "fs";
2978
+ import { existsSync as existsSync13, mkdirSync as mkdirSync5, readdirSync as readdirSync9, readFileSync as readFileSync18, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
2979
2979
  import { dirname as dirname6, isAbsolute, join as join23, resolve as resolve2, sep as sep3 } from "path";
2980
2980
 
2981
2981
  // src/init/detect.ts
@@ -3547,6 +3547,11 @@ function wireBarrel(absPath, barrelImport) {
3547
3547
  async function init(opts) {
3548
3548
  const log = opts.log ?? ((line) => console.log(line));
3549
3549
  const prompt = opts.prompt ?? defaultPrompt;
3550
+ if (!opts.yes && !opts.prompt && !process.stdin.isTTY) {
3551
+ throw new Error(
3552
+ "'jig init' asks questions and stdin is not a terminal, so it cannot. Re-run with --yes to accept the derived defaults, or run it in a terminal. (To choose the mode without a terminal, write jig.config.json first \u2014 init honours it.)"
3553
+ );
3554
+ }
3550
3555
  const migrateLegacy = async (report, describe) => {
3551
3556
  if (!report.present) return;
3552
3557
  for (const line of describe(report)) log(line);
@@ -3642,7 +3647,24 @@ Brand colour adjusted to clear the 4.5:1 contrast floor: l:${originalL}% \u2192
3642
3647
  // a project holding a legacy token layer must keep it rather than gain a
3643
3648
  // second one somewhere else.
3644
3649
  legacyBrandFile(opts.projectRoot);
3645
- const brandRelPath = configuredBrand.path ?? priorBrand ?? relKey(...defaultTokenDir(detection), brandFileName(projectSlug));
3650
+ let relocateTo = null;
3651
+ const currentBrand = configuredBrand.path ?? priorBrand;
3652
+ if (currentBrand) {
3653
+ const wouldBe = relKey(...defaultTokenDir(detection), currentBrand.split("/").pop());
3654
+ const currentDir = currentBrand.split("/").slice(0, -1).join("/");
3655
+ if (wouldBe !== currentBrand && findWireTarget(detection)) {
3656
+ log(`
3657
+ The token layer is at ${currentDir}/, and this project's layout suggests ${wouldBe.split("/").slice(0, -1).join("/")}/.`);
3658
+ if (opts.yes) {
3659
+ log(" Re-run without --yes to be offered the move, or set `brand` in jig.config.json yourself.");
3660
+ } else {
3661
+ const answer = (await prompt(" Move the token layer there? [y/N]: ")).toLowerCase();
3662
+ if (answer === "y" || answer === "yes") relocateTo = wouldBe;
3663
+ else log(" Left it where it is.");
3664
+ }
3665
+ }
3666
+ }
3667
+ const brandRelPath = relocateTo ?? configuredBrand.path ?? priorBrand ?? relKey(...defaultTokenDir(detection), brandFileName(projectSlug));
3646
3668
  const brandAbsPath = join23(opts.projectRoot, ...brandRelPath.split("/"));
3647
3669
  const tokensRelDir = brandRelPath.split("/").slice(0, -1);
3648
3670
  log(
@@ -3682,6 +3704,18 @@ ${configRelPath} already exists and was not created by 'jig init' (or has been e
3682
3704
  writeFileSync4(brandAbsPath, content, "utf8");
3683
3705
  files[brandRelPath] = checksum(content);
3684
3706
  }
3707
+ if (relocateTo && configAction !== "written") {
3708
+ try {
3709
+ const existing = JSON.parse(readFileSync18(configAbsPath, "utf8"));
3710
+ const content = `${JSON.stringify({ ...existing, brand: brandRelPath }, null, 2)}
3711
+ `;
3712
+ writeFileSync4(configAbsPath, content, "utf8");
3713
+ files[configRelPath] = checksum(content);
3714
+ log(` Updated ${configRelPath} to point at the new location.`);
3715
+ } catch {
3716
+ log(` Could not update ${configRelPath} \u2014 set \`brand\` to ${brandRelPath} yourself.`);
3717
+ }
3718
+ }
3685
3719
  if (configAction === "written") {
3686
3720
  const config = { brand: brandRelPath, surfaces };
3687
3721
  const content = `${JSON.stringify(config, null, 2)}
@@ -3753,6 +3787,23 @@ ${configRelPath} already exists and was not created by 'jig init' (or has been e
3753
3787
  }
3754
3788
  }
3755
3789
  writeInitManifest(opts.projectRoot, { version: opts.version, modes: declaredModes, files });
3790
+ if (relocateTo && currentBrand) {
3791
+ const oldDir = currentBrand.split("/").slice(0, -1);
3792
+ const oldAbsDir = join23(opts.projectRoot, ...oldDir);
3793
+ if (existsSync13(oldAbsDir)) {
3794
+ for (const name of readdirSync9(oldAbsDir).filter((f) => f.endsWith(".css"))) {
3795
+ const rel = relKey(...oldDir, name);
3796
+ const abs = join23(oldAbsDir, name);
3797
+ const state = fileState(opts.projectRoot, abs, rel, initManifest);
3798
+ if (!state.tracked || state.modified) {
3799
+ log(` ${rel} was edited \u2014 left in place. Delete it yourself once you have moved anything you need.`);
3800
+ continue;
3801
+ }
3802
+ rmSync2(abs, { force: true });
3803
+ delete files[rel];
3804
+ }
3805
+ }
3806
+ }
3756
3807
  const wireTarget = findWireTarget(detection);
3757
3808
  let wiring;
3758
3809
  if (wireTarget) {
@@ -3763,6 +3814,13 @@ ${configRelPath} already exists and was not created by 'jig init' (or has been e
3763
3814
  );
3764
3815
  const snippet = `@import "${barrelImport}";`;
3765
3816
  try {
3817
+ if (relocateTo && currentBrand) {
3818
+ const abs = join23(opts.projectRoot, wireTarget);
3819
+ const oldDirName = currentBrand.split("/").slice(0, -1).join("/");
3820
+ const before = existsSync13(abs) ? readFileSync18(abs, "utf8") : "";
3821
+ const after = before.split("\n").filter((l) => !(l.includes("@import") && l.includes(oldDirName))).join("\n");
3822
+ if (after !== before) writeFileSync4(abs, after, "utf8");
3823
+ }
3766
3824
  const outcome = wireBarrel(join23(opts.projectRoot, wireTarget), barrelImport);
3767
3825
  wiring = { target: wireTarget, status: outcome.status, snippet };
3768
3826
  const verb = outcome.status === "wired" ? "Wired" : outcome.status === "rewired" ? "Rewired" : "Already present in";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jig-ui",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "A design system for coding agents. 104 numbered UI rules, brand x mode design tokens, and an installer for Claude Code, Codex, Cursor and opencode.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",