@ripast/cli 0.2.1 → 0.2.2

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/cli.mjs +99 -5
  2. package/package.json +2 -2
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import { mkdirSync, readFileSync, renameSync } from "node:fs";
1
+ import { existsSync, mkdirSync, readFileSync, renameSync } from "node:fs";
2
2
  import { dirname, relative, resolve } from "node:path";
3
3
  import process from "node:process";
4
- import { buildDeclarationTree, buildScanGraph, buildUnusedDeclarations, formatAgentDeclarationTree, formatAgentFileScanHits, formatAgentHits, formatAgentScanHits, formatDeclarationTree, formatFileScanHits, formatHits, formatRegressions, formatScanGraph, formatScanHits, formatUnusedDeclarations, printDiffs, resolveVerifyMode, runCssClassFileScan, runCssClassRename, runCssClassScan, runDelete, runMove, runRename, runRenameFile, runReplace, scan, summarize, writeChanges } from "@ripast/core";
4
+ import { buildDeclarationTree, buildScanGraph, buildUnusedDeclarations, formatAgentDeclarationTree, formatAgentFileScanHits, formatAgentHits, formatAgentScanHits, formatDeclarationTree, formatFileScanHits, formatHits, formatRegressions, formatScanGraph, formatScanHits, formatUnusedDeclarations, printDiffs, resolveVerifyMode, runCssClassFileScan, runCssClassRename, runCssClassScan, runDelete, runMove, runRename, runRenameFile, runReplace, runVueTemplateUnwrap, runVueTemplateWrap, scan, summarize, writeChanges } from "@ripast/core";
5
5
  import { defineCommand, runMain } from "citty";
6
6
  import { agent, isAgent } from "std-env";
7
7
  const globArg = {
@@ -67,6 +67,35 @@ function resolveCliVerifyMode(verify, verifyMode) {
67
67
  }
68
68
  return resolveVerifyMode(verify);
69
69
  }
