cli4ai 1.1.3 → 1.1.5
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/package.json +1 -1
- package/src/commands/add.ts +11 -9
package/package.json
CHANGED
package/src/commands/add.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* cli4ai add - Install packages
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { existsSync, symlinkSync, mkdirSync, cpSync, rmSync } from 'fs';
|
|
5
|
+
import { existsSync, symlinkSync, mkdirSync, cpSync, rmSync, readdirSync, statSync, unlinkSync, lstatSync } from 'fs';
|
|
6
6
|
import { resolve, dirname, join, basename, normalize } from 'path';
|
|
7
7
|
import { createInterface } from 'readline';
|
|
8
8
|
import { tmpdir } from 'os';
|
|
@@ -107,8 +107,6 @@ async function confirm(message: string): Promise<boolean> {
|
|
|
107
107
|
* Validate extracted tarball paths to prevent path traversal attacks
|
|
108
108
|
*/
|
|
109
109
|
function validateTarballPaths(extractedDir: string): boolean {
|
|
110
|
-
const { readdirSync, statSync } = require('fs');
|
|
111
|
-
|
|
112
110
|
function checkPath(dir: string): boolean {
|
|
113
111
|
const entries = readdirSync(dir, { withFileTypes: true });
|
|
114
112
|
for (const entry of entries) {
|
|
@@ -151,12 +149,15 @@ async function downloadFromNpm(packageName: string, targetDir: string): Promise<
|
|
|
151
149
|
encoding: 'utf-8'
|
|
152
150
|
});
|
|
153
151
|
|
|
152
|
+
if (packResult.error) {
|
|
153
|
+
throw new Error(`npm not found or failed to execute: ${packResult.error.message}`);
|
|
154
|
+
}
|
|
155
|
+
|
|
154
156
|
if (packResult.status !== 0) {
|
|
155
|
-
throw new Error(`
|
|
157
|
+
throw new Error(`npm pack failed: ${packResult.stderr || packResult.stdout || 'unknown error'}`);
|
|
156
158
|
}
|
|
157
159
|
|
|
158
160
|
// Find the tarball (it will be named like cli4ai-slack-1.0.2.tgz)
|
|
159
|
-
const { readdirSync } = await import('fs');
|
|
160
161
|
const files = readdirSync(tmpDir);
|
|
161
162
|
const tarball = files.find(f => f.endsWith('.tgz'));
|
|
162
163
|
|
|
@@ -501,17 +502,19 @@ async function resolvePackage(
|
|
|
501
502
|
|
|
502
503
|
// Auto-resolve to @cli4ai/ scope and try npm
|
|
503
504
|
const scopedName = `@cli4ai/${pkg}`;
|
|
505
|
+
let npmError: string | undefined;
|
|
504
506
|
try {
|
|
505
507
|
log(`Resolving ${pkg} as ${scopedName}...`);
|
|
506
508
|
const pkgPath = await downloadFromNpm(scopedName, targetDir);
|
|
507
509
|
const manifest = loadManifest(pkgPath);
|
|
508
510
|
return { manifest, path: pkgPath, fromNpm: true };
|
|
509
|
-
} catch {
|
|
510
|
-
|
|
511
|
+
} catch (err) {
|
|
512
|
+
npmError = err instanceof Error ? err.message : String(err);
|
|
511
513
|
}
|
|
512
514
|
|
|
513
515
|
outputError('NOT_FOUND', `Package not found: ${pkg}`, {
|
|
514
|
-
hint: `Tried @cli4ai/${pkg} on npm. Use --local flag for local paths, or add a local registry with "cli4ai config --add-registry <path>"
|
|
516
|
+
hint: `Tried @cli4ai/${pkg} on npm. Use --local flag for local paths, or add a local registry with "cli4ai config --add-registry <path>"`,
|
|
517
|
+
npmError
|
|
515
518
|
});
|
|
516
519
|
}
|
|
517
520
|
|
|
@@ -527,7 +530,6 @@ async function installPackage(
|
|
|
527
530
|
// Remove existing if present
|
|
528
531
|
if (existsSync(pkgDir)) {
|
|
529
532
|
try {
|
|
530
|
-
const { unlinkSync, rmSync, lstatSync } = await import('fs');
|
|
531
533
|
const stat = lstatSync(pkgDir);
|
|
532
534
|
if (stat.isSymbolicLink()) {
|
|
533
535
|
unlinkSync(pkgDir);
|