@evident-ai/cli 3.1.1-dev.7ab010b → 3.1.1-dev.7b045d5

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/dist/index.js CHANGED
@@ -11,8 +11,8 @@ import chalk2 from "chalk";
11
11
 
12
12
  // src/lib/config.ts
13
13
  import Conf from "conf";
14
- import { homedir } from "os";
15
- import { join } from "path";
14
+ import { chmodSync, existsSync, statSync } from "fs";
15
+ import { dirname } from "path";
16
16
  var PRODUCTION_API_URL = "https://api.production.evident.run/v1";
17
17
  var PRODUCTION_TUNNEL_URL = "wss://tunnel.production.evident.run";
18
18
  var defaults = {
@@ -47,8 +47,35 @@ var credentials = new Conf({
47
47
  projectName: "evident",
48
48
  projectSuffix: "",
49
49
  configName: "credentials",
50
- defaults: {}
50
+ defaults: {},
51
+ configFileMode: 384
51
52
  });
53
+ var CREDENTIALS_FILE_MODE = 384;
54
+ var CREDENTIALS_DIR_MODE = 448;
55
+ var permissionWarningEmitted = false;
56
+ function hardenCredentialsPermissions() {
57
+ if (process.platform === "win32") {
58
+ return;
59
+ }
60
+ const file = credentials.path;
61
+ for (const [path, mode] of [
62
+ [file, CREDENTIALS_FILE_MODE],
63
+ [dirname(file), CREDENTIALS_DIR_MODE]
64
+ ]) {
65
+ try {
66
+ if (existsSync(path) && (statSync(path).mode & 511) !== mode) {
67
+ chmodSync(path, mode);
68
+ }
69
+ } catch (err) {
70
+ if (!permissionWarningEmitted) {
71
+ permissionWarningEmitted = true;
72
+ console.error(
73
+ `[config] could not restrict permissions on ${path}; the credentials file may be readable by other users on this machine: ${err instanceof Error ? err.message : String(err)}`
74
+ );
75
+ }
76
+ }
77
+ }
78
+ }
52
79
  function getApiUrlConfig() {
53
80
  return getApiUrl();
54
81
  }
@@ -59,6 +86,7 @@ function credentialsKey() {
59
86
  return getApiUrl();
60
87
  }
61
88
  function getCredentials() {
89
+ hardenCredentialsPermissions();
62
90
  const byEndpoint = credentials.get("byEndpoint") ?? {};
63
91
  return byEndpoint[credentialsKey()] ?? {};
64
92
  }
@@ -70,14 +98,17 @@ function setCredentials(creds) {
70
98
  expiresAt: creds.expiresAt
71
99
  };
72
100
  credentials.set("byEndpoint", byEndpoint);
101
+ hardenCredentialsPermissions();
73
102
  }
74
103
  function clearCredentials() {
75
104
  const byEndpoint = credentials.get("byEndpoint") ?? {};
76
105
  delete byEndpoint[credentialsKey()];
77
106
  credentials.set("byEndpoint", byEndpoint);
107
+ hardenCredentialsPermissions();
78
108
  }
79
109
  function clearAllCredentials() {
80
110
  credentials.clear();
111
+ hardenCredentialsPermissions();
81
112
  }