70
+ function recoverSmushedPair(oldArg, newArg) {
71
+ const cwd = process.cwd();
72
+ if (!!oldArg && existsSync(resolve(cwd, oldArg)) && newArg) return {
73
+ old: oldArg,
74
+ new: newArg
75
+ };
76
+ if (!oldArg) return {
77
+ old: oldArg,
78
+ new: newArg
79
+ };
80
+ const candidates = [];
81
+ for (const sep of [
82
+ /\s+/,
83
+ /\s*,\s*/,
84
+ /\s*:\s*/
85
+ ]) {
86
+ const parts = oldArg.split(sep).filter(Boolean);
87
+ if (parts.length === 2) candidates.push([parts[0], parts[1]]);
88
+ }
89
+ for (const [a, b] of candidates) if (existsSync(resolve(cwd, a)) && !existsSync(resolve(cwd, b))) return {
90
+ old: a,
91
+ new: b,
92
+ warning: `recovered smushed positional args: treating "${oldArg}" as old="${a}" new="${b}". Quote each path separately next time.`
93
+ };
94
+ return {
95
+ old: oldArg,
96
+ new: newArg
97
+ };
98
+ }
70
99
  function resolveExportFilter(raw) {
71
100
  if (raw !== "all" && raw !== "exported" && raw !== "local") {
72
101
  process.stderr.write(`ripast: --exports must be "all", "exported", or "local".\n`);
@@ -407,7 +436,9 @@ const renameFileCmd = defineCommand({
407
436
  },
408
437
  async run({ args }) {
409
438
  const verifyMode = resolveCliVerifyMode(args.verify, args.verifyMode);
410
- const r = await runRenameFile(args.old, args.new, {
439
+ const recovered = recoverSmushedPair(args.old, args.new);
440
+ if (recovered.warning) process.stderr.write(`warning: ${recovered.warning}\n`);
441
+ const r = await runRenameFile(recovered.old, recovered.new, {
411
442
  tsconfig: args.tsconfig,
412
443
  verify: verifyMode
413
444
  });
@@ -455,7 +486,7 @@ const renameFileCmd = defineCommand({
455
486
  for (const w of r.warnings) process.stderr.write(`warning: ${w}\n`);
456
487
  if (agentProfile) {
457
488
  process.stdout.write(`${profileHeader()}\n`);
458
- process.stdout.write(`rename-file: ${args.old} -> ${args.new}\n`);
489
+ process.stdout.write(`rename-file: ${recovered.old} -> ${recovered.new}\n`);
459
490
  process.stdout.write(`consumers: ${r.changes.length}/${r.scanned}, +${s.linesAdded} -${s.linesRemoved} lines\n`);
460
491
  if (selfChangeDisplay) process.stdout.write(`self: rewrote moved file's own relative imports\n`);
461
492
  process.stdout.write(`mode: ${apply ? blockedByRegression ? "blocked" : "applied" : "dry-run"}\n`);
@@ -641,6 +672,15 @@ function resolveCssClassFileScanSort(raw) {
641
672
  }
642
673
  return raw;
643
674
  }
675
+ const scopeArg = {
676
+ type: "string",
677
+ description: "Restrict to a single .vue file (skips glob/rg)."
678
+ };
679
+ const rootOnlyArg = {
680
+ type: "boolean",
681
+ default: false,
682
+ description: "Match only template-root elements (direct children of <template>); ignores nested matches."
683
+ };
644
684
  runMain(defineCommand({
645
685
  meta: {
646
686
  name: "ripast",
@@ -656,7 +696,61 @@ runMain(defineCommand({
656
696
  "move": moveCmd,
657
697
  "delete": deleteCmd,
658
698
  "css-class-rename": cssClassRenameCmd,
659
- "css-class-scan": cssClassScanCmd
699
+ "css-class-scan": cssClassScanCmd,
700
+ "vue-template-wrap": defineCommand({
701
+ meta: {
702
+ name: "vue-template-wrap",
703
+ description: "Wrap every matching element in a Vue <template> with a parent component. Selector: \"Tag\" or \"Tag[attr]\" / \"Tag[attr=value]\". Wrapper: tag name with optional inline attributes (e.g. \"ProPageStates name=\\\"lh\\\"\")."
704
+ },
705
+ args: {
706
+ selector: {
707
+ type: "positional",
708
+ required: true
709
+ },
710
+ wrapper: {
711
+ type: "positional",
712
+ required: true
713
+ },
714
+ glob: globArg,
715
+ scope: scopeArg,
716
+ rootOnly: rootOnlyArg,
717
+ apply: applyArg,
718
+ profile: profileArg,
719
+ json: jsonArg
720
+ },
721
+ async run({ args }) {
722
+ emitResult(await runVueTemplateWrap(args.selector, args.wrapper, {
723
+ glob: args.glob ? args.glob.split(",") : void 0,
724
+ scope: args.scope,
725
+ rootOnly: args.rootOnly
726
+ }), !!args.apply, false, !!args.json, resolveProfile(args.profile).agentProfile);
727
+ }
728
+ }),
729
+ "vue-template-unwrap": defineCommand({
730
+ meta: {
731
+ name: "vue-template-unwrap",
732
+ description: "Remove every matching element in a Vue <template>, hoisting its children up one level. Inverse of vue-template-wrap."
733
+ },
734
+ args: {
735
+ selector: {
736
+ type: "positional",
737
+ required: true
738
+ },
739
+ glob: globArg,
740
+ scope: scopeArg,
741
+ rootOnly: rootOnlyArg,
742
+ apply: applyArg,
743
+ profile: profileArg,
744
+ json: jsonArg
745
+ },
746
+ async run({ args }) {
747
+ emitResult(await runVueTemplateUnwrap(args.selector, {
748
+ glob: args.glob ? args.glob.split(",") : void 0,
749
+ scope: args.scope,
750
+ rootOnly: args.rootOnly
751
+ }), !!args.apply, false, !!args.json, resolveProfile(args.profile).agentProfile);
752
+ }
753
+ })
660
754
  }
661
755
  }));
662
756
  export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ripast/cli",
3
3
  "type": "module",
4
- "version": "0.2.1",
4
+ "version": "0.2.2",
5
5
  "description": "CLI for ripast. Deterministic AST refactors (rename, move, find-usages, tailwind/CSS class migration) for TypeScript and frontend frameworks. Auto-installs framework adapters as needed.",
6
6
  "author": {
7
7
  "name": "Harlan Wilton",
@@ -50,7 +50,7 @@
50
50
  "dependencies": {
51
51
  "citty": "^0.2.2",
52
52
  "std-env": "^4.1.0",
53
- "@ripast/core": "0.2.1"
53
+ "@ripast/core": "0.2.2"
54
54
  },
55
55
  "scripts": {
56
56
  "build": "obuild",