slicejs-cli 3.6.0 → 3.6.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.
package/README.md CHANGED
@@ -70,6 +70,38 @@ so each project keeps its pinned CLI version.
70
70
 
71
71
  ## Main commands
72
72
 
73
+ Inside initialized projects, prefer package scripts (`pnpm run ...`, `npm run ...`)
74
+ over direct binary calls.
75
+
76
+ Common script workflow:
77
+
78
+ ```bash
79
+ pnpm run dev
80
+ pnpm run build
81
+ pnpm run start
82
+ pnpm run browse
83
+ pnpm run get -- Button
84
+ pnpm run sync
85
+ ```
86
+
87
+ Alternative with local devDependency resolution:
88
+
89
+ ```bash
90
+ pnpm exec slice dev
91
+ ```
92
+
93
+ If `slicejs-cli` is installed globally, `slice` can be executed directly from PATH.
94
+
95
+ For pnpm v10+, if build scripts are restricted, configure `allowBuilds` in
96
+ `pnpm-workspace.yaml`:
97
+
98
+ ```yaml
99
+ allowBuilds:
100
+ slicejs-cli: true
101
+ ```
102
+
103
+ `slice init --pm pnpm` now writes this automatically.
104
+
73
105
  | Command | Description |
74
106
  |---------|-------------|
75
107
  | `slice init` | Initialize a Slice.js project |
@@ -89,17 +121,21 @@ When you install `slicejs-cli`, the `postinstall` script automatically configure
89
121
  ```json
90
122
  {
91
123
  "scripts": {
92
- "slice:dev": "slice dev",
93
- "slice:start": "slice start",
94
- "slice:create": "slice component create",
95
- "slice:list": "slice component list",
96
- "slice:delete": "slice component delete",
97
- "slice:init": "slice init",
98
- "slice:get": "slice get",
99
- "slice:browse": "slice browse",
100
- "slice:sync": "slice sync",
101
- "slice:version": "slice version",
102
- "slice:update": "slice update"
124
+ "slice:init": "node ./node_modules/slicejs-cli/client.js init",
125
+ "slice:dev": "node ./node_modules/slicejs-cli/client.js dev",
126
+ "slice:build": "node ./node_modules/slicejs-cli/client.js build",
127
+ "slice:start": "node ./node_modules/slicejs-cli/client.js start",
128
+ "slice:create": "node ./node_modules/slicejs-cli/client.js component create",
129
+ "slice:list": "node ./node_modules/slicejs-cli/client.js component list",
130
+ "slice:delete": "node ./node_modules/slicejs-cli/client.js component delete",
131
+ "slice:get": "node ./node_modules/slicejs-cli/client.js get",
132
+ "slice:browse": "node ./node_modules/slicejs-cli/client.js browse",
133
+ "slice:sync": "node ./node_modules/slicejs-cli/client.js sync",
134
+ "slice:doctor": "node ./node_modules/slicejs-cli/client.js doctor",
135
+ "slice:version": "node ./node_modules/slicejs-cli/client.js version",
136
+ "slice:help": "node ./node_modules/slicejs-cli/client.js --help",
137
+ "slice:update": "node ./node_modules/slicejs-cli/client.js update",
138
+ "slice:types": "node ./node_modules/slicejs-cli/client.js types generate"
103
139
  }
104
140
  }
105
141
  ```
package/client.js CHANGED
@@ -31,6 +31,8 @@ import {
31
31
  detectPackageManager,
32
32
  getAvailablePackageManagers,
33
33
  isPackageManagerAvailable,
34
+ resolvePackageManager,
35
+ runScriptCommand,
34
36
  SUPPORTED_PACKAGE_MANAGERS
35
37
  } from './commands/utils/PackageManager.js';
36
38
  import { SLICE_SCRIPTS } from './commands/utils/sliceScripts.js';
@@ -103,7 +105,7 @@ sliceClient
103
105
  .command("init")
104
106
  .description("Initialize a new Slice.js project")
105
107
  .option("-y, --yes [name]", "Skip prompts and initialize with project name")
