overmux 0.0.2 → 0.0.4

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.
Files changed (72) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/auth/.vite/manifest.json +2 -2
  3. package/dist/auth/assets/{index-Bx8JhwVi.css → index-BM9gETvx.css} +1 -1
  4. package/dist/auth/assets/{index-CHIE7qYj.js → index-DabAfcs1.js} +1 -1
  5. package/dist/auth/index.html +2 -2
  6. package/dist/bin.js +430 -18
  7. package/dist/bin.js.map +1 -1
  8. package/dist/docs/200-getting-started/100-install-and-run-overmux.md +1 -2
  9. package/dist/docs/300-fundamentals/100-project-structure.md +20 -0
  10. package/dist/docs/300-fundamentals/300-theming.md +51 -0
  11. package/dist/docs/400-reference/100-configuration.md +20 -0
  12. package/dist/docs/400-reference/200-server-api.md +18 -0
  13. package/dist/docs/400-reference/300-client-api.md +36 -0
  14. package/dist/docs/400-reference/400-cli/050-init.md +17 -0
  15. package/dist/docs/400-reference/400-cli/350-instance.md +24 -0
  16. package/dist/exports/client.d.ts +33 -3
  17. package/dist/exports/client.d.ts.map +1 -1
  18. package/dist/exports/client.js +123 -14
  19. package/dist/exports/client.js.map +1 -1
  20. package/dist/exports/{index-D3_Dpy_T.d.ts → index-DS70rKzo.d.ts} +14 -2
  21. package/dist/exports/index-DS70rKzo.d.ts.map +1 -0
  22. package/dist/exports/index.d.ts +2 -2
  23. package/dist/exports/index.js +1 -1
  24. package/dist/exports/index.js.map +1 -1
  25. package/dist/exports/{notifications-kDp16bU_.js → notifications-av0FK0yZ.js} +7 -2
  26. package/dist/exports/{notifications-kDp16bU_.js.map → notifications-av0FK0yZ.js.map} +1 -1
  27. package/dist/exports/server.d.ts.map +1 -1
  28. package/dist/exports/server.js +52 -10
  29. package/dist/exports/server.js.map +1 -1
  30. package/dist/internal/server/coordinator/server-child.js +110 -46
  31. package/dist/internal/server/coordinator/server-child.js.map +1 -1
  32. package/docs/200-getting-started/100-install-and-run-overmux.md +1 -2
  33. package/docs/300-fundamentals/100-project-structure.md +20 -0
  34. package/docs/300-fundamentals/300-theming.md +51 -0
  35. package/docs/400-reference/100-configuration.md +20 -0
  36. package/docs/400-reference/200-server-api.md +18 -0
  37. package/docs/400-reference/300-client-api.md +36 -0
  38. package/docs/400-reference/400-cli/050-init.md +17 -0
  39. package/docs/400-reference/400-cli/350-instance.md +24 -0
  40. package/package.json +2 -2
  41. package/src/internal/cli/app.ts +7 -1
  42. package/src/internal/cli/commands/init-template.ts +146 -0
  43. package/src/internal/cli/commands/init.ts +267 -0
  44. package/src/internal/cli/commands/instance.ts +58 -0
  45. package/src/internal/cli/commands/integration.ts +15 -0
  46. package/src/internal/cli/commands/zellij-install.ts +96 -0
  47. package/src/internal/cli/parse-port.ts +2 -1
  48. package/src/internal/client/auth/auth-shell.css +17 -1
  49. package/src/internal/client/auth/auth-shell.tsx +2 -11
  50. package/src/internal/client/auth/login-code-input.tsx +140 -0
  51. package/src/internal/client/browser-api.ts +17 -3
  52. package/src/internal/client/clipboard.ts +22 -0
  53. package/src/internal/client/host/desktop-host.ts +15 -0
  54. package/src/internal/client/host/environment.ts +67 -0
  55. package/src/internal/client/host/instance-forwarding.ts +21 -0
  56. package/src/internal/client/host/notification-forwarding.ts +1 -10
  57. package/src/internal/client/host/overmux-host.tsx +8 -0
  58. package/src/internal/client/overmux-react.ts +24 -2
  59. package/src/internal/client/websocket.ts +48 -20
  60. package/src/internal/server/auth/instance-control.ts +24 -3
  61. package/src/internal/server/runtime/create-runtime.ts +12 -1
  62. package/src/internal/server/runtime/runtime-instance.ts +46 -0
  63. package/src/internal/server/runtime/runtime-resources.ts +3 -0
  64. package/src/internal/server/server-startup-options.ts +9 -4
  65. package/src/internal/server/start-application-server.ts +20 -12
  66. package/src/internal/server/websocket-server.ts +7 -0
  67. package/src/internal/shared/index.ts +2 -0
  68. package/src/internal/shared/protocol.ts +10 -1
  69. package/src/public/client.ts +5 -0
  70. package/src/public/config.ts +7 -0
  71. package/src/public/index.ts +2 -0
  72. package/dist/exports/index-D3_Dpy_T.d.ts.map +0 -1
