@camerontaylor/paseo-protocol 0.8.0-fork.1
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 +12 -0
- package/dist/agent-attention-notification.d.ts +43 -0
- package/dist/agent-attention-notification.js +141 -0
- package/dist/agent-deep-link.d.ts +8 -0
- package/dist/agent-deep-link.js +49 -0
- package/dist/agent-labels.d.ts +10 -0
- package/dist/agent-labels.js +21 -0
- package/dist/agent-lifecycle.d.ts +3 -0
- package/dist/agent-lifecycle.js +8 -0
- package/dist/agent-state-bucket.d.ts +14 -0
- package/dist/agent-state-bucket.js +41 -0
- package/dist/agent-title-limits.d.ts +2 -0
- package/dist/agent-title-limits.js +2 -0
- package/dist/agent-types.d.ts +478 -0
- package/dist/agent-types.js +22 -0
- package/dist/binary-frames/demux.d.ts +11 -0
- package/dist/binary-frames/demux.js +23 -0
- package/dist/binary-frames/file-transfer.d.ts +51 -0
- package/dist/binary-frames/file-transfer.js +108 -0
- package/dist/binary-frames/index.d.ts +4 -0
- package/dist/binary-frames/index.js +4 -0
- package/dist/binary-frames/terminal.d.ts +35 -0
- package/dist/binary-frames/terminal.js +100 -0
- package/dist/branch-slug.d.ts +14 -0
- package/dist/branch-slug.js +49 -0
- package/dist/browser-automation/capabilities.d.ts +7 -0
- package/dist/browser-automation/capabilities.js +31 -0
- package/dist/browser-automation/rpc-schemas.d.ts +1112 -0
- package/dist/browser-automation/rpc-schemas.js +462 -0
- package/dist/chat/rpc-schemas.d.ts +158 -0
- package/dist/chat/rpc-schemas.js +104 -0
- package/dist/chat/types.d.ts +30 -0
- package/dist/chat/types.js +23 -0
- package/dist/check-traits.d.ts +11 -0
- package/dist/check-traits.js +10 -0
- package/dist/client-capabilities.d.ts +20 -0
- package/dist/client-capabilities.js +47 -0
- package/dist/connection-offer.d.ts +36 -0
- package/dist/connection-offer.js +53 -0
- package/dist/daemon-endpoints.d.ts +47 -0
- package/dist/daemon-endpoints.js +201 -0
- package/dist/error-utils.d.ts +11 -0
- package/dist/error-utils.js +27 -0
- package/dist/forge-manifest.d.ts +66 -0
- package/dist/forge-manifest.js +92 -0
- package/dist/generated/validation/ws-outbound.aot.d.ts +2 -0
- package/dist/generated/validation/ws-outbound.aot.js +98097 -0
- package/dist/git-remote.d.ts +33 -0
- package/dist/git-remote.js +94 -0
- package/dist/gitea-status.d.ts +10 -0
- package/dist/gitea-status.js +23 -0
- package/dist/gitlab-pipeline.d.ts +10 -0
- package/dist/gitlab-pipeline.js +17 -0
- package/dist/host-connection-schema.d.ts +11 -0
- package/dist/host-connection-schema.js +9 -0
- package/dist/literal-union.d.ts +2 -0
- package/dist/literal-union.js +2 -0
- package/dist/loop/rpc-schemas.d.ts +636 -0
- package/dist/loop/rpc-schemas.js +164 -0
- package/dist/messages.d.ts +60742 -0
- package/dist/messages.js +6152 -0
- package/dist/paseo-config-schema.d.ts +138 -0
- package/dist/paseo-config-schema.js +98 -0
- package/dist/paseo-tool-call-detail.d.ts +15 -0
- package/dist/paseo-tool-call-detail.js +305 -0
- package/dist/path-utils.d.ts +2 -0
- package/dist/path-utils.js +16 -0
- package/dist/plugin-requirements.d.ts +11 -0
- package/dist/plugin-requirements.js +26 -0
- package/dist/plugin-source-reference.d.ts +7 -0
- package/dist/plugin-source-reference.js +41 -0
- package/dist/provider-config.d.ts +139 -0
- package/dist/provider-config.js +115 -0
- package/dist/provider-icon-names.d.ts +5 -0
- package/dist/provider-icon-names.js +54 -0
- package/dist/provider-manifest.d.ts +37 -0
- package/dist/provider-manifest.js +261 -0
- package/dist/provider-snapshot-codec.d.ts +18 -0
- package/dist/provider-snapshot-codec.js +71 -0
- package/dist/schedule/cadence.d.ts +6 -0
- package/dist/schedule/cadence.js +28 -0
- package/dist/schedule/cron-expression.d.ts +13 -0
- package/dist/schedule/cron-expression.js +97 -0
- package/dist/schedule/rpc-schemas.d.ts +568 -0
- package/dist/schedule/rpc-schemas.js +155 -0
- package/dist/schedule/types.d.ts +201 -0
- package/dist/schedule/types.js +68 -0
- package/dist/search/text-match.d.ts +71 -0
- package/dist/search/text-match.js +291 -0
- package/dist/ssh-transport.d.ts +11 -0
- package/dist/ssh-transport.js +72 -0
- package/dist/terminal-activity.d.ts +21 -0
- package/dist/terminal-activity.js +25 -0
- package/dist/terminal-input-mode.d.ts +30 -0
- package/dist/terminal-input-mode.js +180 -0
- package/dist/terminal-key-input.d.ts +13 -0
- package/dist/terminal-key-input.js +210 -0
- package/dist/terminal-profiles.d.ts +41 -0
- package/dist/terminal-profiles.js +270 -0
- package/dist/terminal-snapshot.d.ts +3 -0
- package/dist/terminal-snapshot.js +184 -0
- package/dist/terminal-stream-protocol.d.ts +2 -0
- package/dist/terminal-stream-protocol.js +2 -0
- package/dist/terminal-subscription-key.d.ts +2 -0
- package/dist/terminal-subscription-key.js +9 -0
- package/dist/timeline-identity.d.ts +3 -0
- package/dist/timeline-identity.js +8 -0
- package/dist/tool-call-display.d.ts +11 -0
- package/dist/tool-call-display.js +136 -0
- package/dist/tool-name-normalization.d.ts +9 -0
- package/dist/tool-name-normalization.js +82 -0
- package/dist/validation/ws-outbound-schema-metadata.d.ts +11418 -0
- package/dist/validation/ws-outbound-schema-metadata.js +3 -0
- package/dist/validation/ws-outbound.d.ts +12 -0
- package/dist/validation/ws-outbound.js +8 -0
- package/dist/workspace-labels.d.ts +9 -0
- package/dist/workspace-labels.js +19 -0
- package/package.json +44 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ChatMessageSchema, ChatRoomDetailSchema } from "./types.js";
|
|
3
|
+
// COMPAT(chatRooms): retained after the v0.3.0 feature removal; remove after 2027-02-09 when mixed-version peers no longer send legacy messages.
|
|
4
|
+
export const ChatCreateRequestSchema = z.object({
|
|
5
|
+
type: z.literal("chat/create"),
|
|
6
|
+
requestId: z.string(),
|
|
7
|
+
name: z.string(),
|
|
8
|
+
purpose: z.string().optional(),
|
|
9
|
+
});
|
|
10
|
+
export const ChatListRequestSchema = z.object({
|
|
11
|
+
type: z.literal("chat/list"),
|
|
12
|
+
requestId: z.string(),
|
|
13
|
+
});
|
|
14
|
+
export const ChatInspectRequestSchema = z.object({
|
|
15
|
+
type: z.literal("chat/inspect"),
|
|
16
|
+
requestId: z.string(),
|
|
17
|
+
room: z.string(),
|
|
18
|
+
});
|
|
19
|
+
export const ChatDeleteRequestSchema = z.object({
|
|
20
|
+
type: z.literal("chat/delete"),
|
|
21
|
+
requestId: z.string(),
|
|
22
|
+
room: z.string(),
|
|
23
|
+
});
|
|
24
|
+
export const ChatPostRequestSchema = z.object({
|
|
25
|
+
type: z.literal("chat/post"),
|
|
26
|
+
requestId: z.string(),
|
|
27
|
+
room: z.string(),
|
|
28
|
+
body: z.string(),
|
|
29
|
+
authorAgentId: z.string().optional(),
|
|
30
|
+
replyToMessageId: z.string().optional(),
|
|
31
|
+
});
|
|
32
|
+
export const ChatReadRequestSchema = z.object({
|
|
33
|
+
type: z.literal("chat/read"),
|
|
34
|
+
requestId: z.string(),
|
|
35
|
+
room: z.string(),
|
|
36
|
+
limit: z.number().int().nonnegative().optional(),
|
|
37
|
+
since: z.string().optional(),
|
|
38
|
+
authorAgentId: z.string().optional(),
|
|
39
|
+
});
|
|
40
|
+
export const ChatWaitRequestSchema = z.object({
|
|
41
|
+
type: z.literal("chat/wait"),
|
|
42
|
+
requestId: z.string(),
|
|
43
|
+
room: z.string(),
|
|
44
|
+
afterMessageId: z.string().optional(),
|
|
45
|
+
timeoutMs: z.number().int().nonnegative().optional(),
|
|
46
|
+
});
|
|
47
|
+
export const ChatCreateResponseSchema = z.object({
|
|
48
|
+
type: z.literal("chat/create/response"),
|
|
49
|
+
payload: z.object({
|
|
50
|
+
requestId: z.string(),
|
|
51
|
+
room: ChatRoomDetailSchema.nullable(),
|
|
52
|
+
error: z.string().nullable(),
|
|
53
|
+
}),
|
|
54
|
+
});
|
|
55
|
+
export const ChatListResponseSchema = z.object({
|
|
56
|
+
type: z.literal("chat/list/response"),
|
|
57
|
+
payload: z.object({
|
|
58
|
+
requestId: z.string(),
|
|
59
|
+
rooms: z.array(ChatRoomDetailSchema),
|
|
60
|
+
error: z.string().nullable(),
|
|
61
|
+
}),
|
|
62
|
+
});
|
|
63
|
+
export const ChatInspectResponseSchema = z.object({
|
|
64
|
+
type: z.literal("chat/inspect/response"),
|
|
65
|
+
payload: z.object({
|
|
66
|
+
requestId: z.string(),
|
|
67
|
+
room: ChatRoomDetailSchema.nullable(),
|
|
68
|
+
error: z.string().nullable(),
|
|
69
|
+
}),
|
|
70
|
+
});
|
|
71
|
+
export const ChatDeleteResponseSchema = z.object({
|
|
72
|
+
type: z.literal("chat/delete/response"),
|
|
73
|
+
payload: z.object({
|
|
74
|
+
requestId: z.string(),
|
|
75
|
+
room: ChatRoomDetailSchema.nullable(),
|
|
76
|
+
error: z.string().nullable(),
|
|
77
|
+
}),
|
|
78
|
+
});
|
|
79
|
+
export const ChatPostResponseSchema = z.object({
|
|
80
|
+
type: z.literal("chat/post/response"),
|
|
81
|
+
payload: z.object({
|
|
82
|
+
requestId: z.string(),
|
|
83
|
+
message: ChatMessageSchema.nullable(),
|
|
84
|
+
error: z.string().nullable(),
|
|
85
|
+
}),
|
|
86
|
+
});
|
|
87
|
+
export const ChatReadResponseSchema = z.object({
|
|
88
|
+
type: z.literal("chat/read/response"),
|
|
89
|
+
payload: z.object({
|
|
90
|
+
requestId: z.string(),
|
|
91
|
+
messages: z.array(ChatMessageSchema),
|
|
92
|
+
error: z.string().nullable(),
|
|
93
|
+
}),
|
|
94
|
+
});
|
|
95
|
+
export const ChatWaitResponseSchema = z.object({
|
|
96
|
+
type: z.literal("chat/wait/response"),
|
|
97
|
+
payload: z.object({
|
|
98
|
+
requestId: z.string(),
|
|
99
|
+
messages: z.array(ChatMessageSchema),
|
|
100
|
+
timedOut: z.boolean(),
|
|
101
|
+
error: z.string().nullable(),
|
|
102
|
+
}),
|
|
103
|
+
});
|
|
104
|
+
//# sourceMappingURL=rpc-schemas.js.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const ChatRoomSchema: z.ZodObject<{
|
|
3
|
+
id: z.ZodString;
|
|
4
|
+
name: z.ZodString;
|
|
5
|
+
purpose: z.ZodNullable<z.ZodString>;
|
|
6
|
+
createdAt: z.ZodString;
|
|
7
|
+
updatedAt: z.ZodString;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
export type ChatRoom = z.infer<typeof ChatRoomSchema>;
|
|
10
|
+
export declare const ChatMessageSchema: z.ZodObject<{
|
|
11
|
+
id: z.ZodString;
|
|
12
|
+
roomId: z.ZodString;
|
|
13
|
+
authorAgentId: z.ZodString;
|
|
14
|
+
body: z.ZodString;
|
|
15
|
+
replyToMessageId: z.ZodNullable<z.ZodString>;
|
|
16
|
+
mentionAgentIds: z.ZodArray<z.ZodString>;
|
|
17
|
+
createdAt: z.ZodString;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
export type ChatMessage = z.infer<typeof ChatMessageSchema>;
|
|
20
|
+
export declare const ChatRoomDetailSchema: z.ZodObject<{
|
|
21
|
+
id: z.ZodString;
|
|
22
|
+
name: z.ZodString;
|
|
23
|
+
purpose: z.ZodNullable<z.ZodString>;
|
|
24
|
+
createdAt: z.ZodString;
|
|
25
|
+
updatedAt: z.ZodString;
|
|
26
|
+
messageCount: z.ZodNumber;
|
|
27
|
+
lastMessageAt: z.ZodNullable<z.ZodString>;
|
|
28
|
+
}, z.core.$strip>;
|
|
29
|
+
export type ChatRoomDetail = z.infer<typeof ChatRoomDetailSchema>;
|
|
30
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// COMPAT(chatRooms): retained after the v0.3.0 feature removal; remove after 2027-02-09 when mixed-version peers no longer send legacy messages.
|
|
3
|
+
export const ChatRoomSchema = z.object({
|
|
4
|
+
id: z.string(),
|
|
5
|
+
name: z.string(),
|
|
6
|
+
purpose: z.string().nullable(),
|
|
7
|
+
createdAt: z.string(),
|
|
8
|
+
updatedAt: z.string(),
|
|
9
|
+
});
|
|
10
|
+
export const ChatMessageSchema = z.object({
|
|
11
|
+
id: z.string(),
|
|
12
|
+
roomId: z.string(),
|
|
13
|
+
authorAgentId: z.string(),
|
|
14
|
+
body: z.string(),
|
|
15
|
+
replyToMessageId: z.string().nullable(),
|
|
16
|
+
mentionAgentIds: z.array(z.string()),
|
|
17
|
+
createdAt: z.string(),
|
|
18
|
+
});
|
|
19
|
+
export const ChatRoomDetailSchema = ChatRoomSchema.extend({
|
|
20
|
+
messageCount: z.number().int().nonnegative(),
|
|
21
|
+
lastMessageAt: z.string().nullable(),
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forge-neutral check traits carried on the wire alongside the stable check
|
|
3
|
+
* status union. Traits are open-ended by design (unknown values must be
|
|
4
|
+
* ignored by consumers); these constants cover the traits the shipped forges
|
|
5
|
+
* emit today so producers and the presentation layer cannot drift apart.
|
|
6
|
+
*/
|
|
7
|
+
export declare const CHECK_TRAIT_MANUAL = "manual";
|
|
8
|
+
export declare const CHECK_TRAIT_ACTION_REQUIRED = "action_required";
|
|
9
|
+
export declare const CHECK_TRAIT_WARNING = "warning";
|
|
10
|
+
export type KnownCheckTrait = typeof CHECK_TRAIT_MANUAL | typeof CHECK_TRAIT_ACTION_REQUIRED | typeof CHECK_TRAIT_WARNING;
|
|
11
|
+
//# sourceMappingURL=check-traits.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forge-neutral check traits carried on the wire alongside the stable check
|
|
3
|
+
* status union. Traits are open-ended by design (unknown values must be
|
|
4
|
+
* ignored by consumers); these constants cover the traits the shipped forges
|
|
5
|
+
* emit today so producers and the presentation layer cannot drift apart.
|
|
6
|
+
*/
|
|
7
|
+
export const CHECK_TRAIT_MANUAL = "manual";
|
|
8
|
+
export const CHECK_TRAIT_ACTION_REQUIRED = "action_required";
|
|
9
|
+
export const CHECK_TRAIT_WARNING = "warning";
|
|
10
|
+
//# sourceMappingURL=check-traits.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const CLIENT_CAPS: {
|
|
2
|
+
readonly explicitEventSubscriptions: "explicit_event_subscriptions";
|
|
3
|
+
readonly allProviders: "all_providers";
|
|
4
|
+
readonly selectiveAgentTimeline: "selective_agent_timeline";
|
|
5
|
+
readonly reasoningMergeEnum: "reasoning_merge_enum";
|
|
6
|
+
readonly customModeIcons: "custom_mode_icons";
|
|
7
|
+
readonly terminalReflowableSnapshot: "terminal_reflowable_snapshot";
|
|
8
|
+
readonly providerSubagents: "provider_subagents";
|
|
9
|
+
readonly sideConversations: "side_conversations";
|
|
10
|
+
readonly projectUpdates: "project_updates";
|
|
11
|
+
readonly compactProviderSnapshots: "compact_provider_snapshots";
|
|
12
|
+
readonly providerSnapshotReferences: "provider_snapshot_references";
|
|
13
|
+
readonly timelineReplacementInvalidation: "timeline_replacement_invalidation";
|
|
14
|
+
readonly timelineNotifications: "timeline_notifications";
|
|
15
|
+
readonly pluginTimelineItems: "plugin_timeline_items";
|
|
16
|
+
readonly workspaceSetupBlocked: "workspace_setup_blocked";
|
|
17
|
+
readonly browserHost: "browser_host";
|
|
18
|
+
};
|
|
19
|
+
export type ClientCapability = (typeof CLIENT_CAPS)[keyof typeof CLIENT_CAPS];
|
|
20
|
+
//# sourceMappingURL=client-capabilities.d.ts.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export const CLIENT_CAPS = {
|
|
2
|
+
// Clients outside the Paseo app version series can explicitly accept provider IDs.
|
|
3
|
+
// COMPAT(explicitEventSubscriptions): added in v0.8.0, remove legacy broadcasts after 2027-03-08.
|
|
4
|
+
explicitEventSubscriptions: "explicit_event_subscriptions",
|
|
5
|
+
allProviders: "all_providers",
|
|
6
|
+
// COMPAT(selectiveAgentTimeline): added in v0.1.106. Capable clients receive
|
|
7
|
+
// agent streams only for their explicit viewed set. Remove after 2027-01-12
|
|
8
|
+
// once the supported client floor is >= v0.1.106.
|
|
9
|
+
selectiveAgentTimeline: "selective_agent_timeline",
|
|
10
|
+
reasoningMergeEnum: "reasoning_merge_enum",
|
|
11
|
+
// COMPAT(customModeIcons): added in v0.1.84. Old clients pin AgentModeIcon to
|
|
12
|
+
// a closed enum and crash rendering unknown values; daemon downgrades icons
|
|
13
|
+
// outside the legacy set to "ShieldCheck" when this cap is absent. Drop the
|
|
14
|
+
// gate when floor >= v0.1.84.
|
|
15
|
+
customModeIcons: "custom_mode_icons",
|
|
16
|
+
// COMPAT(terminalReflowableSnapshot): added in v0.1.88. The daemon attaches
|
|
17
|
+
// per-row soft-wrap flags (gridWrapped/scrollbackWrapped) to terminal snapshots
|
|
18
|
+
// only when the client advertises this, so restored content can reflow on resize.
|
|
19
|
+
// Old clients use a strict TerminalState schema and would reject the extra fields.
|
|
20
|
+
// Drop the gate (always send the flags) when floor >= v0.1.88.
|
|
21
|
+
terminalReflowableSnapshot: "terminal_reflowable_snapshot",
|
|
22
|
+
// COMPAT(providerSubagents): added in v0.1.107. The daemon emits provider-owned
|
|
23
|
+
// child descriptors and timelines only to clients that understand the new messages.
|
|
24
|
+
providerSubagents: "provider_subagents",
|
|
25
|
+
// COMPAT(sideConversations): added in 0.7.0-beta.2.fork.1, fork-only — stock peers never gain it, so the gate lasts as long as stock peers are supported.
|
|
26
|
+
sideConversations: "side_conversations",
|
|
27
|
+
// COMPAT(projectUpdates): added in v0.1.109, remove gate after 2027-01-15.
|
|
28
|
+
projectUpdates: "project_updates",
|
|
29
|
+
// COMPAT(compactProviderSnapshots): added in v0.2.X. Capable clients receive
|
|
30
|
+
// provider catalogs with shared thinking sets and may revalidate by content hash.
|
|
31
|
+
// Remove the legacy snapshot encoding after 2027-02-04.
|
|
32
|
+
compactProviderSnapshots: "compact_provider_snapshots",
|
|
33
|
+
providerSnapshotReferences: "provider_snapshot_references",
|
|
34
|
+
// COMPAT(timelineReplacementInvalidation): added in v0.5.0, remove legacy
|
|
35
|
+
// reconstructed timeline replay after 2027-02-21 once the client floor supports invalidation.
|
|
36
|
+
timelineReplacementInvalidation: "timeline_replacement_invalidation",
|
|
37
|
+
// COMPAT(timelineNotifications): added in v0.7.2. The daemon omits notification
|
|
38
|
+
// timeline items for older clients whose strict timeline union rejects them.
|
|
39
|
+
// Remove after 2027-03-03 once the supported client floor is >= v0.7.2.
|
|
40
|
+
timelineNotifications: "timeline_notifications",
|
|
41
|
+
// COMPAT(pluginTimelineItems): added in v0.8.0, remove after 2027-03-07 once client floor >= v0.8.0.
|
|
42
|
+
pluginTimelineItems: "plugin_timeline_items",
|
|
43
|
+
// COMPAT(workspaceSetupBlocked): added in v0.8.0, remove after 2027-03-07 once client floor >= v0.8.0.
|
|
44
|
+
workspaceSetupBlocked: "workspace_setup_blocked",
|
|
45
|
+
browserHost: "browser_host",
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=client-capabilities.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Relay-only pairing offer.
|
|
4
|
+
*
|
|
5
|
+
* `serverId` is a stable daemon identifier scoped to `PASEO_HOME`, and is also
|
|
6
|
+
* used as the relay session identifier.
|
|
7
|
+
*/
|
|
8
|
+
export declare const ConnectionOfferV2Schema: z.ZodObject<{
|
|
9
|
+
v: z.ZodLiteral<2>;
|
|
10
|
+
serverId: z.ZodString;
|
|
11
|
+
daemonPublicKeyB64: z.ZodString;
|
|
12
|
+
relay: z.ZodObject<{
|
|
13
|
+
endpoint: z.ZodString;
|
|
14
|
+
useTls: z.ZodOptional<z.ZodBoolean>;
|
|
15
|
+
}, z.core.$strip>;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
export type ConnectionOfferV2 = z.infer<typeof ConnectionOfferV2Schema>;
|
|
18
|
+
export declare const ConnectionOfferSchema: z.ZodObject<{
|
|
19
|
+
v: z.ZodLiteral<2>;
|
|
20
|
+
serverId: z.ZodString;
|
|
21
|
+
daemonPublicKeyB64: z.ZodString;
|
|
22
|
+
relay: z.ZodObject<{
|
|
23
|
+
endpoint: z.ZodString;
|
|
24
|
+
useTls: z.ZodOptional<z.ZodBoolean>;
|
|
25
|
+
}, z.core.$strip>;
|
|
26
|
+
}, z.core.$strip>;
|
|
27
|
+
export type ConnectionOffer = ConnectionOfferV2;
|
|
28
|
+
export declare function decodeOfferFragmentPayload(encoded: string): unknown;
|
|
29
|
+
/**
|
|
30
|
+
* Parse a pairing-offer URL of the form `https://app.paseo.sh/#offer=<base64url>`.
|
|
31
|
+
*
|
|
32
|
+
* Returns `null` if the input has no `#offer=` fragment. Throws if the fragment
|
|
33
|
+
* exists but the payload is malformed or fails schema validation.
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseConnectionOfferFromUrl(input: string): ConnectionOffer | null;
|
|
36
|
+
//# sourceMappingURL=connection-offer.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Relay-only pairing offer.
|
|
4
|
+
*
|
|
5
|
+
* `serverId` is a stable daemon identifier scoped to `PASEO_HOME`, and is also
|
|
6
|
+
* used as the relay session identifier.
|
|
7
|
+
*/
|
|
8
|
+
export const ConnectionOfferV2Schema = z.object({
|
|
9
|
+
v: z.literal(2),
|
|
10
|
+
serverId: z.string().min(1),
|
|
11
|
+
daemonPublicKeyB64: z.string().min(1),
|
|
12
|
+
relay: z.object({
|
|
13
|
+
endpoint: z.string().min(1),
|
|
14
|
+
useTls: z.boolean().optional(),
|
|
15
|
+
}),
|
|
16
|
+
});
|
|
17
|
+
export const ConnectionOfferSchema = ConnectionOfferV2Schema;
|
|
18
|
+
function decodeBase64UrlToUtf8(input) {
|
|
19
|
+
const base64 = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
20
|
+
const padded = base64.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), "=");
|
|
21
|
+
const binary = globalThis.atob(padded);
|
|
22
|
+
const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
|
|
23
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
24
|
+
}
|
|
25
|
+
export function decodeOfferFragmentPayload(encoded) {
|
|
26
|
+
const json = decodeBase64UrlToUtf8(encoded);
|
|
27
|
+
return JSON.parse(json);
|
|
28
|
+
}
|
|
29
|
+
const OFFER_FRAGMENT_PREFIX = "#offer=";
|
|
30
|
+
function extractOfferFragmentEncoded(input) {
|
|
31
|
+
const trimmed = input.trim();
|
|
32
|
+
if (!trimmed)
|
|
33
|
+
return null;
|
|
34
|
+
const fragmentIndex = trimmed.indexOf(OFFER_FRAGMENT_PREFIX);
|
|
35
|
+
if (fragmentIndex === -1)
|
|
36
|
+
return null;
|
|
37
|
+
const encoded = trimmed.slice(fragmentIndex + OFFER_FRAGMENT_PREFIX.length).trim();
|
|
38
|
+
return encoded.length > 0 ? encoded : null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Parse a pairing-offer URL of the form `https://app.paseo.sh/#offer=<base64url>`.
|
|
42
|
+
*
|
|
43
|
+
* Returns `null` if the input has no `#offer=` fragment. Throws if the fragment
|
|
44
|
+
* exists but the payload is malformed or fails schema validation.
|
|
45
|
+
*/
|
|
46
|
+
export function parseConnectionOfferFromUrl(input) {
|
|
47
|
+
const encoded = extractOfferFragmentEncoded(input);
|
|
48
|
+
if (!encoded)
|
|
49
|
+
return null;
|
|
50
|
+
const payload = decodeOfferFragmentPayload(encoded);
|
|
51
|
+
return ConnectionOfferSchema.parse(payload);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=connection-offer.js.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export interface HostPortParts {
|
|
2
|
+
host: string;
|
|
3
|
+
port: number;
|
|
4
|
+
isIpv6: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface ConnectionUriParts extends HostPortParts {
|
|
7
|
+
useTls: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface ParsedConnectionUri extends ConnectionUriParts {
|
|
10
|
+
password?: string;
|
|
11
|
+
}
|
|
12
|
+
export type RelayRole = "server" | "client";
|
|
13
|
+
export type RelayProtocolVersion = "1" | "2";
|
|
14
|
+
export declare const CURRENT_RELAY_PROTOCOL_VERSION: RelayProtocolVersion;
|
|
15
|
+
export declare const DEFAULT_RELAY_ENDPOINT = "relay.paseo.sh:443";
|
|
16
|
+
export declare function normalizeRelayProtocolVersion(value: unknown, fallback?: RelayProtocolVersion): RelayProtocolVersion;
|
|
17
|
+
export declare function parseHostPort(input: string): HostPortParts;
|
|
18
|
+
export declare function normalizeHostPort(input: string): string;
|
|
19
|
+
export declare function parseConnectionUri(input: string): ParsedConnectionUri;
|
|
20
|
+
export declare function serializeConnectionUri(parts: ConnectionUriParts): string;
|
|
21
|
+
export declare function serializeConnectionUriForStorage(parts: ParsedConnectionUri): string;
|
|
22
|
+
export declare function normalizeLoopbackToLocalhost(endpoint: string): string;
|
|
23
|
+
export declare function deriveLabelFromEndpoint(endpoint: string): string;
|
|
24
|
+
export interface WebSocketUrlOptions {
|
|
25
|
+
useTls: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare function buildDaemonWebSocketUrl(endpoint: string, opts: WebSocketUrlOptions): string;
|
|
28
|
+
export declare function buildRelayWebSocketUrl(params: {
|
|
29
|
+
endpoint: string;
|
|
30
|
+
useTls: boolean;
|
|
31
|
+
serverId: string;
|
|
32
|
+
role: RelayRole;
|
|
33
|
+
/**
|
|
34
|
+
* Per-connection routing identifier used by the daemon to open server data sockets.
|
|
35
|
+
* Clients should NOT provide this — the relay assigns a routing ID on connect.
|
|
36
|
+
*/
|
|
37
|
+
connectionId?: string;
|
|
38
|
+
version?: RelayProtocolVersion | 1 | 2;
|
|
39
|
+
}): string;
|
|
40
|
+
/**
|
|
41
|
+
* @deprecated Migration fallback for stored relay connections/offers that predate
|
|
42
|
+
* explicit relay useTls. Delete after two release cycles.
|
|
43
|
+
*/
|
|
44
|
+
export declare function shouldUseTlsForDefaultHostedRelay(endpoint: string): boolean;
|
|
45
|
+
export declare function extractHostPortFromWebSocketUrl(wsUrl: string): string;
|
|
46
|
+
export declare function isRelayClientWebSocketUrl(url: string): boolean;
|
|
47
|
+
//# sourceMappingURL=daemon-endpoints.d.ts.map
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
export const CURRENT_RELAY_PROTOCOL_VERSION = "2";
|
|
2
|
+
export const DEFAULT_RELAY_ENDPOINT = "relay.paseo.sh:443";
|
|
3
|
+
export function normalizeRelayProtocolVersion(value, fallback = CURRENT_RELAY_PROTOCOL_VERSION) {
|
|
4
|
+
if (value == null) {
|
|
5
|
+
return fallback;
|
|
6
|
+
}
|
|
7
|
+
let normalized = "";
|
|
8
|
+
if (typeof value === "string") {
|
|
9
|
+
normalized = value.trim();
|
|
10
|
+
}
|
|
11
|
+
else if (typeof value === "number") {
|
|
12
|
+
normalized = String(value);
|
|
13
|
+
}
|
|
14
|
+
if (!normalized) {
|
|
15
|
+
return fallback;
|
|
16
|
+
}
|
|
17
|
+
if (normalized === "1" || normalized === "2") {
|
|
18
|
+
return normalized;
|
|
19
|
+
}
|
|
20
|
+
throw new Error('Relay version must be "1" or "2"');
|
|
21
|
+
}
|
|
22
|
+
function parsePort(portStr, context) {
|
|
23
|
+
const port = Number(portStr);
|
|
24
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
25
|
+
throw new Error(`${context}: port must be between 1 and 65535`);
|
|
26
|
+
}
|
|
27
|
+
return port;
|
|
28
|
+
}
|
|
29
|
+
export function parseHostPort(input) {
|
|
30
|
+
const trimmed = input.trim();
|
|
31
|
+
if (!trimmed) {
|
|
32
|
+
throw new Error("Host is required");
|
|
33
|
+
}
|
|
34
|
+
// IPv6: [::1]:6767
|
|
35
|
+
if (trimmed.startsWith("[")) {
|
|
36
|
+
const match = trimmed.match(/^\[([^\]]+)\]:(\d{1,5})$/);
|
|
37
|
+
if (!match) {
|
|
38
|
+
throw new Error("Invalid host:port (expected [::1]:6767)");
|
|
39
|
+
}
|
|
40
|
+
const host = match[1].trim();
|
|
41
|
+
if (!host)
|
|
42
|
+
throw new Error("Host is required");
|
|
43
|
+
const port = parsePort(match[2], "Invalid host:port");
|
|
44
|
+
return { host, port, isIpv6: true };
|
|
45
|
+
}
|
|
46
|
+
const match = trimmed.match(/^(.+):(\d{1,5})$/);
|
|
47
|
+
if (!match) {
|
|
48
|
+
throw new Error("Invalid host:port (expected localhost:6767)");
|
|
49
|
+
}
|
|
50
|
+
const host = match[1].trim();
|
|
51
|
+
if (!host)
|
|
52
|
+
throw new Error("Host is required");
|
|
53
|
+
const port = parsePort(match[2], "Invalid host:port");
|
|
54
|
+
return { host, port, isIpv6: false };
|
|
55
|
+
}
|
|
56
|
+
export function normalizeHostPort(input) {
|
|
57
|
+
const { host, port, isIpv6 } = parseHostPort(input);
|
|
58
|
+
return isIpv6 ? `[${host}]:${port}` : `${host}:${port}`;
|
|
59
|
+
}
|
|
60
|
+
export function parseConnectionUri(input) {
|
|
61
|
+
const trimmed = input.trim();
|
|
62
|
+
if (!trimmed) {
|
|
63
|
+
throw new Error("Connection URI is required");
|
|
64
|
+
}
|
|
65
|
+
let parsed;
|
|
66
|
+
try {
|
|
67
|
+
parsed = new URL(trimmed);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
throw new Error("Invalid connection URI");
|
|
71
|
+
}
|
|
72
|
+
if (parsed.protocol !== "tcp:") {
|
|
73
|
+
throw new Error("Connection URI protocol must be tcp:");
|
|
74
|
+
}
|
|
75
|
+
if (!parsed.hostname) {
|
|
76
|
+
throw new Error("Connection URI host is required");
|
|
77
|
+
}
|
|
78
|
+
if (!parsed.port) {
|
|
79
|
+
throw new Error("Connection URI port is required");
|
|
80
|
+
}
|
|
81
|
+
if (parsed.username || parsed.password) {
|
|
82
|
+
throw new Error("Connection URI userinfo is not supported");
|
|
83
|
+
}
|
|
84
|
+
const isIpv6 = parsed.hostname.startsWith("[") && parsed.hostname.endsWith("]");
|
|
85
|
+
const host = isIpv6 ? parsed.hostname.slice(1, -1) : parsed.hostname;
|
|
86
|
+
const password = parsed.searchParams.get("password") || undefined;
|
|
87
|
+
return {
|
|
88
|
+
host,
|
|
89
|
+
port: parsePort(parsed.port, "Invalid connection URI"),
|
|
90
|
+
isIpv6,
|
|
91
|
+
useTls: parsed.searchParams.get("ssl") === "true",
|
|
92
|
+
...(password ? { password } : {}),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
export function serializeConnectionUri(parts) {
|
|
96
|
+
return createConnectionUri(parts).toString();
|
|
97
|
+
}
|
|
98
|
+
export function serializeConnectionUriForStorage(parts) {
|
|
99
|
+
const url = createConnectionUri(parts);
|
|
100
|
+
if (parts.password) {
|
|
101
|
+
url.searchParams.set("password", parts.password);
|
|
102
|
+
}
|
|
103
|
+
return url.toString();
|
|
104
|
+
}
|
|
105
|
+
function createConnectionUri(parts) {
|
|
106
|
+
const hostPart = parts.isIpv6 ? `[${parts.host}]` : parts.host;
|
|
107
|
+
const url = new URL(`tcp://${hostPart}:${parts.port}`);
|
|
108
|
+
if (parts.useTls) {
|
|
109
|
+
url.searchParams.set("ssl", "true");
|
|
110
|
+
}
|
|
111
|
+
return url;
|
|
112
|
+
}
|
|
113
|
+
export function normalizeLoopbackToLocalhost(endpoint) {
|
|
114
|
+
const { host, port, isIpv6 } = parseHostPort(endpoint);
|
|
115
|
+
if (host === "127.0.0.1" || (!isIpv6 && host === "0.0.0.0")) {
|
|
116
|
+
return `localhost:${port}`;
|
|
117
|
+
}
|
|
118
|
+
if (isIpv6 && (host === "::1" || host === "::")) {
|
|
119
|
+
return `localhost:${port}`;
|
|
120
|
+
}
|
|
121
|
+
return endpoint;
|
|
122
|
+
}
|
|
123
|
+
export function deriveLabelFromEndpoint(endpoint) {
|
|
124
|
+
try {
|
|
125
|
+
const { host } = parseHostPort(endpoint);
|
|
126
|
+
return host || "Unnamed Host";
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return "Unnamed Host";
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
export function buildDaemonWebSocketUrl(endpoint, opts) {
|
|
133
|
+
const { host, port, isIpv6 } = parseHostPort(endpoint);
|
|
134
|
+
const protocol = opts.useTls ? "wss" : "ws";
|
|
135
|
+
const hostPart = isIpv6 ? `[${host}]` : host;
|
|
136
|
+
return new URL(`${protocol}://${hostPart}:${port}/ws`).toString();
|
|
137
|
+
}
|
|
138
|
+
export function buildRelayWebSocketUrl(params) {
|
|
139
|
+
const { host, port, isIpv6 } = parseHostPort(params.endpoint);
|
|
140
|
+
const protocol = params.useTls ? "wss" : "ws";
|
|
141
|
+
const hostPart = isIpv6 ? `[${host}]` : host;
|
|
142
|
+
const url = new URL(`${protocol}://${hostPart}:${port}/ws`);
|
|
143
|
+
url.searchParams.set("serverId", params.serverId);
|
|
144
|
+
url.searchParams.set("role", params.role);
|
|
145
|
+
url.searchParams.set("v", normalizeRelayProtocolVersion(params.version));
|
|
146
|
+
if (params.connectionId) {
|
|
147
|
+
url.searchParams.set("connectionId", params.connectionId);
|
|
148
|
+
}
|
|
149
|
+
return url.toString();
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* @deprecated Migration fallback for stored relay connections/offers that predate
|
|
153
|
+
* explicit relay useTls. Delete after two release cycles.
|
|
154
|
+
*/
|
|
155
|
+
export function shouldUseTlsForDefaultHostedRelay(endpoint) {
|
|
156
|
+
try {
|
|
157
|
+
const { port } = parseHostPort(endpoint);
|
|
158
|
+
return port === 443;
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
export function extractHostPortFromWebSocketUrl(wsUrl) {
|
|
165
|
+
const parsed = new URL(wsUrl);
|
|
166
|
+
if (parsed.protocol !== "ws:" && parsed.protocol !== "wss:") {
|
|
167
|
+
throw new Error("Invalid WebSocket URL protocol");
|
|
168
|
+
}
|
|
169
|
+
if (parsed.pathname.replace(/\/+$/, "") !== "/ws") {
|
|
170
|
+
throw new Error("Invalid WebSocket URL (expected /ws path)");
|
|
171
|
+
}
|
|
172
|
+
const host = parsed.hostname;
|
|
173
|
+
let port;
|
|
174
|
+
if (parsed.port) {
|
|
175
|
+
port = Number(parsed.port);
|
|
176
|
+
}
|
|
177
|
+
else if (parsed.protocol === "wss:") {
|
|
178
|
+
port = 443;
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
port = 80;
|
|
182
|
+
}
|
|
183
|
+
if (!host) {
|
|
184
|
+
throw new Error("Invalid WebSocket URL (missing hostname)");
|
|
185
|
+
}
|
|
186
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
187
|
+
throw new Error("Invalid WebSocket URL (invalid port)");
|
|
188
|
+
}
|
|
189
|
+
const isIpv6 = host.includes(":") && !host.startsWith("[") && !host.endsWith("]");
|
|
190
|
+
return isIpv6 ? `[${host}]:${port}` : `${host}:${port}`;
|
|
191
|
+
}
|
|
192
|
+
export function isRelayClientWebSocketUrl(url) {
|
|
193
|
+
try {
|
|
194
|
+
const parsed = new URL(url);
|
|
195
|
+
return parsed.searchParams.get("role") === "client" && parsed.searchParams.has("serverId");
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=daemon-endpoints.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts a human-readable error message from an unknown error value.
|
|
3
|
+
* Handles Error instances, string errors, and other types safely.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getErrorMessage(error: unknown): string;
|
|
6
|
+
/**
|
|
7
|
+
* Extracts an error message from an unknown error value, with a fallback
|
|
8
|
+
* for when no message can be extracted.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getErrorMessageOr(error: unknown, fallback: string): string;
|
|
11
|
+
//# sourceMappingURL=error-utils.d.ts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts a human-readable error message from an unknown error value.
|
|
3
|
+
* Handles Error instances, string errors, and other types safely.
|
|
4
|
+
*/
|
|
5
|
+
export function getErrorMessage(error) {
|
|
6
|
+
if (error instanceof Error) {
|
|
7
|
+
return error.message;
|
|
8
|
+
}
|
|
9
|
+
if (typeof error === "string") {
|
|
10
|
+
return error;
|
|
11
|
+
}
|
|
12
|
+
return String(error);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Extracts an error message from an unknown error value, with a fallback
|
|
16
|
+
* for when no message can be extracted.
|
|
17
|
+
*/
|
|
18
|
+
export function getErrorMessageOr(error, fallback) {
|
|
19
|
+
if (error instanceof Error) {
|
|
20
|
+
return error.message;
|
|
21
|
+
}
|
|
22
|
+
if (typeof error === "string" && error.length > 0) {
|
|
23
|
+
return error;
|
|
24
|
+
}
|
|
25
|
+
return fallback;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=error-utils.js.map
|