forge-memory 0.2.112 → 0.2.114
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 +5 -1
- package/bin/forge-memory.mjs +49 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -55,7 +55,11 @@ the iOS Simulator but not for a physical phone.
|
|
|
55
55
|
|
|
56
56
|
The base install stays one command on purpose. The detailed companion transport
|
|
57
57
|
reference lives in the Forge repo at `docs/companion-iroh.md` and in the published
|
|
58
|
-
docs at `https://albertbuchard.github.io/forge/companion-transport.html`.
|
|
58
|
+
docs at `https://albertbuchard.github.io/forge/companion-transport.html`. Forge
|
|
59
|
+
Memory ships prebuilt Iroh host binaries for common desktop platforms and a bundled
|
|
60
|
+
Rust source fallback for other machines. If neither a prebuilt host nor Cargo is
|
|
61
|
+
available, `pair-ios` stops with transport-specific repair guidance instead of
|
|
62
|
+
printing a localhost QR that a physical iPhone cannot use.
|
|
59
63
|
|
|
60
64
|
`configure` reruns the full guided flow using the current config as defaults.
|
|
61
65
|
Install and configure run Forge doctor before finishing. `doctor --repair` creates
|
package/bin/forge-memory.mjs
CHANGED
|
@@ -1616,6 +1616,22 @@ class PairingRequestError extends Error {
|
|
|
1616
1616
|
}
|
|
1617
1617
|
}
|
|
1618
1618
|
|
|
1619
|
+
class PairingTransportUnavailableError extends Error {
|
|
1620
|
+
constructor(message, detail = {}) {
|
|
1621
|
+
super(message);
|
|
1622
|
+
this.name = "PairingTransportUnavailableError";
|
|
1623
|
+
this.code = "pairing_transport_unavailable";
|
|
1624
|
+
this.detail = detail;
|
|
1625
|
+
this.guidance = [
|
|
1626
|
+
"Run npx forge-memory doctor --repair so Forge Memory refreshes the packaged runtime and companion transport files.",
|
|
1627
|
+
"Then rerun npx forge-memory pair-ios.",
|
|
1628
|
+
"On unsupported platforms, install Rust/Cargo so Forge can build the bundled companion Iroh source fallback.",
|
|
1629
|
+
"For an explicit Tailscale or LAN fallback, rerun with npx forge-memory pair-ios --manual-http --public-url <phone-reachable Forge URL>.",
|
|
1630
|
+
"Do not scan a QR whose API URL is 127.0.0.1 on a physical iPhone; that address only works in the iOS Simulator."
|
|
1631
|
+
];
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1619
1635
|
async function bootstrapLocalOperatorSession(config) {
|
|
1620
1636
|
const sessionUrl = forgeApiUrl(config, "/api/v1/auth/operator-session");
|
|
1621
1637
|
let response;
|
|
@@ -1706,7 +1722,39 @@ async function createPairing(config, options = {}) {
|
|
|
1706
1722
|
{ url: pairingUrl.toString(), status: response.status }
|
|
1707
1723
|
);
|
|
1708
1724
|
}
|
|
1709
|
-
|
|
1725
|
+
const pairing = await response.json();
|
|
1726
|
+
assertPairingTransportUsable(pairing, { requestedTransportMode: transportMode });
|
|
1727
|
+
return pairing;
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1730
|
+
function assertPairingTransportUsable(pairing, { requestedTransportMode }) {
|
|
1731
|
+
const payload = pairing?.qrPayload;
|
|
1732
|
+
if (!payload || requestedTransportMode !== "iroh") {
|
|
1733
|
+
return;
|
|
1734
|
+
}
|
|
1735
|
+
const resolvedTransportMode = payload.transportMode ?? payload.transport?.protocol;
|
|
1736
|
+
const resolvedProtocol = payload.transport?.protocol;
|
|
1737
|
+
if (resolvedTransportMode === "iroh" || resolvedProtocol === "iroh") {
|
|
1738
|
+
return;
|
|
1739
|
+
}
|
|
1740
|
+
const apiBaseUrl = payload.apiBaseUrl ?? "";
|
|
1741
|
+
const lastError = payload.transport?.lastError;
|
|
1742
|
+
const notes = Array.isArray(payload.transport?.notes) ? payload.transport.notes : [];
|
|
1743
|
+
throw new PairingTransportUnavailableError(
|
|
1744
|
+
[
|
|
1745
|
+
"Forge created a direct HTTP pairing while default iOS pairing requested Iroh.",
|
|
1746
|
+
isLoopbackPairingUrl(apiBaseUrl)
|
|
1747
|
+
? `The generated API URL is ${apiBaseUrl}, which a physical iPhone cannot reach.`
|
|
1748
|
+
: apiBaseUrl
|
|
1749
|
+
? `The generated API URL is ${apiBaseUrl}, but this was not an Iroh pairing.`
|
|
1750
|
+
: "The response did not include a usable Iroh API URL.",
|
|
1751
|
+
lastError ? `Iroh error: ${lastError}` : "",
|
|
1752
|
+
notes.length ? `Notes: ${notes.join(" ")}` : ""
|
|
1753
|
+
]
|
|
1754
|
+
.filter(Boolean)
|
|
1755
|
+
.join(" "),
|
|
1756
|
+
{ apiBaseUrl, transportMode: resolvedTransportMode, protocol: resolvedProtocol }
|
|
1757
|
+
);
|
|
1710
1758
|
}
|
|
1711
1759
|
|
|
1712
1760
|
function validatePairingOptions({ transportMode, publicUrl }) {
|
package/package.json
CHANGED