@ripast/cli 0.0.0 → 0.0.1
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/bin/ripast.mjs +3 -1
- package/dist/cli.mjs +172 -29
- package/package.json +2 -2
package/bin/ripast.mjs
CHANGED
|
@@ -45,7 +45,9 @@ function ensureAdapters(needed) {
|
|
|
45
45
|
const require = createRequire(import.meta.url)
|
|
46
46
|
const missing = []
|
|
47
47
|
for (const name of needed) {
|
|
48
|
-
try {
|
|
48
|
+
try {
|
|
49
|
+
require.resolve(`@ripast/${name}`)
|
|
50
|
+
}
|
|
49
51
|
catch { missing.push(`@ripast/${name}`) }
|
|
50
52
|
}
|
|
51
53
|
if (!missing.length)
|
package/dist/cli.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { mkdirSync, readFileSync, renameSync } from "node:fs";
|
|
2
2
|
import { dirname, resolve } from "node:path";
|
|
3
3
|
import process from "node:process";
|
|
4
|
-
import { buildDeclarationTree, buildScanGraph, formatAgentDeclarationTree, formatAgentHits, formatAgentScanHits, formatDeclarationTree, formatHits, formatRegressions, formatScanGraph, formatScanHits, printDiffs, resolveVerifyMode, runCssClassRename, runCssClassScan, runMove, runRename, runRenameFile, 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, 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 = {
|
|
@@ -69,7 +69,7 @@ function resolveCliVerifyMode(verify, verifyMode) {
|
|
|
69
69
|
}
|
|
70
70
|
function resolveExportFilter(raw) {
|
|
71
71
|
if (raw !== "all" && raw !== "exported" && raw !== "local") {
|
|
72
|
-
process.stderr.write(`ripast
|
|
72
|
+
process.stderr.write(`ripast: --exports must be "all", "exported", or "local".\n`);
|
|
73
73
|
process.exit(2);
|
|
74
74
|
}
|
|
75
75
|
return raw;
|
|
@@ -162,6 +162,42 @@ const renameCmd = defineCommand({
|
|
|
162
162
|
}), !!args.apply, verifyMode !== "none", !!args.json, resolveProfile(args.profile).agentProfile);
|
|
163
163
|
}
|
|
164
164
|
});
|
|
165
|
+
const replaceCmd = defineCommand({
|
|
166
|
+
meta: {
|
|
167
|
+
name: "replace",
|
|
168
|
+
description: "Replace an imported symbol with another project export; updates imports and call sites."
|
|
169
|
+
},
|
|
170
|
+
args: {
|
|
171
|
+
"from": {
|
|
172
|
+
type: "positional",
|
|
173
|
+
required: true
|
|
174
|
+
},
|
|
175
|
+
"to": {
|
|
176
|
+
type: "positional",
|
|
177
|
+
required: true
|
|
178
|
+
},
|
|
179
|
+
"tsconfig": { type: "string" },
|
|
180
|
+
"glob": globArg,
|
|
181
|
+
"target-scope": {
|
|
182
|
+
type: "string",
|
|
183
|
+
description: "Restrict target symbol resolution to a single file when multiple files export the same name."
|
|
184
|
+
},
|
|
185
|
+
"apply": applyArg,
|
|
186
|
+
"verify": verifyArg,
|
|
187
|
+
"verifyMode": verifyModeArg,
|
|
188
|
+
"profile": profileArg,
|
|
189
|
+
"json": jsonArg
|
|
190
|
+
},
|
|
191
|
+
async run({ args }) {
|
|
192
|
+
const verifyMode = resolveCliVerifyMode(args.verify, args.verifyMode);
|
|
193
|
+
emitResult(await runReplace(args.from, args.to, {
|
|
194
|
+
tsconfig: args.tsconfig,
|
|
195
|
+
glob: args.glob ? args.glob.split(",") : void 0,
|
|
196
|
+
verify: verifyMode,
|
|
197
|
+
targetScope: args["target-scope"]
|
|
198
|
+
}), !!args.apply, verifyMode !== "none", !!args.json, resolveProfile(args.profile).agentProfile);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
165
201
|
const treeCmd = defineCommand({
|
|
166
202
|
meta: {
|
|
167
203
|
name: "tree",
|
|
@@ -191,6 +227,30 @@ const treeCmd = defineCommand({
|
|
|
191
227
|
process.stdout.write(`${formatDeclarationTree(tree, !!args.json)}\n`);
|
|
192
228
|
}
|
|
193
229
|
});
|
|
230
|
+
const unusedCmd = defineCommand({
|
|
231
|
+
meta: {
|
|
232
|
+
name: "unused",
|
|
233
|
+
description: "Find unreferenced top-level declarations."
|
|
234
|
+
},
|
|
235
|
+
args: {
|
|
236
|
+
glob: globArg,
|
|
237
|
+
exports: {
|
|
238
|
+
type: "string",
|
|
239
|
+
description: "Declaration filter: all, exported, or local. Defaults to local."
|
|
240
|
+
},
|
|
241
|
+
tsconfig: { type: "string" },
|
|
242
|
+
json: jsonArg
|
|
243
|
+
},
|
|
244
|
+
run({ args }) {
|
|
245
|
+
const exportFilter = args.exports == null ? "local" : resolveExportFilter(args.exports);
|
|
246
|
+
const unused = buildUnusedDeclarations({
|
|
247
|
+
glob: args.glob ? args.glob.split(",") : void 0,
|
|
248
|
+
exports: exportFilter,
|
|
249
|
+
tsconfig: args.tsconfig
|
|
250
|
+
});
|
|
251
|
+
process.stdout.write(`${formatUnusedDeclarations(unused, !!args.json)}\n`);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
194
254
|
const moveCmd = defineCommand({
|
|
195
255
|
meta: {
|
|
196
256
|
name: "move",
|
|
@@ -228,6 +288,36 @@ const moveCmd = defineCommand({
|
|
|
228
288
|
}), !!args.apply, verifyMode !== "none", !!args.json, resolveProfile(args.profile).agentProfile);
|
|
229
289
|
}
|
|
230
290
|
});
|
|
291
|
+
const deleteCmd = defineCommand({
|
|
292
|
+
meta: {
|
|
293
|
+
name: "delete",
|
|
294
|
+
description: "Delete an unused top-level declaration from a file; refuses if references remain."
|
|
295
|
+
},
|
|
296
|
+
args: {
|
|
297
|
+
symbol: {
|
|
298
|
+
type: "positional",
|
|
299
|
+
required: true
|
|
300
|
+
},
|
|
301
|
+
from: {
|
|
302
|
+
type: "string",
|
|
303
|
+
required: true,
|
|
304
|
+
description: "Source file path."
|
|
305
|
+
},
|
|
306
|
+
tsconfig: { type: "string" },
|
|
307
|
+
apply: applyArg,
|
|
308
|
+
verify: verifyArg,
|
|
309
|
+
verifyMode: verifyModeArg,
|
|
310
|
+
profile: profileArg,
|
|
311
|
+
json: jsonArg
|
|
312
|
+
},
|
|
313
|
+
async run({ args }) {
|
|
314
|
+
const verifyMode = resolveCliVerifyMode(args.verify, args.verifyMode);
|
|
315
|
+
emitResult(await runDelete(args.symbol, args.from, {
|
|
316
|
+
tsconfig: args.tsconfig,
|
|
317
|
+
verify: verifyMode
|
|
318
|
+
}), !!args.apply, verifyMode !== "none", !!args.json, resolveProfile(args.profile).agentProfile);
|
|
319
|
+
}
|
|
320
|
+
});
|
|
231
321
|
function emitResult(r, apply, verify = false, json = false, agentProfile = false) {
|
|
232
322
|
const s = summarize(r.changes);
|
|
233
323
|
if (json) {
|
|
@@ -458,6 +548,82 @@ function buildRenameMap(from, to, mapPath) {
|
|
|
458
548
|
}
|
|
459
549
|
return new Map(entries);
|
|
460
550
|
}
|
|
551
|
+
const cssClassScanCmd = defineCommand({
|
|
552
|
+
meta: {
|
|
553
|
+
name: "css-class-scan",
|
|
554
|
+
description: "Tokenize every class site (strings, Vue class attrs, @apply) and emit sortable token or file frequency lists. Use --sort count-asc for rare tokens or --by file for files introducing the most unique classes."
|
|
555
|
+
},
|
|
556
|
+
args: {
|
|
557
|
+
pattern: {
|
|
558
|
+
type: "string",
|
|
559
|
+
description: "Comma-separated globs matched against the bare token (e.g. \"bg-*,text-*\"). Default: all tokens."
|
|
560
|
+
},
|
|
561
|
+
glob: globArg,
|
|
562
|
+
by: {
|
|
563
|
+
type: "string",
|
|
564
|
+
description: "Group by token or file. Default: token."
|
|
565
|
+
},
|
|
566
|
+
sort: {
|
|
567
|
+
type: "string",
|
|
568
|
+
description: "Sort order. Token: count-desc, count-asc, token. File: unique-desc, unique-asc, count-desc, count-asc, file."
|
|
569
|
+
},
|
|
570
|
+
profile: profileArg,
|
|
571
|
+
json: jsonArg
|
|
572
|
+
},
|
|
573
|
+
run({ args }) {
|
|
574
|
+
const { agentProfile } = resolveProfile(args.profile);
|
|
575
|
+
const by = resolveCssClassScanGroup(args.by);
|
|
576
|
+
const base = {
|
|
577
|
+
glob: args.glob ? args.glob.split(",") : void 0,
|
|
578
|
+
pattern: args.pattern ? args.pattern.split(",") : void 0
|
|
579
|
+
};
|
|
580
|
+
if (by === "file") {
|
|
581
|
+
const hits = runCssClassFileScan({
|
|
582
|
+
...base,
|
|
583
|
+
sort: resolveCssClassFileScanSort(args.sort)
|
|
584
|
+
});
|
|
585
|
+
if (agentProfile && !args.json) {
|
|
586
|
+
process.stdout.write(`${profileHeader()}\n${formatAgentFileScanHits(hits)}\n`);
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
process.stdout.write(`${formatFileScanHits(hits, !!args.json)}\n`);
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
const hits = runCssClassScan({
|
|
593
|
+
...base,
|
|
594
|
+
sort: resolveCssClassScanSort(args.sort)
|
|
595
|
+
});
|
|
596
|
+
if (agentProfile && !args.json) {
|
|
597
|
+
process.stdout.write(`${profileHeader()}\n${formatAgentScanHits(hits)}\n`);
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
process.stdout.write(`${formatScanHits(hits, !!args.json)}\n`);
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
function resolveCssClassScanGroup(raw) {
|
|
604
|
+
if (raw == null) return "token";
|
|
605
|
+
if (raw !== "token" && raw !== "file") {
|
|
606
|
+
process.stderr.write(`ripast css-class-scan: --by must be "token" or "file".\n`);
|
|
607
|
+
process.exit(2);
|
|
608
|
+
}
|
|
609
|
+
return raw;
|
|
610
|
+
}
|
|
611
|
+
function resolveCssClassScanSort(raw) {
|
|
612
|
+
if (raw == null) return "count-desc";
|
|
613
|
+
if (raw !== "count-desc" && raw !== "count-asc" && raw !== "token") {
|
|
614
|
+
process.stderr.write(`ripast css-class-scan: --sort must be "count-desc", "count-asc", or "token".\n`);
|
|
615
|
+
process.exit(2);
|
|
616
|
+
}
|
|
617
|
+
return raw;
|
|
618
|
+
}
|
|
619
|
+
function resolveCssClassFileScanSort(raw) {
|
|
620
|
+
if (raw == null) return "unique-desc";
|
|
621
|
+
if (raw !== "unique-desc" && raw !== "unique-asc" && raw !== "count-desc" && raw !== "count-asc" && raw !== "file") {
|
|
622
|
+
process.stderr.write(`ripast css-class-scan: --sort with --by file must be "unique-desc", "unique-asc", "count-desc", "count-asc", or "file".\n`);
|
|
623
|
+
process.exit(2);
|
|
624
|
+
}
|
|
625
|
+
return raw;
|
|
626
|
+
}
|
|
461
627
|
runMain(defineCommand({
|
|
462
628
|
meta: {
|
|
463
629
|
name: "ripast",
|
|
@@ -466,37 +632,14 @@ runMain(defineCommand({
|
|
|
466
632
|
subCommands: {
|
|
467
633
|
"scan": scanCmd,
|
|
468
634
|
"tree": treeCmd,
|
|
635
|
+
"unused": unusedCmd,
|
|
469
636
|
"rename": renameCmd,
|
|
637
|
+
"replace": replaceCmd,
|
|
470
638
|
"rename-file": renameFileCmd,
|
|
471
639
|
"move": moveCmd,
|
|
640
|
+
"delete": deleteCmd,
|
|
472
641
|
"css-class-rename": cssClassRenameCmd,
|
|
473
|
-
"css-class-scan":
|
|
474
|
-
meta: {
|
|
475
|
-
name: "css-class-scan",
|
|
476
|
-
description: "Tokenize every class site (strings, Vue class attrs, @apply) and emit a frequency-sorted list. Feeds --map for css-class-rename."
|
|
477
|
-
},
|
|
478
|
-
args: {
|
|
479
|
-
pattern: {
|
|
480
|
-
type: "string",
|
|
481
|
-
description: "Comma-separated globs matched against the bare token (e.g. \"bg-*,text-*\"). Default: all tokens."
|
|
482
|
-
},
|
|
483
|
-
glob: globArg,
|
|
484
|
-
profile: profileArg,
|
|
485
|
-
json: jsonArg
|
|
486
|
-
},
|
|
487
|
-
run({ args }) {
|
|
488
|
-
const { agentProfile } = resolveProfile(args.profile);
|
|
489
|
-
const hits = runCssClassScan({
|
|
490
|
-
glob: args.glob ? args.glob.split(",") : void 0,
|
|
491
|
-
pattern: args.pattern ? args.pattern.split(",") : void 0
|
|
492
|
-
});
|
|
493
|
-
if (agentProfile && !args.json) {
|
|
494
|
-
process.stdout.write(`${profileHeader()}\n${formatAgentScanHits(hits)}\n`);
|
|
495
|
-
return;
|
|
496
|
-
}
|
|
497
|
-
process.stdout.write(`${formatScanHits(hits, !!args.json)}\n`);
|
|
498
|
-
}
|
|
499
|
-
})
|
|
642
|
+
"css-class-scan": cssClassScanCmd
|
|
500
643
|
}
|
|
501
644
|
}));
|
|
502
645
|
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ripast/cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.1",
|
|
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.0.
|
|
53
|
+
"@ripast/core": "0.0.1"
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|
|
56
56
|
"build": "obuild",
|