82
113
  function getCliName() {
83
114
  const argv1 = process.argv[1] || "";
@@ -373,7 +404,8 @@ async function deviceFlowLogin(options) {
373
404
  }
374
405
  async function tokenLogin() {
375
406
  console.log("Token login mode.");
376
- console.log("Visit your Evident dashboard to generate a CLI token.");
407
+ console.log("Run `evident login` on a machine with a browser to get a token.");
408
+ console.log("Manage or revoke existing tokens under Settings \u2192 CLI tokens.");
377
409
  blank();
378
410
  process.stdout.write("Paste token: ");
379
411
  const token = await new Promise((resolve3) => {
@@ -467,8 +499,8 @@ async function whoami() {
467
499
  }
468
500
 
469
501
  // src/commands/run.ts
470
- import { homedir as homedir3 } from "os";
471
- import { isAbsolute as isAbsolute2, join as join3, parse, resolve as resolvePath } from "path";
502
+ import { homedir as homedir2 } from "os";
503
+ import { isAbsolute as isAbsolute2, join as join2, parse, resolve as resolvePath } from "path";
472
504
  import chalk6 from "chalk";
473
505
 
474
506
  // ../../packages/types/src/telemetry/index.ts
@@ -2042,12 +2074,12 @@ var RunnerConnection = class {
2042
2074
  };
2043
2075
 
2044
2076
  // src/lib/channels/driver.ts
2045
- import { homedir as homedir2 } from "os";
2077
+ import { homedir } from "os";
2046
2078
 
2047
2079
  // src/lib/file-push.ts
2048
2080
  import { randomUUID } from "crypto";
2049
2081
  import { chmod, mkdir, open as open2, realpath, rename, unlink } from "fs/promises";
2050
- import { basename, dirname, isAbsolute, join as join2, relative, resolve as resolve2, sep } from "path";
2082
+ import { basename, dirname as dirname2, isAbsolute, join, relative, resolve as resolve2, sep } from "path";
2051
2083
  var FILE_MODE = 384;
2052
2084
  var DIRECTORY_MODE = 448;
2053
2085
  async function writePushedFile(request) {
@@ -2078,9 +2110,9 @@ async function writePushedFile(request) {
2078
2110
  }
2079
2111
  try {
2080
2112
  const { existingAncestor, missingSegments } = await resolveNearestExistingAncestor(
2081
- dirname(candidate)
2113
+ dirname2(candidate)
2082
2114
  );
2083
- const realTarget = join2(existingAncestor, ...missingSegments, basename(candidate));
2115
+ const realTarget = join(existingAncestor, ...missingSegments, basename(candidate));
2084
2116
  const allowedDirectory = await findContainingAllowedDirectory(allowedDirectories, realTarget);
2085
2117
  if (allowedDirectory === null) {
2086
2118
  return refuse("path_not_allowed", "The runner does not allow writing to that location.", {
@@ -2090,8 +2122,8 @@ async function writePushedFile(request) {
2090
2122
  }
2091
2123
  if (missingSegments.length > 0) {
2092
2124
  await createMissingDirectories(existingAncestor, missingSegments);
2093
- const realParent = await realpath(dirname(realTarget));
2094
- if (realParent !== dirname(realTarget) || !contains(allowedDirectory, realTarget)) {
2125
+ const realParent = await realpath(dirname2(realTarget));
2126
+ if (realParent !== dirname2(realTarget) || !contains(allowedDirectory, realTarget)) {
2095
2127
  return refuse("path_not_allowed", "The runner does not allow writing to that location.", {
2096
2128
  path: realTarget,
2097
2129
  bytes,
@@ -2116,7 +2148,7 @@ function expandAndValidate(requestedPath, homeDir) {
2116
2148
  if (requestedPath.trim() === "" || requestedPath.includes("\0")) {
2117
2149
  return null;
2118
2150
  }
2119
- const expanded = requestedPath === "~" ? homeDir : requestedPath.startsWith("~/") ? join2(homeDir, requestedPath.slice(2)) : requestedPath;
2151
+ const expanded = requestedPath === "~" ? homeDir : requestedPath.startsWith("~/") ? join(homeDir, requestedPath.slice(2)) : requestedPath;
2120
2152
  if (expanded.split(/[/\\]/).includes("..")) {
2121
2153
  return null;
2122
2154
  }
@@ -2134,7 +2166,7 @@ async function resolveNearestExistingAncestor(directory) {
2134
2166
  try {
2135
2167
  return { existingAncestor: await realpath(current), missingSegments };
2136
2168
  } catch (err) {
2137
- const parent = dirname(current);
2169
+ const parent = dirname2(current);
2138
2170
  if (err.code !== "ENOENT" || parent === current) {
2139
2171
  throw err;
2140
2172
  }
@@ -2189,13 +2221,13 @@ function contains(realDirectory, realTarget) {
2189
2221
  async function createMissingDirectories(existingAncestor, missingSegments) {
2190
2222
  let current = existingAncestor;
2191
2223
  for (const segment of missingSegments) {
2192
- current = join2(current, segment);
2224
+ current = join(current, segment);
2193
2225
  await mkdir(current, { recursive: true, mode: DIRECTORY_MODE });
2194
2226
  await chmod(current, DIRECTORY_MODE);
2195
2227
  }
2196
2228
  }
2197
2229
  async function writeAtomically(realTarget, content) {
2198
- const temporaryPath = join2(dirname(realTarget), `.evident-push-${randomUUID()}.tmp`);
2230
+ const temporaryPath = join(dirname2(realTarget), `.evident-push-${randomUUID()}.tmp`);
2199
2231
  let handle;
2200
2232
  try {
2201
2233
  handle = await open2(temporaryPath, "wx", FILE_MODE);
@@ -2708,7 +2740,7 @@ var ChannelDriver = class _ChannelDriver {
2708
2740
  this.stuckQueuedMs = config2.stuckQueuedMs ?? DEFAULT_STUCK_QUEUED_MS;
2709
2741
  this.now = config2.now ?? (() => Date.now());
2710
2742
  this.fileSyncDirectories = config2.fileSyncDirectories ?? [];
2711
- this.homeDir = config2.homeDir ?? homedir2();
2743
+ this.homeDir = config2.homeDir ?? homedir();
2712
2744
  }
2713
2745
  /** The IPv4-loopback base URL for the local `opencode serve`. */
2714
2746
  get opencodeBase() {
@@ -5106,7 +5138,7 @@ function resolveFileSyncDirectories(raw, homeDir) {
5106
5138
  if (trimmed === "") {
5107
5139
  throw new Error("--enable-file-sync-to requires a directory path (got an empty value)");
5108
5140
  }
5109
- const expanded = trimmed === "~" ? homeDir : trimmed.startsWith("~/") ? join3(homeDir, trimmed.slice(2)) : trimmed;
5141
+ const expanded = trimmed === "~" ? homeDir : trimmed.startsWith("~/") ? join2(homeDir, trimmed.slice(2)) : trimmed;
5110
5142
  if (!isAbsolute2(expanded)) {
5111
5143
  throw new Error(`--enable-file-sync-to requires an absolute directory path; got "${entry}"`);
5112
5144
  }
@@ -5447,7 +5479,7 @@ async function run(options) {
5447
5479
  let fileSyncDirectories;
5448
5480
  try {
5449
5481
  logLevel = resolveLogLevel(options);
5450
- fileSyncDirectories = resolveFileSyncDirectories(options.enableFileSyncTo, homedir3());
5482
+ fileSyncDirectories = resolveFileSyncDirectories(options.enableFileSyncTo, homedir2());
5451
5483
  } catch (error2) {
5452
5484
  const message = error2 instanceof Error ? error2.message : String(error2);
5453
5485
  if (options.json) {
@@ -5682,7 +5714,7 @@ async function run(options) {
5682
5714
  // #559: the `--enable-file-sync-to` allow-list. Empty ⇒ pending files are
5683
5715
  // REJECTED with `file_sync_disabled` on the ack, not silently ignored.
5684
5716
  fileSyncDirectories,
5685
- homeDir: homedir3(),
5717
+ homeDir: homedir2(),
5686
5718
  log: (entry) => (
5687
5719
  // Thread the driver's real level straight through so `debug`/`warn`
5688
5720
  // survive the sink filter (they no longer collapse to info). `type`