106
- .option("--pm <packageManager>", "Package manager to use (npm, pnpm or yarn). Auto-detected when omitted")
108
+ .option("--pm <packageManager>", "Package manager to use (pnpm or npm). Auto-detected when omitted")
107
109
  .action(async (options) => {
108
110
  let projectName = 'my-slice-app';
109
111
  if (options.yes) {
@@ -150,7 +152,7 @@ sliceClient
150
152
  } else if (!options.yes) {
151
153
  const available = getAvailablePackageManagers();
152
154
  if (available.length === 0) {
153
- Print.error('No package manager found (npm, pnpm or yarn). Install one and retry.');
155
+ Print.error('No package manager found (pnpm or npm). Install one and retry.');
154
156
  return;
155
157
  }
156
158
  const { pm } = await inquirer.prompt([
@@ -165,9 +167,9 @@ sliceClient
165
167
  packageManager = pm;
166
168
  } else {
167
169
  const available = getAvailablePackageManagers();
168
- packageManager = available.includes('npm') ? 'npm' : available[0];
170
+ packageManager = available.includes('pnpm') ? 'pnpm' : available[0];
169
171
  if (!packageManager) {
170
- Print.error('No package manager found (npm, pnpm or yarn). Install one and retry.');
172
+ Print.error('No package manager found (pnpm or npm). Install one and retry.');
171
173
  return;
172
174
  }
173
175
  }
@@ -638,6 +640,7 @@ sliceClient
638
640
 
639
641
  const projectRoot = getProjectRoot(import.meta.url);
640
642
  const pkgPath = path.join(projectRoot, 'package.json');
643
+ const packageManager = resolvePackageManager(projectRoot).name;
641
644
 
642
645
  // Shared with post.js and slice init — see commands/utils/sliceScripts.js
643
646
  const sliceScripts = SLICE_SCRIPTS;
@@ -665,12 +668,12 @@ sliceClient
665
668
  }
666
669
 
667
670
  fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2), 'utf-8');
668
- console.log(`✅ slicejs-cli installed successfully. Added ${addedCount} npm scripts to package.json.`);
669
- console.log(' Run: npm run slice:dev');
671
+ console.log(`✅ slicejs-cli installed successfully. Added ${addedCount} package scripts to package.json.`);
672
+ console.log(` Run: ${runScriptCommand(packageManager, 'slice:dev')}`);
670
673
  } catch (err) {
671
674
  console.log('✅ slicejs-cli installed successfully.');
672
675
  console.log(' Could not auto-configure scripts:', err.message);
673
- console.log(' Run: npx slice dev');
676
+ console.log(` Configure scripts manually and run: ${runScriptCommand(packageManager, 'slice:dev')}`);
674
677
  }
675
678
  });
676
679
 
@@ -6,7 +6,8 @@ import { minify as terserMinify } from 'terser';
6
6
  import { minify } from 'html-minifier-terser';
7
7
  import CleanCSS from 'clean-css';
8
8
  import Print from '../Print.js';
9
- import { getSrcPath, getDistPath, getConfigPath } from '../utils/PathHelper.js';
9
+ import { getSrcPath, getDistPath, getConfigPath, getProjectRoot } from '../utils/PathHelper.js';
10
+ import { resolvePackageManager, runScriptCommand } from '../utils/PackageManager.js';
10
11
 
11
12
  /**
12
13
  * Loads configuration from sliceConfig.json
@@ -441,6 +442,7 @@ async function analyzeBuild() {
441
442
  */
