overmux 0.0.9 → 0.0.11
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/CHANGELOG.md +21 -0
- package/dist/bin.js +1 -1
- package/dist/bin.js.map +1 -1
- package/dist/docs/400-reference/200-configuration.md +35 -0
- package/dist/docs/400-reference/500-server/400-notifications.md +4 -0
- package/dist/docs/400-reference/600-client/030-native-web-view.md +166 -0
- package/dist/docs/400-reference/600-client/300-tech-stack-recommendations.md +1 -0
- package/dist/docs/400-reference/700-cli/600-docs.md +1 -1
- package/dist/exports/client.d.ts +43 -7
- package/dist/exports/client.d.ts.map +1 -1
- package/dist/exports/client.js +172 -22
- package/dist/exports/client.js.map +1 -1
- package/dist/exports/index.js +1 -1
- package/dist/exports/index.js.map +1 -1
- package/dist/internal/server/coordinator/server-child.js +25 -1
- package/dist/internal/server/coordinator/server-child.js.map +1 -1
- package/dist/push/THIRD_PARTY_NOTICES.md +30 -0
- package/dist/push/badge.png +0 -0
- package/dist/push/icon.png +0 -0
- package/dist/push/sw.js +88 -0
- package/dist/push/sw.js.map +1 -0
- package/docs/400-reference/200-configuration.md +35 -0
- package/docs/400-reference/500-server/400-notifications.md +4 -0
- package/docs/400-reference/600-client/030-native-web-view.md +166 -0
- package/docs/400-reference/600-client/300-tech-stack-recommendations.md +1 -0
- package/docs/400-reference/700-cli/600-docs.md +1 -1
- package/package.json +3 -3
- package/src/internal/client/background-notifications.ts +3 -1
- package/src/internal/client/client-definition.ts +9 -13
- package/src/internal/client/host/desktop-host.ts +28 -2
- package/src/internal/client/host/hosted-pages/browser-notification-settings.tsx +8 -3
- package/src/internal/client/native-web-view.tsx +158 -0
- package/src/internal/client/push-assets/badge.png +0 -0
- package/src/internal/client/push-assets/icon.png +0 -0
- package/src/internal/client/push-service-worker.ts +118 -0
- package/src/internal/client/register-push-worker.ts +63 -0
- package/src/internal/client/shortcuts.tsx +17 -31
- package/src/internal/server/http/routes.ts +47 -2
- package/src/internal/shared/routes.ts +2 -0
- package/src/public/client.ts +5 -0
package/dist/exports/index.js
CHANGED
|
@@ -12,7 +12,7 @@ Run \`overmux docs path\` to find the installed documentation directory for the
|
|
|
12
12
|
Inspect TypeScript source in installed packages, e.g. \`node_modules/overmux/src\` and \`node_modules/@overmux/xterm/src\`.
|
|
13
13
|
|
|
14
14
|
Inspect these files so guidance matches the versions used by the application.`;
|
|
15
|
-
const techStackRecommendationsSnippetContent = `Prefer pnpm as the package manager, TanStack Router for routing, shadcn/ui for UI components, and Zod for schemas and runtime validation. Follow the application's established stack when it already differs.`;
|
|
15
|
+
const techStackRecommendationsSnippetContent = `Prefer pnpm as the package manager, TanStack Router for routing, shadcn/ui for UI components, and Zod for schemas and runtime validation. For custom Git diff views, prefer @pierre/diffs (https://diffs.com/). Follow the application's established stack when it already differs.`;
|
|
16
16
|
const aiContextContentBySnippet = {
|
|
17
17
|
[packageSourceSnippet]: packageSourceSnippetContent,
|
|
18
18
|
[techStackRecommendationsSnippet]: techStackRecommendationsSnippetContent
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../ai-context/dist/index.js","../../src/public/ai-context.ts","../../src/public/config.ts","../../src/public/contracts.ts"],"sourcesContent":["//#region src/index.ts\nconst packageSourceSnippet = \"package-source\";\nconst techStackRecommendationsSnippet = \"tech-stack-recommendations\";\nconst aiContextSnippets = [packageSourceSnippet, techStackRecommendationsSnippet];\nconst coreAiContextSnippets = [packageSourceSnippet];\nconst defaultAiContextSnippets = [...coreAiContextSnippets, techStackRecommendationsSnippet];\nconst packageSourceSnippetContent = `Overmux ships with documentation and TypeScript source.\n\nRun \\`overmux docs path\\` to find the installed documentation directory for the Overmux CLI. This prints a documentation directory, not source paths.\n\nInspect TypeScript source in installed packages, e.g. \\`node_modules/overmux/src\\` and \\`node_modules/@overmux/xterm/src\\`.\n\nInspect these files so guidance matches the versions used by the application.`;\nconst techStackRecommendationsSnippetContent = `Prefer pnpm as the package manager, TanStack Router for routing, shadcn/ui for UI components, and Zod for schemas and runtime validation. Follow the application's established stack when it already differs.`;\nconst aiContextContentBySnippet = {\n\t[packageSourceSnippet]: packageSourceSnippetContent,\n\t[techStackRecommendationsSnippet]: techStackRecommendationsSnippetContent\n};\n//#endregion\nexport { aiContextContentBySnippet, aiContextSnippets, coreAiContextSnippets, defaultAiContextSnippets, packageSourceSnippet, techStackRecommendationsSnippet };\n\n//# sourceMappingURL=index.js.map","import {\n aiContextContentBySnippet,\n type AiContextSnippetDefinition,\n} from \"@overmux/ai-context\";\n\nexport {\n coreAiContextSnippets,\n defaultAiContextSnippets,\n packageSourceSnippet,\n techStackRecommendationsSnippet,\n type AiContextSnippet,\n type AiContextSnippetDefinition,\n} from \"@overmux/ai-context\";\n\nexport const composeAiContext = (snippets: AiContextSnippetDefinition) =>\n snippets.length === 0\n ? \"\"\n : `${snippets\n .map(\n (snippet) => `## ${snippet}\\n\\n${aiContextContentBySnippet[snippet]}`,\n )\n .join(\"\\n\\n\")}\\n`;\n","import { z } from \"zod\";\n\nimport type { AiContextSnippetDefinition } from \"./ai-context\";\nimport type { Notifications } from \"./notifications\";\nimport type { ResourceContract, StreamContract } from \"./contracts\";\n\nexport type RuntimeDisposer = () => Promise<void> | void;\n\nexport type InstanceContext = {\n getInstanceId: () => string;\n getDeepLinkPrefix: () => string;\n};\n\ntype ResourceInputMap = Readonly<Record<string, unknown>>;\n\n// Keep IDs paired with their raw inputs when checking calls and reusable handlers.\ntype InvalidationArguments<TInputs extends ResourceInputMap> = {\n [TId in keyof TInputs & string]: [resourceId: TId, input?: TInputs[TId]];\n}[keyof TInputs & string];\n\nexport type HandlerContext<TInputs extends ResourceInputMap = {}> = {\n instance: InstanceContext;\n invalidate: (...args: InvalidationArguments<TInputs>) => void;\n signal: AbortSignal;\n};\n\nexport type OperationContext<TInputs extends ResourceInputMap = {}> =\n HandlerContext<TInputs> & {\n notifications: Notifications;\n };\n\nexport type OperationDefinition<\n TInput extends z.ZodType = z.ZodType,\n TOutput extends z.ZodType = z.ZodVoid,\n TContext = OperationContext,\n> = {\n handle: (\n input: z.output<TInput>,\n context: TContext,\n ) => Promise<z.input<NoInfer<TOutput>>> | z.input<NoInfer<TOutput>>;\n input: TInput;\n output: TOutput;\n};\n\n// Infer schemas from this definition, not a surrounding operation map's broad constraint.\nexport const defineOperation = <\n TInput extends z.ZodType,\n TOutput extends z.ZodType = z.ZodVoid,\n TContext = OperationContext,\n>({\n handle,\n input,\n output,\n}: {\n handle: OperationDefinition<TInput, TOutput, TContext>[\"handle\"];\n input: TInput;\n output?: TOutput;\n}): OperationDefinition<NoInfer<TInput>, NoInfer<TOutput>, TContext> => ({\n handle,\n input,\n output: (output ?? z.void()) as TOutput,\n});\n\nexport type QueryResourceDefinition<\n TInput extends z.ZodType = z.ZodType,\n TOutput extends z.ZodType = z.ZodType,\n TContext = HandlerContext,\n> = {\n contract: ResourceContract<TInput, TOutput>;\n kind: \"query\";\n read: (\n input: z.output<TInput>,\n context: TContext,\n ) => Promise<z.input<NoInfer<TOutput>>> | z.input<NoInfer<TOutput>>;\n};\n\nexport type SubscriptionResourceDefinition<\n TInput extends z.ZodType = z.ZodType,\n TOutput extends z.ZodType = z.ZodType,\n TContext = HandlerContext,\n> = {\n contract: ResourceContract<TInput, TOutput>;\n kind: \"subscription\";\n read: QueryResourceDefinition<TInput, TOutput, TContext>[\"read\"];\n subscribe: (\n input: z.output<TInput>,\n invalidate: () => void,\n context: TContext,\n ) => RuntimeDisposer | Promise<RuntimeDisposer>;\n};\n\nexport type DerivedResourceDefinition<\n TInput extends z.ZodType = z.ZodType,\n TOutput extends z.ZodType = z.ZodType,\n TDependencies extends Readonly<Record<string, string>> = Readonly<\n Record<string, string>\n >,\n TDependencyOutputs = Readonly<Record<string, unknown>>,\n> = {\n combine: (dependencies: TDependencyOutputs) => z.input<NoInfer<TOutput>>;\n contract: ResourceContract<TInput, TOutput>;\n dependencies: TDependencies;\n kind: \"derived\";\n};\n\ntype AnyZodType = z.ZodType<any, any, any>;\n\nexport type ResourceDefinition =\n | QueryResourceDefinition<\n AnyZodType,\n AnyZodType,\n HandlerContext<ResourceInputMap>\n >\n | SubscriptionResourceDefinition<\n AnyZodType,\n AnyZodType,\n HandlerContext<ResourceInputMap>\n >\n | DerivedResourceDefinition<AnyZodType, AnyZodType, any, any>;\n\nexport type StreamSession<TClientMessage = unknown> = {\n dispose?: RuntimeDisposer;\n onMessage?: (message: TClientMessage) => Promise<void> | void;\n};\n\nexport type StreamHandlerDefinition<\n TInput extends z.ZodType = z.ZodType,\n TClientMessage extends z.ZodType = z.ZodType,\n TServerMessage extends z.ZodType = z.ZodType,\n TContext = HandlerContext,\n> = {\n contract: StreamContract<TInput, TClientMessage, TServerMessage>;\n open: (\n input: z.output<TInput>,\n context: TContext & {\n emit: (message: z.input<NoInfer<TServerMessage>>) => void;\n fail: (cause: unknown) => void;\n },\n ) =>\n | Promise<StreamSession<z.output<TClientMessage>>>\n | StreamSession<z.output<TClientMessage>>;\n};\n\nexport const defineStreamHandler = <\n TInput extends z.ZodType,\n TClientMessage extends z.ZodType,\n TServerMessage extends z.ZodType,\n TContext = HandlerContext,\n>(\n contract: StreamContract<TInput, TClientMessage, TServerMessage>,\n open: StreamHandlerDefinition<\n TInput,\n TClientMessage,\n TServerMessage,\n TContext\n >[\"open\"],\n): StreamHandlerDefinition<\n TInput,\n TClientMessage,\n TServerMessage,\n TContext\n> => ({\n contract,\n open,\n});\n\ntype ResourceContracts = Record<\n string,\n ResourceContract<AnyZodType, AnyZodType>\n>;\n\ntype ResourceInputs<TContracts extends ResourceContracts> = {\n [TId in keyof TContracts]: z.input<TContracts[TId][\"input\"]>;\n};\n\ntype DependencyOutputs<\n TContracts extends ResourceContracts,\n TDependencies extends Record<string, unknown>,\n> = {\n [TName in keyof TDependencies]: TDependencies[TName] extends keyof TContracts\n ? z.output<TContracts[TDependencies[TName]][\"output\"]>\n : never;\n};\n\ntype DependencySource<TDependencies> = {\n [TId in keyof TDependencies]: TDependencies[TId] extends Record<\n string,\n string\n >\n ? { dependencies: TDependencies[TId] }\n : { dependencies?: never };\n};\n\ntype QueryFor<\n TContract extends ResourceContract<AnyZodType, AnyZodType>,\n TContracts extends ResourceContracts,\n> = {\n contract: TContract;\n} & Omit<\n QueryResourceDefinition<\n TContract[\"input\"],\n TContract[\"output\"],\n HandlerContext<ResourceInputs<NoInfer<TContracts>>>\n >,\n \"contract\"\n>;\n\ntype SubscriptionFor<\n TContract extends ResourceContract<AnyZodType, AnyZodType>,\n TContracts extends ResourceContracts,\n> = { contract: TContract } & Omit<\n SubscriptionResourceDefinition<\n TContract[\"input\"],\n TContract[\"output\"],\n HandlerContext<ResourceInputs<NoInfer<TContracts>>>\n >,\n \"contract\"\n>;\n\ntype DerivedFor<\n TContract extends ResourceContract<AnyZodType, AnyZodType>,\n TDependencies extends Record<string, string>,\n TDependencyOutputs,\n> = {\n combine: (\n dependencies: TDependencyOutputs,\n ) => z.input<NoInfer<TContract[\"output\"]>>;\n contract: TContract;\n dependencies: TDependencies;\n kind: \"derived\";\n};\n\ntype ConfiguredResource<\n TContracts extends ResourceContracts,\n TDependencies,\n TId extends keyof TContracts,\n> =\n | QueryFor<TContracts[TId], TContracts>\n | SubscriptionFor<TContracts[TId], TContracts>\n | (TId extends keyof TDependencies\n ? TDependencies[TId] extends Record<\n string,\n Exclude<keyof TContracts, TId> & string\n >\n ? DerivedFor<\n TContracts[TId],\n TDependencies[TId],\n DependencyOutputs<TContracts, NoInfer<TDependencies[TId]>>\n >\n : never\n : never);\n\ntype ConfiguredResources<\n TContracts extends ResourceContracts,\n TDependencies,\n> = {\n [TId in keyof TContracts]: ConfiguredResource<TContracts, TDependencies, TId>;\n} & DependencySource<TDependencies>;\n\nexport type AuthDuration = `${number}${\"m\" | \"h\" | \"d\"}`;\n\nexport type AuthConfigDefinition = {\n mode: \"cli-login\";\n origins?: string[];\n sessionLifetime?: \"forever\" | AuthDuration;\n trustedProxyPeer?: string;\n};\n\nexport type ServerConfigDefinition = {\n host?: string;\n port?: number;\n productionWebAssetsDir?: string;\n watch?: boolean;\n};\n\ntype StreamDefinitions<TContext = HandlerContext<ResourceInputMap>> = Readonly<\n Record<\n string,\n StreamHandlerDefinition<AnyZodType, AnyZodType, AnyZodType, TContext>\n >\n>;\n\ntype OperationDefinitions = Readonly<\n Record<\n string,\n OperationDefinition<\n AnyZodType,\n AnyZodType,\n OperationContext<ResourceInputMap>\n >\n >\n>;\n\ntype OperationInputs = Record<string, AnyZodType>;\n\ntype OperationOutputSchema<\n TOutputs,\n TId extends PropertyKey,\n> = TId extends keyof TOutputs\n ? TOutputs[TId] extends z.ZodType\n ? TOutputs[TId]\n : z.ZodVoid\n : z.ZodVoid;\n\ntype ConfiguredOperations<\n TInputs extends OperationInputs,\n TOutputs,\n TContracts extends ResourceContracts,\n> = {\n [TId in keyof TInputs]: {\n input: TInputs[TId];\n output?: OperationOutputSchema<TOutputs, TId>;\n handle: OperationDefinition<\n TInputs[TId],\n OperationOutputSchema<TOutputs, TId>,\n OperationContext<ResourceInputs<TContracts>>\n >[\"handle\"];\n };\n} & {\n [TId in keyof TOutputs]: TOutputs[TId] extends z.ZodType\n ? { output: TOutputs[TId] }\n : { output?: never };\n};\n\ntype NormalizedOperations<\n TInputs extends OperationInputs,\n TOutputs,\n TContracts extends ResourceContracts,\n> = {\n [TId in keyof TInputs]: OperationDefinition<\n TInputs[TId],\n OperationOutputSchema<TOutputs, TId>,\n OperationContext<ResourceInputs<TContracts>>\n >;\n};\n\nconst normalizeOperations = <\n TInputs extends OperationInputs,\n TOutputs,\n TContracts extends ResourceContracts,\n>(\n operations: ConfiguredOperations<TInputs, TOutputs, TContracts> | undefined,\n): NormalizedOperations<TInputs, TOutputs, TContracts> | undefined => {\n if (operations === undefined) {\n return undefined;\n }\n // Preserve every key and handler; only absent output schemas become ZodVoid.\n return Object.fromEntries(\n Object.entries(operations).map(([id, definition]) => [\n id,\n { ...definition, output: definition.output ?? z.void() },\n ]),\n ) as NormalizedOperations<TInputs, TOutputs, TContracts>;\n};\n\nexport type ConfigDefinition<\n TResources extends Readonly<Record<string, unknown>> = Readonly<\n Record<string, ResourceDefinition>\n >,\n TStreams extends StreamDefinitions = StreamDefinitions,\n TOperations extends OperationDefinitions = OperationDefinitions,\n> = {\n operations?: TOperations;\n resources: TResources;\n streams?: TStreams;\n};\n\nexport type OvermuxConfigDefinition<\n TServer extends ConfigDefinition = ConfigDefinition,\n> = ServerConfigDefinition & {\n aiContextSnippets?: AiContextSnippetDefinition;\n auth: AuthConfigDefinition;\n debug?: boolean;\n instanceId?: string | ((context: { port: number }) => string);\n server: TServer;\n vite?: string;\n};\n\nexport type OvermuxServerResources<TServer> = TServer extends {\n resources: infer TResources;\n}\n ? TResources\n : never;\n\nexport type OvermuxServerStreams<TServer> = TServer extends {\n streams?: infer TStreams;\n}\n ? NonNullable<TStreams>\n : never;\n\nexport type OvermuxServerOperations<TServer> = TServer extends {\n operations?: infer TOperations;\n}\n ? NonNullable<TOperations>\n : never;\n\nexport const defineOvermuxServer = <\n const TContracts extends ResourceContracts = {},\n const TDependencies = {},\n const TStreams extends StreamDefinitions = {},\n const TInputs extends OperationInputs = {},\n const TOutputs = {},\n>(definition: {\n operations?: ConfiguredOperations<TInputs, TOutputs, NoInfer<TContracts>>;\n resources: ConfiguredResources<TContracts, TDependencies>;\n streams?: TStreams &\n StreamDefinitions<HandlerContext<ResourceInputs<NoInfer<TContracts>>>>;\n}): ConfigDefinition<\n ConfiguredResources<TContracts, TDependencies>,\n TStreams,\n NormalizedOperations<TInputs, TOutputs, TContracts>\n> => ({\n ...definition,\n operations: normalizeOperations(definition.operations),\n});\n\nexport const defineOvermuxConfig = <const TServer extends ConfigDefinition>(\n definition: OvermuxConfigDefinition<TServer>,\n): OvermuxConfigDefinition<TServer> => definition;\n","import { z } from \"zod\";\n\nexport const noInputSchema = z.void();\n\nexport const jsonValueSchema: z.ZodType<unknown> = z.lazy(() =>\n z.union([\n z.string(),\n z.number().finite(),\n z.boolean(),\n z.null(),\n z.array(jsonValueSchema),\n z.record(z.string(), jsonValueSchema),\n ]),\n);\n\nexport const parseJsonValue = <T>(value: T): T =>\n jsonValueSchema.parse(value) as T;\n\nexport type ContractInputArguments<TInput extends z.ZodType> =\n undefined extends z.input<TInput>\n ? [input?: Exclude<z.input<TInput>, undefined>]\n : [input: z.input<TInput>];\n\nexport type ResourceContract<\n TInput extends z.ZodType = z.ZodType,\n TOutput extends z.ZodType = z.ZodType,\n> = {\n input: TInput;\n output: TOutput;\n};\n\nexport const defineResourceContract = <\n TInput extends z.ZodType,\n TOutput extends z.ZodType,\n>(\n contract: ResourceContract<TInput, TOutput>,\n): ResourceContract<TInput, TOutput> => contract;\n\nexport type StreamContract<\n TInput extends z.ZodType = z.ZodType,\n TClientMessage extends z.ZodType = z.ZodType,\n TServerMessage extends z.ZodType = z.ZodType,\n> = {\n clientMessage: TClientMessage;\n input: TInput;\n serverMessage: TServerMessage;\n};\n\nexport const defineStreamContract = <\n TInput extends z.ZodType,\n TClientMessage extends z.ZodType,\n TServerMessage extends z.ZodType,\n>(\n contract: StreamContract<TInput, TClientMessage, TServerMessage>,\n): StreamContract<TInput, TClientMessage, TServerMessage> => contract;\n"],"mappings":";;;AACA,MAAM,uBAAuB;AAC7B,MAAM,kCAAkC;AAExC,MAAM,wBAAwB,CAAC,oBAAoB;AACnD,MAAM,2BAA2B,CAAC,GAAG,uBAAuB,+BAA+B;AAC3F,MAAM,8BAA8B;;;;;;;AAOpC,MAAM,yCAAyC;AAC/C,MAAM,4BAA4B;EAChC,uBAAuB;EACvB,kCAAkC;AACpC;;;ACHA,MAAa,oBAAoB,aAC/B,SAAS,WAAW,IAChB,KACA,GAAG,SACA,KACE,YAAY,MAAM,QAAQ,MAAM,0BAA0B,UAC7D,CAAC,CACA,KAAK,MAAM,EAAE;;;ACwBtB,MAAa,mBAIX,EACA,QACA,OACA,cAKuE;CACvE;CACA;CACA,QAAS,UAAU,EAAE,KAAK;AAC5B;AAkFA,MAAa,uBAMX,UACA,UAWI;CACJ;CACA;AACF;AA4KA,MAAM,uBAKJ,eACoE;CACpE,IAAI,eAAe,KAAA,GACjB;CAGF,OAAO,OAAO,YACZ,OAAO,QAAQ,UAAU,CAAC,CAAC,KAAK,CAAC,IAAI,gBAAgB,CACnD,IACA;EAAE,GAAG;EAAY,QAAQ,WAAW,UAAU,EAAE,KAAK;CAAE,CACzD,CAAC,CACH;AACF;AA2CA,MAAa,uBAMX,gBASI;CACJ,GAAG;CACH,YAAY,oBAAoB,WAAW,UAAU;AACvD;AAEA,MAAa,uBACX,eACqC;;;AChavC,MAAa,gBAAgB,EAAE,KAAK;AAEpC,MAAa,kBAAsC,EAAE,WACnD,EAAE,MAAM;CACN,EAAE,OAAO;CACT,EAAE,OAAO,CAAC,CAAC,OAAO;CAClB,EAAE,QAAQ;CACV,EAAE,KAAK;CACP,EAAE,MAAM,eAAe;CACvB,EAAE,OAAO,EAAE,OAAO,GAAG,eAAe;AACtC,CAAC,CACH;AAEA,MAAa,kBAAqB,UAChC,gBAAgB,MAAM,KAAK;AAe7B,MAAa,0BAIX,aACsC;AAYxC,MAAa,wBAKX,aAC2D"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../ai-context/dist/index.js","../../src/public/ai-context.ts","../../src/public/config.ts","../../src/public/contracts.ts"],"sourcesContent":["//#region src/index.ts\nconst packageSourceSnippet = \"package-source\";\nconst techStackRecommendationsSnippet = \"tech-stack-recommendations\";\nconst aiContextSnippets = [packageSourceSnippet, techStackRecommendationsSnippet];\nconst coreAiContextSnippets = [packageSourceSnippet];\nconst defaultAiContextSnippets = [...coreAiContextSnippets, techStackRecommendationsSnippet];\nconst packageSourceSnippetContent = `Overmux ships with documentation and TypeScript source.\n\nRun \\`overmux docs path\\` to find the installed documentation directory for the Overmux CLI. This prints a documentation directory, not source paths.\n\nInspect TypeScript source in installed packages, e.g. \\`node_modules/overmux/src\\` and \\`node_modules/@overmux/xterm/src\\`.\n\nInspect these files so guidance matches the versions used by the application.`;\nconst techStackRecommendationsSnippetContent = `Prefer pnpm as the package manager, TanStack Router for routing, shadcn/ui for UI components, and Zod for schemas and runtime validation. For custom Git diff views, prefer @pierre/diffs (https://diffs.com/). Follow the application's established stack when it already differs.`;\nconst aiContextContentBySnippet = {\n\t[packageSourceSnippet]: packageSourceSnippetContent,\n\t[techStackRecommendationsSnippet]: techStackRecommendationsSnippetContent\n};\n//#endregion\nexport { aiContextContentBySnippet, aiContextSnippets, coreAiContextSnippets, defaultAiContextSnippets, packageSourceSnippet, techStackRecommendationsSnippet };\n\n//# sourceMappingURL=index.js.map","import {\n aiContextContentBySnippet,\n type AiContextSnippetDefinition,\n} from \"@overmux/ai-context\";\n\nexport {\n coreAiContextSnippets,\n defaultAiContextSnippets,\n packageSourceSnippet,\n techStackRecommendationsSnippet,\n type AiContextSnippet,\n type AiContextSnippetDefinition,\n} from \"@overmux/ai-context\";\n\nexport const composeAiContext = (snippets: AiContextSnippetDefinition) =>\n snippets.length === 0\n ? \"\"\n : `${snippets\n .map(\n (snippet) => `## ${snippet}\\n\\n${aiContextContentBySnippet[snippet]}`,\n )\n .join(\"\\n\\n\")}\\n`;\n","import { z } from \"zod\";\n\nimport type { AiContextSnippetDefinition } from \"./ai-context\";\nimport type { Notifications } from \"./notifications\";\nimport type { ResourceContract, StreamContract } from \"./contracts\";\n\nexport type RuntimeDisposer = () => Promise<void> | void;\n\nexport type InstanceContext = {\n getInstanceId: () => string;\n getDeepLinkPrefix: () => string;\n};\n\ntype ResourceInputMap = Readonly<Record<string, unknown>>;\n\n// Keep IDs paired with their raw inputs when checking calls and reusable handlers.\ntype InvalidationArguments<TInputs extends ResourceInputMap> = {\n [TId in keyof TInputs & string]: [resourceId: TId, input?: TInputs[TId]];\n}[keyof TInputs & string];\n\nexport type HandlerContext<TInputs extends ResourceInputMap = {}> = {\n instance: InstanceContext;\n invalidate: (...args: InvalidationArguments<TInputs>) => void;\n signal: AbortSignal;\n};\n\nexport type OperationContext<TInputs extends ResourceInputMap = {}> =\n HandlerContext<TInputs> & {\n notifications: Notifications;\n };\n\nexport type OperationDefinition<\n TInput extends z.ZodType = z.ZodType,\n TOutput extends z.ZodType = z.ZodVoid,\n TContext = OperationContext,\n> = {\n handle: (\n input: z.output<TInput>,\n context: TContext,\n ) => Promise<z.input<NoInfer<TOutput>>> | z.input<NoInfer<TOutput>>;\n input: TInput;\n output: TOutput;\n};\n\n// Infer schemas from this definition, not a surrounding operation map's broad constraint.\nexport const defineOperation = <\n TInput extends z.ZodType,\n TOutput extends z.ZodType = z.ZodVoid,\n TContext = OperationContext,\n>({\n handle,\n input,\n output,\n}: {\n handle: OperationDefinition<TInput, TOutput, TContext>[\"handle\"];\n input: TInput;\n output?: TOutput;\n}): OperationDefinition<NoInfer<TInput>, NoInfer<TOutput>, TContext> => ({\n handle,\n input,\n output: (output ?? z.void()) as TOutput,\n});\n\nexport type QueryResourceDefinition<\n TInput extends z.ZodType = z.ZodType,\n TOutput extends z.ZodType = z.ZodType,\n TContext = HandlerContext,\n> = {\n contract: ResourceContract<TInput, TOutput>;\n kind: \"query\";\n read: (\n input: z.output<TInput>,\n context: TContext,\n ) => Promise<z.input<NoInfer<TOutput>>> | z.input<NoInfer<TOutput>>;\n};\n\nexport type SubscriptionResourceDefinition<\n TInput extends z.ZodType = z.ZodType,\n TOutput extends z.ZodType = z.ZodType,\n TContext = HandlerContext,\n> = {\n contract: ResourceContract<TInput, TOutput>;\n kind: \"subscription\";\n read: QueryResourceDefinition<TInput, TOutput, TContext>[\"read\"];\n subscribe: (\n input: z.output<TInput>,\n invalidate: () => void,\n context: TContext,\n ) => RuntimeDisposer | Promise<RuntimeDisposer>;\n};\n\nexport type DerivedResourceDefinition<\n TInput extends z.ZodType = z.ZodType,\n TOutput extends z.ZodType = z.ZodType,\n TDependencies extends Readonly<Record<string, string>> = Readonly<\n Record<string, string>\n >,\n TDependencyOutputs = Readonly<Record<string, unknown>>,\n> = {\n combine: (dependencies: TDependencyOutputs) => z.input<NoInfer<TOutput>>;\n contract: ResourceContract<TInput, TOutput>;\n dependencies: TDependencies;\n kind: \"derived\";\n};\n\ntype AnyZodType = z.ZodType<any, any, any>;\n\nexport type ResourceDefinition =\n | QueryResourceDefinition<\n AnyZodType,\n AnyZodType,\n HandlerContext<ResourceInputMap>\n >\n | SubscriptionResourceDefinition<\n AnyZodType,\n AnyZodType,\n HandlerContext<ResourceInputMap>\n >\n | DerivedResourceDefinition<AnyZodType, AnyZodType, any, any>;\n\nexport type StreamSession<TClientMessage = unknown> = {\n dispose?: RuntimeDisposer;\n onMessage?: (message: TClientMessage) => Promise<void> | void;\n};\n\nexport type StreamHandlerDefinition<\n TInput extends z.ZodType = z.ZodType,\n TClientMessage extends z.ZodType = z.ZodType,\n TServerMessage extends z.ZodType = z.ZodType,\n TContext = HandlerContext,\n> = {\n contract: StreamContract<TInput, TClientMessage, TServerMessage>;\n open: (\n input: z.output<TInput>,\n context: TContext & {\n emit: (message: z.input<NoInfer<TServerMessage>>) => void;\n fail: (cause: unknown) => void;\n },\n ) =>\n | Promise<StreamSession<z.output<TClientMessage>>>\n | StreamSession<z.output<TClientMessage>>;\n};\n\nexport const defineStreamHandler = <\n TInput extends z.ZodType,\n TClientMessage extends z.ZodType,\n TServerMessage extends z.ZodType,\n TContext = HandlerContext,\n>(\n contract: StreamContract<TInput, TClientMessage, TServerMessage>,\n open: StreamHandlerDefinition<\n TInput,\n TClientMessage,\n TServerMessage,\n TContext\n >[\"open\"],\n): StreamHandlerDefinition<\n TInput,\n TClientMessage,\n TServerMessage,\n TContext\n> => ({\n contract,\n open,\n});\n\ntype ResourceContracts = Record<\n string,\n ResourceContract<AnyZodType, AnyZodType>\n>;\n\ntype ResourceInputs<TContracts extends ResourceContracts> = {\n [TId in keyof TContracts]: z.input<TContracts[TId][\"input\"]>;\n};\n\ntype DependencyOutputs<\n TContracts extends ResourceContracts,\n TDependencies extends Record<string, unknown>,\n> = {\n [TName in keyof TDependencies]: TDependencies[TName] extends keyof TContracts\n ? z.output<TContracts[TDependencies[TName]][\"output\"]>\n : never;\n};\n\ntype DependencySource<TDependencies> = {\n [TId in keyof TDependencies]: TDependencies[TId] extends Record<\n string,\n string\n >\n ? { dependencies: TDependencies[TId] }\n : { dependencies?: never };\n};\n\ntype QueryFor<\n TContract extends ResourceContract<AnyZodType, AnyZodType>,\n TContracts extends ResourceContracts,\n> = {\n contract: TContract;\n} & Omit<\n QueryResourceDefinition<\n TContract[\"input\"],\n TContract[\"output\"],\n HandlerContext<ResourceInputs<NoInfer<TContracts>>>\n >,\n \"contract\"\n>;\n\ntype SubscriptionFor<\n TContract extends ResourceContract<AnyZodType, AnyZodType>,\n TContracts extends ResourceContracts,\n> = { contract: TContract } & Omit<\n SubscriptionResourceDefinition<\n TContract[\"input\"],\n TContract[\"output\"],\n HandlerContext<ResourceInputs<NoInfer<TContracts>>>\n >,\n \"contract\"\n>;\n\ntype DerivedFor<\n TContract extends ResourceContract<AnyZodType, AnyZodType>,\n TDependencies extends Record<string, string>,\n TDependencyOutputs,\n> = {\n combine: (\n dependencies: TDependencyOutputs,\n ) => z.input<NoInfer<TContract[\"output\"]>>;\n contract: TContract;\n dependencies: TDependencies;\n kind: \"derived\";\n};\n\ntype ConfiguredResource<\n TContracts extends ResourceContracts,\n TDependencies,\n TId extends keyof TContracts,\n> =\n | QueryFor<TContracts[TId], TContracts>\n | SubscriptionFor<TContracts[TId], TContracts>\n | (TId extends keyof TDependencies\n ? TDependencies[TId] extends Record<\n string,\n Exclude<keyof TContracts, TId> & string\n >\n ? DerivedFor<\n TContracts[TId],\n TDependencies[TId],\n DependencyOutputs<TContracts, NoInfer<TDependencies[TId]>>\n >\n : never\n : never);\n\ntype ConfiguredResources<\n TContracts extends ResourceContracts,\n TDependencies,\n> = {\n [TId in keyof TContracts]: ConfiguredResource<TContracts, TDependencies, TId>;\n} & DependencySource<TDependencies>;\n\nexport type AuthDuration = `${number}${\"m\" | \"h\" | \"d\"}`;\n\nexport type AuthConfigDefinition = {\n mode: \"cli-login\";\n origins?: string[];\n sessionLifetime?: \"forever\" | AuthDuration;\n trustedProxyPeer?: string;\n};\n\nexport type ServerConfigDefinition = {\n host?: string;\n port?: number;\n productionWebAssetsDir?: string;\n watch?: boolean;\n};\n\ntype StreamDefinitions<TContext = HandlerContext<ResourceInputMap>> = Readonly<\n Record<\n string,\n StreamHandlerDefinition<AnyZodType, AnyZodType, AnyZodType, TContext>\n >\n>;\n\ntype OperationDefinitions = Readonly<\n Record<\n string,\n OperationDefinition<\n AnyZodType,\n AnyZodType,\n OperationContext<ResourceInputMap>\n >\n >\n>;\n\ntype OperationInputs = Record<string, AnyZodType>;\n\ntype OperationOutputSchema<\n TOutputs,\n TId extends PropertyKey,\n> = TId extends keyof TOutputs\n ? TOutputs[TId] extends z.ZodType\n ? TOutputs[TId]\n : z.ZodVoid\n : z.ZodVoid;\n\ntype ConfiguredOperations<\n TInputs extends OperationInputs,\n TOutputs,\n TContracts extends ResourceContracts,\n> = {\n [TId in keyof TInputs]: {\n input: TInputs[TId];\n output?: OperationOutputSchema<TOutputs, TId>;\n handle: OperationDefinition<\n TInputs[TId],\n OperationOutputSchema<TOutputs, TId>,\n OperationContext<ResourceInputs<TContracts>>\n >[\"handle\"];\n };\n} & {\n [TId in keyof TOutputs]: TOutputs[TId] extends z.ZodType\n ? { output: TOutputs[TId] }\n : { output?: never };\n};\n\ntype NormalizedOperations<\n TInputs extends OperationInputs,\n TOutputs,\n TContracts extends ResourceContracts,\n> = {\n [TId in keyof TInputs]: OperationDefinition<\n TInputs[TId],\n OperationOutputSchema<TOutputs, TId>,\n OperationContext<ResourceInputs<TContracts>>\n >;\n};\n\nconst normalizeOperations = <\n TInputs extends OperationInputs,\n TOutputs,\n TContracts extends ResourceContracts,\n>(\n operations: ConfiguredOperations<TInputs, TOutputs, TContracts> | undefined,\n): NormalizedOperations<TInputs, TOutputs, TContracts> | undefined => {\n if (operations === undefined) {\n return undefined;\n }\n // Preserve every key and handler; only absent output schemas become ZodVoid.\n return Object.fromEntries(\n Object.entries(operations).map(([id, definition]) => [\n id,\n { ...definition, output: definition.output ?? z.void() },\n ]),\n ) as NormalizedOperations<TInputs, TOutputs, TContracts>;\n};\n\nexport type ConfigDefinition<\n TResources extends Readonly<Record<string, unknown>> = Readonly<\n Record<string, ResourceDefinition>\n >,\n TStreams extends StreamDefinitions = StreamDefinitions,\n TOperations extends OperationDefinitions = OperationDefinitions,\n> = {\n operations?: TOperations;\n resources: TResources;\n streams?: TStreams;\n};\n\nexport type OvermuxConfigDefinition<\n TServer extends ConfigDefinition = ConfigDefinition,\n> = ServerConfigDefinition & {\n aiContextSnippets?: AiContextSnippetDefinition;\n auth: AuthConfigDefinition;\n debug?: boolean;\n instanceId?: string | ((context: { port: number }) => string);\n server: TServer;\n vite?: string;\n};\n\nexport type OvermuxServerResources<TServer> = TServer extends {\n resources: infer TResources;\n}\n ? TResources\n : never;\n\nexport type OvermuxServerStreams<TServer> = TServer extends {\n streams?: infer TStreams;\n}\n ? NonNullable<TStreams>\n : never;\n\nexport type OvermuxServerOperations<TServer> = TServer extends {\n operations?: infer TOperations;\n}\n ? NonNullable<TOperations>\n : never;\n\nexport const defineOvermuxServer = <\n const TContracts extends ResourceContracts = {},\n const TDependencies = {},\n const TStreams extends StreamDefinitions = {},\n const TInputs extends OperationInputs = {},\n const TOutputs = {},\n>(definition: {\n operations?: ConfiguredOperations<TInputs, TOutputs, NoInfer<TContracts>>;\n resources: ConfiguredResources<TContracts, TDependencies>;\n streams?: TStreams &\n StreamDefinitions<HandlerContext<ResourceInputs<NoInfer<TContracts>>>>;\n}): ConfigDefinition<\n ConfiguredResources<TContracts, TDependencies>,\n TStreams,\n NormalizedOperations<TInputs, TOutputs, TContracts>\n> => ({\n ...definition,\n operations: normalizeOperations(definition.operations),\n});\n\nexport const defineOvermuxConfig = <const TServer extends ConfigDefinition>(\n definition: OvermuxConfigDefinition<TServer>,\n): OvermuxConfigDefinition<TServer> => definition;\n","import { z } from \"zod\";\n\nexport const noInputSchema = z.void();\n\nexport const jsonValueSchema: z.ZodType<unknown> = z.lazy(() =>\n z.union([\n z.string(),\n z.number().finite(),\n z.boolean(),\n z.null(),\n z.array(jsonValueSchema),\n z.record(z.string(), jsonValueSchema),\n ]),\n);\n\nexport const parseJsonValue = <T>(value: T): T =>\n jsonValueSchema.parse(value) as T;\n\nexport type ContractInputArguments<TInput extends z.ZodType> =\n undefined extends z.input<TInput>\n ? [input?: Exclude<z.input<TInput>, undefined>]\n : [input: z.input<TInput>];\n\nexport type ResourceContract<\n TInput extends z.ZodType = z.ZodType,\n TOutput extends z.ZodType = z.ZodType,\n> = {\n input: TInput;\n output: TOutput;\n};\n\nexport const defineResourceContract = <\n TInput extends z.ZodType,\n TOutput extends z.ZodType,\n>(\n contract: ResourceContract<TInput, TOutput>,\n): ResourceContract<TInput, TOutput> => contract;\n\nexport type StreamContract<\n TInput extends z.ZodType = z.ZodType,\n TClientMessage extends z.ZodType = z.ZodType,\n TServerMessage extends z.ZodType = z.ZodType,\n> = {\n clientMessage: TClientMessage;\n input: TInput;\n serverMessage: TServerMessage;\n};\n\nexport const defineStreamContract = <\n TInput extends z.ZodType,\n TClientMessage extends z.ZodType,\n TServerMessage extends z.ZodType,\n>(\n contract: StreamContract<TInput, TClientMessage, TServerMessage>,\n): StreamContract<TInput, TClientMessage, TServerMessage> => contract;\n"],"mappings":";;;AACA,MAAM,uBAAuB;AAC7B,MAAM,kCAAkC;AAExC,MAAM,wBAAwB,CAAC,oBAAoB;AACnD,MAAM,2BAA2B,CAAC,GAAG,uBAAuB,+BAA+B;AAC3F,MAAM,8BAA8B;;;;;;;AAOpC,MAAM,yCAAyC;AAC/C,MAAM,4BAA4B;EAChC,uBAAuB;EACvB,kCAAkC;AACpC;;;ACHA,MAAa,oBAAoB,aAC/B,SAAS,WAAW,IAChB,KACA,GAAG,SACA,KACE,YAAY,MAAM,QAAQ,MAAM,0BAA0B,UAC7D,CAAC,CACA,KAAK,MAAM,EAAE;;;ACwBtB,MAAa,mBAIX,EACA,QACA,OACA,cAKuE;CACvE;CACA;CACA,QAAS,UAAU,EAAE,KAAK;AAC5B;AAkFA,MAAa,uBAMX,UACA,UAWI;CACJ;CACA;AACF;AA4KA,MAAM,uBAKJ,eACoE;CACpE,IAAI,eAAe,KAAA,GACjB;CAGF,OAAO,OAAO,YACZ,OAAO,QAAQ,UAAU,CAAC,CAAC,KAAK,CAAC,IAAI,gBAAgB,CACnD,IACA;EAAE,GAAG;EAAY,QAAQ,WAAW,UAAU,EAAE,KAAK;CAAE,CACzD,CAAC,CACH;AACF;AA2CA,MAAa,uBAMX,gBASI;CACJ,GAAG;CACH,YAAY,oBAAoB,WAAW,UAAU;AACvD;AAEA,MAAa,uBACX,eACqC;;;AChavC,MAAa,gBAAgB,EAAE,KAAK;AAEpC,MAAa,kBAAsC,EAAE,WACnD,EAAE,MAAM;CACN,EAAE,OAAO;CACT,EAAE,OAAO,CAAC,CAAC,OAAO;CAClB,EAAE,QAAQ;CACV,EAAE,KAAK;CACP,EAAE,MAAM,eAAe;CACvB,EAAE,OAAO,EAAE,OAAO,GAAG,eAAe;AACtC,CAAC,CACH;AAEA,MAAa,kBAAqB,UAChC,gBAAgB,MAAM,KAAK;AAe7B,MAAa,0BAIX,aACsC;AAYxC,MAAa,wBAKX,aAC2D"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { serve } from "@hono/node-server";
|
|
2
2
|
import { chmod, link, mkdir, open, readFile, realpath, rename, rm, stat } from "node:fs/promises";
|
|
3
3
|
import { createServer, isIP } from "node:net";
|
|
4
|
-
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
4
|
+
import { basename, dirname, isAbsolute, join, resolve } from "node:path";
|
|
5
5
|
import { createJiti } from "jiti";
|
|
6
6
|
import { ZodError, z } from "zod";
|
|
7
7
|
import { homedir, hostname } from "node:os";
|
|
@@ -1574,6 +1574,8 @@ const createRuntimeManifestHandler = ({ runtime }) => (context) => {
|
|
|
1574
1574
|
};
|
|
1575
1575
|
//#endregion
|
|
1576
1576
|
//#region src/internal/shared/routes.ts
|
|
1577
|
+
const pushNotificationIconPath = "/_overmux/push/icon.png";
|
|
1578
|
+
const pushNotificationBadgePath = "/_overmux/push/badge.png";
|
|
1577
1579
|
const runtimeWebSocketPath = "/api/socket";
|
|
1578
1580
|
const viteInfrastructurePath = "/_overmux/vite/*";
|
|
1579
1581
|
//#endregion
|
|
@@ -1608,6 +1610,17 @@ const registerHttpRoutes = ({ app, auth, authAssetsDirectory, backgroundNotifica
|
|
|
1608
1610
|
path: "*",
|
|
1609
1611
|
handler: createRequestLoggingMiddleware({ serverLogger })
|
|
1610
1612
|
},
|
|
1613
|
+
...[pushNotificationIconPath, pushNotificationBadgePath].map((path) => ({
|
|
1614
|
+
method: "GET",
|
|
1615
|
+
path,
|
|
1616
|
+
handler: async (context) => {
|
|
1617
|
+
const asset = await readFile(fileURLToPath(new URL(`../push/${basename(path)}`, import.meta.resolve("overmux"))));
|
|
1618
|
+
context.header("Cache-Control", "public, max-age=86400");
|
|
1619
|
+
context.header("Content-Type", "image/png");
|
|
1620
|
+
context.header("X-Content-Type-Options", "nosniff");
|
|
1621
|
+
return context.body(new Uint8Array(asset));
|
|
1622
|
+
}
|
|
1623
|
+
})),
|
|
1611
1624
|
{
|
|
1612
1625
|
method: "GET",
|
|
1613
1626
|
path: "/_overmux/auth-shell/*",
|
|
@@ -1639,6 +1652,17 @@ const registerHttpRoutes = ({ app, auth, authAssetsDirectory, backgroundNotifica
|
|
|
1639
1652
|
path: "*",
|
|
1640
1653
|
handler: authentication.authenticate
|
|
1641
1654
|
},
|
|
1655
|
+
{
|
|
1656
|
+
method: "GET",
|
|
1657
|
+
path: "/sw.js",
|
|
1658
|
+
handler: async (context) => {
|
|
1659
|
+
const script = await readFile(fileURLToPath(new URL("../push/sw.js", import.meta.resolve("overmux"))), "utf8");
|
|
1660
|
+
context.header("Cache-Control", "no-cache");
|
|
1661
|
+
context.header("Content-Type", "text/javascript; charset=UTF-8");
|
|
1662
|
+
context.header("X-Content-Type-Options", "nosniff");
|
|
1663
|
+
return context.body(script);
|
|
1664
|
+
}
|
|
1665
|
+
},
|
|
1642
1666
|
{
|
|
1643
1667
|
method: "POST",
|
|
1644
1668
|
path: "/api/auth/logout",
|