@otto-code/protocol 0.5.0

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 (102) hide show
  1. package/README.md +12 -0
  2. package/dist/agent-attention-notification.d.ts +41 -0
  3. package/dist/agent-attention-notification.js +140 -0
  4. package/dist/agent-labels.d.ts +7 -0
  5. package/dist/agent-labels.js +11 -0
  6. package/dist/agent-lifecycle.d.ts +3 -0
  7. package/dist/agent-lifecycle.js +8 -0
  8. package/dist/agent-personalities.d.ts +32 -0
  9. package/dist/agent-personalities.js +69 -0
  10. package/dist/agent-state-bucket.d.ts +14 -0
  11. package/dist/agent-state-bucket.js +41 -0
  12. package/dist/agent-title-limits.d.ts +2 -0
  13. package/dist/agent-title-limits.js +2 -0
  14. package/dist/agent-types.d.ts +479 -0
  15. package/dist/agent-types.js +22 -0
  16. package/dist/artifacts/rpc-schemas.d.ts +396 -0
  17. package/dist/artifacts/rpc-schemas.js +175 -0
  18. package/dist/artifacts/types.d.ts +166 -0
  19. package/dist/artifacts/types.js +73 -0
  20. package/dist/binary-frames/demux.d.ts +11 -0
  21. package/dist/binary-frames/demux.js +23 -0
  22. package/dist/binary-frames/file-transfer.d.ts +50 -0
  23. package/dist/binary-frames/file-transfer.js +107 -0
  24. package/dist/binary-frames/index.d.ts +4 -0
  25. package/dist/binary-frames/index.js +4 -0
  26. package/dist/binary-frames/terminal.d.ts +31 -0
  27. package/dist/binary-frames/terminal.js +99 -0
  28. package/dist/branch-slug.d.ts +14 -0
  29. package/dist/branch-slug.js +49 -0
  30. package/dist/browser-automation/capabilities.d.ts +7 -0
  31. package/dist/browser-automation/capabilities.js +31 -0
  32. package/dist/browser-automation/rpc-schemas.d.ts +1329 -0
  33. package/dist/browser-automation/rpc-schemas.js +555 -0
  34. package/dist/chat/rpc-schemas.d.ts +158 -0
  35. package/dist/chat/rpc-schemas.js +103 -0
  36. package/dist/chat/types.d.ts +30 -0
  37. package/dist/chat/types.js +22 -0
  38. package/dist/client-capabilities.d.ts +8 -0
  39. package/dist/client-capabilities.js +16 -0
  40. package/dist/connection-offer.d.ts +36 -0
  41. package/dist/connection-offer.js +53 -0
  42. package/dist/daemon-endpoints.d.ts +47 -0
  43. package/dist/daemon-endpoints.js +201 -0
  44. package/dist/default-personalities.d.ts +3 -0
  45. package/dist/default-personalities.js +127 -0
  46. package/dist/effort.d.ts +32 -0
  47. package/dist/effort.js +99 -0
  48. package/dist/error-utils.d.ts +11 -0
  49. package/dist/error-utils.js +27 -0
  50. package/dist/generated/validation/ws-outbound.aot.d.ts +2 -0
  51. package/dist/generated/validation/ws-outbound.aot.js +48755 -0
  52. package/dist/git-hosting.d.ts +21 -0
  53. package/dist/git-hosting.js +36 -0
  54. package/dist/git-remote.d.ts +18 -0
  55. package/dist/git-remote.js +84 -0
  56. package/dist/host-connection-schema.d.ts +11 -0
  57. package/dist/host-connection-schema.js +9 -0
  58. package/dist/literal-union.d.ts +2 -0
  59. package/dist/literal-union.js +2 -0
  60. package/dist/loop/rpc-schemas.d.ts +636 -0
  61. package/dist/loop/rpc-schemas.js +163 -0
  62. package/dist/messages.d.ts +38505 -0
  63. package/dist/messages.js +4719 -0
  64. package/dist/otto-config-schema.d.ts +136 -0
  65. package/dist/otto-config-schema.js +96 -0
  66. package/dist/path-utils.d.ts +2 -0
  67. package/dist/path-utils.js +16 -0
  68. package/dist/provider-config.d.ts +266 -0
  69. package/dist/provider-config.js +238 -0
  70. package/dist/provider-icon-names.d.ts +5 -0
  71. package/dist/provider-icon-names.js +52 -0
  72. package/dist/provider-manifest.d.ts +34 -0
  73. package/dist/provider-manifest.js +227 -0
  74. package/dist/schedule/cron-expression.d.ts +13 -0
  75. package/dist/schedule/cron-expression.js +97 -0
  76. package/dist/schedule/rpc-schemas.d.ts +667 -0
  77. package/dist/schedule/rpc-schemas.js +155 -0
  78. package/dist/schedule/types.d.ts +236 -0
  79. package/dist/schedule/types.js +84 -0
  80. package/dist/terminal-activity.d.ts +21 -0
  81. package/dist/terminal-activity.js +25 -0
  82. package/dist/terminal-input-mode.d.ts +26 -0
  83. package/dist/terminal-input-mode.js +151 -0
  84. package/dist/terminal-key-input.d.ts +13 -0
  85. package/dist/terminal-key-input.js +201 -0
  86. package/dist/terminal-profiles.d.ts +6 -0
  87. package/dist/terminal-profiles.js +28 -0
  88. package/dist/terminal-snapshot.d.ts +3 -0
  89. package/dist/terminal-snapshot.js +178 -0
  90. package/dist/terminal-stream-protocol.d.ts +2 -0
  91. package/dist/terminal-stream-protocol.js +2 -0
  92. package/dist/terminal-subscription-key.d.ts +2 -0
  93. package/dist/terminal-subscription-key.js +9 -0
  94. package/dist/tool-call-display.d.ts +11 -0
  95. package/dist/tool-call-display.js +135 -0
  96. package/dist/tool-name-normalization.d.ts +9 -0
  97. package/dist/tool-name-normalization.js +82 -0
  98. package/dist/validation/ws-outbound-schema-metadata.d.ts +7256 -0
  99. package/dist/validation/ws-outbound-schema-metadata.js +3 -0
  100. package/dist/validation/ws-outbound.d.ts +12 -0
  101. package/dist/validation/ws-outbound.js +8 -0
  102. package/package.json +42 -0
