offsite 0.0.5 → 0.0.7
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 +16 -15
- package/apps/server/dist/main.mjs +31 -6
- package/apps/server/dist/main.mjs.map +1 -1
- package/apps/web/dist/assets/{angular-html-B53hPuXT.js → angular-html-CxKqLP98.js} +1 -1
- package/apps/web/dist/assets/{angular-ts--nhprFvo.js → angular-ts-ChaIimso.js} +1 -1
- package/apps/web/dist/assets/{apl-BMZ6gSxk.js → apl-C79wKZ96.js} +1 -1
- package/apps/web/dist/assets/{astro-BTM15MDF.js → astro-Bjd0-rUa.js} +1 -1
- package/apps/web/dist/assets/{blade-Dr8Nx-1X.js → blade-CwnKAXvb.js} +1 -1
- package/apps/web/dist/assets/{c-CYWvPMKX.js → c-Z516m-0_.js} +1 -1
- package/apps/web/dist/assets/{chapel-C8sB6Foh.js → chapel-CjZ9_INP.js} +1 -1
- package/apps/web/dist/assets/{cobol-FnuKKfgs.js → cobol-loY0YFmk.js} +1 -1
- package/apps/web/dist/assets/{coffee-DJrh6kIB.js → coffee-UH3lFVdK.js} +1 -1
- package/apps/web/dist/assets/{cpp-BLAvrTU1.js → cpp-DglnXsh6.js} +1 -1
- package/apps/web/dist/assets/{crystal-BthZctDJ.js → crystal-8bvlXru4.js} +1 -1
- package/apps/web/dist/assets/{css-DjklwMwW.js → css-BR1q7k6_.js} +1 -1
- package/apps/web/dist/assets/{edge-BunAX5o-.js → edge-BxokJ4MN.js} +1 -1
- package/apps/web/dist/assets/{elixir-DgeksfSS.js → elixir-BUaqVZQr.js} +1 -1
- package/apps/web/dist/assets/{elm-l1eWnD1P.js → elm-D_9smeEe.js} +1 -1
- package/apps/web/dist/assets/{erb-JKFWiSFc.js → erb-DOZIqXQH.js} +1 -1
- package/apps/web/dist/assets/{git-rebase-AsNqLj-a.js → git-rebase-DN-oOLvo.js} +1 -1
- package/apps/web/dist/assets/{glimmer-js-B8iwahHO.js → glimmer-js-dSW-hX4N.js} +1 -1
- package/apps/web/dist/assets/{glimmer-ts-7zfF4XN6.js → glimmer-ts-BgJbFWVH.js} +1 -1
- package/apps/web/dist/assets/{glsl-BJka2Ayq.js → glsl-FkhRNxnG.js} +1 -1
- package/apps/web/dist/assets/{graphql-7lx4uUDH.js → graphql-BKHVf0BT.js} +1 -1
- package/apps/web/dist/assets/{hack-Jm3cv9jc.js → hack-obS7Vybj.js} +1 -1
- package/apps/web/dist/assets/{haml-Csl_BhoG.js → haml-8M07SKZy.js} +1 -1
- package/apps/web/dist/assets/{handlebars-CFp1rmy8.js → handlebars-Cyb9PeHi.js} +1 -1
- package/apps/web/dist/assets/{html-D_zffrV4.js → html-Dwl7QR96.js} +1 -1
- package/apps/web/dist/assets/{html-derivative-B-pqZuPW.js → html-derivative-Dx3lESlT.js} +1 -1
- package/apps/web/dist/assets/{http-CU_emOoa.js → http-CKSR21d-.js} +1 -1
- package/apps/web/dist/assets/{hurl-BRBJ1eQP.js → hurl-DGaDIWma.js} +1 -1
- package/apps/web/dist/assets/index-5vPpgW8A.css +2 -0
- package/apps/web/dist/assets/index-BJCHT3_X.js +1148 -0
- package/apps/web/dist/assets/{java-DWuVSV9c.js → java-BmaAOMbe.js} +1 -1
- package/apps/web/dist/assets/{javascript-CPq3YNXl.js → javascript-Dh-l17xw.js} +1 -1
- package/apps/web/dist/assets/{jinja-Cwr4gaQT.js → jinja-C14B9X7r.js} +1 -1
- package/apps/web/dist/assets/{jison-tIc7kJPc.js → jison-DOLQZnVk.js} +1 -1
- package/apps/web/dist/assets/{json-CuLUmV8d.js → json-CKQXRUCT.js} +1 -1
- package/apps/web/dist/assets/{jsx-c0vioNM-.js → jsx-D3LXQmFh.js} +1 -1
- package/apps/web/dist/assets/{julia-DL1_3nCX.js → julia-BONGpLSW.js} +1 -1
- package/apps/web/dist/assets/{just-Dz1Oq8ln.js → just-1ImCRd19.js} +1 -1
- package/apps/web/dist/assets/{latex-BtJjjmHB.js → latex-C6nf8qng.js} +1 -1
- package/apps/web/dist/assets/{liquid-CUxfxikC.js → liquid-OyHcMLT8.js} +1 -1
- package/apps/web/dist/assets/{lua-FURW1z3g.js → lua-CFyXSn73.js} +1 -1
- package/apps/web/dist/assets/{marko-D33gqJht.js → marko-w4Xaqrn8.js} +1 -1
- package/apps/web/dist/assets/{mdc-rJL-euOm.js → mdc-CipE4q24.js} +1 -1
- package/apps/web/dist/assets/{nginx-CChB1oIE.js → nginx-CidGWCuA.js} +1 -1
- package/apps/web/dist/assets/{nim-C3VcT8nQ.js → nim-DqvuZ6-V.js} +1 -1
- package/apps/web/dist/assets/{org-CX9ySstM.js → org-C8k2emY1.js} +1 -1
- package/apps/web/dist/assets/{perl-BmdWqdcq.js → perl-D06UK6ou.js} +1 -1
- package/apps/web/dist/assets/{php-CMtd7vHw.js → php-POxwc-vY.js} +1 -1
- package/apps/web/dist/assets/{pug-DRlx8d5w.js → pug-BzSRzYD8.js} +1 -1
- package/apps/web/dist/assets/{qml-WYwqwy0P.js → qml-DZF7i2J0.js} +1 -1
- package/apps/web/dist/assets/{r-C1yAXCUm.js → r-Cem3rJmc.js} +1 -1
- package/apps/web/dist/assets/{razor-RKu7WkDv.js → razor-DG8dmRN8.js} +1 -1
- package/apps/web/dist/assets/{regexp-DuLU1P7q.js → regexp-B4kXooBf.js} +1 -1
- package/apps/web/dist/assets/{rst-CmK0AAXk.js → rst-DKLtDtVi.js} +1 -1
- package/apps/web/dist/assets/{ruby-DwgaoIUu.js → ruby-CamS7fke.js} +1 -1
- package/apps/web/dist/assets/{sas-iTrXuHXc.js → sas-B0QV8BKG.js} +1 -1
- package/apps/web/dist/assets/{scss-CEysq-zA.js → scss-PDWZBsRp.js} +1 -1
- package/apps/web/dist/assets/{shellscript-B0mTpBTm.js → shellscript-CdzFXVZ3.js} +1 -1
- package/apps/web/dist/assets/{shellsession-BuzD9EVx.js → shellsession-BTvaJuzj.js} +1 -1
- package/apps/web/dist/assets/{soy-ClDsFuFk.js → soy-CKjkt_DB.js} +1 -1
- package/apps/web/dist/assets/{sql-Dc1h3orO.js → sql-CvyoBOik.js} +1 -1
- package/apps/web/dist/assets/{stata-l31dxrtC.js → stata-DKSZtLec.js} +1 -1
- package/apps/web/dist/assets/{surrealql-x6LM7pkl.js → surrealql-DLiWChn8.js} +1 -1
- package/apps/web/dist/assets/{svelte-CtkYFYuK.js → svelte-BEKUDT0w.js} +1 -1
- package/apps/web/dist/assets/{templ-DHMinkR-.js → templ-Cwpj8Ert.js} +1 -1
- package/apps/web/dist/assets/{tex-CXbWoQMY.js → tex-eE29FuOr.js} +1 -1
- package/apps/web/dist/assets/{ts-tags-BikYq-3m.js → ts-tags-CS_oR42m.js} +1 -1
- package/apps/web/dist/assets/{tsx-zHJnYG9T.js → tsx-CXh89N3W.js} +1 -1
- package/apps/web/dist/assets/{twig-DKCfiSr9.js → twig-DE2-3Vmd.js} +1 -1
- package/apps/web/dist/assets/{typescript-K9TDgxRD.js → typescript-xOdvp9de.js} +1 -1
- package/apps/web/dist/assets/{typst-BpXkFpDR.js → typst-B_JeYRUR.js} +1 -1
- package/apps/web/dist/assets/{vue-BYYRFXPM.js → vue-dnoj_d3g.js} +1 -1
- package/apps/web/dist/assets/{vue-html-BR347tzO.js → vue-html-UHMeN4EH.js} +1 -1
- package/apps/web/dist/assets/{vue-vine-Jv4OHYgW.js → vue-vine-Cl2xkrIS.js} +1 -1
- package/apps/web/dist/assets/{xml-DuYGU-7M.js → xml-BgkAAaUc.js} +1 -1
- package/apps/web/dist/assets/{xsl-B950Zbyt.js → xsl-C4H21Kbc.js} +1 -1
- package/apps/web/dist/assets/{yaml-XFYTn8dR.js → yaml-Ce1Tbjry.js} +1 -1
- package/apps/web/dist/index.html +2 -2
- package/package.json +2 -1
- package/apps/web/dist/assets/index-0B-Gdd7b.css +0 -2
- package/apps/web/dist/assets/index-CJuLsqhP.js +0 -1148
package/README.md
CHANGED
|
@@ -12,21 +12,22 @@ npx offsite
|
|
|
12
12
|
|
|
13
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
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, use it from [offsite.sayad.dev](https://offsite.sayad.dev)
|
|
20
|
-
| `offsite pair` | Makes a pairing token for another browser and prints its links. `--name` labels it |
|
|
21
|
-
| `offsite unpair` | Lists paired browsers so you can pick which to unpair
|
|
22
|
-
|
|
23
|
-
| Flag
|
|
24
|
-
|
|
|
25
|
-
| `--host`
|
|
26
|
-
| `--port`
|
|
27
|
-
| `--dir`
|
|
28
|
-
| `--no-auth`
|
|
29
|
-
| `--no-pair`
|
|
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, use it from [offsite.sayad.dev](https://offsite.sayad.dev) |
|
|
20
|
+
| `offsite pair` | Makes a pairing token for another browser and prints its links and a QR code. `--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
|
+
| `--fallback` | none | Address the pairing links add for when this one is unreachable, e.g. a Cloudflare tunnel |
|
|
30
31
|
|
|
31
32
|
Pairing tokens stay in `tokens.json` inside `--dir`. A running offsite disconnects an unpaired browser within seconds.
|
|
32
33
|
|
|
@@ -2,6 +2,7 @@ import { createReadStream, existsSync, lstatSync, mkdirSync, readFileSync, readd
|
|
|
2
2
|
import { createServer } from "node:http";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { consola } from "consola";
|
|
5
|
+
import { renderUnicodeCompact } from "uqr";
|
|
5
6
|
import { WebSocketServer } from "ws";
|
|
6
7
|
import os from "node:os";
|
|
7
8
|
import { deleteSession, forkSession, getSessionMessages, getSubagentMessages, listSessions, query, renameSession } from "@anthropic-ai/claude-agent-sdk";
|
|
@@ -47,7 +48,7 @@ function broadcast(event) {
|
|
|
47
48
|
//#region src/args.ts
|
|
48
49
|
let command = "web";
|
|
49
50
|
let name = null;
|
|
50
|
-
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 the pairing token").option("--no-pair", "Don't create a pairing token or print pairing links");
|
|
51
|
+
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 the pairing token").option("--no-pair", "Don't create a pairing token or print pairing links").option("--fallback <url>", "Address to try when this one is unreachable, e.g. a Cloudflare tunnel");
|
|
51
52
|
program.command("web", { isDefault: true }).description("Starts the server and the web app, same as offsite");
|
|
52
53
|
program.command("serve").description("Starts only the server, without the web app").action(() => {
|
|
53
54
|
command = "serve";
|
|
@@ -85,15 +86,18 @@ function lock() {
|
|
|
85
86
|
if (!hasCode(error, "EEXIST")) throw error;
|
|
86
87
|
}
|
|
87
88
|
let content;
|
|
89
|
+
let modified;
|
|
88
90
|
try {
|
|
89
91
|
content = readFileSync(lockFile, "utf8");
|
|
92
|
+
modified = statSync(lockFile).mtimeMs;
|
|
90
93
|
} catch (error) {
|
|
91
94
|
if (hasCode(error, "ENOENT")) return lock();
|
|
92
95
|
throw error;
|
|
93
96
|
}
|
|
94
97
|
const pid = Number(content);
|
|
95
|
-
|
|
96
|
-
|
|
98
|
+
const validPid = Number.isInteger(pid) && pid > 0;
|
|
99
|
+
const writtenThisBoot = modified > Date.now() - os.uptime() * 1e3;
|
|
100
|
+
if (validPid && writtenThisBoot && pid !== process.pid && isRunning(pid)) {
|
|
97
101
|
consola.error(`offsite is already running for ${home} (pid ${pid})`);
|
|
98
102
|
process.exit(1);
|
|
99
103
|
}
|
|
@@ -3787,7 +3791,7 @@ var Run = class {
|
|
|
3787
3791
|
return;
|
|
3788
3792
|
}
|
|
3789
3793
|
case "result": {
|
|
3790
|
-
if (message.subtype !== "success") this.add(notice(message.errors.join("\n") || message.subtype));
|
|
3794
|
+
if (message.subtype !== "success" && message.terminal_reason !== "aborted_streaming" && message.terminal_reason !== "aborted_tools") this.add(notice(message.errors.filter((error) => !error.startsWith("[ede_diagnostic]")).join("\n") || message.subtype));
|
|
3791
3795
|
this.finishTurn();
|
|
3792
3796
|
const usage = this.model === null ? void 0 : message.modelUsage[this.model];
|
|
3793
3797
|
if (this.context !== null && usage !== void 0) this.context = {
|
|
@@ -5630,11 +5634,17 @@ if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
|
5630
5634
|
process.exit(1);
|
|
5631
5635
|
}
|
|
5632
5636
|
const address = `http://${args.host}:${port}`;
|
|
5637
|
+
const fallback = args.fallback === void 0 ? null : readFallback(args.fallback);
|
|
5633
5638
|
if (args.command === "pair") {
|
|
5634
5639
|
const links = pairingLinks(addToken(args.name));
|
|
5635
|
-
console.log(
|
|
5636
|
-
console.log(
|
|
5640
|
+
console.log(`Scan this to pair a phone with ${HOSTED_APP}:`);
|
|
5641
|
+
console.log("");
|
|
5642
|
+
console.log(renderUnicodeCompact(links.hosted, { border: 2 }));
|
|
5643
|
+
console.log("");
|
|
5644
|
+
console.log("Or open one of these links in the browser to pair:");
|
|
5637
5645
|
console.log(` ${links.hosted}`);
|
|
5646
|
+
console.log(` ${links.local}`);
|
|
5647
|
+
if (fallback !== null) console.log(`Fallback: ${fallback}`);
|
|
5638
5648
|
process.exit(0);
|
|
5639
5649
|
}
|
|
5640
5650
|
if (args.command === "unpair") {
|
|
@@ -5745,9 +5755,24 @@ async function unpair() {
|
|
|
5745
5755
|
removeTokens(picked);
|
|
5746
5756
|
console.log(`Unpaired ${picked.length} ${picked.length === 1 ? "browser" : "browsers"}; a running offsite disconnects them within seconds`);
|
|
5747
5757
|
}
|
|
5758
|
+
function readFallback(link) {
|
|
5759
|
+
let url;
|
|
5760
|
+
try {
|
|
5761
|
+
url = new URL(link);
|
|
5762
|
+
} catch {
|
|
5763
|
+
console.error(`invalid fallback URL ${link}`);
|
|
5764
|
+
process.exit(1);
|
|
5765
|
+
}
|
|
5766
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
5767
|
+
console.error(`the fallback URL ${link} needs http:// or https://`);
|
|
5768
|
+
process.exit(1);
|
|
5769
|
+
}
|
|
5770
|
+
return url.origin;
|
|
5771
|
+
}
|
|
5748
5772
|
function pairingLinks(token) {
|
|
5749
5773
|
const hosted = new URLSearchParams({
|
|
5750
5774
|
machine: address,
|
|
5775
|
+
...fallback !== null && { fallback },
|
|
5751
5776
|
...token !== null && { token }
|
|
5752
5777
|
});
|
|
5753
5778
|
return {
|