cosmoremote 2.0.5 → 2.0.6

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/cli.js CHANGED
@@ -1,10 +1,65 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
+ const child_process_1 = require("child_process");
4
5
  const commander_1 = require("commander");
5
6
  const bridge_1 = require("./bridge");
6
7
  const DEFAULT_BACKEND_URL = process.env.BACKEND_URL ?? "wss://cosmoremote-api.azurewebsites.net";
7
8
  const DEFAULT_WORKDIR = process.env.COSMOREMOTE_WORKDIR ?? (0, bridge_1.inferWorkspaceRoot)();
9
+ /** Find any other cosmoremote bridge listening on `port` and terminate it.
10
+ * Without this, an out-of-date long-running bridge keeps serving from its
11
+ * in-memory state (old version, no folder lister, stale skills, etc.) and the
12
+ * next `cosmoremote start` aborts on EADDRINUSE — the user thinks they are on
13
+ * the latest version when they are still talking to the old daemon. */
14
+ function killExistingBridge(port) {
15
+ const ownPid = process.pid;
16
+ let pids = [];
17
+ try {
18
+ const out = (0, child_process_1.execSync)(`lsof -nP -iTCP:${port} -sTCP:LISTEN -t`, { encoding: "utf-8" }).trim();
19
+ pids = out
20
+ .split(/\s+/)
21
+ .map((s) => parseInt(s, 10))
22
+ .filter((n) => Number.isFinite(n) && n !== ownPid);
23
+ }
24
+ catch {
25
+ // No listener on that port — nothing to do.
26
+ return;
27
+ }
28
+ if (pids.length === 0)
29
+ return;
30
+ console.log(` [boot] Found ${pids.length} existing bridge process(es) on port ${port}: ${pids.join(", ")}. Terminating...`);
31
+ for (const pid of pids) {
32
+ try {
33
+ process.kill(pid, "SIGTERM");
34
+ }
35
+ catch (err) {
36
+ console.log(` [boot] SIGTERM to pid=${pid} failed: ${err.message}`);
37
+ }
38
+ }
39
+ // Poll for up to ~3s waiting for the port to free; SIGKILL stragglers.
40
+ const deadline = Date.now() + 3000;
41
+ while (Date.now() < deadline) {
42
+ try {
43
+ (0, child_process_1.execSync)(`lsof -nP -iTCP:${port} -sTCP:LISTEN -t`, { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] });
44
+ }
45
+ catch {
46
+ console.log(` [boot] Port ${port} freed.`);
47
+ return;
48
+ }
49
+ // 100ms sleep without spinning the event loop too hot
50
+ const start = Date.now();
51
+ while (Date.now() - start < 100) { /* busy-wait, bounded */ }
52
+ }
53
+ for (const pid of pids) {
54
+ try {
55
+ process.kill(pid, "SIGKILL");
56
+ console.log(` [boot] SIGKILL pid=${pid} (did not exit on SIGTERM)`);
57
+ }
58
+ catch {
59
+ /* already gone */
60
+ }
61
+ }
62
+ }
8
63
  const program = new commander_1.Command();
9
64
  program
10
65
  .name("cosmoremote")
@@ -18,8 +73,10 @@ program
18
73
  .option("-w, --workdir <path>", "Workspace directory (defaults to current directory)")
