@enactprotocol/cli 2.3.1 → 2.3.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.
@@ -225,27 +225,31 @@ async function learnHandler(
225
225
  const attestations = attestationsResponse.attestations;
226
226
 
227
227
  if (attestations.length === 0) {
228
- // No attestations found
229
- info(`${symbols.warning} Tool ${toolName}@${version} has no attestations.`);
228
+ // No attestations found — but if minimum_attestations is 0, that's fine
229
+ if (minimumAttestations === 0) {
230
+ // User explicitly configured zero required attestations — allow access
231
+ } else {
232
+ info(`${symbols.warning} Tool ${toolName}@${version} has no attestations.`);
230
233
 
231
- if (trustPolicy === "require_attestation") {
232
- throw new TrustError(
233
- "Trust policy requires attestations. Cannot display documentation from unverified tools."
234
- );
235
- }
236
- if (ctx.isInteractive && trustPolicy === "prompt") {
237
- dim("Documentation from unverified tools may contain malicious content.");
238
- const proceed = await confirm("View documentation from unverified tool?");
239
- if (!proceed) {
240
- info("Cancelled.");
241
- process.exit(0);
234
+ if (trustPolicy === "require_attestation") {
235
+ throw new TrustError(
236
+ "Trust policy requires attestations. Cannot display documentation from unverified tools."
237
+ );
238
+ }
239
+ if (ctx.isInteractive && trustPolicy === "prompt") {
240
+ dim("Documentation from unverified tools may contain malicious content.");
241
+ const proceed = await confirm("View documentation from unverified tool?");
242
+ if (!proceed) {
243
+ info("Cancelled.");
244
+ process.exit(0);
245
+ }
246
+ } else if (!ctx.isInteractive && trustPolicy === "prompt") {
247
+ throw new TrustError(
248
+ "Cannot display documentation from unverified tools in non-interactive mode."
249
+ );
242
250
  }
243
- } else if (!ctx.isInteractive && trustPolicy === "prompt") {
244
- throw new TrustError(
245
- "Cannot display documentation from unverified tools in non-interactive mode."
246
- );
247
251
  }
248
- // trustPolicy === "allow" - continue without prompting
252
+ // trustPolicy === "allow" or minimumAttestations === 0 - continue without prompting
249
253
  } else {
250
254
  // Verify attestations locally (never trust registry's verification status)
251
255
  const verifiedAuditors = await verifyAllAttestations(
@@ -318,22 +318,22 @@ function atomicReplace(targetDir: string, sourceDir: string): void {
318
318
  async function extractToCache(
319
319
  bundleData: ArrayBuffer,
320
320
  toolName: string,
321
- version: string
321
+ _version: string
322
322
  ): Promise<string> {
323
323
  const cacheDir = getCacheDir();
324
324
  const toolPath = toolNameToPath(toolName);
325
- const versionDir = join(cacheDir, toolPath, `v${version.replace(/^v/, "")}`);
325
+ const destDir = join(cacheDir, toolPath);
326
326
 
327
327
  // Create a temporary file for the bundle
328
328
  const tempFile = join(cacheDir, `bundle-${Date.now()}.tar.gz`);
329
329
  mkdirSync(dirname(tempFile), { recursive: true });
330
330
  writeFileSync(tempFile, Buffer.from(bundleData));
331
331
 
332
- // Create destination directory
333
- mkdirSync(versionDir, { recursive: true });
332
+ // Create destination directory (flat, no version subdirectory — matches resolver)
333
+ mkdirSync(destDir, { recursive: true });
334
334
 
335
335
  // Extract using tar command
336
- const proc = Bun.spawn(["tar", "-xzf", tempFile, "-C", versionDir], {
336
+ const proc = Bun.spawn(["tar", "-xzf", tempFile, "-C", destDir], {
337
337
  stdout: "pipe",
338
338
  stderr: "pipe",
339
339
  });
@@ -352,7 +352,7 @@ async function extractToCache(
352
352
  throw new Error(`Failed to extract bundle: ${stderr}`);
353
353
  }
354
354
 
355
- return versionDir;
355
+ return destDir;
356
356
  }
357
357
 
358
358
  /**
@@ -450,22 +450,26 @@ async function fetchAndCacheTool(
450
450
  const attestations = attestationsResponse.attestations;
451
451
 
452
452
  if (attestations.length === 0) {
453
- // No attestations found
454
- info(`${symbols.warning} Tool ${toolName}@${targetVersion} has no attestations.`);
453
+ // No attestations found — but if minimum_attestations is 0, that's fine
454
+ if (minimumAttestations === 0) {
455
+ // User explicitly configured zero required attestations — allow execution
456
+ } else {
457
+ info(`${symbols.warning} Tool ${toolName}@${targetVersion} has no attestations.`);
455
458
 
456
- if (trustPolicy === "require_attestation") {
457
- throw new TrustError("Trust policy requires attestations. Execution blocked.");
458
- }
459
- if (ctx.isInteractive && trustPolicy === "prompt") {
460
- const proceed = await confirm("Run unverified tool?");
461
- if (!proceed) {
462
- info("Execution cancelled.");
463
- process.exit(0);
459
+ if (trustPolicy === "require_attestation") {
460
+ throw new TrustError("Trust policy requires attestations. Execution blocked.");
461
+ }
462
+ if (ctx.isInteractive && trustPolicy === "prompt") {
463
+ const proceed = await confirm("Run unverified tool?");
464
+ if (!proceed) {
465
+ info("Execution cancelled.");
466
+ process.exit(0);
467
+ }
468
+ } else if (!ctx.isInteractive && trustPolicy === "prompt") {
469
+ throw new TrustError("Cannot run unverified tools in non-interactive mode.");
464
470
  }
465
- } else if (!ctx.isInteractive && trustPolicy === "prompt") {
466
- throw new TrustError("Cannot run unverified tools in non-interactive mode.");
467
471
  }
468
- // trustPolicy === "allow" - continue without prompting
472
+ // trustPolicy === "allow" or minimumAttestations === 0 - continue without prompting
469
473
  } else {
470
474
  // Verify attestations locally (never trust registry's verification status)
471
475
  const verifiedAuditors = await verifyAllAttestations(
package/src/index.ts CHANGED
@@ -37,7 +37,7 @@ import {
37
37
  } from "./commands";
38
38
  import { error, formatError } from "./utils";
39
39
 
40
- export const version = "2.3.1";
40
+ export const version = "2.3.5";
41
41
 
42
42
  // Export types for external use
43
43
  export type { GlobalOptions, CommandContext } from "./types";