codeam-cli 2.16.1 → 2.16.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.
Files changed (2) hide show
  1. package/dist/index.js +93 -21
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -424,7 +424,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
424
424
  // package.json
425
425
  var package_default = {
426
426
  name: "codeam-cli",
427
- version: "2.16.1",
427
+ version: "2.16.2",
428
428
  description: "Workflow-continuity bridge for AI coding agents. Wrap Claude Code or Codex in a PTY and supervise, approve, and redirect the session from any device \u2014 async. The terminal companion for CodeAgent Mobile.",
429
429
  type: "commonjs",
430
430
  main: "dist/index.js",
@@ -6262,6 +6262,7 @@ var HistoryService = class _HistoryService {
6262
6262
 
6263
6263
  // src/services/file-watcher.service.ts
6264
6264
  var import_child_process7 = require("child_process");
6265
+ var os13 = __toESM(require("os"));
6265
6266
  var path15 = __toESM(require("path"));
6266
6267
 
6267
6268
  // src/services/file-watcher/diff-parser.ts
@@ -6397,6 +6398,44 @@ var API_BASE5 = process.env.CODEAM_API_URL ?? DEFAULT_API_BASE_URL;
6397
6398
  var DEBOUNCE_MS = 250;
6398
6399
  var MAX_RETRIES = 2;
6399
6400
  var RETRY_BACKOFF_MS = 300;
6401
+ var WINDOWS_LEGACY_JUNCTIONS = [
6402
+ /[\\/]Application Data([\\/]|$)/i,
6403
+ /[\\/]Cookies([\\/]|$)/i,
6404
+ /[\\/]Local Settings([\\/]|$)/i,
6405
+ /[\\/]My Documents([\\/]|$)/i,
6406
+ /[\\/]NetHood([\\/]|$)/i,
6407
+ /[\\/]PrintHood([\\/]|$)/i,
6408
+ /[\\/]Recent([\\/]|$)/i,
6409
+ /[\\/]SendTo([\\/]|$)/i,
6410
+ /[\\/]Start Menu([\\/]|$)/i,
6411
+ /[\\/]Templates([\\/]|$)/i
6412
+ ];
6413
+ function isUnsafeWindowsWatchRoot(dir, homedir12) {
6414
+ const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
6415
+ const cwd = norm(dir);
6416
+ const home = norm(homedir12);
6417
+ if (cwd === home) return true;
6418
+ if (/^[a-z]:$/.test(cwd)) return true;
6419
+ const sysRoots = [
6420
+ "c:\\windows",
6421
+ "c:\\program files",
6422
+ "c:\\program files (x86)",
6423
+ "c:\\programdata"
6424
+ ];
6425
+ for (const root of sysRoots) {
6426
+ if (cwd === root || cwd.startsWith(root + "\\")) return true;
6427
+ }
6428
+ return false;
6429
+ }
6430
+ var _chokidarSeam = {
6431
+ load: () => {
6432
+ try {
6433
+ return require("chokidar");
6434
+ } catch {
6435
+ return null;
6436
+ }
6437
+ }
6438
+ };
6400
6439
  var FileWatcherService = class {
6401
6440
  constructor(opts) {
6402
6441
  this.opts = opts;
@@ -6419,14 +6458,19 @@ var FileWatcherService = class {
6419
6458
  if (this.stopped) {
6420
6459
  throw new Error("FileWatcherService has already been stopped \u2014 re-instantiate to restart.");
6421
6460
  }
6422
- let chokidar2;
6423
- try {
6424
- chokidar2 = require("chokidar");
6425
- } catch (err) {
6461
+ const isWin = process.platform === "win32";
6462
+ if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir, os13.homedir())) {
6463
+ log.warn(
6464
+ "fileWatcher",
6465
+ `refusing to watch ${this.opts.workingDir} \u2014 looks like a Windows user-profile or system path. Run codeam from your project folder to enable file change emission.`
6466
+ );
6467
+ return;
6468
+ }
6469
+ const chokidar2 = _chokidarSeam.load();
6470
+ if (!chokidar2) {
6426
6471
  log.warn(
6427
6472
  "fileWatcher",
6428
- `chokidar unavailable \u2014 file change emission disabled`,
6429
- err
6473
+ `chokidar unavailable \u2014 file change emission disabled`
6430
6474
  );
6431
6475
  return;
6432
6476
  }
@@ -6444,11 +6488,22 @@ var FileWatcherService = class {
6444
6488
  /\.parcel-cache/,
6445
6489
  // Build outputs that aren't a typical "dist" target
6446
6490
  /target\//,
6447
- /__pycache__/
6491
+ /__pycache__/,
6492
+ // Windows-only: skip legacy user-profile junctions whose ACLs
6493
+ // throw EPERM during chokidar's recursive traversal.
6494
+ ...isWin ? WINDOWS_LEGACY_JUNCTIONS : []
6448
6495
  ],
6449
6496
  ignoreInitial: true,
6450
6497
  // we only care about post-start changes
6451
6498
  persistent: true,
6499
+ // Windows-only safety net: don't follow reparse points, and let
6500
+ // chokidar swallow EPERM/EACCES on unreadable paths instead of
6501
+ // bubbling them up as fatal errors. Both are no-ops on macOS
6502
+ // (fsevents traversal doesn't fail on permission errors).
6503
+ ...isWin ? {
6504
+ followSymlinks: false,
6505
+ ignorePermissionErrors: true
6506
+ } : {},
6452
6507
  awaitWriteFinish: {
6453
6508
  // Coalesces rapid sequential writes (npm install spam, build
6454
6509
  // tools emitting bursts). Lower than chokidar's default so
@@ -6461,6 +6516,13 @@ var FileWatcherService = class {
6461
6516
  watcher.on("add", (filePath) => this.schedule(filePath, "add"));
6462
6517
  watcher.on("change", (filePath) => this.schedule(filePath, "change"));
6463
6518
  watcher.on("unlink", (filePath) => this.schedule(filePath, "unlink"));
6519
+ watcher.on("error", (err) => {
6520
+ const code = err?.code ?? "unknown";
6521
+ log.warn(
6522
+ "fileWatcher",
6523
+ `chokidar error (code=${code}) \u2014 watcher continues: ${err}`
6524
+ );
6525
+ });
6464
6526
  this.watcher = watcher;
6465
6527
  log.info(
6466
6528
  "fileWatcher",
@@ -7199,7 +7261,7 @@ function buildKeepAlive(ctx) {
7199
7261
 
7200
7262
  // src/commands/start/handlers.ts
7201
7263
  var fs14 = __toESM(require("fs"));
7202
- var os13 = __toESM(require("os"));
7264
+ var os14 = __toESM(require("os"));
7203
7265
  var path19 = __toESM(require("path"));
7204
7266
  var import_crypto3 = require("crypto");
7205
7267
  var import_child_process11 = require("child_process");
@@ -8007,7 +8069,7 @@ function closeTerminal(sessionId) {
8007
8069
  function saveFilesTemp(files) {
8008
8070
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
8009
8071
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
8010
- const tmpPath = path19.join(os13.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
8072
+ const tmpPath = path19.join(os14.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
8011
8073
  fs14.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
8012
8074
  return tmpPath;
8013
8075
  });
@@ -8596,7 +8658,7 @@ async function pair(args2 = []) {
8596
8658
 
8597
8659
  // src/commands/pair-auto.ts
8598
8660
  var fs15 = __toESM(require("fs"));
8599
- var os14 = __toESM(require("os"));
8661
+ var os15 = __toESM(require("os"));
8600
8662
  var import_crypto5 = require("crypto");
8601
8663
  var API_BASE7 = process.env.CODEAM_API_URL ?? DEFAULT_API_BASE_URL;
8602
8664
  function fail(msg) {
@@ -8636,7 +8698,7 @@ async function claim(token, pluginId) {
8636
8698
  pluginId,
8637
8699
  ideName: "codeam-cli (codespace)",
8638
8700
  ideVersion: process.env.npm_package_version ?? "unknown",
8639
- hostname: os14.hostname(),
8701
+ hostname: os15.hostname(),
8640
8702
  codespaceName: process.env.CODESPACE_NAME ?? "",
8641
8703
  // Current git branch of the codespace's working directory, so the
8642
8704
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -10741,7 +10803,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
10741
10803
  // src/agents/claude/local-token.ts
10742
10804
  var import_node_child_process2 = require("child_process");
10743
10805
  var fs16 = __toESM(require("fs"));
10744
- var os15 = __toESM(require("os"));
10806
+ var os16 = __toESM(require("os"));
10745
10807
  var path24 = __toESM(require("path"));
10746
10808
  var import_node_util3 = require("util");
10747
10809
  var execFileP7 = (0, import_node_util3.promisify)(import_node_child_process2.execFile);
@@ -10752,7 +10814,7 @@ var KEYCHAIN_SERVICE_NAMES = [
10752
10814
  "Anthropic Claude"
10753
10815
  ];
10754
10816
  function claudeCredentialsPaths() {
10755
- const home = os15.homedir();
10817
+ const home = os16.homedir();
10756
10818
  return [
10757
10819
  path24.join(home, ".claude", ".credentials.json"),
10758
10820
  path24.join(home, ".config", "claude", ".credentials.json")
@@ -10787,10 +10849,10 @@ async function extractLocalClaudeToken() {
10787
10849
 
10788
10850
  // src/agents/codex/local-token.ts
10789
10851
  var fs17 = __toESM(require("fs"));
10790
- var os16 = __toESM(require("os"));
10852
+ var os17 = __toESM(require("os"));
10791
10853
  var path25 = __toESM(require("path"));
10792
10854
  function codexCredentialsPath() {
10793
- return path25.join(os16.homedir(), ".codex", "auth.json");
10855
+ return path25.join(os17.homedir(), ".codex", "auth.json");
10794
10856
  }
10795
10857
  async function extractLocalCodexToken() {
10796
10858
  const file = codexCredentialsPath();
@@ -10981,10 +11043,20 @@ async function link(args2 = []) {
10981
11043
  await uploadAndSucceed(meta, paired, pluginId, captured);
10982
11044
  }
10983
11045
  async function captureFreshCredentials(meta) {
11046
+ const isWin = process.platform === "win32";
10984
11047
  const watcher = import_chokidar.default.watch(meta.watchPaths(), {
10985
11048
  persistent: true,
10986
11049
  ignoreInitial: false,
10987
- awaitWriteFinish: { stabilityThreshold: 500, pollInterval: 100 }
11050
+ awaitWriteFinish: { stabilityThreshold: 500, pollInterval: 100 },
11051
+ // Windows-only: when a credential file's ancestor is missing,
11052
+ // chokidar walks up to the closest existing parent and starts
11053
+ // traversing it. On a default Windows shell that ancestor is
11054
+ // `C:\Users\<u>`, which contains legacy junctions whose ACL makes
11055
+ // `fs.watch` throw EPERM (#43). These flags are no-ops on macOS,
11056
+ // where the user has read access to their entire home.
11057
+ ...isWin ? { followSymlinks: false, ignorePermissionErrors: true } : {}
11058
+ });
11059
+ watcher.on("error", () => {
10988
11060
  });
10989
11061
  let child = null;
10990
11062
  let keychainPoll = null;
@@ -11085,7 +11157,7 @@ async function uploadAndSucceed(meta, paired, pluginId, token) {
11085
11157
  // src/commands/version.ts
11086
11158
  var import_picocolors12 = __toESM(require("picocolors"));
11087
11159
  function version() {
11088
- const v = true ? "2.16.1" : "unknown";
11160
+ const v = true ? "2.16.2" : "unknown";
11089
11161
  console.log(`${import_picocolors12.default.bold("codeam-cli")} ${import_picocolors12.default.cyan(v)}`);
11090
11162
  }
11091
11163
 
@@ -11128,7 +11200,7 @@ function help() {
11128
11200
 
11129
11201
  // src/lib/updateNotifier.ts
11130
11202
  var fs19 = __toESM(require("fs"));
11131
- var os17 = __toESM(require("os"));
11203
+ var os18 = __toESM(require("os"));
11132
11204
  var path27 = __toESM(require("path"));
11133
11205
  var https7 = __toESM(require("https"));
11134
11206
  var import_picocolors14 = __toESM(require("picocolors"));
@@ -11137,7 +11209,7 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
11137
11209
  var TTL_MS = 24 * 60 * 60 * 1e3;
11138
11210
  var REQUEST_TIMEOUT_MS = 1500;
11139
11211
  function cachePath() {
11140
- const dir = path27.join(os17.homedir(), ".codeam");
11212
+ const dir = path27.join(os18.homedir(), ".codeam");
11141
11213
  return path27.join(dir, "update-check.json");
11142
11214
  }
11143
11215
  function readCache() {
@@ -11225,7 +11297,7 @@ function checkForUpdates() {
11225
11297
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
11226
11298
  if (process.env.CI) return;
11227
11299
  if (!process.stdout.isTTY) return;
11228
- const current = true ? "2.16.1" : null;
11300
+ const current = true ? "2.16.2" : null;
11229
11301
  if (!current) return;
11230
11302
  const cache = readCache();
11231
11303
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.16.1",
3
+ "version": "2.16.2",
4
4
  "description": "Workflow-continuity bridge for AI coding agents. Wrap Claude Code or Codex in a PTY and supervise, approve, and redirect the session from any device — async. The terminal companion for CodeAgent Mobile.",
5
5
  "type": "commonjs",
6
6
  "main": "dist/index.js",