442
443
  export default async function buildProduction(options = {}) {
443
444
  const startTime = Date.now();
445
+ const packageManager = resolvePackageManager(getProjectRoot(import.meta.url)).name;
444
446
 
445
447
  try {
446
448
  Print.title('🔨 Building Slice.js project for production...');
@@ -483,7 +485,7 @@ export default async function buildProduction(options = {}) {
483
485
  Print.info('Your optimized project is ready in the /dist directory');
484
486
  Print.newLine();
485
487
  Print.info('Next steps:');
486
- console.log(' • Use "npm run slice:start" to test the production build');
488
+ console.log(` • Use "${runScriptCommand(packageManager, 'start')}" to test the production build`);
487
489
  console.log(' • All Slice.js components and architecture preserved');
488
490
 
489
491
  return true;
@@ -499,6 +501,7 @@ export default async function buildProduction(options = {}) {
499
501
  */
500
502
  export async function serveProductionBuild(port) {
501
503
  try {
504
+ const packageManager = resolvePackageManager(getProjectRoot(import.meta.url)).name;
502
505
  const config = loadConfig();
503
506
  const defaultPort = config?.server?.port || 3001;
504
507
  const finalPort = port || defaultPort;
@@ -533,7 +536,7 @@ export async function serveProductionBuild(port) {
533
536
  Print.success(`Production preview server running at http://localhost:${finalPort}`);
534
537
  Print.info('Press Ctrl+C to stop the server');
535
538
  Print.info('This server previews your production build from /dist');
536
- Print.warning('This is a preview server - use "npm run slice:start" for the full production server');
539
+ Print.warning(`This is a preview server - use "${runScriptCommand(packageManager, 'start')}" for the full production server`);
537
540
  });
538
541
 
539
542
  } catch (error) {
@@ -154,8 +154,7 @@ export async function checkPackageManagerSetup(projectRoot = getProjectRoot(impo
154
154
 
155
155
  const LOCKFILE_PM = {
156
156
  'package-lock.json': 'npm',
157
- 'pnpm-lock.yaml': 'pnpm',
158
- 'yarn.lock': 'yarn'
157
+ 'pnpm-lock.yaml': 'pnpm'
159
158
  };
160
159
  const lockfiles = [];
161
160
  for (const lockfile of Object.keys(LOCKFILE_PM)) {
@@ -32,6 +32,61 @@ async function fetchLatestVersion(packageName) {
32
32
  }
33
33
  }
34
34
 
35
+ function getRunningCliVersion() {
36
+ try {
37
+ const cliRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
38
+ const cliPkg = fs.readJsonSync(path.join(cliRoot, 'package.json'));
39
+ return typeof cliPkg.version === 'string' ? cliPkg.version : null;
40
+ } catch {
41
+ return null;
42
+ }
43
+ }
44
+
45
+ async function ensurePnpmAllowBuilds(projectRoot) {
46
+ const workspacePath = path.join(projectRoot, 'pnpm-workspace.yaml');
47
+ const allowBuildLine = ' slicejs-cli: true';
48
+
49
+ if (!(await fs.pathExists(workspacePath))) {
50
+ await fs.writeFile(workspacePath, `allowBuilds:\n${allowBuildLine}\n`, 'utf8');
51
+ return;
52
+ }
53
+
54
+ const raw = await fs.readFile(workspacePath, 'utf8');
55
+ const lines = raw.split(/\r?\n/);
56
+ const allowIdx = lines.findIndex((line) => /^allowBuilds:\s*$/.test(line));
57
+
58
+ if (allowIdx === -1) {
59
+ const suffix = raw.endsWith('\n') ? '' : '\n';
60
+ await fs.writeFile(workspacePath, `${raw}${suffix}allowBuilds:\n${allowBuildLine}\n`, 'utf8');
61
+ return;
62
+ }
63
+
64
+ let blockEnd = lines.length;
65
+ for (let i = allowIdx + 1; i < lines.length; i++) {
66
+ const line = lines[i];
67
+ if (!line.trim()) continue;
68
+ if (!/^\s/.test(line)) {
69
+ blockEnd = i;
70
+ break;
71
+ }
72
+ }
73
+
74
+ let found = false;
75
+ for (let i = allowIdx + 1; i < blockEnd; i++) {
76
+ if (/^\s+slicejs-cli\s*:/.test(lines[i])) {
77
+ lines[i] = allowBuildLine;
78
+ found = true;
79
+ break;
80
+ }
81
+ }
82
+
83
+ if (!found) {
84
+ lines.splice(blockEnd, 0, allowBuildLine);
85
+ }
86
+
87
+ await fs.writeFile(workspacePath, `${lines.join('\n').replace(/\n*$/, '\n')}`, 'utf8');
88
+ }
89
+
35
90
  // Create the project manifest BEFORE any install runs. Without a package.json in
36
91
  // the project folder, npm/pnpm walk up the directory tree looking for the nearest
37
92
  // manifest and anchor node_modules (and the dependency entry) OUTSIDE the project.
@@ -93,6 +148,10 @@ export default async function initializeProject(options = {}) {
93
148
  const packageManager = options.packageManager
94
149
  || resolvePackageManager(projectRoot).name;
95
150
 
151
+ if (packageManager === 'pnpm') {
152
+ await ensurePnpmAllowBuilds(projectRoot);
153
+ }
154
+
96
155
  // 0. CREATE PROJECT MANIFEST FIRST — must exist before any install so the
97
156
  // package manager anchors node_modules inside the project folder.
98
157
  await ensureProjectManifest(projectRoot, packageManager);
@@ -103,6 +162,9 @@ export default async function initializeProject(options = {}) {
103
162
  let sliceBaseDir;
104
163
  try {
105
164
  latestVersion = await fetchLatestVersion('slicejs-web-framework');
165
+ const frameworkPackage = latestVersion
166
+ ? `slicejs-web-framework@${latestVersion}`
167
+ : 'slicejs-web-framework';
106
168
  const installedPkgPath = getPath(import.meta.url, 'node_modules', 'slicejs-web-framework', 'package.json');
107
169
  let installed = null;
108
170
  if (await fs.pathExists(installedPkgPath)) {
@@ -110,11 +172,7 @@ export default async function initializeProject(options = {}) {
110
172
  installed = pkg.version;
111
173
  }
112
174
  if (!installed || (latestVersion && installed !== latestVersion)) {
113
- // Install WITHOUT pinning an exact version: the package manager
114
- // resolves it under its own policies (e.g. pnpm minimumReleaseAge
115
- // quarantines versions younger than the configured age — pinning
116
- // the registry's freshest version would make resolution fail).
117
- execSync(installCommand(packageManager, 'slicejs-web-framework'), { cwd: projectRoot, stdio: 'inherit' });
175
+ execSync(installCommand(packageManager, frameworkPackage), { cwd: projectRoot, stdio: 'inherit' });
118
176
  }
119
177
  if (await fs.pathExists(installedPkgPath)) {
120
178
  const pkg = await fs.readJson(installedPkgPath);
@@ -145,13 +203,24 @@ export default async function initializeProject(options = {}) {
145
203
  const cliSpinner = ora('Installing slicejs-cli as devDependency...').start();
146
204
  try {
147
205
  const cliPkgPath = getPath(import.meta.url, 'node_modules', 'slicejs-cli', 'package.json');
148
- if (!(await fs.pathExists(cliPkgPath))) {
149
- execSync(installCommand(packageManager, 'slicejs-cli', { dev: true }), { cwd: projectRoot, stdio: 'inherit' });
206
+ const currentCliVersion = getRunningCliVersion();
207
+ const cliPackage = currentCliVersion
208
+ ? `slicejs-cli@${currentCliVersion}`
209
+ : 'slicejs-cli';
210
+
211
+ let installedCliVersion = null;
212
+ if (await fs.pathExists(cliPkgPath)) {
213
+ const pkg = await fs.readJson(cliPkgPath);
214
+ installedCliVersion = pkg.version;
215
+ }
216
+
217
+ if (!installedCliVersion || (currentCliVersion && installedCliVersion !== currentCliVersion)) {
218
+ execSync(installCommand(packageManager, cliPackage, { dev: true }), { cwd: projectRoot, stdio: 'inherit' });
150
219
  }
151
220
  cliSpinner.succeed('slicejs-cli installed locally');
152
221
  } catch (err) {
153
222
  cliSpinner.warn('Could not install slicejs-cli locally — scripts will use the global CLI');
154
- Print.info(`You can add it later with: ${installCommand(packageManager, 'slicejs-cli', { dev: true })}`);
223
+ Print.info(`You can add it later with: ${installCommand(packageManager, `slicejs-cli@${getRunningCliVersion() || 'latest'}`, { dev: true })}`);
155
224
  }
156
225
 
157
226
  // These derive from sliceBaseDir (which comes from npm install or fallback),
@@ -256,20 +325,20 @@ export default async function initializeProject(options = {}) {
256
325
  componentsSpinner.succeed(`All ${successful} Visual components installed successfully`);
257
326
  } else if (successful > 0) {
258
327
  componentsSpinner.warn(`${successful} components installed, ${failed} failed`);
259
- Print.info('You can install failed components later using "slice get <component-name>"');
328
+ Print.info(`You can install failed components later using "${packageManager} run get -- <component-name>"`);
260
329
  } else {
261
330
  componentsSpinner.fail('Failed to install Visual components');
262
331
  }
263
332
  } else {
264
333
  componentsSpinner.warn('No Visual components found in registry');
265
- Print.info('You can add components later using "slice get <component-name>"');
334
+ Print.info(`You can add components later using "${packageManager} run get -- <component-name>"`);
266
335
  }
267
336
 
268
337
  } catch (error) {
269
338
  componentsSpinner.fail('Could not download Visual components from official repository');
270
339
  Print.error(`Repository error: ${error.message}`);
271
340
  Print.info('Project initialized without Visual components');
272
- Print.info('You can add them later using "slice get <component-name>"');
341
+ Print.info(`You can add them later using "${packageManager} run get -- <component-name>"`);
273
342
  }
274
343
 
275
344
  // 3b. DOWNLOAD STARTER SERVICE COMPONENTS FROM OFFICIAL REPOSITORY
@@ -295,7 +364,7 @@ export default async function initializeProject(options = {}) {
295
364
  serviceSpinner.succeed(`All ${successful} Service components installed successfully`);
296
365
  } else if (successful > 0) {
297
366
  serviceSpinner.warn(`${successful} Service components installed, ${failed} failed`);
298
- Print.info('You can install failed components later using "slice get <component-name>"');
367
+ Print.info(`You can install failed components later using "${packageManager} run get -- <component-name>"`);
299
368
  } else {
300
369
  serviceSpinner.fail('Failed to install Service components');
301
370
  }
@@ -305,7 +374,7 @@ export default async function initializeProject(options = {}) {
305
374
  } catch (error) {
306
375
  serviceSpinner.fail('Could not download Service components from official repository');
307
376
  Print.error(`Repository error: ${error.message}`);
308
- Print.info('You can add them later using "slice get <component-name>"');
377
+ Print.info(`You can add them later using "${packageManager} run get -- <component-name>"`);
309
378
  }
310
379
 
311
380
  // 4. CONFIGURE SCRIPTS IN PROJECT package.json
@@ -330,25 +399,25 @@ export default async function initializeProject(options = {}) {
330
399
  pkg.scripts = pkg.scripts || {};
331
400
  pkg.dependencies = pkg.dependencies || {};
332
401
 
333
- // Comandos principales
334
- pkg.scripts['dev'] = 'slice dev';
335
- pkg.scripts['build'] = 'slice build';
336
- pkg.scripts['start'] = 'slice start';
402
+ // Main scripts (local CLI path, no global launcher dependency)
403
+ pkg.scripts['dev'] = SLICE_SCRIPTS['slice:dev'];
404
+ pkg.scripts['build'] = SLICE_SCRIPTS['slice:build'];
405
+ pkg.scripts['start'] = SLICE_SCRIPTS['slice:start'];
337
406
 
338
407
  // Component management
339
- pkg.scripts['component:create'] = 'slice component create';
340
- pkg.scripts['component:list'] = 'slice component list';
341
- pkg.scripts['component:delete'] = 'slice component delete';
408
+ pkg.scripts['component:create'] = SLICE_SCRIPTS['slice:create'];
409
+ pkg.scripts['component:list'] = SLICE_SCRIPTS['slice:list'];
410
+ pkg.scripts['component:delete'] = SLICE_SCRIPTS['slice:delete'];
342
411
 
343
- // Atajos de repositorio
344
- pkg.scripts['get'] = 'slice get';
345
- pkg.scripts['browse'] = 'slice browse';
346
- pkg.scripts['sync'] = 'slice sync';
412
+ // Registry shortcuts
413
+ pkg.scripts['get'] = SLICE_SCRIPTS['slice:get'];
414
+ pkg.scripts['browse'] = SLICE_SCRIPTS['slice:browse'];
415
+ pkg.scripts['sync'] = SLICE_SCRIPTS['slice:sync'];
347
416
 
348
417
  // slice:* namespaced set — shared with post.js and `slice postinstall`
349
418
  // (commands/utils/sliceScripts.js) so the three never drift apart.
350
419
  Object.assign(pkg.scripts, SLICE_SCRIPTS);
351
- pkg.scripts['run'] = 'slice dev';
420
+ pkg.scripts['run'] = SLICE_SCRIPTS['slice:dev'];
352
421
 
353
422
  // Module configuration
354
423
  pkg.type = 'module';
@@ -378,9 +447,9 @@ export default async function initializeProject(options = {}) {
378
447
  Print.title('Next steps:');
379
448
  console.log(` cd ${projectName}`);
380
449
  console.log(` ${packageManager} run dev - Start development server`);
381
- console.log(' slice browse - View available components');
382
- console.log(' slice get Button - Install specific components');
383
- console.log(' slice sync - Update all components to latest versions');
450
+ console.log(` ${packageManager} run browse - View available components`);
451
+ console.log(` ${packageManager} run get -- Button - Install specific components`);
452
+ console.log(` ${packageManager} run sync - Update all components to latest versions`);
384
453
 
385
454
  } catch (error) {
386
455
  Print.error('Unexpected error initializing project:', error.message);
@@ -1,29 +1,28 @@
1
1
  // commands/utils/PackageManager.js
2
2
  //
3
- // Package manager detection and command building (npm / pnpm / yarn).
3
+ // Package manager detection and command building (pnpm / npm).
4
4
  // Resolution priority for an existing project:
5
5
  // 1. "packageManager" field in the project package.json (corepack convention)
6
6
  // 2. Lockfile present at the project root
7
7
  // 3. npm_config_user_agent (set when the CLI runs via `npx` / `pnpm dlx` / a PM script)
8
8
  // 4. The only PM binary available on PATH (if exactly one)
9
9
  // When everything is ambiguous, detectPackageManager() returns null so callers
10
- // can prompt the user (interactive init) or fall back to npm (non-interactive).
10
+ // can prompt the user (interactive init) or fall back to pnpm (non-interactive).
11
11
 
12
12
  import fs from 'fs-extra'
13
13
  import path from 'path'
14
14
  import { spawnSync } from 'node:child_process'
15
15
 
16
- export const SUPPORTED_PACKAGE_MANAGERS = ['npm', 'pnpm', 'yarn']
16
+ export const SUPPORTED_PACKAGE_MANAGERS = ['pnpm', 'npm']
17
17
 
18
18
  const LOCKFILES = {
19
19
  'pnpm-lock.yaml': 'pnpm',
20
- 'package-lock.json': 'npm',
21
- 'yarn.lock': 'yarn'
20
+ 'package-lock.json': 'npm'
22
21
  }
23
22
 
24
23
  export function parseUserAgent(userAgent = process.env.npm_config_user_agent) {
25
24
  if (!userAgent) return null
26
- const match = userAgent.match(/^(npm|pnpm|yarn)\/(\S+)/)
25
+ const match = userAgent.match(/^(npm|pnpm)\/(\S+)/)
27
26
  if (!match) return null
28
27
  return { name: match[1], version: match[2], source: 'user-agent' }
29
28
  }
@@ -34,7 +33,7 @@ export function fromPackageManagerField(projectRoot) {
34
33
  if (!fs.pathExistsSync(pkgPath)) return null
35
34
  const pkg = fs.readJsonSync(pkgPath)
36
35
  if (typeof pkg.packageManager !== 'string') return null
37
- const match = pkg.packageManager.match(/^(npm|pnpm|yarn)@(\S+)/)
36
+ const match = pkg.packageManager.match(/^(npm|pnpm)@(\S+)/)
38
37
  if (!match) return null
39
38
  return { name: match[1], version: match[2], source: 'package-manager-field' }
40
39
  } catch {
@@ -109,7 +108,7 @@ export function detectPackageManager(projectRoot, { userAgent = process.env.npm_
109
108
  }
110
109
 
111
110
  /**
112
- * Non-interactive resolution: detection first, then npm if available,
111
+ * Non-interactive resolution: detection first, then pnpm if available,
113
112
  * then whatever binary exists. Never returns null so update/doctor flows
114
113
  * always have a usable PM name (commands fail later with a clear error
115
114
  * if no PM is actually installed).
@@ -119,16 +118,17 @@ export function resolvePackageManager(projectRoot, options = {}) {
119
118
  if (detected) return detected
120
119
 
121
120
  const available = getAvailablePackageManagers()
121
+ if (available.includes('pnpm')) return { name: 'pnpm', version: null, source: 'fallback' }
122
122
  if (available.includes('npm')) return { name: 'npm', version: null, source: 'fallback' }
123
123
  if (available.length > 0) return { name: available[0], version: null, source: 'fallback' }
124
- return { name: 'npm', version: null, source: 'fallback (none detected)' }
124
+ return { name: 'pnpm', version: null, source: 'fallback (none detected)' }
125
125
  }
126
126
 
127
127
  export function installCommand(pmName, packages, { dev = false, global: isGlobal = false } = {}) {
128
128
  const pkgs = Array.isArray(packages) ? packages.join(' ') : packages
129
129
  const flags = [isGlobal ? '-g' : '', dev ? '-D' : ''].filter(Boolean).join(' ')
130
130
  const flagSuffix = flags ? ` ${flags}` : ''
131
- if (pmName === 'pnpm' || pmName === 'yarn') {
131
+ if (pmName === 'pnpm') {
132
132
  return `${pmName} add${flagSuffix} ${pkgs}`
133
133
  }
134
134
  return `npm install${flagSuffix} ${pkgs}`
@@ -137,7 +137,7 @@ export function installCommand(pmName, packages, { dev = false, global: isGlobal
137
137
  export function uninstallCommand(pmName, packages, { global: isGlobal = false } = {}) {
138
138
  const pkgs = Array.isArray(packages) ? packages.join(' ') : packages
139
139
  const flagSuffix = isGlobal ? ' -g' : ''
140
- if (pmName === 'pnpm' || pmName === 'yarn') {
140
+ if (pmName === 'pnpm') {
141
141
  return `${pmName} remove${flagSuffix} ${pkgs}`
142
142
  }
143
143
  return `npm uninstall${flagSuffix} ${pkgs}`
@@ -5,17 +5,19 @@
5
5
  // client.js, and `slice init` — so the three can never drift apart (they did:
6
6
  // client.js was missing slice:types, and none of them had slice:build).
7
7
  export const SLICE_SCRIPTS = {
8
- 'slice:init': 'slice init',
9
- 'slice:dev': 'slice dev',
10
- 'slice:build': 'slice build',
11
- 'slice:start': 'slice start',
12
- 'slice:create': 'slice component create',
13
- 'slice:list': 'slice component list',
14
- 'slice:delete': 'slice component delete',
15
- 'slice:get': 'slice get',
16
- 'slice:browse': 'slice browse',
17
- 'slice:sync': 'slice sync',
18
- 'slice:version': 'slice version',
19
- 'slice:update': 'slice update',
20
- 'slice:types': 'slice types generate',
8
+ 'slice:init': 'node ./node_modules/slicejs-cli/client.js init',
9
+ 'slice:dev': 'node ./node_modules/slicejs-cli/client.js dev',
10
+ 'slice:build': 'node ./node_modules/slicejs-cli/client.js build',
11
+ 'slice:start': 'node ./node_modules/slicejs-cli/client.js start',
12
+ 'slice:create': 'node ./node_modules/slicejs-cli/client.js component create',
13
+ 'slice:list': 'node ./node_modules/slicejs-cli/client.js component list',
14
+ 'slice:delete': 'node ./node_modules/slicejs-cli/client.js component delete',
15
+ 'slice:get': 'node ./node_modules/slicejs-cli/client.js get',
16
+ 'slice:browse': 'node ./node_modules/slicejs-cli/client.js browse',
17
+ 'slice:sync': 'node ./node_modules/slicejs-cli/client.js sync',
18
+ 'slice:doctor': 'node ./node_modules/slicejs-cli/client.js doctor',
19
+ 'slice:version': 'node ./node_modules/slicejs-cli/client.js version',
20
+ 'slice:help': 'node ./node_modules/slicejs-cli/client.js --help',
21
+ 'slice:update': 'node ./node_modules/slicejs-cli/client.js update',
22
+ 'slice:types': 'node ./node_modules/slicejs-cli/client.js types generate',
21
23
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slicejs-cli",
3
- "version": "3.6.0",
3
+ "version": "3.6.2",
4
4
  "description": "Command client for developing web applications with Slice.js framework",
5
5
  "main": "client.js",
6
6
  "bin": {
@@ -34,7 +34,9 @@
34
34
  "slice:sync": "slice sync",
35
35
  "slice:version": "slice version",
36
36
  "slice:update": "slice update",
37
- "slice:types": "slice types generate"
37
+ "slice:types": "slice types generate",
38
+ "slice:doctor": "node ./node_modules/slicejs-cli/client.js doctor",
39
+ "slice:help": "node ./node_modules/slicejs-cli/client.js --help"
38
40
  },
39
41
  "keywords": [
40
42
  "framework",
@@ -69,4 +71,4 @@
69
71
  "devDependencies": {
70
72
  "@playwright/test": "^1.60.0"
71
73
  }
72
- }
74
+ }
package/post.js CHANGED
@@ -3,6 +3,7 @@ import path from 'path';
3
3
  import { fileURLToPath } from 'url';
4
4
  import { getProjectRoot, getPath } from './commands/utils/PathHelper.js';
5
5
  import { SLICE_SCRIPTS } from './commands/utils/sliceScripts.js';
6
+ import { resolvePackageManager, runScriptCommand } from './commands/utils/PackageManager.js';
6
7
 
7
8
  const __filename = fileURLToPath(import.meta.url);
8
9
 
@@ -21,6 +22,7 @@ if (isGlobal) {
21
22
 
22
23
  const projectRoot = getProjectRoot(import.meta.url);
23
24
  const pkgPath = getPath(import.meta.url, 'package.json');
25
+ const packageManager = resolvePackageManager(projectRoot).name;
24
26
 
25
27
  const sliceScripts = SLICE_SCRIPTS;
26
28
 
@@ -47,12 +49,12 @@ try {
47
49
  }
48
50
 
49
51
  fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2), 'utf-8');
50
- console.log(`✅ slicejs-cli installed successfully. Added ${addedCount} npm scripts to package.json.`);
51
- console.log(' Run: npm run slice:dev');
52
+ console.log(`✅ slicejs-cli installed successfully. Added ${addedCount} package scripts to package.json.`);
53
+ console.log(` Run: ${runScriptCommand(packageManager, 'slice:dev')}`);
52
54
  } catch (err) {
53
55
  console.log('✅ slicejs-cli installed successfully.');
54
56
  console.log(' Could not auto-configure scripts:', err.message);
55
- console.log(' Run: npx slice dev');
57
+ console.log(` Configure scripts manually and run: ${runScriptCommand(packageManager, 'slice:dev')}`);
56
58
  }
57
59
 
58
60
  process.exit(0);