19
74
  .action(async (opts) => {
20
75
  const workdir = opts.workdir ?? DEFAULT_WORKDIR;
76
+ const port = parseInt(opts.port, 10);
77
+ killExistingBridge(port);
21
78
  await (0, bridge_1.startBridge)({
22
- port: parseInt(opts.port, 10),
79
+ port,
23
80
  backendUrl: opts.backend,
24
81
  workdir,
25
82
  });
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,qCAA2D;AAE3D,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,yCAAyC,CAAC;AACjG,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,IAAA,2BAAkB,GAAE,CAAC;AAEhF,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,CAAC,8DAA8D,CAAC;KAC3E,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,CAAC;KAC5D,MAAM,CAAC,iBAAiB,EAAE,mBAAmB,EAAE,mBAAmB,CAAC;KACnE,MAAM,CAAC,sBAAsB,EAAE,qDAAqD,CAAC;KACrF,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,eAAe,CAAC;IAChD,MAAM,IAAA,oBAAW,EAAC;QAChB,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QAC7B,UAAU,EAAE,IAAI,CAAC,OAAO;QACxB,OAAO;KACR,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -25,22 +25,31 @@ function listProjectFolders(workspaceRoot, depth = 5, max = 500) {
25
25
  if (!(0, fs_1.existsSync)(workspaceRoot))
26
26
  return [];
27
27
  const out = [];
28
- function walk(dir, currentDepth) {
29
- if (currentDepth > depth || out.length >= max)
30
- return;
28
+ // Breadth-first scan so depth 1 (the picker's "home" view) is always fully
29
+ // populated before any deeper recursion can burn through the `max` cap.
30
+ // A previous DFS walk on workspaceRoot=$HOME would recurse fully into
31
+ // /Users/foo/Applications/... and exhaust the cap before ever visiting
32
+ // Desktop/, Documents/, etc., leaving the picker apparently empty.
33
+ const queue = [
34
+ { dir: workspaceRoot, depth: 1 },
35
+ ];
36
+ while (queue.length > 0 && out.length < max) {
37
+ const node = queue.shift();
38
+ if (node.depth > depth)
39
+ continue;
31
40
  let entries;
32
41
  try {
33
- entries = (0, fs_1.readdirSync)(dir);
42
+ entries = (0, fs_1.readdirSync)(node.dir);
34
43
  }
35
44
  catch {
36
- return;
45
+ continue;
37
46
  }
38
47
  for (const entry of entries) {
39
48
  if (entry.startsWith("."))
40
49
  continue;
41
50
  if (SKIP_NAMES.has(entry))
42
51
  continue;
43
- const full = (0, path_1.join)(dir, entry);
52
+ const full = (0, path_1.join)(node.dir, entry);
44
53
  let stat;
45
54
  try {
46
55
  stat = (0, fs_1.statSync)(full);
@@ -56,12 +65,12 @@ function listProjectFolders(workspaceRoot, depth = 5, max = 500) {
56
65
  lastActivity: stat.mtime.toISOString(),
57
66
  });
58
67
  if (out.length >= max)
59
- return;
60
- if (currentDepth < depth)
61
- walk(full, currentDepth + 1);
68
+ break;
69
+ if (node.depth < depth) {
70
+ queue.push({ dir: full, depth: node.depth + 1 });
71
+ }
62
72
  }
63
73
  }
64
- walk(workspaceRoot, 1);
65
74
  out.sort((a, b) => b.lastActivity.localeCompare(a.lastActivity));
66
75
  return out;
67
76
  }
@@ -1 +1 @@
1
- {"version":3,"file":"project-folders.js","sourceRoot":"","sources":["../src/project-folders.ts"],"names":[],"mappings":";;AA+BA,gDAwCC;AAvED,2BAAuD;AACvD,+BAA4B;AAW5B,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IACzB,cAAc;IACd,MAAM;IACN,OAAO;IACP,MAAM;IACN,OAAO;IACP,QAAQ;IACR,OAAO;IACP,MAAM;IACN,MAAM;IACN,aAAa;IACb,SAAS;IACT,OAAO;IACP,SAAS;CACV,CAAC,CAAC;AAEH;;4EAE4E;AAC5E,SAAgB,kBAAkB,CAChC,aAAqB,EACrB,QAAgB,CAAC,EACjB,MAAc,GAAG;IAEjB,IAAI,CAAC,IAAA,eAAU,EAAC,aAAa,CAAC;QAAE,OAAO,EAAE,CAAC;IAC1C,MAAM,GAAG,GAAoB,EAAE,CAAC;IAEhC,SAAS,IAAI,CAAC,GAAW,EAAE,YAAoB;QAC7C,IAAI,YAAY,GAAG,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG;YAAE,OAAO;QACtD,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,GAAG,IAAA,gBAAW,EAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YACpC,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,SAAS;YACpC,MAAM,IAAI,GAAG,IAAA,WAAI,EAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC9B,IAAI,IAAI,CAAC;YACT,IAAI,CAAC;gBACH,IAAI,GAAG,IAAA,aAAQ,EAAC,IAAI,CAAC,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;gBAAE,SAAS;YAClC,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,KAAK;gBACX,IAAI,EAAE,IAAI;gBACV,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;aACvC,CAAC,CAAC;YACH,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG;gBAAE,OAAO;YAC9B,IAAI,YAAY,GAAG,KAAK;gBAAE,IAAI,CAAC,IAAI,EAAE,YAAY,GAAG,CAAC,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IACvB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;IACjE,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"project-folders.js","sourceRoot":"","sources":["../src/project-folders.ts"],"names":[],"mappings":";;AA+BA,gDAqDC;AApFD,2BAAuD;AACvD,+BAA4B;AAW5B,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IACzB,cAAc;IACd,MAAM;IACN,OAAO;IACP,MAAM;IACN,OAAO;IACP,QAAQ;IACR,OAAO;IACP,MAAM;IACN,MAAM;IACN,aAAa;IACb,SAAS;IACT,OAAO;IACP,SAAS;CACV,CAAC,CAAC;AAEH;;4EAE4E;AAC5E,SAAgB,kBAAkB,CAChC,aAAqB,EACrB,QAAgB,CAAC,EACjB,MAAc,GAAG;IAEjB,IAAI,CAAC,IAAA,eAAU,EAAC,aAAa,CAAC;QAAE,OAAO,EAAE,CAAC;IAC1C,MAAM,GAAG,GAAoB,EAAE,CAAC;IAEhC,2EAA2E;IAC3E,wEAAwE;IACxE,sEAAsE;IACtE,uEAAuE;IACvE,mEAAmE;IACnE,MAAM,KAAK,GAA0C;QACnD,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE;KACjC,CAAC;IAEF,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,EAAG,CAAC;QAC5B,IAAI,IAAI,CAAC,KAAK,GAAG,KAAK;YAAE,SAAS;QAEjC,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,GAAG,IAAA,gBAAW,EAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YACpC,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,SAAS;YACpC,MAAM,IAAI,GAAG,IAAA,WAAI,EAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACnC,IAAI,IAAI,CAAC;YACT,IAAI,CAAC;gBACH,IAAI,GAAG,IAAA,aAAQ,EAAC,IAAI,CAAC,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;gBAAE,SAAS;YAClC,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,KAAK;gBACX,IAAI,EAAE,IAAI;gBACV,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;aACvC,CAAC,CAAC;YACH,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG;gBAAE,MAAM;YAC7B,IAAI,IAAI,CAAC,KAAK,GAAG,KAAK,EAAE,CAAC;gBACvB,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;IACH,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;IACjE,OAAO,GAAG,CAAC;AACb,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cosmoremote",
3
- "version": "2.0.5",
3
+ "version": "2.0.6",
4
4
  "description": "CosmoRemote bridge — connect your Mac to the CosmoRemote iOS/Android app to control Claude Code and Codex remotely",
5
5
  "author": "Matheus Weber",
6
6
  "license": "MIT",