epicshop 6.84.0 → 6.84.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.
@@ -119,6 +119,45 @@ async function isDirectoryEmpty(targetPath) {
119
119
  return false;
120
120
  }
121
121
  }
122
+ async function findWorkshopEntryFromCwd(startDir) {
123
+ let currentDir = startDir ? path.resolve(startDir) : process.cwd();
124
+ // If the user gave us a file path (or something that isn't a directory),
125
+ // treat the containing folder as the start point.
126
+ try {
127
+ const stats = await fs.stat(currentDir);
128
+ if (!stats.isDirectory()) {
129
+ currentDir = path.dirname(currentDir);
130
+ }
131
+ }
132
+ catch {
133
+ // If the path doesn't exist, we still attempt to walk upward from it.
134
+ }
135
+ const root = path.parse(currentDir).root;
136
+ while (currentDir !== root) {
137
+ const packageJsonPath = path.join(currentDir, 'package.json');
138
+ try {
139
+ const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
140
+ if (packageJson.epicshop) {
141
+ return {
142
+ title: (typeof packageJson.epicshop?.title === 'string' &&
143
+ packageJson.epicshop.title
144
+ ? packageJson.epicshop.title
145
+ : packageJson.name || path.basename(currentDir)) ?? currentDir,
146
+ repoName: path.basename(currentDir),
147
+ path: currentDir,
148
+ };
149
+ }
150
+ }
151
+ catch {
152
+ // Not a workshop root, keep walking up.
153
+ }
154
+ const parentDir = path.dirname(currentDir);
155
+ if (parentDir === currentDir)
156
+ break;
157
+ currentDir = parentDir;
158
+ }
159
+ return null;
160
+ }
122
161
  async function listWorkshopsInDirectory(reposDir) {
123
162
  try {
124
163
  const entries = await fs.readdir(reposDir, { withFileTypes: true });
@@ -544,6 +583,7 @@ export async function cleanup({ silent = false, force = false, targets, workshop
544
583
  try {
545
584
  let selectedTargets = resolveCleanupTargets(targets);
546
585
  let selectedWorkshopTargets = resolveWorkshopCleanupTargets(workshopTargets);
586
+ const hasExplicitWorkshopSelection = (workshops?.length ?? 0) > 0;
547
587
  if ((workshops?.length ?? 0) > 0 || selectedWorkshopTargets.length > 0) {
548
588
  if (!selectedTargets.includes('workshops')) {
549
589
  selectedTargets.push('workshops');
@@ -558,6 +598,7 @@ export async function cleanup({ silent = false, force = false, targets, workshop
558
598
  let configPath = '';
559
599
  let allWorkshops = [];
560
600
  let workshopIdentities = [];
601
+ let contextWorkshop = null;
561
602
  let workshopSummaries = [];
562
603
  let workshopBytes = 0;
563
604
  let legacyCacheBytes = 0;
@@ -582,12 +623,38 @@ export async function cleanup({ silent = false, force = false, targets, workshop
582
623
  } = await resolveCleanupPaths(paths));
583
624
  const needsWorkshopInventory = selectedTargets.length === 0 || selectedTargets.includes('workshops');
584
625
  if (needsWorkshopInventory) {
585
- updateSpinner(analysisSpinner, 'Finding installed workshops...');
586
- allWorkshops = await listWorkshopsInDirectory(reposDir);
626
+ const workshopFromCwd = await findWorkshopEntryFromCwd();
627
+ const shouldScopeToCwdWorkshop = !hasExplicitWorkshopSelection && Boolean(workshopFromCwd);
628
+ if (shouldScopeToCwdWorkshop && workshopFromCwd) {
629
+ // Context-aware behavior: when running inside a workshop and no
630
+ // explicit `--workshops` were provided, we treat the current workshop
631
+ // as the only workshop candidate. This avoids suggesting other
632
+ // workshops in prompts and keeps size estimates accurate.
633
+ allWorkshops = [workshopFromCwd];
634
+ }
635
+ else {
636
+ updateSpinner(analysisSpinner, 'Finding installed workshops...');
637
+ allWorkshops = await listWorkshopsInDirectory(reposDir);
638
+ // If we're inside a workshop that isn't in the configured repos
639
+ // directory (e.g. working on a workshop repo elsewhere), still allow
640
+ // cleanup to target the current workshop.
641
+ if (workshopFromCwd) {
642
+ const cwdId = getWorkshopInstanceId(workshopFromCwd.path);
643
+ const alreadyIncluded = allWorkshops.some((w) => getWorkshopInstanceId(w.path) === cwdId);
644
+ if (!alreadyIncluded) {
645
+ allWorkshops.push(workshopFromCwd);
646
+ }
647
+ }
648
+ }
587
649
  workshopIdentities = allWorkshops.map((workshop) => ({
588
650
  ...workshop,
589
651
  id: getWorkshopInstanceId(workshop.path),
590
652
  }));
653
+ if (workshopFromCwd) {
654
+ const cwdId = getWorkshopInstanceId(workshopFromCwd.path);
655
+ contextWorkshop =
656
+ workshopIdentities.find((workshop) => workshop.id === cwdId) ?? null;
657
+ }
591
658
  }
592
659
  if (selectedTargets.length === 0) {
593
660
  if (allWorkshops.length > 0) {
@@ -685,6 +752,12 @@ export async function cleanup({ silent = false, force = false, targets, workshop
685
752
  console.log(chalk.yellow('No workshops found to clean up.'));
686
753
  }
687
754
  }
755
+ else if (!hasExplicitWorkshopSelection && contextWorkshop) {
756
+ // Context-aware default: if we're running from inside a workshop and no
757
+ // `--workshops` were provided, skip suggesting other workshops and
758
+ // default to the current workshop.
759
+ selectedWorkshops = [contextWorkshop];
760
+ }
688
761
  else if (workshops && workshops.length > 0) {
689
762
  const resolved = resolveWorkshopSelection(workshopIdentities, workshops);
690
763
  if (resolved.missing.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "epicshop",
3
- "version": "6.84.0",
3
+ "version": "6.84.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -99,7 +99,7 @@
99
99
  "build:watch": "nx watch --projects=epicshop -- nx run \\$NX_PROJECT_NAME:build"
100
100
  },
101
101
  "dependencies": {
102
- "@epic-web/workshop-utils": "6.84.0",
102
+ "@epic-web/workshop-utils": "6.84.2",
103
103
  "@inquirer/prompts": "^8.2.0",
104
104
  "@sentry/node": "^10.38.0",
105
105
  "chalk": "^5.6.2",