@@ -1,5 +1,7 @@
1
1
  import {
2
2
  clientProtocolMessageSchema,
3
+ createInstanceIdentity,
4
+ type InstanceIdentity,
3
5
  decodeProtocolFrame,
4
6
  encodeProtocolMessage,
5
7
  serverProtocolMessageSchema,
@@ -42,6 +44,8 @@ export type TransportStatus =
42
44
  | "disconnected";
43
45
 
44
46
  export type WebSocketTransport = {
47
+ getInstance: () => InstanceIdentity | undefined;
48
+ subscribeInstance: (listener: () => void) => () => void;
45
49
  activate: () => void;
46
50
  dispose: () => void;
47
51
  openStream: (input: {
@@ -99,6 +103,12 @@ export const createWebSocketTransport = ({
99
103
  let reconnectTimer: ReturnType<typeof setTimeout> | undefined;
100
104
  let socket: WebSocket | undefined;
101
105
  let status: TransportStatus = "disconnected";
106
+ let instance: InstanceIdentity | undefined;
107
+ const instanceListeners = new Set<() => void>();
108
+ const setInstance = (next: InstanceIdentity | undefined) => {
109
+ instance = next;
110
+ instanceListeners.forEach((listener) => listener());
111
+ };
102
112
  const diagnosticQueue: ClientDiagnosticEvent[] = [];
103
113
  const requests = new Map<string, Request>();
104
114
  const subscriptions = new Map<string, Subscription>();
@@ -115,7 +125,7 @@ export const createWebSocketTransport = ({
115
125
  statusListeners.forEach((listener) => listener(status));
116
126
  };
117
127
  const send = (message: unknown) => {
118
- if (socket?.readyState !== WebSocket.OPEN) {
128
+ if (socket?.readyState !== WebSocket.OPEN || !instance) {
119
129
  return false;
120
130
  }
121
131
  // Apply outbound backpressure before queued messages consume unbounded memory.
@@ -189,6 +199,7 @@ export const createWebSocketTransport = ({
189
199
  requests.clear();
190
200
  };
191
201
  const reportDisconnect = () => {
202
+ setInstance(undefined);
192
203
  const error = disconnected();
193
204
  rejectRequests(error);
194
205
  subscriptions.forEach(({ onError }) => onError(error));
@@ -208,17 +219,8 @@ export const createWebSocketTransport = ({
208
219
  const next = createSocket();
209
220
  next.binaryType = "arraybuffer";
210
221
  socket = next;
211
- next.addEventListener("open", () => {
212
- if (socket !== next) {
213
- return;
214
- }
215
- reconnectDelay = 250;
216
- setStatus("connected");
217
- flushDiagnostics();
218
- restore();
219
- });
220
222
  next.addEventListener("message", (event) => {
221
- if (socket !== next) {
223
+ if (socket !== next || disposed) {
222
224
  return;
223
225
  }
224
226
  let decoded: unknown;
@@ -238,6 +240,19 @@ export const createWebSocketTransport = ({
238
240
  return;
239
241
  }
240
242
  const message = parsed.data;
243
+ if (message.type === "server-info" && !instance) {
244
+ setInstance(createInstanceIdentity(message.instanceId));
245
+ reconnectDelay = 250;
246
+ setStatus("connected");
247
+ flushDiagnostics();
248
+ restore();
249
+ return;
250
+ }
251
+ if (!instance || message.type === "server-info") {
252
+ reportDisconnect();
253
+ next.close(1002, "expected server discovery before traffic");
254
+ return;
255
+ }
241
256
  if (
242
257
  message.type === "update-available" ||
243
258
  message.type === "restarting"
@@ -312,6 +327,11 @@ export const createWebSocketTransport = ({
312
327
  };
313
328
 
314
329
  return {
330
+ getInstance: () => instance,
331
+ subscribeInstance: (listener) => {
332
+ instanceListeners.add(listener);
333
+ return () => instanceListeners.delete(listener);
334
+ },
315
335
  activate: () => {
316
336
  active = true;
317
337
  connect();
@@ -335,6 +355,10 @@ export const createWebSocketTransport = ({
335
355
  onOpen,
336
356
  streamName,
337
357
  }) => {
358
+ if (!active || disposed) {
359
+ onError(disconnected());
360
+ return { close: () => {}, send: () => false };
361
+ }
338
362
  const streamId = operationId();
339
363
  const stream: Stream = {
340
364
  input,
@@ -347,15 +371,19 @@ export const createWebSocketTransport = ({
347
371
  streamName,
348
372
  };
349
373
  streams.set(streamId, stream);
350
- stream.status = send({
351
- input,
352
- operationId: streamId,
353
- streamId,
354
- streamName,
355
- type: "stream-open",
356
- })
357
- ? "opening"
358
- : "disconnected";
374
+ // Initial connection is not a failure: restore sends stream-open when the socket
375
+ // opens, then stream-opened flushes queued messages. Actual failures still reject.
376
+ stream.status =
377
+ status === "connecting" ||
378
+ send({
379
+ input,
380
+ operationId: streamId,
381
+ streamId,
382
+ streamName,
383
+ type: "stream-open",
384
+ })
385
+ ? "opening"
386
+ : "disconnected";
359
387
  if (stream.status === "disconnected") {
360
388
  onError(disconnected());
361
389
  }
@@ -5,6 +5,8 @@ import { tmpdir } from "node:os";
5
5
  import { join } from "node:path";
6
6
  import { z } from "zod";
7
7
 
8
+ import { instanceIdSchema } from "@overmux/shared";
9
+
8
10
  import { getOvermuxPaths } from "../paths";
9
11
  import {
10
12
  readPrivateJson,
@@ -15,6 +17,7 @@ import type { AuthService } from "./auth-service";
15
17
  const maxControlMessageBytes = 16_384;
16
18
 
17
19
  const controlRequestSchema = z.discriminatedUnion("type", [
20
+ z.object({ type: z.literal("get-instance") }).strict(),
18
21
  z.object({ type: z.literal("ping") }).strict(),
19
22
  z.object({ type: z.literal("create-login") }).strict(),
20
23
  z.object({ type: z.literal("issue-bearer") }).strict(),
@@ -44,6 +47,9 @@ const sessionSchema = z
44
47
  .strict();
45
48
 
46
49
  const controlResponseSchemas = {
50
+ "get-instance": z
51
+ .object({ instanceId: instanceIdSchema, ok: z.literal(true) })
52
+ .strict(),
47
53
  "create-login": z
48
54
  .object({ login: loginGrantSchema, ok: z.literal(true) })
49
55
  .strict(),
@@ -164,7 +170,18 @@ const writeResponse = (socket: Socket, response: unknown) => {
164
170
  socket.end(`${JSON.stringify(response)}\n`);
165
171
  };
166
172
 
167
- const handleRequest = async (auth: AuthService, request: ControlRequest) => {
173
+ const handleRequest = async ({
174
+ auth,
175
+ instanceId,
176
+ request,
177
+ }: {
178
+ auth: AuthService;
179
+ instanceId: string;
180
+ request: ControlRequest;
181
+ }) => {
182
+ if (request.type === "get-instance") {
183
+ return { instanceId, ok: true };
184
+ }
168
185
  if (request.type === "ping") {
169
186
  return { ok: true };
170
187
  }
@@ -185,9 +202,11 @@ const handleRequest = async (auth: AuthService, request: ControlRequest) => {
185
202
 
186
203
  const handleConnection = async ({
187
204
  auth,
205
+ instanceId,
188
206
  socket,
189
207
  }: {
190
208
  auth: AuthService;
209
+ instanceId: string;
191
210
  socket: Socket;
192
211
  }) => {
193
212
  try {
@@ -196,7 +215,7 @@ const handleConnection = async ({
196
215
  socket,
197
216
  });
198
217
  const request = controlRequestSchema.parse(JSON.parse(frame.toString()));
199
- writeResponse(socket, await handleRequest(auth, request));
218
+ writeResponse(socket, await handleRequest({ auth, instanceId, request }));
200
219
  } catch (cause) {
201
220
  writeResponse(socket, {
202
221
  error: cause instanceof Error ? cause.message : "Invalid control request",
@@ -214,11 +233,13 @@ const handleConnection = async ({
214
233
  export const startInstanceControl = async ({
215
234
  auth,
216
235
  apiUrl,
236
+ instanceId,
217
237
  port,
218
238
  url,
219
239
  }: {
220
240
  auth: AuthService;
221
241
  apiUrl: string;
242
+ instanceId: string;
222
243
  port: number;
223
244
  url: string;
224
245
  }): Promise<InstanceControl> => {
@@ -232,7 +253,7 @@ export const startInstanceControl = async ({
232
253
  const server = createServer((socket) => {
233
254
  sockets.add(socket);
234
255
  socket.once("close", () => sockets.delete(socket));
235
- void handleConnection({ auth, socket });
256
+ void handleConnection({ auth, instanceId, socket });
236
257
  });
237
258
  const close = async () => {
238
259
  sockets.forEach((socket) => socket.destroy());
@@ -2,7 +2,12 @@
2
2
 
3
3
  import type { RuntimeConfigDefinition } from "@overmux/shared/node";
4
4
 
5
- import type { Notifications } from "../../../public/index";
5
+ import type {
6
+ InstanceContext,
7
+ InstanceIdentity,
8
+ Notifications,
9
+ } from "../../../public/index";
10
+ import { createRuntimeInstance } from "./runtime-instance";
6
11
  import { protocolVersion, type RuntimeManifest } from "../../shared/index";
7
12
 
8
13
  import { createRuntimeLifecycle } from "./runtime-lifecycle";
@@ -23,6 +28,8 @@ import {
23
28
  } from "./runtime-streams";
24
29
 
25
30
  export type Runtime = {
31
+ instance: InstanceContext;
32
+ establishInstance: (port: number) => InstanceIdentity;
26
33
  manifest: RuntimeManifest;
27
34
  dispose: () => Promise<void>;
28
35
  getOperation: (name: string) => RuntimeOperation | undefined;
@@ -44,10 +51,12 @@ export const createRuntime = async ({
44
51
  signal,
45
52
  }: CreateRuntimeOptions): Promise<Runtime> => {
46
53
  const lifecycle = createRuntimeLifecycle(signal);
54
+ const instance = createRuntimeInstance(config.instanceId);
47
55
  try {
48
56
  const resources = createRuntimeResources({
49
57
  definitions: (config.server.resources ??
50
58
  {}) as RuntimeResourceDefinitions,
59
+ instance: instance.context,
51
60
  lifecycle,
52
61
  });
53
62
  const context = resources.context;
@@ -74,6 +83,8 @@ export const createRuntime = async ({
74
83
  streams: [...streams.names],
75
84
  };
76
85
  return {
86
+ instance: instance.context,
87
+ establishInstance: instance.establish,
77
88
  manifest,
78
89
  dispose: lifecycle.dispose,
79
90
  getOperation: operations.get,
@@ -0,0 +1,46 @@
1
+ import { hostname } from "node:os";
2
+ import type { RuntimeConfigDefinition } from "@overmux/shared/node";
3
+ import {
4
+ createInstanceIdentity,
5
+ type InstanceIdentity,
6
+ } from "../../shared/index";
7
+ import type { InstanceContext } from "../../../public/config";
8
+
9
+ // The scope exists during preparation, but identity is immutable once the listener
10
+ // binds. No handler or connection may observe it before establishment.
11
+ export const createRuntimeInstance = (
12
+ configured: RuntimeConfigDefinition["instanceId"],
13
+ ) => {
14
+ let identity: InstanceIdentity | undefined;
15
+ const get = () => {
16
+ if (!identity) {
17
+ throw new Error("Overmux instance identity is not ready");
18
+ }
19
+ return identity;
20
+ };
21
+ const context: InstanceContext = {
22
+ getInstanceId: () => get().instanceId,
23
+ getDeepLinkPrefix: () => get().deepLinkPrefix,
24
+ };
25
+ return {
26
+ context,
27
+ establish: (port: number) => {
28
+ if (identity) {
29
+ throw new Error("Overmux instance identity is already established");
30
+ }
31
+ try {
32
+ identity = createInstanceIdentity(
33
+ typeof configured === "function"
34
+ ? configured({ port })
35
+ : (configured ?? `${hostname()}-${port}`),
36
+ );
37
+ } catch (cause) {
38
+ throw new Error(
39
+ "Invalid Overmux instance ID; configure instanceId with a canonical lowercase ID",
40
+ { cause },
41
+ );
42
+ }
43
+ return identity;
44
+ },
45
+ };
46
+ };
@@ -42,11 +42,13 @@ type InvalidationListener = {
42
42
 
43
43
  type CreateRuntimeResourcesOptions = {
44
44
  definitions: RuntimeResourceDefinitions;
45
+ instance: HandlerContext["instance"];
45
46
  lifecycle: RuntimeLifecycle;
46
47
  };
47
48
 
48
49
  export const createRuntimeResources = ({
49
50
  definitions,
51
+ instance,
50
52
  lifecycle,
51
53
  }: CreateRuntimeResourcesOptions): RuntimeResources => {
52
54
  const graph = createResourceDependencyGraph(definitions);
@@ -104,6 +106,7 @@ export const createRuntimeResources = ({
104
106
  };
105
107
 
106
108
  const context = (signal?: AbortSignal): HandlerContext => ({
109
+ instance,
107
110
  invalidate,
108
111
  signal: lifecycle.requestSignal(signal),
109
112
  });
@@ -7,6 +7,13 @@ import { z } from "zod";
7
7
 
8
8
  import type { ServerConfigDefinition } from "../../public/index";
9
9
 
10
+ const serverStartupOverridesRuntimeSchema = serverConfigRuntimeSchema
11
+ .omit({ port: true })
12
+ .extend({
13
+ // Port 0 asks the OS for a free port for internal listeners and tests; it must not leak into user config.
14
+ port: z.number().int().min(0).max(65_535).optional(),
15
+ });
16
+
10
17
  export type ResolvedServerStartupOptions = {
11
18
  host: string;
12
19
  logFile?: string;
@@ -24,10 +31,8 @@ export const resolveServerStartupOptions = ({
24
31
  configPath: string;
25
32
  overrides?: ServerConfigDefinition;
26
33
  }): ResolvedServerStartupOptions => {
27
- const validatedOverrides = serverConfigRuntimeSchema
28
- .omit({ port: true })
29
- .extend({ port: z.number().int().min(0).max(65_535).optional() })
30
- .parse(overrides);
34
+ const validatedOverrides =
35
+ serverStartupOverridesRuntimeSchema.parse(overrides);
31
36
  const configuredLogFile = config.logFile
32
37
  ? resolve(dirname(configPath), config.logFile)
33
38
  : undefined;
@@ -279,24 +279,20 @@ const startApplicationTransport = async ({
279
279
  ? undefined
280
280
  : startup.productionWebAssetsDir,
281
281
  });
282
+ // Binding allocates the actual port. Reject early HTTP traffic until identity
283
+ // and trusted origins are established; WebSocket upgrades attach only after that.
284
+ let ready = false;
282
285
  const server = serve({
283
- fetch: app.fetch,
286
+ fetch: (request, env) =>
287
+ ready
288
+ ? app.fetch(request, env)
289
+ : new Response("Starting", { status: 503 }),
284
290
  hostname: startup.host,
285
291
  port: startup.port,
286
292
  });
287
293
  resources.add(() => closeNodeServer(server, runtime.dispose));
288
- const webSockets = createWebSocketServer({
289
- auth,
290
- developmentWebTarget,
291
- runtime,
292
- server,
293
- serverLogger: logger,
294
- });
295
- resources.add(webSockets.close);
296
- announceRestarting = webSockets.announceRestarting;
297
- notifications.attachLiveDelivery(webSockets.broadcastNotification);
298
-
299
294
  const address = await getServerAddress(server);
295
+ runtime.establishInstance(address.port);
300
296
  const urlHost = startup.host.includes(":")
301
297
  ? `[${startup.host}]`
302
298
  : startup.host;
@@ -309,9 +305,21 @@ const startApplicationTransport = async ({
309
305
  : urlHost;
310
306
  const origins = authOrigins.establish(localUrl);
311
307
  authService.setOrigins(origins);
308
+ const webSockets = createWebSocketServer({
309
+ auth,
310
+ developmentWebTarget,
311
+ runtime,
312
+ server,
313
+ serverLogger: logger,
314
+ });
315
+ resources.add(webSockets.close);
316
+ announceRestarting = webSockets.announceRestarting;
317
+ notifications.attachLiveDelivery(webSockets.broadcastNotification);
318
+ ready = true;
312
319
  const instanceControl = await startInstanceControl({
313
320
  auth: authService,
314
321
  apiUrl: `http://${controlApiHost}:${address.port}`,
322
+ instanceId: runtime.instance.getInstanceId(),
315
323
  port: address.port,
316
324
  url: origins[0]!,
317
325
  });
@@ -247,6 +247,13 @@ export const createWebSocketServer = ({
247
247
  sessionSockets,
248
248
  socket: webSocket,
249
249
  });
250
+ // Discovery precedes all connection traffic, including sticky announcements.
251
+ webSocket.send(
252
+ encodeProtocolFrame({
253
+ type: "server-info",
254
+ instanceId: runtime.instance.getInstanceId(),
255
+ }),
256
+ );
250
257
  webSocketServer.emit("connection", webSocket, request);
251
258
  attachWebSocketConnection({ runtime, serverLogger, socket: webSocket });
252
259
  if (updateAvailable) {
@@ -1,2 +1,4 @@
1
1
  export * from "./background-notifications";
2
2
  export * from "./protocol";
3
+ export { createInstanceIdentity, instanceIdSchema } from "@overmux/shared";
4
+ export type { InstanceIdentity } from "@overmux/shared";
@@ -1,10 +1,11 @@
1
1
  import { z } from "zod";
2
+ import { instanceIdSchema } from "@overmux/shared";
2
3
 
3
4
  import { notificationSchema } from "../../public/notifications";
4
5
 
5
6
  // Compatibility gate, not negotiation: open tabs may still run older client assets.
6
7
  // The exact version rejects incompatible runtime manifest and wire formats before later traffic.
7
- export const protocolVersion = 9 as const;
8
+ export const protocolVersion = 10 as const;
8
9
 
9
10
  // Application-defined WebSocket close codes shared by server and browser transports.
10
11
  export const webSocketCloseCode = {
@@ -139,7 +140,15 @@ export const protocolErrorMessageSchema = z.object({
139
140
  type: z.literal("error"),
140
141
  });
141
142
 
143
+ export const serverInfoMessageSchema = z
144
+ .object({
145
+ type: z.literal("server-info"),
146
+ instanceId: instanceIdSchema,
147
+ })
148
+ .strict();
149
+
142
150
  export const serverProtocolMessageSchema = z.discriminatedUnion("type", [
151
+ serverInfoMessageSchema,
143
152
  resourceResultMessageSchema,
144
153
  resourceInvalidatedMessageSchema,
145
154
  streamOpenedMessageSchema,
@@ -2,7 +2,12 @@ export {
2
2
  disableBackgroundNotifications,
3
3
  enableBackgroundNotifications,
4
4
  } from "../internal/client/background-notifications";
5
+ export {
6
+ readClipboardText,
7
+ writeClipboardText,
8
+ } from "../internal/client/clipboard";
5
9
  export type { OvermuxServerApi } from "../internal/client/browser-api";
10
+ export type { InstanceIdentity } from "@overmux/shared";
6
11
  export {
7
12
  createOvermuxHooks,
8
13
  type ResourceResult,
@@ -6,7 +6,13 @@ import type { ResourceContract, StreamContract } from "./contracts";
6
6
 
7
7
  export type RuntimeDisposer = () => Promise<void> | void;
8
8
 
9
+ export type InstanceContext = {
10
+ getInstanceId: () => string;
11
+ getDeepLinkPrefix: () => string;
12
+ };
13
+
9
14
  export type HandlerContext = {
15
+ instance: InstanceContext;
10
16
  invalidate: (contract: ResourceContract, input?: unknown) => void;
11
17
  signal: AbortSignal;
12
18
  };
@@ -245,6 +251,7 @@ export type OvermuxConfigDefinition<
245
251
  aiContextSnippets?: AiContextSnippetDefinition;
246
252
  auth: AuthConfigDefinition;
247
253
  debug?: boolean;
254
+ instanceId?: string | ((context: { port: number }) => string);
248
255
  server: TServer;
249
256
  vite?: string;
250
257
  };
@@ -21,6 +21,7 @@ export type {
21
21
  ConfigDefinition,
22
22
  DerivedResourceDefinition,
23
23
  HandlerContext,
24
+ InstanceContext,
24
25
  OperationContext,
25
26
  OperationDefinition,
26
27
  OvermuxConfigDefinition,
@@ -49,6 +50,7 @@ export type {
49
50
  } from "./contracts";
50
51
  export { notificationLinkSchema, notificationSchema } from "./notifications";
51
52
  export type { Notification, Notifications } from "./notifications";
53
+ export type { InstanceIdentity } from "@overmux/shared";
52
54
  export {
53
55
  createOvermuxSettingsPath,
54
56
  overmuxLogoutPath,
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-D3_Dpy_T.d.ts","names":[],"sources":["../../../shared/dist/index.d.ts","../../src/public/ai-context.ts","../../src/public/notifications.ts","../../src/public/contracts.ts","../../src/public/config.ts"],"mappings":"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"}