mindwire 0.1.52 → 0.1.54
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 +97 -2
- package/dist/apps.d.ts +94 -0
- package/dist/bots.d.ts +168 -0
- package/dist/{chunk-4XL565EU.js → chunk-P3JTWITC.js} +190 -7
- package/dist/chunk-P3JTWITC.js.map +1 -0
- package/dist/{chunk-RTMQJIKW.js → chunk-ZNEFE6KD.js} +4 -10
- package/dist/chunk-ZNEFE6KD.js.map +1 -0
- package/dist/cli.js +21 -25
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +12 -0
- package/dist/{connection-change-6E7QLJFC.js → connection-change-RVS6XWTC.js} +3 -3
- package/dist/{connection-change-6E7QLJFC.js.map → connection-change-RVS6XWTC.js.map} +1 -1
- package/dist/{controller-566LDBZD.js → controller-2WCEJ3F2.js} +4 -4
- package/dist/{controller-566LDBZD.js.map → controller-2WCEJ3F2.js.map} +1 -1
- package/dist/{controller-handoff-KNEQ5W6J.js → controller-handoff-7EOSPHSD.js} +3 -3
- package/dist/{controller-handoff-KNEQ5W6J.js.map → controller-handoff-7EOSPHSD.js.map} +1 -1
- package/dist/handoffs.d.ts +91 -0
- package/dist/index.cjs +209 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +200 -10
- package/dist/index.js.map +1 -1
- package/dist/integrations.d.ts +72 -0
- package/dist/target/docker.d.ts +9 -1
- package/dist/types.d.ts +21 -1
- package/dist/workspace.d.ts +14 -0
- package/package.json +10 -11
- package/dist/chunk-4XL565EU.js.map +0 -1
- package/dist/chunk-RTMQJIKW.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { websocketURL, readJSON, writeJSON, acquireProcessLock, computerClient, versionAtLeast } from './chunk-
|
|
1
|
+
import { websocketURL, readJSON, writeJSON, acquireProcessLock, computerClient, versionAtLeast } from './chunk-P3JTWITC.js';
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
import { setTimeout } from 'timers/promises';
|
|
4
4
|
|
|
@@ -10,12 +10,6 @@ function connectionInfo(relay, host) {
|
|
|
10
10
|
if (relay.kind === "none") return { provider: "direct", address: host ? "persistent" : "network" };
|
|
11
11
|
return { provider: relay.kind, address: ["cloudflare", "ngrok"].includes(relay.kind) && !relay.url ? "temporary" : "persistent" };
|
|
12
12
|
}
|
|
13
|
-
function connectionDescription(info) {
|
|
14
|
-
const name = { oblien: "Oblien", cloudflare: "Cloudflare", ngrok: "ngrok", custom: "Your tunnel", direct: "Direct SSH / VPN" }[info.provider];
|
|
15
|
-
if (info.address === "temporary") return `${name} \xB7 temporary address. For reconnect after a restart, run mindwire connection to choose a persistent address.`;
|
|
16
|
-
if (info.address === "network") return `${name} \xB7 reachable network required. Use a VPN hostname for access across networks.`;
|
|
17
|
-
return `${name} \xB7 persistent address. Saved phones retry automatically when this computer is online.`;
|
|
18
|
-
}
|
|
19
13
|
|
|
20
14
|
// src/computer/directory-http.ts
|
|
21
15
|
var DirectoryRequestError = class extends Error {
|
|
@@ -301,6 +295,6 @@ function updateProgress(update) {
|
|
|
301
295
|
return `${update.version} \xB7 ${phase[update.status]}`;
|
|
302
296
|
}
|
|
303
297
|
|
|
304
|
-
export { activeUpdate, connectionAddress,
|
|
305
|
-
//# sourceMappingURL=chunk-
|
|
306
|
-
//# sourceMappingURL=chunk-
|
|
298
|
+
export { activeUpdate, connectionAddress, connectionInfo, disableAddressDiscovery, discoveryDescription, discoveryPreference, enableAddressDiscovery, queueServiceUpdate, reconcileAddressDiscovery, saveDiscoveryPreference, updateComputer, updateProgress };
|
|
299
|
+
//# sourceMappingURL=chunk-ZNEFE6KD.js.map
|
|
300
|
+
//# sourceMappingURL=chunk-ZNEFE6KD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/computer/provider-info.ts","../src/computer/directory-http.ts","../src/computer/discovery.ts","../src/computer/service-update.ts"],"names":["delay","join"],"mappings":";;;;;AAKO,SAAS,iBAAA,CAAkB,OAAqB,IAAA,EAAuB;AAC5E,EAAA,OAAO,KAAA,CAAM,IAAA,KAAS,MAAA,GAAS,CAAA,IAAA,EAAO,QAAQ,SAAS,CAAA,CAAA,GACnD,KAAA,CAAM,GAAA,GAAM,aAAa,KAAA,CAAM,GAAG,CAAA,GAAI,CAAA,UAAA,EAAa,MAAM,IAAI,CAAA,CAAA;AACnE;AAGO,SAAS,cAAA,CAAe,OAAqB,IAAA,EAAuC;AACzF,EAAA,IAAI,KAAA,CAAM,IAAA,KAAS,MAAA,EAAQ,OAAO,EAAE,UAAU,QAAA,EAAU,OAAA,EAAS,IAAA,GAAO,YAAA,GAAe,SAAA,EAAU;AACjG,EAAA,OAAO,EAAE,QAAA,EAAU,KAAA,CAAM,IAAA,EAAM,OAAA,EAAS,CAAC,YAAA,EAAc,OAAO,CAAA,CAAE,QAAA,CAAS,MAAM,IAAI,CAAA,IAAK,CAAC,KAAA,CAAM,GAAA,GAAM,cAAc,YAAA,EAAa;AAClI;;;ACdO,IAAM,qBAAA,GAAN,cAAoC,KAAA,CAAM;AAAA,EAC/C,WAAA,CACW,MAAA,EACA,IAAA,EACA,UAAA,GAAa,CAAA,EACtB;AACA,IAAA,KAAA;AAAA,MACE,MAAA,KAAW,CAAA,GACP,mFAAA,GACA,CAAA,4CAAA,EAA+C,IAAI,CAAA,EAAA;AAAA,KACzD;AARS,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AACA,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AAAA,EAOX;AAAA,EATW,MAAA;AAAA,EACA,IAAA;AAAA,EACA,UAAA;AAQb,CAAA;AAGA,eAAsB,gBAAA,CAAoB,GAAA,EAAa,IAAA,EAAc,IAAA,EAAe,MAAA,EAAkC;AACpH,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI;AACF,IAAA,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,GAAM,IAAA,EAAM;AAAA,MACjC,MAAA,EAAQ,MAAA;AAAA,MACR,QAAA,EAAU,OAAA;AAAA,MACV,MAAA,EAAQ,MAAA,GAAS,WAAA,CAAY,GAAA,CAAI,CAAC,MAAA,EAAQ,WAAA,CAAY,OAAA,CAAQ,GAAM,CAAC,CAAC,CAAA,GAAI,WAAA,CAAY,QAAQ,GAAM,CAAA;AAAA,MACpG,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,MAAA,EAAQ;AAAA,OACV;AAAA,MACA,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI;AAAA,KAC1B,CAAA;AAAA,EACH,CAAA,CAAA,MAAQ;AACN,IAAA,MAAA,EAAQ,cAAA,EAAe;AACvB,IAAA,MAAM,IAAI,qBAAA,CAAsB,CAAA,EAAG,aAAa,CAAA;AAAA,EAClD;AACA,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,IAAA,EAAM,SAAA,EAAU;AACxC,EAAA,MAAM,SAAuB,EAAC;AAC9B,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,IAAI;AACF,IAAA,IAAI,MAAA;AACF,MAAA,WAAS;AACP,QAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAI,MAAM,OAAO,IAAA,EAAK;AAC1C,QAAA,IAAI,IAAA,EAAM;AACV,QAAA,MAAA,IAAU,KAAA,CAAM,UAAA;AAChB,QAAA,IAAI,SAAS,EAAA,GAAK,IAAA,EAAM,MAAM,IAAI,MAAM,uDAAuD,CAAA;AAC/F,QAAA,MAAA,CAAO,KAAK,KAAK,CAAA;AAAA,MACnB;AAAA,EACJ,CAAA,SAAE;AACA,IAAA,KAAK,MAAA,EAAQ,MAAA,EAAO,CAAE,KAAA,CAAM,MAAM;AAAA,IAAC,CAAC,CAAA;AAAA,EACtC;AACA,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI;AACF,IAAA,IAAA,GAAO,IAAA,CAAK,MAAM,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,CAAE,QAAA,CAAS,MAAM,CAAC,CAAA;AAAA,EAC1D,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,qBAAA,CAAsB,QAAA,CAAS,MAAA,EAAQ,kBAAkB,CAAA;AAAA,EACrE;AACA,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,QAAS,IAAA,EAAqC,KAAA;AACpD,IAAA,MAAM,IAAA,GAAO,OAAO,KAAA,KAAU,QAAA,GAAW,QAAS,KAAA,EAAqC,IAAA;AACvF,IAAA,MAAM,aAAa,MAAA,CAAO,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAC,CAAA;AAC7D,IAAA,MAAM,IAAI,qBAAA;AAAA,MACR,QAAA,CAAS,MAAA;AAAA,MACT,OAAO,IAAA,KAAS,QAAA,IAAY,iBAAiB,IAAA,CAAK,IAAI,IAAI,IAAA,GAAO,iBAAA;AAAA,MACjE,MAAA,CAAO,QAAA,CAAS,UAAU,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,UAAU,CAAC,CAAA,GAAI;AAAA,KACxE;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;;;ACvDO,IAAM,kBAAA,GAAqB,4BAAA;AAC3B,IAAM,aAAA,GAAgB,8BAA8B,kBAAkB,CAAA,CAAA;AAGtE,IAAM,sBAAsB,CAAC,SAAA,KAClC,SAA8B,IAAA,CAAK,SAAA,EAAW,oCAAoC,CAAC;AAIrF,eAAsB,uBAAA,CAAwB,WAAmB,KAAA,EAA2C;AAC1G,EAAA,MAAM,UAAA,GAAa,EAAE,GAAG,KAAA,EAAO,GAAA,EAAK,KAAA,CAAM,GAAA,GAAM,YAAA,CAAa,KAAA,CAAM,GAAG,CAAA,GAAI,MAAA,EAAU;AACpF,EAAA,MAAM,SAAA,CAAU,IAAA,CAAK,SAAA,EAAW,oCAAoC,GAAG,UAAU,CAAA;AACnF;AAEO,SAAS,aAAa,KAAA,EAAuB;AAClD,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,IAAI,IAAI,KAAK,CAAA;AAAA,EACrB,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,MAAM,sCAAsC,CAAA;AAAA,EACxD;AACA,EAAA,IACE,KAAA,CAAM,MAAA,GAAS,IAAA,IACf,UAAA,CAAW,IAAA,CAAK,KAAK,CAAA,IACrB,GAAA,CAAI,QAAA,IACJ,GAAA,CAAI,QAAA,IACJ,GAAA,CAAI,UACJ,GAAA,CAAI,IAAA,IACH,GAAA,CAAI,QAAA,KAAa,QAAA,IAChB,EAAE,GAAA,CAAI,QAAA,KAAa,OAAA,IAAW,CAAC,WAAA,EAAa,WAAA,EAAa,OAAO,CAAA,CAAE,QAAA,CAAS,GAAA,CAAI,QAAQ,CAAA,CAAA,EACzF;AACA,IAAA,MAAM,IAAI,MAAM,yEAAyE,CAAA;AAAA,EAC3F;AACA,EAAA,IAAI,GAAA,CAAI,QAAA,KAAa,GAAA,EAAK,GAAA,CAAI,QAAA,GAAW,kBAAA;AACzC,EAAA,IAAI,GAAA,CAAI,QAAA,CAAS,QAAA,CAAS,GAAG,KAAK,GAAA,CAAI,QAAA,CAAS,QAAA,CAAS,IAAI,CAAA,IAAK,GAAA,CAAI,QAAA,CAAS,QAAA,CAAS,GAAG,CAAA,EAAG;AAC3F,IAAA,MAAM,IAAI,MAAM,2DAA2D,CAAA;AAAA,EAC7E;AACA,EAAA,OAAO,GAAA,CAAI,IAAA;AACb;AAEA,eAAsB,uBAAuB,OAAA,EAQR;AACnC,EAAA,MAAM,IAAA,GAAO,MAAM,kBAAA,CAAmB,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW,sBAAsB,CAAA,EAAG,EAAE,MAAA,EAAQ,OAAA,CAAQ,MAAA,EAAQ,CAAA;AACjH,EAAA,IAAI;AACF,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,MAAM,OAAA,CAAQ,QAAA,CAAS,QAAA,CAAS,SAAA,EAAU;AAAA,IACrD,SAAS,KAAA,EAAO;AACd,MAAA,IAAK,MAA8B,MAAA,KAAW,GAAA;AAC5C,QAAA,MAAM,IAAI,MAAM,yEAAyE,CAAA;AAC3F,MAAA,MAAM,KAAA;AAAA,IACR;AACA,IAAA,MAAM,UAAA,GAAa,MAAM,mBAAA,CAAoB,OAAA,CAAQ,SAAS,CAAA;AAC9D,IAAA,IAAI,OAAA,CAAQ,SAAA,IAAa,UAAA,EAAY,OAAA,KAAY,OAAO,OAAO,MAAA;AAG/D,IAAA,MAAM,GAAA,GAAM,YAAA;AAAA,MACV,OAAA,CAAQ,OAAO,OAAA,CAAQ,GAAA,CAAI,0BAA0B,MAAA,CAAO,GAAA,IAAO,YAAY,GAAA,IAAO;AAAA,KACxF;AACA,IAAA,IACE,MAAA,CAAO,GAAA,IACP,MAAA,CAAO,GAAA,KAAQ,GAAA,KACd,MAAA,CAAO,OAAA,IAAA,CAAY,MAAA,CAAO,QAAA,IAAY,CAAA,OAAQ,MAAA,CAAO,iBAAA,IAAqB,CAAA,CAAA,CAAA,EAC3E;AACA,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AACA,IAAA,MAAM,wBAAwB,OAAA,CAAQ,SAAA,EAAW,EAAE,OAAA,EAAS,IAAA,EAAM,KAAK,CAAA;AACvE,IAAA,IAAI,CAAC,MAAA,CAAO,OAAA,IAAW,MAAA,CAAO,GAAA,KAAQ,OAAO,MAAA,CAAO,KAAA,EAAO,QAAA,CAAS,YAAY,CAAA,EAAG;AACjF,MAAA,OAAA,CAAQ,MAAA,CAAO,MAAM,CAAA,yCAAA,EAA4C,IAAI,IAAI,GAAG,CAAA,CAAE,IAAI,CAAA,MAAA,CAAG,CAAA;AACrF,MAAA,IAAI;AACF,QAAA,MAAM,SAAA,GAAY,MAAM,gBAAA,CAAwC,GAAA,EAAK,0BAAA,EAA4B;AAAA,UAC/F,aAAa,MAAA,CAAO;AAAA,SACtB,EAAG,QAAQ,MAAM,CAAA;AACjB,QAAA,IACE,OAAO,SAAA,EAAW,SAAA,KAAc,QAAA,IAChC,SAAA,CAAU,SAAA,CAAU,MAAA,GAAS,EAAA,IAC7B,SAAA,CAAU,SAAA,CAAU,MAAA,GAAS,IAAA,EAC7B;AACA,UAAA,MAAM,IAAI,MAAM,iEAAiE,CAAA;AAAA,QACnF;AACA,QAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,QAAA,CAAS,SAAS,mBAAA,CAAoB,GAAA,EAAK,UAAU,SAAS,CAAA;AAC1F,QAAA,MAAM,WAAW,MAAM,gBAAA,CAA0C,KAAK,gBAAA,EAAkB,KAAA,EAAO,QAAQ,MAAM,CAAA;AAC7G,QAAA,IAAI,QAAA,EAAU,gBAAgB,MAAA,CAAO,WAAA;AACnC,UAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,MACtE,SAAS,KAAA,EAAO;AACd,QAAA,IAAI,iBAAiB,qBAAA,EAAuB;AAC1C,UAAA,IAAI,KAAA,CAAM,MAAA,KAAW,GAAA,IAAO,KAAA,CAAM,MAAA,KAAW,GAAA;AAC3C,YAAA,MAAM,IAAI,KAAA;AAAA,cACR;AAAA,aACF;AACF,UAAA,IAAI,MAAM,MAAA,KAAW,GAAA;AACnB,YAAA,MAAM,IAAI,KAAA;AAAA,cACR;AAAA,aACF;AACF,UAAA,IAAI,MAAM,IAAA,KAAS,kBAAA;AACjB,YAAA,MAAM,IAAI,KAAA;AAAA,cACR;AAAA,aACF;AACF,UAAA,IAAI,KAAA,CAAM,MAAA,KAAW,GAAA,IAAO,KAAA,CAAM,MAAA,KAAW,GAAA;AAC3C,YAAA,MAAM,IAAI,KAAA;AAAA,cACR;AAAA,aACF;AACF,UAAA,IAAI,MAAM,MAAA,KAAW,GAAA;AACnB,YAAA,MAAM,IAAI,KAAA;AAAA,cACR;AAAA,aACF;AACF,UAAA,IAAI,MAAM,MAAA,KAAW,GAAA;AACnB,YAAA,MAAM,IAAI,KAAA;AAAA,cACR;AAAA,aACF;AAAA,QACJ;AACA,QAAA,MAAM,KAAA;AAAA,MACR;AACA,MAAA,MAAA,GAAS,MAAM,OAAA,CAAQ,QAAA,CAAS,QAAA,CAAS,kBAAA,CAAmB,MAAM,GAAG,CAAA;AAAA,IACvE;AACA,IAAA,IAAI,OAAA,CAAQ,kBAAA,KAAuB,KAAA,EAAO,OAAO,MAAA;AACjD,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,IAAA;AAC9B,IAAA,OAAO,IAAA,CAAK,GAAA,EAAI,GAAI,QAAA,EAAU;AAC5B,MAAA,MAAA,GAAS,MAAM,OAAA,CAAQ,QAAA,CAAS,QAAA,CAAS,SAAA,EAAU;AACnD,MAAA,IAAI,MAAA,CAAO,WAAW,MAAA,CAAO,QAAA,IAAY,OAAO,iBAAA,KAAsB,MAAA,CAAO,UAAU,OAAO,MAAA;AAC9F,MAAA,IAAI,MAAA,CAAO,OAAO,QAAA,CAAS,YAAY,KAAK,MAAA,CAAO,KAAA,EAAO,SAAS,gBAAgB,CAAA;AACjF,QAAA,MAAM,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAA;AAC9B,MAAA,MAAMA,WAAM,GAAA,EAAK,KAAA,CAAA,EAAW,EAAE,MAAA,EAAQ,OAAA,CAAQ,QAAQ,CAAA;AAAA,IACxD;AACA,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF,CAAA,SAAE;AACA,IAAA,MAAM,MAAM,KAAA,EAAM;AAAA,EACpB;AACF;AAEA,eAAsB,uBAAA,CAAwB,SAAA,EAAmB,QAAA,EAAoB,SAAA,GAAY,KAAA,EAAyC;AACxI,EAAA,MAAM,OAAO,MAAM,kBAAA,CAAmB,IAAA,CAAK,SAAA,EAAW,sBAAsB,CAAC,CAAA;AAC7E,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,QAAA,CAAS,SAAA,EAAU;AACjD,IAAA,MAAM,UAAA,GAAa,MAAM,mBAAA,CAAoB,SAAS,CAAA;AACtD,IAAA,IAAI,SAAA,IAAa,UAAA,EAAY,OAAA,KAAY,IAAA,EAAM,OAAO,MAAA;AACtD,IAAA,MAAM,uBAAA,CAAwB,SAAA,EAAW,EAAE,OAAA,EAAS,KAAA,EAAO,KAAK,MAAA,CAAO,GAAA,IAAO,UAAA,EAAY,GAAA,EAAK,CAAA;AAC/F,IAAA,IAAI,CAAC,MAAA,CAAO,OAAA,EAAS,OAAO,MAAA;AAC5B,IAAA,OAAO,MAAM,QAAA,CAAS,QAAA,CAAS,kBAAA,CAAmB,KAAK,CAAA;AAAA,EACzD,CAAA,SAAE;AAAU,IAAA,MAAM,MAAM,KAAA,EAAM;AAAA,EAAG;AACnC;AAKA,eAAsB,0BAA0B,OAAA,EAE9B;AAChB,EAAA,MAAM,UAAA,GAAa,MAAM,mBAAA,CAAoB,OAAA,CAAQ,SAAS,CAAA;AAC9D,EAAA,MAAM,EAAE,WAAW,MAAA,EAAO,GAAI,MAAM,OAAA,CAAQ,QAAA,CAAS,SAAS,IAAA,EAAK;AACnE,EAAA,MAAM,SAAA,GAAY,QAAQ,MAAA,CAAO,KAAA,CAAM,SAAS,YAAA,IAAgB,CAAC,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,GAAA;AACtF,EAAA,MAAM,UAAU,UAAA,EAAY,OAAA,KAAY,QAAQ,OAAA,IAAW,SAAA,IAAa,CAAC,MAAA,EAAQ,GAAA,CAAA;AACjF,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,IAAI,UAAA,EAAY,OAAA,KAAY,KAAA,IAAS,MAAA,EAAQ,OAAA,EAAS,MAAM,uBAAA,CAAwB,OAAA,CAAQ,SAAA,EAAW,OAAA,CAAQ,QAAA,EAAU,IAAI,CAAA;AAC7H,IAAA;AAAA,EACF;AACA,EAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,IAAI,MAAM,+DAA+D,CAAA;AAC5F,EAAA,MAAM,GAAA,GAAM,aAAa,UAAA,EAAY,GAAA,IAAO,QAAQ,GAAA,CAAI,sBAAA,IAA0B,MAAA,CAAO,GAAA,IAAO,aAAa,CAAA;AAC7G,EAAA,IAAI,MAAA,CAAO,OAAA,IAAW,MAAA,CAAO,GAAA,KAAQ,GAAA,IAAO,CAAC,MAAA,CAAO,KAAA,EAAO,QAAA,CAAS,YAAY,CAAA,EAAG;AACnF,EAAA,MAAM,sBAAA,CAAuB;AAAA,IAAE,GAAG,OAAA;AAAA,IAAS,GAAA;AAAA,IAAK,kBAAA,EAAoB,KAAA;AAAA,IAAO,SAAA,EAAW,IAAA;AAAA,IACpF,MAAA,EAAQ;AAAA,MAAE,KAAA,GAAQ;AAAA,MAAC,CAAA;AAAA,MAAG,IAAA,GAAO;AAAA,MAAC,CAAA;AAAA,MAAG,UAAU,YAAY;AAAE,QAAA,MAAM,IAAI,MAAM,+BAA+B,CAAA;AAAA,MAAG,CAAA;AAAA,MACzG,QAAQ,YAAY;AAAE,QAAA,MAAM,IAAI,MAAM,+BAA+B,CAAA;AAAA,MAAG;AAAA;AAAE,GAAG,CAAA;AACnF;AAEO,SAAS,qBAAqB,MAAA,EAAqD;AACxF,EAAA,IAAI,CAAC,MAAA,EAAQ,OAAA,EAAS,OAAO,8EAAA;AAC7B,EAAA,IAAI,MAAA,CAAO,KAAA,EAAO,OAAO,MAAA,CAAO,KAAA;AAChC,EAAA,OAAO,OAAO,QAAA,IAAY,MAAA,CAAO,iBAAA,KAAsB,MAAA,CAAO,WAC1D,wGAAA,GACA,mDAAA;AACN;ACtLO,SAAS,aAAa,MAAA,EAA8D;AACzF,EAAA,OAAO,CAAC,CAAC,MAAA,IAAU,CAAC,QAAA,EAAU,aAAA,EAAe,SAAA,EAAW,YAAY,CAAA,CAAE,QAAA,CAAS,MAAA,CAAO,MAAM,CAAA;AAC9F;AAIA,eAAsB,kBAAA,CAAmB,MAAA,EAAsB,OAAA,EAAiB,KAAA,GAAQ,KAAA,EAAgC;AACtH,EAAA,KAAA,IAAS,OAAA,GAAU,KAAK,OAAA,EAAA,EAAW;AACjC,IAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,QAAA,CAAS,YAAA,EAAa;AACpD,IAAA,IAAI,aAAa,QAAQ,CAAA,KAAM,CAAC,KAAA,IAAS,QAAA,CAAS,QAAQ,OAAO,QAAA;AACjE,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,MAAA,CAAO,QAAA,CAAS,aAAA,CAAc,YAAA,CAAa,QAAQ,CAAA,GAAI,QAAA,CAAS,OAAA,GAAU,OAAA,EAAS,EAAE,KAAA,EAAO,CAAA;AAAA,IAC3G,SAAS,KAAA,EAAO;AACd,MAAA,IAAK,KAAA,CAA8B,MAAA,KAAW,GAAA,IAAO,OAAA,IAAW,GAAG,MAAM,KAAA;AAAA,IAE3E;AAAA,EACF;AACF;AAMA,eAAsB,eAAe,OAAA,EAKR;AAC3B,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,OAAA,CAAQ,MAAM,EAAE,CAAA;AAChD,EAAA,IAAI,CAAC,sCAAsC,IAAA,CAAK,OAAO,GAAG,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAC7H,EAAA,MAAM,UAAU,OAAA,CAAQ,OAAA,KAAY,MAAM,cAAA,CAAe,QAAQ,SAAS,CAAA,CAAA;AAC1E,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,IAAK,QAAQ,SAAA,IAAa,IAAA,CAAA;AACpD,EAAA,IAAI,WAAuC,IAAA,GAAO,EAAA;AAClD,EAAA,WAAS;AACP,IAAA,OAAA,CAAQ,QAAQ,cAAA,EAAe;AAC/B,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,MAAM,MAAA,GAAS,MAAM,OAAA,EAAQ;AAC7B,MAAA,MAAM,SAAA,GAAA,CAAa,MAAM,MAAA,CAAO,MAAA,IAAU,OAAA,CAAQ,OAAA,CAAQ,MAAM,EAAE,CAAA;AAClE,MAAA,IAAI,cAAc,OAAA,IAAW,CAAC,QAAQ,cAAA,IAAkB,cAAA,CAAe,WAAW,OAAO,CAAA;AACvF,QAAA,OAAO,EAAE,OAAA,EAAS,SAAA,EAAW,QAAA,EAAU,IAAA,EAAK;AAC9C,MAAA,SAAA,GAAY,MAAM,kBAAA,CAAmB,MAAA,EAAQ,OAAA,EAAS,QAAQ,KAAK,CAAA;AAAA,IACrE;AAGA,IAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAyBC,IAAAA,CAAK,QAAQ,SAAA,EAAW,sBAAsB,CAAC,CAAA,IAAK,SAAA;AAClG,IAAA,IAAI,MAAA,CAAO,EAAA,KAAO,SAAA,CAAU,EAAA,EAAI;AAE9B,MAAA,SAAA,GAAY,MAAA;AAAA,IACd,CAAA,MAAO;AACL,MAAA,MAAM,MAAM,CAAA,EAAG,MAAA,CAAO,EAAE,CAAA,CAAA,EAAI,OAAO,MAAM,CAAA,CAAA;AACzC,MAAA,IAAI,SAAS,GAAA,EAAK;AAAE,QAAA,IAAA,GAAO,GAAA;AAAK,QAAA,OAAA,CAAQ,aAAa,MAAM,CAAA;AAAA,MAAG;AAC9D,MAAA,IAAI,MAAA,CAAO,WAAW,QAAA,EAAU,MAAM,IAAI,KAAA,CAAM,MAAA,CAAO,SAAS,8DAA8D,CAAA;AAC9H,MAAA,IAAI,MAAA,CAAO,WAAW,UAAA,EAAY;AAChC,QAAA,SAAA,GAAY,MAAA;AACZ,QAAA,IAAI,IAAA,CAAK,GAAA,EAAI,GAAI,QAAA,EAAU;AAAA,MAC7B,WAAW,CAAC,OAAA,CAAQ,KAAA,IAAS,MAAA,CAAO,WAAW,SAAA,EAAW;AACxD,QAAA,OAAO,EAAE,OAAA,EAAS,QAAA,EAAU,KAAA,EAAO,MAAA,EAAO;AAAA,MAC5C;AAAA,IACF;AACA,IAAA,IAAI,IAAA,CAAK,KAAI,IAAK,QAAA,SAAiB,EAAE,OAAA,EAAS,QAAA,EAAU,KAAA,EAAO,MAAA,EAAO;AACtE,IAAA,MAAMD,WAAM,GAAA,EAAK,MAAA,EAAW,EAAE,MAAA,EAAQ,OAAA,CAAQ,QAAQ,CAAA;AAAA,EACxD;AACF;AAEO,SAAS,eAAe,MAAA,EAAgC;AAC7D,EAAA,MAAM,KAAA,GAAkD;AAAA,IACtD,IAAA,EAAM,OAAA;AAAA,IAAS,MAAA,EAAQ,QAAA;AAAA,IAAU,WAAA,EAAa,oCAAA;AAAA,IAC9C,OAAA,EAAS,mCAAA;AAAA,IAAqC,UAAA,EAAY,0BAAA;AAAA,IAC1D,QAAA,EAAU,WAAA;AAAA,IAAa,MAAA,EAAQ;AAAA,GACjC;AACA,EAAA,OAAO,GAAG,MAAA,CAAO,OAAO,SAAM,KAAA,CAAM,MAAA,CAAO,MAAM,CAAC,CAAA,CAAA;AACpD","file":"chunk-ZNEFE6KD.js","sourcesContent":["import type { ComputerConnectionInfo } from \"../computer.js\";\nimport type { RelayOptions } from \"./relay.js\";\nimport { websocketURL } from \"./relay.js\";\n\n/** Credential renewal does not change the address already saved by the phone. */\nexport function connectionAddress(relay: RelayOptions, host?: string): string {\n return relay.kind === \"none\" ? `ssh:${host ?? \"network\"}`\n : relay.url ? websocketURL(relay.url) : `temporary:${relay.kind}`;\n}\n\n/** Public, non-secret metadata. Route/SSH identity is independent of provider credentials. */\nexport function connectionInfo(relay: RelayOptions, host?: string): ComputerConnectionInfo {\n if (relay.kind === \"none\") return { provider: \"direct\", address: host ? \"persistent\" : \"network\" };\n return { provider: relay.kind, address: [\"cloudflare\", \"ngrok\"].includes(relay.kind) && !relay.url ? \"temporary\" : \"persistent\" };\n}\n\nexport function connectionDescription(info: ComputerConnectionInfo): string {\n const name = { oblien: \"Oblien\", cloudflare: \"Cloudflare\", ngrok: \"ngrok\", custom: \"Your tunnel\", direct: \"Direct SSH / VPN\" }[info.provider];\n if (info.address === \"temporary\") return `${name} · temporary address. For reconnect after a restart, run mindwire connection to choose a persistent address.`;\n if (info.address === \"network\") return `${name} · reachable network required. Use a VPN hostname for access across networks.`;\n return `${name} · persistent address. Saved phones retry automatically when this computer is online.`;\n}\n","export class DirectoryRequestError extends Error {\n constructor(\n readonly status: number,\n readonly code: string,\n readonly retryAfter = 0,\n ) {\n super(\n status === 0\n ? \"Couldn't reach the address directory securely. Check its HTTPS address and retry.\"\n : `The address directory rejected the request (${code}).`,\n );\n }\n}\n\n/** Bounded, same-origin requests. No redirects, cookie jar or retained credentials. */\nexport async function directoryRequest<T>(url: string, path: string, body: unknown, signal?: AbortSignal): Promise<T> {\n let response: Response;\n try {\n response = await fetch(url + path, {\n method: \"POST\",\n redirect: \"error\",\n signal: signal ? AbortSignal.any([signal, AbortSignal.timeout(10_000)]) : AbortSignal.timeout(10_000),\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(body),\n });\n } catch {\n signal?.throwIfAborted();\n throw new DirectoryRequestError(0, \"unreachable\");\n }\n const reader = response.body?.getReader();\n const chunks: Uint8Array[] = [];\n let length = 0;\n try {\n if (reader)\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n length += value.byteLength;\n if (length > 64 * 1024) throw new Error(\"The address directory returned an oversized response.\");\n chunks.push(value);\n }\n } finally {\n void reader?.cancel().catch(() => {});\n }\n let data: unknown;\n try {\n data = JSON.parse(Buffer.concat(chunks).toString(\"utf8\"));\n } catch {\n throw new DirectoryRequestError(response.status, \"invalid_response\");\n }\n if (!response.ok) {\n const error = (data as { error?: unknown } | null)?.error;\n const code = typeof error === \"string\" ? error : (error as { code?: unknown } | null)?.code;\n const retryAfter = Number(response.headers.get(\"Retry-After\"));\n throw new DirectoryRequestError(\n response.status,\n typeof code === \"string\" && /^[a-z_]{1,64}$/.test(code) ? code : \"directory_error\",\n Number.isFinite(retryAfter) ? Math.max(0, Math.min(60, retryAfter)) : 0,\n );\n }\n return data as T;\n}\n","import { join } from \"node:path\";\nimport { setTimeout as delay } from \"node:timers/promises\";\nimport type { Mindwire } from \"../client.js\";\nimport type { ComputerDiscoveryStatus } from \"../computer.js\";\nimport { acquireProcessLock } from \"./lock.js\";\nimport type { SetupPrompt } from \"./setup-prompt.js\";\nimport { directoryRequest, DirectoryRequestError } from \"./directory-http.js\";\nimport { readJSON, writeJSON, type ComputerConfig } from \"./lifecycle.js\";\n\nexport const DIRECTORY_API_PATH = \"/api/computer-directory/v1\";\nexport const DIRECTORY_URL = `https://console.mindwire.sh${DIRECTORY_API_PATH}`;\n\nexport interface DiscoveryPreference { enabled: boolean; url?: string }\nexport const discoveryPreference = (directory: string) =>\n readJSON<DiscoveryPreference>(join(directory, \"computer-discovery-preference.json\"));\n\n/** Desired setup is durable even if enrollment is temporarily offline. The\n * daemon remains the authority for signed publications and phone access. */\nexport async function saveDiscoveryPreference(directory: string, value: DiscoveryPreference): Promise<void> {\n const preference = { ...value, url: value.url ? directoryURL(value.url) : undefined };\n await writeJSON(join(directory, \"computer-discovery-preference.json\"), preference);\n}\n\nexport function directoryURL(value: string): string {\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n throw new Error(\"Enter the directory's HTTPS API URL.\");\n }\n if (\n value.length > 2048 ||\n /[\\s\\x00]/.test(value) ||\n url.username ||\n url.password ||\n url.search ||\n url.hash ||\n (url.protocol !== \"https:\" &&\n !(url.protocol === \"http:\" && [\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(url.hostname)))\n ) {\n throw new Error(\"Use an HTTPS directory URL without credentials, a query, or a fragment.\");\n }\n if (url.pathname === \"/\") url.pathname = DIRECTORY_API_PATH;\n if (url.pathname.endsWith(\"/\") || url.pathname.includes(\"//\") || url.pathname.includes(\"%\")) {\n throw new Error(\"Use the exact directory API URL without a trailing slash.\");\n }\n return url.href;\n}\n\nexport async function enableAddressDiscovery(options: {\n directory: string;\n computer: Mindwire;\n prompt: SetupPrompt;\n url?: string;\n waitForPublication?: boolean;\n signal?: AbortSignal;\n reconcile?: boolean;\n}): Promise<ComputerDiscoveryStatus> {\n const lock = await acquireProcessLock(join(options.directory, \"discovery-setup.lock\"), { signal: options.signal });\n try {\n let status: ComputerDiscoveryStatus;\n try {\n status = await options.computer.computer.discovery();\n } catch (error) {\n if ((error as { status?: number }).status === 404)\n throw new Error(\"Update the Mindwire service before enabling automatic address recovery.\");\n throw error;\n }\n const preference = await discoveryPreference(options.directory);\n if (options.reconcile && preference?.enabled === false) return status;\n // Preserve a saved private directory across upgrades. Credentials belonging\n // to another provider are never read by this flow.\n const url = directoryURL(\n options.url ?? process.env.MINDWIRE_DIRECTORY_URL ?? status.url ?? preference?.url ?? DIRECTORY_URL,\n );\n if (\n status.url &&\n status.url !== url &&\n (status.enabled || (status.sequence ?? 0) !== (status.publishedSequence ?? 0))\n ) {\n throw new Error(\n \"Disable the current directory with mindwire discovery disable and wait for its withdrawal before changing the directory URL.\",\n );\n }\n await saveDiscoveryPreference(options.directory, { enabled: true, url });\n if (!status.enabled || status.url !== url || status.error?.includes(\"enrollment\")) {\n options.prompt.print(`Enabling encrypted address recovery with ${new URL(url).host}…`);\n try {\n const challenge = await directoryRequest<{ challenge: string }>(url, \"/registrations/challenge\", {\n directoryId: status.directoryId,\n }, options.signal);\n if (\n typeof challenge?.challenge !== \"string\" ||\n challenge.challenge.length < 16 ||\n challenge.challenge.length > 2048\n ) {\n throw new Error(\"The address directory returned an invalid enrollment challenge.\");\n }\n const proof = await options.computer.computer.directoryEnrollment(url, challenge.challenge);\n const enrolled = await directoryRequest<{ directoryId: string }>(url, \"/registrations\", proof, options.signal);\n if (enrolled?.directoryId !== status.directoryId)\n throw new Error(\"The directory acknowledged a different computer.\");\n } catch (error) {\n if (error instanceof DirectoryRequestError) {\n if (error.status === 404 || error.status === 501)\n throw new Error(\n \"The address directory isn't available at this URL. Your existing connection still works; retry after the backend is deployed.\",\n );\n if (error.status === 409)\n throw new Error(\n \"This computer's directory registration is revoked or conflicts with its saved identity. Contact the directory operator.\",\n );\n if (error.code === \"account_required\")\n throw new Error(\n \"This directory still requires an account. Update its Mindwire backend to enable key-based registration, or choose another directory with --directory-url.\",\n );\n if (error.status === 401 || error.status === 403)\n throw new Error(\n \"The directory couldn't verify this computer's key or challenge. Retry enrollment.\",\n );\n if (error.status === 429)\n throw new Error(\n \"The directory's registration limit was reached. Retry later or use another directory.\",\n );\n if (error.status === 503)\n throw new Error(\n \"The directory is temporarily unavailable or at capacity. Your existing connection still works.\",\n );\n }\n throw error;\n }\n status = await options.computer.computer.configureDiscovery(true, url);\n }\n if (options.waitForPublication === false) return status;\n const deadline = Date.now() + 15_000;\n while (Date.now() < deadline) {\n status = await options.computer.computer.discovery();\n if (status.enabled && status.sequence && status.publishedSequence === status.sequence) return status;\n if (status.error?.includes(\"enrollment\") || status.error?.includes(\"older revision\"))\n throw new Error(status.error);\n await delay(250, undefined, { signal: options.signal });\n }\n throw new Error(\n \"Address recovery is configured and will retry in the background. Run mindwire discovery status to check publication.\",\n );\n } finally {\n await lock?.close();\n }\n}\n\nexport async function disableAddressDiscovery(directory: string, computer: Mindwire, reconcile = false): Promise<ComputerDiscoveryStatus> {\n const lock = await acquireProcessLock(join(directory, \"discovery-setup.lock\"));\n try {\n const status = await computer.computer.discovery();\n const preference = await discoveryPreference(directory);\n if (reconcile && preference?.enabled === true) return status;\n await saveDiscoveryPreference(directory, { enabled: false, url: status.url ?? preference?.url });\n if (!status.enabled) return status;\n return await computer.computer.configureDiscovery(false);\n } finally { await lock?.close(); }\n}\n\n/** Runs once after startup and retries failed enrollment in the controller. A\n * healthy setup makes only a local status read: publication/renewal stays in Go.\n * Direct/VPN/custom connections never opt into a hosted directory implicitly. */\nexport async function reconcileAddressDiscovery(options: {\n directory: string; config: ComputerConfig; computer: Mindwire; signal?: AbortSignal;\n}): Promise<void> {\n const preference = await discoveryPreference(options.directory);\n const { discovery: status } = await options.computer.computer.info();\n const automatic = options.config.relay.kind === \"cloudflare\" && !options.config.relay.url;\n const enabled = preference?.enabled ?? (status?.enabled || automatic && !status?.url);\n if (!enabled) {\n if (preference?.enabled === false && status?.enabled) await disableAddressDiscovery(options.directory, options.computer, true);\n return;\n }\n if (!status) throw new Error(\"Update the Mindwire service to enable automatic reconnection.\");\n const url = directoryURL(preference?.url ?? process.env.MINDWIRE_DIRECTORY_URL ?? status.url ?? DIRECTORY_URL);\n if (status.enabled && status.url === url && !status.error?.includes(\"enrollment\")) return;\n await enableAddressDiscovery({ ...options, url, waitForPublication: false, reconcile: true,\n prompt: { print() {}, open() {}, question: async () => { throw new Error(\"Unexpected interactive setup.\"); },\n secret: async () => { throw new Error(\"Unexpected interactive setup.\"); } } });\n}\n\nexport function discoveryDescription(status: ComputerDiscoveryStatus | undefined): string {\n if (!status?.enabled) return \"Automatic address recovery is off. Enable it with mindwire discovery enable.\";\n if (status.error) return status.error;\n return status.sequence && status.publishedSequence === status.sequence\n ? \"Encrypted address recovery is on. Saved phones can find this computer when its tunnel address changes.\"\n : \"Publishing the computer's encrypted address…\";\n}\n","import { join } from \"node:path\";\nimport { setTimeout as delay } from \"node:timers/promises\";\nimport type { ComputerUpdate } from \"../computer.js\";\nimport type { Mindwire } from \"../client.js\";\nimport { computerClient, readJSON } from \"./lifecycle.js\";\nimport { versionAtLeast } from \"../version.js\";\n\ntype UpdateClient = Pick<Mindwire, \"health\" | \"computer\">;\nexport function activeUpdate(update: ComputerUpdate | undefined): update is ComputerUpdate {\n return !!update && [\"queued\", \"downloading\", \"waiting\", \"restarting\"].includes(update.status);\n}\n\n/** The daemon arbitrates requests. Join an earlier version before requesting the\n * next; promoting a request never creates a second download or bypasses its lease. */\nexport async function queueServiceUpdate(client: UpdateClient, version: string, force = false): Promise<ComputerUpdate> {\n for (let attempt = 0; ; attempt++) {\n const previous = await client.computer.updateStatus();\n if (activeUpdate(previous) && (!force || previous.force)) return previous;\n try {\n return await client.computer.requestUpdate(activeUpdate(previous) ? previous.version : version, { force });\n } catch (error) {\n if ((error as { status?: number }).status !== 409 || attempt >= 2) throw error;\n // Another caller won admission. Read the authoritative request and join it.\n }\n }\n}\n\nexport interface ServiceUpdateResult { version: string; complete: boolean; update?: ComputerUpdate }\n\n/** A CLI may close after queuing: the controller owns download/restart. Human\n * callers get a bounded result, including the exact older request being joined. */\nexport async function updateComputer(options: {\n directory: string; version: string; force?: boolean; allowDowngrade?: boolean;\n onProgress?: (update: ComputerUpdate) => void; signal?: AbortSignal; timeoutMs?: number;\n connect?: () => Promise<UpdateClient>;\n}):\nPromise<ServiceUpdateResult> {\n const version = options.version.replace(/^v/, \"\");\n if (!/^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?$/.test(version)) throw new Error(\"Enter a Mindwire release version, such as 0.1.38.\");\n const connect = options.connect ?? (() => computerClient(options.directory));\n const deadline = Date.now() + (options.timeoutMs ?? 120_000);\n let requested: ComputerUpdate | undefined, last = \"\";\n for (;;) {\n options.signal?.throwIfAborted();\n if (!requested) {\n const client = await connect();\n const installed = (await client.health()).version.replace(/^v/, \"\");\n if (installed === version || !options.allowDowngrade && versionAtLeast(installed, version))\n return { version: installed, complete: true };\n requested = await queueServiceUpdate(client, version, options.force);\n }\n // Progress survives the short API outage during restart. Only the daemon\n // accepts new requests; this read never changes or clears its status.\n const update = await readJSON<ComputerUpdate>(join(options.directory, \"computer-update.json\")) ?? requested;\n if (update.id !== requested.id) {\n // A concurrent update completed/advanced first. Recheck the live service.\n requested = undefined;\n } else {\n const key = `${update.id}:${update.status}`;\n if (last !== key) { last = key; options.onProgress?.(update); }\n if (update.status === \"failed\") throw new Error(update.error ?? \"The service update failed. Run mindwire inspect for details.\");\n if (update.status === \"complete\") {\n requested = undefined;\n if (Date.now() < deadline) continue;\n } else if (!options.force && update.status === \"waiting\") {\n return { version, complete: false, update };\n }\n }\n if (Date.now() >= deadline) return { version, complete: false, update };\n await delay(500, undefined, { signal: options.signal });\n }\n}\n\nexport function updateProgress(update: ComputerUpdate): string {\n const phase: Record<ComputerUpdate[\"status\"], string> = {\n idle: \"Ready\", queued: \"Queued\", downloading: \"Downloading verified release…\",\n waiting: \"Waiting for active work to finish\", restarting: \"Restarting service…\",\n complete: \"Installed\", failed: \"Update failed\",\n };\n return `${update.version} · ${phase[update.status]}`;\n}\n"]}
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { enableAddressDiscovery, disableAddressDiscovery, discoveryDescription, connectionAddress, saveDiscoveryPreference, discoveryPreference, reconcileAddressDiscovery, connectionInfo,
|
|
3
|
-
import { SDK_VERSION, defaultStateDirectory, computerClient, superviseComputer, ensureComputer, readJSON, defaultComputerConfig, computerPairingURI, stopComputer, processStateAlive, providerFailure, acquireProcessLock, writeJSON, currentProcessIdentity, CONTROLLER_PROTOCOL, versionAtLeast, websocketURL, providerNeedsAction, cloudflareCommand, computerPairingQRData, ProviderConnectionError } from './chunk-
|
|
2
|
+
import { enableAddressDiscovery, disableAddressDiscovery, discoveryDescription, connectionAddress, saveDiscoveryPreference, discoveryPreference, reconcileAddressDiscovery, connectionInfo, updateComputer, updateProgress, activeUpdate } from './chunk-ZNEFE6KD.js';
|
|
3
|
+
import { SDK_VERSION, defaultStateDirectory, computerClient, superviseComputer, ensureComputer, readJSON, defaultComputerConfig, computerPairingURI, stopComputer, processStateAlive, providerFailure, acquireProcessLock, writeJSON, currentProcessIdentity, CONTROLLER_PROTOCOL, versionAtLeast, websocketURL, providerNeedsAction, cloudflareCommand, computerPairingQRData, ProviderConnectionError } from './chunk-P3JTWITC.js';
|
|
4
4
|
import { ApiError } from './chunk-PFYKJ6LX.js';
|
|
5
5
|
import { promisify, parseArgs } from 'util';
|
|
6
6
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
@@ -22,7 +22,7 @@ var enterScreen = "\x1B[?1049h\x1B[?25l";
|
|
|
22
22
|
var leaveScreen = "\x1B[0m\x1B[?25h\x1B[?1049l";
|
|
23
23
|
var clearScreen = "\x1B[H\x1B[2J";
|
|
24
24
|
function scanInstruction(invitation) {
|
|
25
|
-
return "mode" in invitation && invitation.mode === "reconnect" ? "Workspaces \u2192 your computer \u2192 Reconnect Computer \u2192 Scan Connection Code" : "Mindwire
|
|
25
|
+
return "mode" in invitation && invitation.mode === "reconnect" ? "Workspaces \u2192 your computer \u2192 Reconnect Computer \u2192 Scan Connection Code" : "In Mindwire on your phone, tap Scan QR code.";
|
|
26
26
|
}
|
|
27
27
|
async function createPairingQR(invitation) {
|
|
28
28
|
const QR = await import('qrcode');
|
|
@@ -67,15 +67,15 @@ textarea{width:100%;margin-top:12px;padding:8px;color:inherit;background:#252528
|
|
|
67
67
|
<small>MINDWIRE</small><h1>${title}</h1><p>${escapeHTML(invitation.name)}</p>
|
|
68
68
|
<div class="code" id="code" role="img" aria-label="Mindwire connection QR code">${svg}</div>
|
|
69
69
|
<p id="expiry" data-expires="${escapeHTML(invitation.expiresAt)}" aria-live="off"></p>
|
|
70
|
-
<div class="steps"><p>${reconnect ? "In Mindwire, open your computer in <strong>Workspaces</strong>, then <strong>Reconnect Computer \u2192 Scan Connection Code</strong>." : "In Mindwire,
|
|
71
|
-
<p>${reconnect ? "Your saved pairing
|
|
70
|
+
<div class="steps"><p>${reconnect ? "In Mindwire, open your computer in <strong>Workspaces</strong>, then <strong>Reconnect Computer \u2192 Scan Connection Code</strong>." : "In Mindwire on your phone, tap <strong>Scan QR code</strong>."}</p>
|
|
71
|
+
<p>${reconnect ? "Your saved pairing stays the same." : "Then approve your phone in the terminal."}</p></div>
|
|
72
72
|
<button type="button" id="copy">Copy ${reconnect ? "reconnect" : "pairing"} link</button>
|
|
73
73
|
<textarea id="link" readonly hidden aria-label="Pairing link">${escapeHTML(computerPairingURI(invitation))}</textarea>
|
|
74
74
|
<footer>You can close this page after ${reconnect ? "reconnecting" : "pairing"}.</footer>
|
|
75
75
|
</main><script>
|
|
76
76
|
const expiry=document.getElementById('expiry'),code=document.getElementById('code'),copy=document.getElementById('copy'),link=document.getElementById('link');
|
|
77
77
|
function tick(){const seconds=Math.max(0,Math.ceil((Date.parse(expiry.dataset.expires)-Date.now())/1000));
|
|
78
|
-
if(!seconds){code.remove();copy.disabled=true;link.value='';link.hidden=true;expiry.textContent='Code expired. Run mindwire connect for a new code.';return;}
|
|
78
|
+
if(!seconds){code.remove();copy.disabled=true;link.value='';link.hidden=true;expiry.textContent='Code expired. Run mindwire connect pair for a new code.';return;}
|
|
79
79
|
expiry.textContent='Expires in '+Math.floor(seconds/60)+':'+String(seconds%60).padStart(2,'0');}
|
|
80
80
|
tick();setInterval(tick,1000);
|
|
81
81
|
copy.addEventListener('click',async()=>{try{await navigator.clipboard.writeText(link.value);copy.textContent='Copied';}
|
|
@@ -103,7 +103,7 @@ async function showPairingInvitation(invitation, options = {}) {
|
|
|
103
103
|
const instruction = scanInstruction(invitation);
|
|
104
104
|
const nextStep = reconnect ? "Scan with a saved phone." : "Approve on this computer only if asked.";
|
|
105
105
|
const waiting = reconnect ? "Your saved pairing stays the same." : "Waiting for your phone\u2026";
|
|
106
|
-
const command = "mindwire connect";
|
|
106
|
+
const command = "mindwire connect pair";
|
|
107
107
|
const output = options.output ?? process.stdout;
|
|
108
108
|
const environment = options.environment ?? process.env;
|
|
109
109
|
const mode = options.mode ?? "auto";
|
|
@@ -1229,8 +1229,8 @@ async function computerDashboard(directory, run2) {
|
|
|
1229
1229
|
const saved = state.devices.filter((device) => !device.revoked);
|
|
1230
1230
|
const running = state.service === "running";
|
|
1231
1231
|
const action = await chooseTerminal([...inspectionText(state).split("\n"), "", "Manage this computer"], [
|
|
1232
|
-
{ value: "
|
|
1233
|
-
{ value: "
|
|
1232
|
+
{ value: "pair", label: "Show QR code \xB7 connect a phone" },
|
|
1233
|
+
{ value: "reconnect", label: running ? "Retry saved connections" : "Start connection" },
|
|
1234
1234
|
{ value: "devices", label: `Phones${saved.length ? ` \xB7 ${saved.length} paired` : ""}` },
|
|
1235
1235
|
{ value: "startup", label: `Start at login \xB7 ${state.startup.enabled ? state.startup.running ? "On" : "Needs repair" : "Off"}` },
|
|
1236
1236
|
{ value: "connection", label: "Connection provider" },
|
|
@@ -1261,7 +1261,7 @@ async function computerDashboard(directory, run2) {
|
|
|
1261
1261
|
break;
|
|
1262
1262
|
case "devices": {
|
|
1263
1263
|
if (!saved.length) {
|
|
1264
|
-
process.stdout.write("No paired phones. Choose
|
|
1264
|
+
process.stdout.write("No paired phones. Choose Show QR code to connect one.\n");
|
|
1265
1265
|
break;
|
|
1266
1266
|
}
|
|
1267
1267
|
const id = await chooseTerminal("Paired phones", saved.map((device2) => ({ value: device2.id, label: deviceSummary([device2], true).trim() })));
|
|
@@ -1324,7 +1324,6 @@ async function computerDashboard(directory, run2) {
|
|
|
1324
1324
|
process.stderr.write(`Mindwire: ${terminalText(error instanceof Error ? error.message : String(error))}
|
|
1325
1325
|
`);
|
|
1326
1326
|
}
|
|
1327
|
-
if (!await chooseTerminal("", [{ value: "continue", label: "Back to Mindwire" }])) return;
|
|
1328
1327
|
}
|
|
1329
1328
|
}
|
|
1330
1329
|
function desktopSummary(info) {
|
|
@@ -1423,7 +1422,7 @@ var help = `Mindwire \u2014 connect this computer to your phone
|
|
|
1423
1422
|
mindwire Interactive status and connection controls
|
|
1424
1423
|
mindwire connect Connect your phone; saved keys reconnect automatically
|
|
1425
1424
|
mindwire reconnect Retry the saved connection
|
|
1426
|
-
mindwire connect pair
|
|
1425
|
+
mindwire connect pair Show a QR code to pair or reconnect a phone
|
|
1427
1426
|
mindwire connection Choose a persistent connection provider
|
|
1428
1427
|
mindwire connection automatic Cloudflare traffic with encrypted Mindwire address recovery
|
|
1429
1428
|
mindwire connection oblien Sign in and use an Oblien tunnel
|
|
@@ -1652,18 +1651,18 @@ async function main(args = process.argv.slice(2)) {
|
|
|
1652
1651
|
}
|
|
1653
1652
|
const info = await client2.computer.info();
|
|
1654
1653
|
const connection = connectionInfo(savedConfig?.relay ?? { kind: "cloudflare" }, savedConfig?.host);
|
|
1655
|
-
emit("ready", { computerId: info.computerId, routes: info.routes, connection }, "Mindwire is running
|
|
1656
|
-
emit("connection", connection
|
|
1654
|
+
emit("ready", { computerId: info.computerId, routes: info.routes, connection }, "Mindwire is running.");
|
|
1655
|
+
emit("connection", connection);
|
|
1657
1656
|
if (command === "start") return;
|
|
1658
1657
|
if (info.routes.some((route) => route.kind === "websocket")) {
|
|
1659
|
-
emit("secure_connection"
|
|
1658
|
+
emit("secure_connection");
|
|
1660
1659
|
}
|
|
1661
1660
|
const devices = await client2.computer.devices();
|
|
1662
1661
|
const saved = devices.filter((device) => !device.revoked);
|
|
1663
1662
|
if (addressChanged && !saved.some((device) => device.addressRecovery)) requestedAction = "pair";
|
|
1664
|
-
if (info.discovery?.enabled) emit("discovery", info.discovery
|
|
1663
|
+
if (info.discovery?.enabled) emit("discovery", info.discovery);
|
|
1665
1664
|
if (saved.length) emit("saved_devices", { devices: saved }, `
|
|
1666
|
-
Saved
|
|
1665
|
+
Saved phones
|
|
1667
1666
|
${deviceSummary(saved)}`);
|
|
1668
1667
|
const question2 = !values.json && process.stdin.isTTY ? async (prompt) => {
|
|
1669
1668
|
const input = createInterface({ input: process.stdin, output: process.stderr });
|
|
@@ -1684,21 +1683,18 @@ ${deviceSummary(saved)}`);
|
|
|
1684
1683
|
if (startupAction !== void 0) {
|
|
1685
1684
|
try {
|
|
1686
1685
|
const startup = await configureStartup(directory, fileURLToPath(import.meta.url), startupAction);
|
|
1687
|
-
emit("startup", startup, startup.enabled ? "
|
|
1686
|
+
emit("startup", startup, startup.enabled ? "Start at login: On" : "Start at login: Off. Enable with mindwire startup enable.");
|
|
1688
1687
|
} catch {
|
|
1689
1688
|
emit("startup_unavailable", {}, "Mindwire is running, but startup setup didn't complete. Run mindwire startup enable to check your system's startup service.");
|
|
1690
1689
|
}
|
|
1691
1690
|
} else {
|
|
1692
|
-
emit("startup", startupPreference, startupPreference.enabled ? startupPreference.running ? "
|
|
1691
|
+
emit("startup", startupPreference, startupPreference.enabled ? startupPreference.running ? "Start at login: On" : "Automatic startup needs repair. Run mindwire startup repair." : "Start at login: Off. Enable with mindwire startup enable.");
|
|
1693
1692
|
}
|
|
1694
1693
|
if (action === "resume") {
|
|
1695
1694
|
const connected = saved.filter((device) => device.connected);
|
|
1696
|
-
if (connected.length) emit("connected", { computerId: info.computerId, devices: connected },
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
Mindwire continues running in the background.`);
|
|
1700
|
-
else emit("waiting_for_phone", { computerId: info.computerId }, "\nReady for your saved phone. Open Mindwire; it will retry this computer's saved connection.");
|
|
1701
|
-
emit("connect_hint", {}, "If the connection was removed from your phone, run mindwire connect pair to scan again.");
|
|
1695
|
+
if (connected.length) emit("connected", { computerId: info.computerId, devices: connected }, "\nYour phone is connected.");
|
|
1696
|
+
else emit("waiting_for_phone", { computerId: info.computerId }, "\nOpen Mindwire on your phone and choose your saved computer.");
|
|
1697
|
+
emit("connect_hint", {}, "Need a QR code? Run mindwire connect pair.");
|
|
1702
1698
|
return;
|
|
1703
1699
|
}
|
|
1704
1700
|
const invitation = await client2.computer.invite((await client2.computer.info()).routes);
|