Merge branch 'main' into dev

Resolve 38 conflicts preserving both sides' work:
- Server: DB-based registries (dev) + WorkspaceGitService/DaemonConfigStore (main)
- App: script proxy/voice MCP (dev) + pin/hide tabs/bootstrap boundary (main)
- Shared: WorkspaceScriptPayload (dev) + git/GitHub runtime schemas (main)
- Deleted workspace-registry-bootstrap.ts (dev's DB approach supersedes)
This commit is contained in:
Mohamed Boudra
2026-04-14 03:05:45 +07:00
333 changed files with 13490 additions and 6317 deletions
+43 -8
View File
@@ -585,6 +585,46 @@ describe("HostRuntimeController", () => {
});
});
it("does not emit legacy typed reason-code transition logs", async () => {
const infoSpy = vi.spyOn(console, "info").mockImplementation(() => undefined);
try {
const host = makeHost({
connections: [
{
id: "direct:lan:6767",
type: "directTcp",
endpoint: "lan:6767",
},
],
});
const clients: FakeDaemonClient[] = [];
const controller = new HostRuntimeController({
host,
deps: makeDeps(
{
"direct:lan:6767": 12,
},
clients,
),
});
await controller.start({ autoProbe: false });
clients[0]?.setConnectionState({
status: "disconnected",
reason: "transport closed",
});
const transitionPayloads = infoSpy.mock.calls
.filter((call) => call[0] === "[HostRuntimeTransition]")
.map((call) => call[1] as { reasonCode?: string | null });
const lastTransition = transitionPayloads[transitionPayloads.length - 1] ?? null;
expect(lastTransition?.reasonCode).toBeUndefined();
} finally {
infoSpy.mockRestore();
}
});
it("marks directory loading on first connection before any directory sync succeeds", async () => {
const host = makeHost();
const clients: FakeDaemonClient[] = [];
@@ -1201,12 +1241,7 @@ describe("HostRuntimeStore", () => {
archivedAt: stale.archivedAt ? new Date(stale.archivedAt) : null,
attentionTimestamp: stale.attentionTimestamp ? new Date(stale.attentionTimestamp) : null,
};
return new Map([
[
stale.id,
staleAgent,
],
]);
return new Map([[stale.id, staleAgent]]);
});
store.syncHosts([host]);
@@ -1322,7 +1357,7 @@ describe("HostRuntimeStore", () => {
store.syncHosts([]);
});
it("keeps a custom host label when re-pairing with an advertised hostname", async () => {
it("uses the latest advertised hostname when re-pairing an existing relay host", async () => {
const store = new HostRuntimeStore({
deps: {
createClient: () => new FakeDaemonClient() as unknown as DaemonClient,
@@ -1345,7 +1380,7 @@ describe("HostRuntimeStore", () => {
await store.upsertConnectionFromOffer(makeOffer(), "mbp");
const pairedHost = store.getHosts().find((host) => host.serverId === "srv_offer");
expect(pairedHost?.label).toBe("Custom name");
expect(pairedHost?.label).toBe("mbp");
store.syncHosts([]);
});
+4 -14
View File
@@ -16,10 +16,7 @@ import {
import { decodeOfferFragmentPayload, normalizeHostPort } from "@/utils/daemon-endpoints";
import { resolveAppVersion } from "@/utils/app-version";
import { ConnectionOfferSchema, type ConnectionOffer } from "@server/shared/connection-offer";
import {
shouldUseDesktopDaemon,
startDesktopDaemon,
} from "@/desktop/daemon/desktop-daemon";
import { shouldUseDesktopDaemon, startDesktopDaemon } from "@/desktop/daemon/desktop-daemon";
import { connectToDaemon } from "@/utils/test-daemon-connection";
import { buildDaemonWebSocketUrl, buildRelayWebSocketUrl } from "@/utils/daemon-endpoints";
import { getOrCreateClientId } from "@/utils/client-id";
@@ -1078,8 +1075,7 @@ export class HostRuntimeController {
}
const REGISTRY_STORAGE_KEY = "@paseo:daemon-registry";
const DEFAULT_LOCALHOST_ENDPOINT =
process.env.EXPO_PUBLIC_LOCAL_DAEMON?.trim() || "localhost:6767";
const DEFAULT_LOCALHOST_ENDPOINT = process.env.EXPO_PUBLIC_LOCAL_DAEMON?.trim() || "localhost:6767";
const DEFAULT_LOCALHOST_BOOTSTRAP_KEY = "@paseo:default-localhost-bootstrap-v1";
const DEFAULT_LOCALHOST_BOOTSTRAP_TIMEOUT_MS = 2500;
const CONNECTION_ONLINE_TIMEOUT_MS = 15_000;
@@ -1287,10 +1283,7 @@ export class HostRuntimeStore {
});
}
async upsertConnectionFromOffer(
offer: ConnectionOffer,
label?: string,
): Promise<HostProfile> {
async upsertConnectionFromOffer(offer: ConnectionOffer, label?: string): Promise<HostProfile> {
return this.upsertRelayConnection({
serverId: offer.serverId,
relayEndpoint: offer.relay.endpoint,
@@ -1560,10 +1553,7 @@ export class HostRuntimeStore {
return { ok: true };
}
if (
snapshot.activeConnectionId === connectionId &&
snapshot.connectionStatus === "error"
) {
if (snapshot.activeConnectionId === connectionId && snapshot.connectionStatus === "error") {
return {
ok: false,
error: new Error(snapshot.lastError ?? "Connection failed before coming online."),