@@ -0,0 +1,158 @@
1
+ import { z } from "zod";
2
+ export declare const ChatCreateRequestSchema: z.ZodObject<{
3
+ type: z.ZodLiteral<"chat/create">;
4
+ requestId: z.ZodString;
5
+ name: z.ZodString;
6
+ purpose: z.ZodOptional<z.ZodString>;
7
+ }, z.core.$strip>;
8
+ export declare const ChatListRequestSchema: z.ZodObject<{
9
+ type: z.ZodLiteral<"chat/list">;
10
+ requestId: z.ZodString;
11
+ }, z.core.$strip>;
12
+ export declare const ChatInspectRequestSchema: z.ZodObject<{
13
+ type: z.ZodLiteral<"chat/inspect">;
14
+ requestId: z.ZodString;
15
+ room: z.ZodString;
16
+ }, z.core.$strip>;
17
+ export declare const ChatDeleteRequestSchema: z.ZodObject<{
18
+ type: z.ZodLiteral<"chat/delete">;
19
+ requestId: z.ZodString;
20
+ room: z.ZodString;
21
+ }, z.core.$strip>;
22
+ export declare const ChatPostRequestSchema: z.ZodObject<{
23
+ type: z.ZodLiteral<"chat/post">;
24
+ requestId: z.ZodString;
25
+ room: z.ZodString;
26
+ body: z.ZodString;
27
+ authorAgentId: z.ZodOptional<z.ZodString>;
28
+ replyToMessageId: z.ZodOptional<z.ZodString>;
29
+ }, z.core.$strip>;
30
+ export declare const ChatReadRequestSchema: z.ZodObject<{
31
+ type: z.ZodLiteral<"chat/read">;
32
+ requestId: z.ZodString;
33
+ room: z.ZodString;
34
+ limit: z.ZodOptional<z.ZodNumber>;
35
+ since: z.ZodOptional<z.ZodString>;
36
+ authorAgentId: z.ZodOptional<z.ZodString>;
37
+ }, z.core.$strip>;
38
+ export declare const ChatWaitRequestSchema: z.ZodObject<{
39
+ type: z.ZodLiteral<"chat/wait">;
40
+ requestId: z.ZodString;
41
+ room: z.ZodString;
42
+ afterMessageId: z.ZodOptional<z.ZodString>;
43
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
44
+ }, z.core.$strip>;
45
+ export declare const ChatCreateResponseSchema: z.ZodObject<{
46
+ type: z.ZodLiteral<"chat/create/response">;
47
+ payload: z.ZodObject<{
48
+ requestId: z.ZodString;
49
+ room: z.ZodNullable<z.ZodObject<{
50
+ id: z.ZodString;
51
+ name: z.ZodString;
52
+ purpose: z.ZodNullable<z.ZodString>;
53
+ createdAt: z.ZodString;
54
+ updatedAt: z.ZodString;
55
+ messageCount: z.ZodNumber;
56
+ lastMessageAt: z.ZodNullable<z.ZodString>;
57
+ }, z.core.$strip>>;
58
+ error: z.ZodNullable<z.ZodString>;
59
+ }, z.core.$strip>;
60
+ }, z.core.$strip>;
61
+ export declare const ChatListResponseSchema: z.ZodObject<{
62
+ type: z.ZodLiteral<"chat/list/response">;
63
+ payload: z.ZodObject<{
64
+ requestId: z.ZodString;
65
+ rooms: z.ZodArray<z.ZodObject<{
66
+ id: z.ZodString;
67
+ name: z.ZodString;
68
+ purpose: z.ZodNullable<z.ZodString>;
69
+ createdAt: z.ZodString;
70
+ updatedAt: z.ZodString;
71
+ messageCount: z.ZodNumber;
72
+ lastMessageAt: z.ZodNullable<z.ZodString>;
73
+ }, z.core.$strip>>;
74
+ error: z.ZodNullable<z.ZodString>;
75
+ }, z.core.$strip>;
76
+ }, z.core.$strip>;
77
+ export declare const ChatInspectResponseSchema: z.ZodObject<{
78
+ type: z.ZodLiteral<"chat/inspect/response">;
79
+ payload: z.ZodObject<{
80
+ requestId: z.ZodString;
81
+ room: z.ZodNullable<z.ZodObject<{
82
+ id: z.ZodString;
83
+ name: z.ZodString;
84
+ purpose: z.ZodNullable<z.ZodString>;
85
+ createdAt: z.ZodString;
86
+ updatedAt: z.ZodString;
87
+ messageCount: z.ZodNumber;
88
+ lastMessageAt: z.ZodNullable<z.ZodString>;
89
+ }, z.core.$strip>>;
90
+ error: z.ZodNullable<z.ZodString>;
91
+ }, z.core.$strip>;
92
+ }, z.core.$strip>;
93
+ export declare const ChatDeleteResponseSchema: z.ZodObject<{
94
+ type: z.ZodLiteral<"chat/delete/response">;
95
+ payload: z.ZodObject<{
96
+ requestId: z.ZodString;
97
+ room: z.ZodNullable<z.ZodObject<{
98
+ id: z.ZodString;
99
+ name: z.ZodString;
100
+ purpose: z.ZodNullable<z.ZodString>;
101
+ createdAt: z.ZodString;
102
+ updatedAt: z.ZodString;
103
+ messageCount: z.ZodNumber;
104
+ lastMessageAt: z.ZodNullable<z.ZodString>;
105
+ }, z.core.$strip>>;
106
+ error: z.ZodNullable<z.ZodString>;
107
+ }, z.core.$strip>;
108
+ }, z.core.$strip>;
109
+ export declare const ChatPostResponseSchema: z.ZodObject<{
110
+ type: z.ZodLiteral<"chat/post/response">;
111
+ payload: z.ZodObject<{
112
+ requestId: z.ZodString;
113
+ message: z.ZodNullable<z.ZodObject<{
114
+ id: z.ZodString;
115
+ roomId: z.ZodString;
116
+ authorAgentId: z.ZodString;
117
+ body: z.ZodString;
118
+ replyToMessageId: z.ZodNullable<z.ZodString>;
119
+ mentionAgentIds: z.ZodArray<z.ZodString>;
120
+ createdAt: z.ZodString;
121
+ }, z.core.$strip>>;
122
+ error: z.ZodNullable<z.ZodString>;
123
+ }, z.core.$strip>;
124
+ }, z.core.$strip>;
125
+ export declare const ChatReadResponseSchema: z.ZodObject<{
126
+ type: z.ZodLiteral<"chat/read/response">;
127
+ payload: z.ZodObject<{
128
+ requestId: z.ZodString;
129
+ messages: z.ZodArray<z.ZodObject<{
130
+ id: z.ZodString;
131
+ roomId: z.ZodString;
132
+ authorAgentId: z.ZodString;
133
+ body: z.ZodString;
134
+ replyToMessageId: z.ZodNullable<z.ZodString>;
135
+ mentionAgentIds: z.ZodArray<z.ZodString>;
136
+ createdAt: z.ZodString;
137
+ }, z.core.$strip>>;
138
+ error: z.ZodNullable<z.ZodString>;
139
+ }, z.core.$strip>;
140
+ }, z.core.$strip>;
141
+ export declare const ChatWaitResponseSchema: z.ZodObject<{
142
+ type: z.ZodLiteral<"chat/wait/response">;
143
+ payload: z.ZodObject<{
144
+ requestId: z.ZodString;
145
+ messages: z.ZodArray<z.ZodObject<{
146
+ id: z.ZodString;
147
+ roomId: z.ZodString;
148
+ authorAgentId: z.ZodString;
149
+ body: z.ZodString;
150
+ replyToMessageId: z.ZodNullable<z.ZodString>;
151
+ mentionAgentIds: z.ZodArray<z.ZodString>;
152
+ createdAt: z.ZodString;
153
+ }, z.core.$strip>>;
154
+ timedOut: z.ZodBoolean;
155
+ error: z.ZodNullable<z.ZodString>;
156
+ }, z.core.$strip>;
157
+ }, z.core.$strip>;
158
+ //# sourceMappingURL=rpc-schemas.d.ts.map
@@ -0,0 +1,103 @@
1
+ import { z } from "zod";
2
+ import { ChatMessageSchema, ChatRoomDetailSchema } from "./types.js";
3
+ export const ChatCreateRequestSchema = z.object({
4
+ type: z.literal("chat/create"),
5
+ requestId: z.string(),
6
+ name: z.string(),
7
+ purpose: z.string().optional(),
8
+ });
9
+ export const ChatListRequestSchema = z.object({
10
+ type: z.literal("chat/list"),
11
+ requestId: z.string(),
12
+ });
13
+ export const ChatInspectRequestSchema = z.object({
14
+ type: z.literal("chat/inspect"),
15
+ requestId: z.string(),
16
+ room: z.string(),
17
+ });
18
+ export const ChatDeleteRequestSchema = z.object({
19
+ type: z.literal("chat/delete"),
20
+ requestId: z.string(),
21
+ room: z.string(),
22
+ });
23
+ export const ChatPostRequestSchema = z.object({
24
+ type: z.literal("chat/post"),
25
+ requestId: z.string(),
26
+ room: z.string(),
27
+ body: z.string(),
28
+ authorAgentId: z.string().optional(),
29
+ replyToMessageId: z.string().optional(),
30
+ });
31
+ export const ChatReadRequestSchema = z.object({
32
+ type: z.literal("chat/read"),
33
+ requestId: z.string(),
34
+ room: z.string(),
35
+ limit: z.number().int().nonnegative().optional(),
36
+ since: z.string().optional(),
37
+ authorAgentId: z.string().optional(),
38
+ });
39
+ export const ChatWaitRequestSchema = z.object({
40
+ type: z.literal("chat/wait"),
41
+ requestId: z.string(),
42
+ room: z.string(),
43
+ afterMessageId: z.string().optional(),
44
+ timeoutMs: z.number().int().nonnegative().optional(),
45
+ });
46
+ export const ChatCreateResponseSchema = z.object({
47
+ type: z.literal("chat/create/response"),
48
+ payload: z.object({
49
+ requestId: z.string(),
50
+ room: ChatRoomDetailSchema.nullable(),
51
+ error: z.string().nullable(),
52
+ }),
53
+ });
54
+ export const ChatListResponseSchema = z.object({
55
+ type: z.literal("chat/list/response"),
56
+ payload: z.object({
57
+ requestId: z.string(),
58
+ rooms: z.array(ChatRoomDetailSchema),
59
+ error: z.string().nullable(),
60
+ }),
61
+ });
62
+ export const ChatInspectResponseSchema = z.object({
63
+ type: z.literal("chat/inspect/response"),
64
+ payload: z.object({
65
+ requestId: z.string(),
66
+ room: ChatRoomDetailSchema.nullable(),
67
+ error: z.string().nullable(),
68
+ }),
69
+ });
70
+ export const ChatDeleteResponseSchema = z.object({
71
+ type: z.literal("chat/delete/response"),
72
+ payload: z.object({
73
+ requestId: z.string(),
74
+ room: ChatRoomDetailSchema.nullable(),
75
+ error: z.string().nullable(),
76
+ }),
77
+ });
78
+ export const ChatPostResponseSchema = z.object({
79
+ type: z.literal("chat/post/response"),
80
+ payload: z.object({
81
+ requestId: z.string(),
82
+ message: ChatMessageSchema.nullable(),
83
+ error: z.string().nullable(),
84
+ }),
85
+ });
86
+ export const ChatReadResponseSchema = z.object({
87
+ type: z.literal("chat/read/response"),
88
+ payload: z.object({
89
+ requestId: z.string(),
90
+ messages: z.array(ChatMessageSchema),
91
+ error: z.string().nullable(),
92
+ }),
93
+ });
94
+ export const ChatWaitResponseSchema = z.object({
95
+ type: z.literal("chat/wait/response"),
96
+ payload: z.object({
97
+ requestId: z.string(),
98
+ messages: z.array(ChatMessageSchema),
99
+ timedOut: z.boolean(),
100
+ error: z.string().nullable(),
101
+ }),
102
+ });
103
+ //# 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,22 @@
1
+ import { z } from "zod";
2
+ export const ChatRoomSchema = z.object({
3
+ id: z.string(),
4
+ name: z.string(),
5
+ purpose: z.string().nullable(),
6
+ createdAt: z.string(),
7
+ updatedAt: z.string(),
8
+ });
9
+ export const ChatMessageSchema = z.object({
10
+ id: z.string(),
11
+ roomId: z.string(),
12
+ authorAgentId: z.string(),
13
+ body: z.string(),
14
+ replyToMessageId: z.string().nullable(),
15
+ mentionAgentIds: z.array(z.string()),
16
+ createdAt: z.string(),
17
+ });
18
+ export const ChatRoomDetailSchema = ChatRoomSchema.extend({
19
+ messageCount: z.number().int().nonnegative(),
20
+ lastMessageAt: z.string().nullable(),
21
+ });
22
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,8 @@
1
+ export declare const CLIENT_CAPS: {
2
+ readonly reasoningMergeEnum: "reasoning_merge_enum";
3
+ readonly customModeIcons: "custom_mode_icons";
4
+ readonly terminalReflowableSnapshot: "terminal_reflowable_snapshot";
5
+ readonly browserHost: "browser_host";
6
+ };
7
+ export type ClientCapability = (typeof CLIENT_CAPS)[keyof typeof CLIENT_CAPS];
8
+ //# sourceMappingURL=client-capabilities.d.ts.map
@@ -0,0 +1,16 @@
1
+ export const CLIENT_CAPS = {
2
+ reasoningMergeEnum: "reasoning_merge_enum",
3
+ // COMPAT(customModeIcons): added in v0.1.84. Old clients pin AgentModeIcon to
4
+ // a closed enum and crash rendering unknown values; daemon downgrades icons
5
+ // outside the legacy set to "ShieldCheck" when this cap is absent. Drop the
6
+ // gate when floor >= v0.1.84.
7
+ customModeIcons: "custom_mode_icons",
8
+ // COMPAT(terminalReflowableSnapshot): added in v0.1.88. The daemon attaches
9
+ // per-row soft-wrap flags (gridWrapped/scrollbackWrapped) to terminal snapshots
10
+ // only when the client advertises this, so restored content can reflow on resize.
11
+ // Old clients use a strict TerminalState schema and would reject the extra fields.
12
+ // Drop the gate (always send the flags) when floor >= v0.1.88.
13
+ terminalReflowableSnapshot: "terminal_reflowable_snapshot",
14
+ browserHost: "browser_host",
15
+ };
16
+ //# 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 `OTTO_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.otto-code.me/#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 `OTTO_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.otto-code.me/#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.otto-code.me: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.otto-code.me: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]:6868
35
+ if (trimmed.startsWith("[")) {
36
+ const match = trimmed.match(/^\[([^\]]+)\]:(\d{1,5})$/);
37
+ if (!match) {
38
+ throw new Error("Invalid host:port (expected [::1]:6868)");
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:6868)");
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,3 @@
1
+ import type { AgentPersonality } from "./messages.js";
2
+ export declare const DEFAULT_AGENT_PERSONALITIES: readonly AgentPersonality[];
3
+ //# sourceMappingURL=default-personalities.d.ts.map