offsite 0.0.43 → 0.0.45

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/README.md CHANGED
@@ -10,32 +10,6 @@ Claude Code, Codex and OpenCode in your browser. It uses the same sessions as th
10
10
  npx offsite
11
11
  ```
12
12
 
13
- Then open the pairing link it prints. It pairs this browser with the server, so only browsers that opened the link can use it.
14
-
15
- | Command | What it does |
16
- | ---------------- | --------------------------------------------------------------------------------- |
17
- | `offsite` | Starts the server and the web app |
18
- | `offsite web` | Same as `offsite` |
19
- | `offsite serve` | Starts only the server |
20
- | `offsite pair` | Makes a pairing token for another browser and prints its link. `--name` labels it |
21
- | `offsite unpair` | Lists paired browsers so you can pick which to unpair |
22
-
23
- | Flag | Default | What it sets |
24
- | ----------- | ------------ | ------------------------------------------------------------ |
25
- | `--host` | `127.0.0.1` | Address to listen on |
26
- | `--port` | `47841` | Port to listen on |
27
- | `--dir` | `~/.offsite` | Folder for settings and accounts |
28
- | `--no-auth` | auth on | Accept connections without the pairing token |
29
- | `--no-pair` | pair on | Don't create a pairing token or print pairing links on start |
30
- | `--pwa` | off | Serve the web app as an installable app that works offline |
31
-
32
- Pairing tokens stay in `tokens.json` inside `--dir`. A running OffSite disconnects an unpaired browser within seconds.
33
-
34
- > [!WARNING]
35
- > With `--no-auth`, anyone who can reach its port, including any website open in your browser, can run your coding agents and open a terminal on your machine.
36
-
37
- Don't use the same session in OffSite and the CLI at the same time. Switching between them is fine.
38
-
39
13
  ## Separate instances
40
14
 
41
15
  Give each instance its own port and `--dir`.
@@ -85,7 +85,7 @@ function broadcast(event) {
85
85
  //#region src/args.ts
86
86
  let command = "web";
87
87
  let name = null;
88
- const program = new Command("offsite").description("Starts the server and the web app").option("--host <host>", "Address to listen on", "127.0.0.1").option("--port <port>", "Port to listen on", "47841").option("--dir <dir>", "Folder for settings and accounts", path.join(os.homedir(), ".offsite")).option("--no-auth", "Accept connections without pairing").option("--no-pair", "Don't create a pairing code or print pairing links").option("--pwa", "Serve the web app as an installable app that works offline").configureHelp({ showGlobalOptions: true });
88
+ const program = new Command("offsite").description("Starts the server and the web app").option("--host <host>", "Address to listen on", "127.0.0.1").option("--port <port>", "Port to listen on", "47841").option("--dir <dir>", "Folder for settings and accounts", path.join(os.homedir(), ".offsite")).option("--no-auth", "Accept connections without pairing").option("--no-pair", "Don't create a pairing code or print pairing links").option("--pwa", "Serve the web app as an installable app that works offline").option("--connect <addresses>", "Add this machine to the web app with these comma separated addresses; needs --no-auth").configureHelp({ showGlobalOptions: true });
89
89
  program.command("web", { isDefault: true }).description("Starts the server and the web app, same as offsite");
90
90
  program.command("serve").description("Starts only the server, without the web app").action(() => {
91
91
  command = "serve";
@@ -100,11 +100,19 @@ program.command("unpair").description("Picks paired browsers to unpair").action(
100
100
  program.parse();
101
101
  const options = program.opts();
102
102
  if (!options.auth && !options.pair) program.error("error: --no-pair can't be used with --no-auth");
103
+ if (options.connect !== void 0 && options.auth) program.error("error: --connect needs --no-auth");
104
+ if (options.connect !== void 0 && command === "serve") program.error("error: --connect can't be used with offsite serve");
105
+ const connect$1 = options.connect === void 0 ? null : options.connect.split(",").map((address) => {
106
+ const url = URL.parse(address);
107
+ if (url === null || url.protocol !== "http:" && url.protocol !== "https:") return program.error(`error: --connect address ${address} needs http:// or https://, like https://example.com`);
108
+ return url.origin;
109
+ });
103
110
  const args = {
104
111
  ...options,
105
112
  dir: path.resolve(options.dir),
106
113
  command,
107
- name
114
+ name,
115
+ connect: connect$1
108
116
  };
109
117
  const serverDir = path.join(import.meta.dirname, "..");
110
118
  //#endregion
@@ -3963,7 +3971,7 @@ async function request(connection, message) {
3963
3971
  tab.minimized = false;
3964
3972
  project.activeTab = tab.id;
3965
3973
  }
3966
- if (project.tabs.length === 0) await createTab(message.projectId);
3974
+ if (project.tabs.length === 0 && message.projectId !== "global") await createTab(message.projectId);
3967
3975
  break;
3968
3976
  }
3969
3977
  }
@@ -6877,12 +6885,12 @@ if (args.auth) setInterval(() => {
6877
6885
  }, UNPAIR_CHECK);
6878
6886
  server.listen(port, args.host, () => {
6879
6887
  startPush(`${args.host}:${port}`);
6880
- if (args.pair && (code !== null || !args.auth)) {
6888
+ if (args.connect === null && args.pair && (code !== null || !args.auth)) {
6881
6889
  const links = pairingLinks(code);
6882
6890
  if (args.command === "web") console.log(`offsite is running at ${links.local}`);
6883
6891
  } else {
6884
6892
  console.log(`offsite is running at ${address}`);
6885
- if (args.pair) console.log("Run offsite pair to pair another browser");
6893
+ if (args.auth && args.pair) console.log("Run offsite pair to pair another browser");
6886
6894
  }
6887
6895
  if (!args.auth) console.warn("auth is off; anyone who can reach this port can control this machine");
6888
6896
  });
@@ -7132,8 +7140,11 @@ function serveFile(pathname, response) {
7132
7140
  return;
7133
7141
  }
7134
7142
  response.setHeader("content-type", contentTypes[path.extname(file)] ?? "application/octet-stream");
7135
- if (!args.pwa && path.basename(file) === "index.html") {
7136
- response.end(readFileSync(file, "utf8").replace(/<link rel="manifest"[^>]*>/, ""));
7143
+ if (path.basename(file) === "index.html") {
7144
+ let page = readFileSync(file, "utf8");
7145
+ if (!args.pwa) page = page.replace(/<link rel="manifest"[^>]*>/, "");
7146
+ if (args.connect !== null) page = page.replace("</head>", `<meta name="offsite-connect" content="${args.connect.join(" ")}"></head>`);
7147
+ response.end(page);
7137
7148
  return;
7138
7149
  }
7139
7150
  createReadStream(file).pipe(response);