@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,166 @@
1
+ import { z } from "zod";
2
+ export declare const ArtifactKindSchema: z.ZodEnum<{
3
+ html: "html";
4
+ }>;
5
+ export type ArtifactKind = z.infer<typeof ArtifactKindSchema>;
6
+ export declare const ArtifactStatusSchema: z.ZodEnum<{
7
+ error: "error";
8
+ generating: "generating";
9
+ ready: "ready";
10
+ }>;
11
+ export type ArtifactStatus = z.infer<typeof ArtifactStatusSchema>;
12
+ export declare const ArtifactSpinnerSchema: z.ZodObject<{
13
+ glowA: z.ZodString;
14
+ glowB: z.ZodString;
15
+ }, z.core.$loose>;
16
+ export type ArtifactSpinner = z.infer<typeof ArtifactSpinnerSchema>;
17
+ export declare const ArtifactMetadataSchema: z.ZodObject<{
18
+ id: z.ZodString;
19
+ name: z.ZodString;
20
+ description: z.ZodString;
21
+ projectId: z.ZodString;
22
+ filePath: z.ZodString;
23
+ kind: z.ZodEnum<{
24
+ html: "html";
25
+ }>;
26
+ starred: z.ZodBoolean;
27
+ status: z.ZodEnum<{
28
+ error: "error";
29
+ generating: "generating";
30
+ ready: "ready";
31
+ }>;
32
+ createdAt: z.ZodString;
33
+ updatedAt: z.ZodString;
34
+ generationAgentId: z.ZodNullable<z.ZodString>;
35
+ generationProvider: z.ZodNullable<z.ZodString>;
36
+ generationModel: z.ZodNullable<z.ZodString>;
37
+ generationModeId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
38
+ generationThinkingOptionId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
39
+ generationSpinner: z.ZodOptional<z.ZodNullable<z.ZodObject<{
40
+ glowA: z.ZodString;
41
+ glowB: z.ZodString;
42
+ }, z.core.$loose>>>;
43
+ errorMessage: z.ZodNullable<z.ZodString>;
44
+ }, z.core.$strip>;
45
+ export type ArtifactMetadata = z.infer<typeof ArtifactMetadataSchema>;
46
+ export declare const ArtifactSummarySchema: z.ZodObject<{
47
+ id: z.ZodString;
48
+ name: z.ZodString;
49
+ description: z.ZodString;
50
+ projectId: z.ZodString;
51
+ filePath: z.ZodString;
52
+ kind: z.ZodEnum<{
53
+ html: "html";
54
+ }>;
55
+ starred: z.ZodBoolean;
56
+ status: z.ZodEnum<{
57
+ error: "error";
58
+ generating: "generating";
59
+ ready: "ready";
60
+ }>;
61
+ createdAt: z.ZodString;
62
+ updatedAt: z.ZodString;
63
+ generationAgentId: z.ZodNullable<z.ZodString>;
64
+ generationProvider: z.ZodNullable<z.ZodString>;
65
+ generationModel: z.ZodNullable<z.ZodString>;
66
+ generationModeId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
67
+ generationThinkingOptionId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
68
+ generationSpinner: z.ZodOptional<z.ZodNullable<z.ZodObject<{
69
+ glowA: z.ZodString;
70
+ glowB: z.ZodString;
71
+ }, z.core.$loose>>>;
72
+ errorMessage: z.ZodNullable<z.ZodString>;
73
+ }, z.core.$strip>;
74
+ export type ArtifactSummary = z.infer<typeof ArtifactSummarySchema>;
75
+ export declare const ArtifactRunTriggerSchema: z.ZodEnum<{
76
+ create: "create";
77
+ regenerate: "regenerate";
78
+ }>;
79
+ export type ArtifactRunTrigger = z.infer<typeof ArtifactRunTriggerSchema>;
80
+ export declare const ArtifactRunStatusSchema: z.ZodEnum<{
81
+ running: "running";
82
+ succeeded: "succeeded";
83
+ failed: "failed";
84
+ }>;
85
+ export type ArtifactRunStatus = z.infer<typeof ArtifactRunStatusSchema>;
86
+ export declare const ArtifactRunSchema: z.ZodObject<{
87
+ id: z.ZodString;
88
+ trigger: z.ZodEnum<{
89
+ create: "create";
90
+ regenerate: "regenerate";
91
+ }>;
92
+ status: z.ZodEnum<{
93
+ running: "running";
94
+ succeeded: "succeeded";
95
+ failed: "failed";
96
+ }>;
97
+ startedAt: z.ZodString;
98
+ endedAt: z.ZodNullable<z.ZodString>;
99
+ agentId: z.ZodNullable<z.ZodString>;
100
+ provider: z.ZodNullable<z.ZodString>;
101
+ model: z.ZodNullable<z.ZodString>;
102
+ error: z.ZodNullable<z.ZodString>;
103
+ }, z.core.$strip>;
104
+ export type ArtifactRun = z.infer<typeof ArtifactRunSchema>;
105
+ export declare const StoredArtifactSchema: z.ZodObject<{
106
+ id: z.ZodString;
107
+ name: z.ZodString;
108
+ description: z.ZodString;
109
+ projectId: z.ZodString;
110
+ filePath: z.ZodString;
111
+ kind: z.ZodEnum<{
112
+ html: "html";
113
+ }>;
114
+ starred: z.ZodBoolean;
115
+ status: z.ZodEnum<{
116
+ error: "error";
117
+ generating: "generating";
118
+ ready: "ready";
119
+ }>;
120
+ createdAt: z.ZodString;
121
+ updatedAt: z.ZodString;
122
+ generationAgentId: z.ZodNullable<z.ZodString>;
123
+ generationProvider: z.ZodNullable<z.ZodString>;
124
+ generationModel: z.ZodNullable<z.ZodString>;
125
+ generationModeId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
126
+ generationThinkingOptionId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
127
+ generationSpinner: z.ZodOptional<z.ZodNullable<z.ZodObject<{
128
+ glowA: z.ZodString;
129
+ glowB: z.ZodString;
130
+ }, z.core.$loose>>>;
131
+ errorMessage: z.ZodNullable<z.ZodString>;
132
+ runs: z.ZodDefault<z.ZodArray<z.ZodObject<{
133
+ id: z.ZodString;
134
+ trigger: z.ZodEnum<{
135
+ create: "create";
136
+ regenerate: "regenerate";
137
+ }>;
138
+ status: z.ZodEnum<{
139
+ running: "running";
140
+ succeeded: "succeeded";
141
+ failed: "failed";
142
+ }>;
143
+ startedAt: z.ZodString;
144
+ endedAt: z.ZodNullable<z.ZodString>;
145
+ agentId: z.ZodNullable<z.ZodString>;
146
+ provider: z.ZodNullable<z.ZodString>;
147
+ model: z.ZodNullable<z.ZodString>;
148
+ error: z.ZodNullable<z.ZodString>;
149
+ }, z.core.$strip>>>;
150
+ }, z.core.$strip>;
151
+ export type StoredArtifact = z.infer<typeof StoredArtifactSchema>;
152
+ export declare const MAX_ARTIFACT_RUNS = 20;
153
+ export interface CreateArtifactInput {
154
+ name: string;
155
+ description: string;
156
+ projectId: string;
157
+ provider: string;
158
+ model?: string;
159
+ modeId?: string;
160
+ thinkingOptionId?: string;
161
+ systemPrompt?: string;
162
+ /** Spinner colors of the chosen Agent Personality, snapshotted onto the
163
+ * artifact so its generating card renders in the personality's identity. */
164
+ spinner?: ArtifactSpinner;
165
+ }
166
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,73 @@
1
+ import { z } from "zod";
2
+ export const ArtifactKindSchema = z.enum(["html"]);
3
+ export const ArtifactStatusSchema = z.enum(["generating", "ready", "error"]);
4
+ // Two glow colors for the generating spinner, snapshotted from the Agent
5
+ // Personality the artifact was generated under (BlobLoader glowA/glowB), so its
6
+ // card spinner renders in the personality's identity. Passthrough for
7
+ // forward-compat, mirroring AgentPersonalitySpinnerSchema in messages.ts.
8
+ export const ArtifactSpinnerSchema = z
9
+ .object({
10
+ glowA: z.string().min(1),
11
+ glowB: z.string().min(1),
12
+ })
13
+ .passthrough();
14
+ export const ArtifactMetadataSchema = z.object({
15
+ id: z.string(),
16
+ name: z.string(),
17
+ description: z.string(),
18
+ projectId: z.string(),
19
+ filePath: z.string(),
20
+ kind: ArtifactKindSchema,
21
+ starred: z.boolean(),
22
+ status: ArtifactStatusSchema,
23
+ createdAt: z.string(),
24
+ updatedAt: z.string(),
25
+ generationAgentId: z.string().nullable(),
26
+ generationProvider: z.string().nullable(),
27
+ generationModel: z.string().nullable(),
28
+ // Requested generation mode/effort, persisted so regeneration re-runs with
29
+ // the same settings. Optional: records written before these fields existed
30
+ // omit them (no migrations). The mode is a *request* — the artifact service
31
+ // only honors unattended modes and otherwise resolves the provider's
32
+ // unattended default, so generation never stalls on an approval prompt.
33
+ generationModeId: z.string().nullable().optional(),
34
+ generationThinkingOptionId: z.string().nullable().optional(),
35
+ // Spinner glow colors of the Agent Personality this artifact was generated
36
+ // under, snapshotted at create time like the provider/model above. Absent ⇒
37
+ // the card falls back to the theme's default spinner colors. Purely additive
38
+ // (no daemon floor needed). See projects/agent-personalities/.
39
+ generationSpinner: ArtifactSpinnerSchema.nullable().optional(),
40
+ errorMessage: z.string().nullable(),
41
+ });
42
+ export const ArtifactSummarySchema = ArtifactMetadataSchema;
43
+ // What kicked off a generation attempt: the first-ever generation (create) or a
44
+ // re-run of an existing artifact (regenerate).
45
+ export const ArtifactRunTriggerSchema = z.enum(["create", "regenerate"]);
46
+ export const ArtifactRunStatusSchema = z.enum(["running", "succeeded", "failed"]);
47
+ // One generation attempt. Mirrors ScheduleRun: a persisted log entry per run so
48
+ // inspect_artifact can show what happened across attempts (which provider/model,
49
+ // whether it succeeded, and the failure/cancel/timeout message when it didn't),
50
+ // rather than only the artifact's current status.
51
+ export const ArtifactRunSchema = z.object({
52
+ id: z.string(),
53
+ trigger: ArtifactRunTriggerSchema,
54
+ status: ArtifactRunStatusSchema,
55
+ startedAt: z.string(),
56
+ endedAt: z.string().nullable(),
57
+ agentId: z.string().nullable(),
58
+ provider: z.string().nullable(),
59
+ model: z.string().nullable(),
60
+ error: z.string().nullable(),
61
+ });
62
+ // The full on-disk record: the lean metadata plus its generation run history.
63
+ // `runs` defaults to [] so records written before run history existed parse
64
+ // unchanged (no migrations — same approach the rest of the store takes).
65
+ // list_artifacts / broadcasts keep sending ArtifactMetadata (runs stripped);
66
+ // only inspect_artifact returns this fuller shape.
67
+ export const StoredArtifactSchema = ArtifactMetadataSchema.extend({
68
+ runs: z.array(ArtifactRunSchema).default([]),
69
+ });
70
+ // Cap on retained run history per artifact. Keeps the on-disk JSON bounded while
71
+ // still showing a useful recent window in inspect_artifact.
72
+ export const MAX_ARTIFACT_RUNS = 20;
73
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,11 @@
1
+ import { type FileTransferFrame } from "./file-transfer.js";
2
+ import { type TerminalStreamFrame } from "./terminal.js";
3
+ export type BinaryFrame = {
4
+ kind: "terminal";
5
+ frame: TerminalStreamFrame;
6
+ } | {
7
+ kind: "file_transfer";
8
+ frame: FileTransferFrame;
9
+ };
10
+ export declare function decodeBinaryFrame(bytes: Uint8Array): BinaryFrame | null;
11
+ //# sourceMappingURL=demux.d.ts.map
@@ -0,0 +1,23 @@
1
+ import { decodeFileTransferFrame, FileTransferOpcode, } from "./file-transfer.js";
2
+ import { decodeTerminalStreamFrame, TerminalStreamOpcode, } from "./terminal.js";
3
+ export function decodeBinaryFrame(bytes) {
4
+ switch (bytes[0]) {
5
+ case TerminalStreamOpcode.Output:
6
+ case TerminalStreamOpcode.Input:
7
+ case TerminalStreamOpcode.Resize:
8
+ case TerminalStreamOpcode.Snapshot:
9
+ case TerminalStreamOpcode.Restore: {
10
+ const frame = decodeTerminalStreamFrame(bytes);
11
+ return frame ? { kind: "terminal", frame } : null;
12
+ }
13
+ case FileTransferOpcode.FileBegin:
14
+ case FileTransferOpcode.FileChunk:
15
+ case FileTransferOpcode.FileEnd: {
16
+ const frame = decodeFileTransferFrame(bytes);
17
+ return frame ? { kind: "file_transfer", frame } : null;
18
+ }
19
+ default:
20
+ return null;
21
+ }
22
+ }
23
+ //# sourceMappingURL=demux.js.map
@@ -0,0 +1,50 @@
1
+ import { z } from "zod";
2
+ export declare const FileTransferOpcode: {
3
+ readonly FileBegin: 16;
4
+ readonly FileChunk: 17;
5
+ readonly FileEnd: 18;
6
+ };
7
+ export type FileTransferOpcode = (typeof FileTransferOpcode)[keyof typeof FileTransferOpcode];
8
+ export declare const FileBeginMetadataSchema: z.ZodObject<{
9
+ mime: z.ZodString;
10
+ size: z.ZodNumber;
11
+ encoding: z.ZodEnum<{
12
+ binary: "binary";
13
+ "utf-8": "utf-8";
14
+ }>;
15
+ modifiedAt: z.ZodString;
16
+ fileName: z.ZodOptional<z.ZodString>;
17
+ }, z.core.$strip>;
18
+ export interface FileBegin {
19
+ opcode: typeof FileTransferOpcode.FileBegin;
20
+ requestId: string;
21
+ metadata: z.infer<typeof FileBeginMetadataSchema>;
22
+ payload: Uint8Array;
23
+ }
24
+ export interface FileChunk {
25
+ opcode: typeof FileTransferOpcode.FileChunk;
26
+ requestId: string;
27
+ payload: Uint8Array;
28
+ }
29
+ export interface FileEnd {
30
+ opcode: typeof FileTransferOpcode.FileEnd;
31
+ requestId: string;
32
+ payload: Uint8Array;
33
+ }
34
+ export type FileTransferFrame = FileBegin | FileChunk | FileEnd;
35
+ type FileTransferFrameInput = {
36
+ opcode: typeof FileTransferOpcode.FileBegin;
37
+ requestId: string;
38
+ metadata: z.infer<typeof FileBeginMetadataSchema>;
39
+ } | {
40
+ opcode: typeof FileTransferOpcode.FileChunk;
41
+ requestId: string;
42
+ payload?: Uint8Array | ArrayBuffer | string;
43
+ } | {
44
+ opcode: typeof FileTransferOpcode.FileEnd;
45
+ requestId: string;
46
+ };
47
+ export declare function encodeFileTransferFrame(input: FileTransferFrameInput): Uint8Array;
48
+ export declare function decodeFileTransferFrame(bytes: Uint8Array): FileTransferFrame | null;
49
+ export {};
50
+ //# sourceMappingURL=file-transfer.d.ts.map
@@ -0,0 +1,107 @@
1
+ import { z } from "zod";
2
+ import { asUint8Array } from "./terminal.js";
3
+ export const FileTransferOpcode = {
4
+ FileBegin: 0x10,
5
+ FileChunk: 0x11,
6
+ FileEnd: 0x12,
7
+ };
8
+ export const FileBeginMetadataSchema = z.object({
9
+ mime: z.string().min(1),
10
+ size: z.number().int().nonnegative(),
11
+ encoding: z.enum(["utf-8", "binary"]),
12
+ modifiedAt: z.string(),
13
+ fileName: z.string().optional(),
14
+ });
15
+ export function encodeFileTransferFrame(input) {
16
+ const requestId = encodeRequestId(input.requestId);
17
+ if (input.opcode === FileTransferOpcode.FileBegin) {
18
+ const metadata = encodeJsonPayload(input.metadata);
19
+ if (metadata.byteLength > 0xffff) {
20
+ throw new RangeError("FileBegin metadata is too long");
21
+ }
22
+ const bytes = new Uint8Array(4 + requestId.byteLength + metadata.byteLength);
23
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
24
+ bytes[0] = input.opcode;
25
+ bytes[1] = requestId.byteLength;
26
+ bytes.set(requestId, 2);
27
+ view.setUint16(2 + requestId.byteLength, metadata.byteLength);
28
+ bytes.set(metadata, 4 + requestId.byteLength);
29
+ return bytes;
30
+ }
31
+ const payload = input.opcode === FileTransferOpcode.FileChunk
32
+ ? (asUint8Array(input.payload ?? new Uint8Array()) ?? new Uint8Array())
33
+ : new Uint8Array();
34
+ const bytes = new Uint8Array(2 + requestId.byteLength + payload.byteLength);
35
+ bytes[0] = input.opcode;
36
+ bytes[1] = requestId.byteLength;
37
+ bytes.set(requestId, 2);
38
+ bytes.set(payload, 2 + requestId.byteLength);
39
+ return bytes;
40
+ }
41
+ export function decodeFileTransferFrame(bytes) {
42
+ if (bytes.byteLength < 2) {
43
+ return null;
44
+ }
45
+ const opcode = bytes[0];
46
+ if (!isFileTransferOpcode(opcode)) {
47
+ return null;
48
+ }
49
+ const requestIdLength = bytes[1];
50
+ if (requestIdLength === 0 || requestIdLength > bytes.byteLength - 2) {
51
+ return null;
52
+ }
53
+ const requestId = decodeRequestId(bytes.subarray(2, 2 + requestIdLength));
54
+ const body = bytes.subarray(2 + requestIdLength);
55
+ if (opcode === FileTransferOpcode.FileBegin) {
56
+ if (body.byteLength < 2) {
57
+ return null;
58
+ }
59
+ const view = new DataView(body.buffer, body.byteOffset, body.byteLength);
60
+ const metadataLength = view.getUint16(0);
61
+ if (metadataLength !== body.byteLength - 2) {
62
+ return null;
63
+ }
64
+ const metadataBytes = body.subarray(2);
65
+ const result = FileBeginMetadataSchema.safeParse(decodeJsonPayload(metadataBytes));
66
+ return result.success
67
+ ? { opcode, requestId, metadata: result.data, payload: new Uint8Array() }
68
+ : null;
69
+ }
70
+ if (opcode === FileTransferOpcode.FileChunk) {
71
+ return { opcode, requestId, payload: body };
72
+ }
73
+ if (body.byteLength !== 0) {
74
+ return null;
75
+ }
76
+ return { opcode, requestId, payload: new Uint8Array() };
77
+ }
78
+ function isFileTransferOpcode(value) {
79
+ return (value === FileTransferOpcode.FileBegin ||
80
+ value === FileTransferOpcode.FileChunk ||
81
+ value === FileTransferOpcode.FileEnd);
82
+ }
83
+ function encodeJsonPayload(value) {
84
+ return new TextEncoder().encode(JSON.stringify(value));
85
+ }
86
+ function encodeRequestId(requestId) {
87
+ const bytes = new TextEncoder().encode(requestId);
88
+ if (bytes.byteLength === 0) {
89
+ throw new RangeError("File transfer requestId is required");
90
+ }
91
+ if (bytes.byteLength > 0xff) {
92
+ throw new RangeError("File transfer requestId is too long");
93
+ }
94
+ return bytes;
95
+ }
96
+ function decodeRequestId(bytes) {
97
+ return new TextDecoder().decode(bytes);
98
+ }
99
+ function decodeJsonPayload(bytes) {
100
+ try {
101
+ return JSON.parse(new TextDecoder().decode(bytes));
102
+ }
103
+ catch {
104
+ return null;
105
+ }
106
+ }
107
+ //# sourceMappingURL=file-transfer.js.map
@@ -0,0 +1,4 @@
1
+ export * from "./demux.js";
2
+ export * from "./file-transfer.js";
3
+ export * from "./terminal.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,4 @@
1
+ export * from "./demux.js";
2
+ export * from "./file-transfer.js";
3
+ export * from "./terminal.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,31 @@
1
+ import { z } from "zod";
2
+ import { TerminalStateSchema } from "../messages.js";
3
+ export declare const TerminalStreamResizeSchema: z.ZodObject<{
4
+ rows: z.ZodNumber;
5
+ cols: z.ZodNumber;
6
+ }, z.core.$strip>;
7
+ export declare const TerminalStreamOpcode: {
8
+ readonly Output: 1;
9
+ readonly Input: 2;
10
+ readonly Resize: 3;
11
+ readonly Snapshot: 4;
12
+ readonly Restore: 5;
13
+ };
14
+ export type TerminalStreamOpcode = (typeof TerminalStreamOpcode)[keyof typeof TerminalStreamOpcode];
15
+ export interface TerminalStreamFrame {
16
+ opcode: TerminalStreamOpcode;
17
+ slot: number;
18
+ payload: Uint8Array;
19
+ }
20
+ export declare function asUint8Array(data: unknown): Uint8Array | null;
21
+ export declare function encodeTerminalStreamFrame(input: {
22
+ opcode: TerminalStreamOpcode;
23
+ slot: number;
24
+ payload?: Uint8Array | ArrayBuffer | string;
25
+ }): Uint8Array;
26
+ export declare function decodeTerminalStreamFrame(bytes: Uint8Array): TerminalStreamFrame | null;
27
+ export declare function encodeTerminalSnapshotPayload(state: z.infer<typeof TerminalStateSchema>): Uint8Array;
28
+ export declare function decodeTerminalSnapshotPayload(bytes: Uint8Array): z.infer<typeof TerminalStateSchema> | null;
29
+ export declare function encodeTerminalResizePayload(input: z.infer<typeof TerminalStreamResizeSchema>): Uint8Array;
30
+ export declare function decodeTerminalResizePayload(bytes: Uint8Array): z.infer<typeof TerminalStreamResizeSchema> | null;
31
+ //# sourceMappingURL=terminal.d.ts.map
@@ -0,0 +1,99 @@
1
+ import { z } from "zod";
2
+ import { TerminalStateSchema } from "../messages.js";
3
+ export const TerminalStreamResizeSchema = z.object({
4
+ rows: z.number().int().positive(),
5
+ cols: z.number().int().positive(),
6
+ });
7
+ export const TerminalStreamOpcode = {
8
+ Output: 0x01,
9
+ Input: 0x02,
10
+ Resize: 0x03,
11
+ Snapshot: 0x04,
12
+ Restore: 0x05,
13
+ };
14
+ export function asUint8Array(data) {
15
+ if (typeof data === "string") {
16
+ if (typeof TextEncoder !== "undefined") {
17
+ return new TextEncoder().encode(data);
18
+ }
19
+ if (typeof Buffer !== "undefined") {
20
+ return new Uint8Array(Buffer.from(data, "utf8"));
21
+ }
22
+ const out = new Uint8Array(data.length);
23
+ for (let index = 0; index < data.length; index += 1) {
24
+ out[index] = data.charCodeAt(index) & 0xff;
25
+ }
26
+ return out;
27
+ }
28
+ if (data instanceof Uint8Array) {
29
+ return data;
30
+ }
31
+ if (typeof ArrayBuffer !== "undefined" && data instanceof ArrayBuffer) {
32
+ return new Uint8Array(data);
33
+ }
34
+ if (ArrayBuffer.isView(data)) {
35
+ return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
36
+ }
37
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(data)) {
38
+ return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
39
+ }
40
+ return null;
41
+ }
42
+ function isTerminalStreamOpcode(value) {
43
+ return (value === TerminalStreamOpcode.Output ||
44
+ value === TerminalStreamOpcode.Input ||
45
+ value === TerminalStreamOpcode.Resize ||
46
+ value === TerminalStreamOpcode.Snapshot ||
47
+ value === TerminalStreamOpcode.Restore);
48
+ }
49
+ export function encodeTerminalStreamFrame(input) {
50
+ const payload = asUint8Array(input.payload ?? new Uint8Array(0)) ?? new Uint8Array(0);
51
+ const bytes = new Uint8Array(2 + payload.byteLength);
52
+ bytes[0] = input.opcode;
53
+ bytes[1] = input.slot & 0xff;
54
+ bytes.set(payload, 2);
55
+ return bytes;
56
+ }
57
+ export function decodeTerminalStreamFrame(bytes) {
58
+ if (bytes.byteLength < 2) {
59
+ return null;
60
+ }
61
+ const opcode = bytes[0];
62
+ if (!isTerminalStreamOpcode(opcode)) {
63
+ return null;
64
+ }
65
+ return {
66
+ opcode,
67
+ slot: bytes[1],
68
+ payload: bytes.subarray(2),
69
+ };
70
+ }
71
+ export function encodeTerminalSnapshotPayload(state) {
72
+ return encodeJsonPayload(state);
73
+ }
74
+ export function decodeTerminalSnapshotPayload(bytes) {
75
+ const parsed = decodeJsonPayload(bytes);
76
+ const result = TerminalStateSchema.safeParse(parsed);
77
+ return result.success ? result.data : null;
78
+ }
79
+ export function encodeTerminalResizePayload(input) {
80
+ return encodeJsonPayload(input);
81
+ }
82
+ export function decodeTerminalResizePayload(bytes) {
83
+ const parsed = decodeJsonPayload(bytes);
84
+ const result = TerminalStreamResizeSchema.safeParse(parsed);
85
+ return result.success ? result.data : null;
86
+ }
87
+ function encodeJsonPayload(value) {
88
+ return new TextEncoder().encode(JSON.stringify(value));
89
+ }
90
+ function decodeJsonPayload(bytes) {
91
+ try {
92
+ const text = new TextDecoder().decode(bytes);
93
+ return JSON.parse(text);
94
+ }
95
+ catch {
96
+ return null;
97
+ }
98
+ }
99
+ //# sourceMappingURL=terminal.js.map
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Validate that a string is a valid git branch name slug.
3
+ * Must be lowercase alphanumeric with hyphens and forward slashes only.
4
+ */
5
+ export declare function validateBranchSlug(slug: string): {
6
+ valid: boolean;
7
+ error?: string;
8
+ };
9
+ export declare const MAX_SLUG_LENGTH = 50;
10
+ /**
11
+ * Convert a string to kebab-case for branch names.
12
+ */
13
+ export declare function slugify(input: string): string;
14
+ //# sourceMappingURL=branch-slug.d.ts.map
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Validate that a string is a valid git branch name slug.
3
+ * Must be lowercase alphanumeric with hyphens and forward slashes only.
4
+ */
5
+ export function validateBranchSlug(slug) {
6
+ if (!slug || slug.length === 0) {
7
+ return { valid: false, error: "Branch name cannot be empty" };
8
+ }
9
+ if (slug.length > 100) {
10
+ return { valid: false, error: "Branch name too long (max 100 characters)" };
11
+ }
12
+ const validPattern = /^[a-z0-9-/]+$/;
13
+ if (!validPattern.test(slug)) {
14
+ return {
15
+ valid: false,
16
+ error: "Branch name must contain only lowercase letters, numbers, hyphens, and forward slashes",
17
+ };
18
+ }
19
+ if (slug.startsWith("-") || slug.endsWith("-")) {
20
+ return {
21
+ valid: false,
22
+ error: "Branch name cannot start or end with a hyphen",
23
+ };
24
+ }
25
+ if (slug.includes("--")) {
26
+ return { valid: false, error: "Branch name cannot have consecutive hyphens" };
27
+ }
28
+ return { valid: true };
29
+ }
30
+ export const MAX_SLUG_LENGTH = 50;
31
+ /**
32
+ * Convert a string to kebab-case for branch names.
33
+ */
34
+ export function slugify(input) {
35
+ const slug = input
36
+ .toLowerCase()
37
+ .replace(/[^a-z0-9]+/g, "-")
38
+ .replace(/^-+|-+$/g, "");
39
+ if (slug.length <= MAX_SLUG_LENGTH) {
40
+ return slug;
41
+ }
42
+ const truncated = slug.slice(0, MAX_SLUG_LENGTH);
43
+ const lastHyphen = truncated.lastIndexOf("-");
44
+ if (lastHyphen > MAX_SLUG_LENGTH / 2) {
45
+ return truncated.slice(0, lastHyphen);
46
+ }
47
+ return truncated.replace(/-+$/, "");
48
+ }
49
+ //# sourceMappingURL=branch-slug.js.map
@@ -0,0 +1,7 @@
1
+ import { z } from "zod";
2
+ export declare const BrowserAutomationHostCapabilitySchema: z.ZodObject<{
3
+ supportedCommands: z.ZodPipe<z.ZodArray<z.ZodString>, z.ZodTransform<("type" | "select" | "fill" | "logs" | "list_tabs" | "new_tab" | "snapshot" | "click" | "wait" | "keypress" | "navigate" | "back" | "forward" | "reload" | "screenshot" | "upload" | "hover" | "drag" | "evaluate" | "inspect" | "network" | "scroll" | "resize" | "close_tab")[], string[]>>;
4
+ hostKind: z.ZodDefault<z.ZodString>;
5
+ }, z.core.$loose>;
6
+ export type BrowserAutomationHostCapability = z.infer<typeof BrowserAutomationHostCapabilitySchema>;
7
+ //# sourceMappingURL=capabilities.d.ts.map
@@ -0,0 +1,31 @@
1
+ import { z } from "zod";
2
+ import { BROWSER_AUTOMATION_COMMAND_NAMES, } from "./rpc-schemas.js";
3
+ const KNOWN_BROWSER_AUTOMATION_COMMAND_NAMES = new Set(BROWSER_AUTOMATION_COMMAND_NAMES);
4
+ export const BrowserAutomationHostCapabilitySchema = z
5
+ .object({
6
+ supportedCommands: z.array(z.string().min(1)).transform((commands, context) => {
7
+ const supportedCommands = [];
8
+ const seen = new Set();
9
+ for (const command of commands) {
10
+ if (!isKnownBrowserAutomationCommandName(command) || seen.has(command)) {
11
+ continue;
12
+ }
13
+ seen.add(command);
14
+ supportedCommands.push(command);
15
+ }
16
+ if (supportedCommands.length === 0) {
17
+ context.addIssue({
18
+ code: "custom",
19
+ message: "supportedCommands must include at least one known browser automation command",
20
+ });
21
+ return z.NEVER;
22
+ }
23
+ return supportedCommands;
24
+ }),
25
+ hostKind: z.string().min(1).default("browser host"),
26
+ })
27
+ .passthrough();
28
+ function isKnownBrowserAutomationCommandName(value) {
29
+ return KNOWN_BROWSER_AUTOMATION_COMMAND_NAMES.has(value);
30
+ }
31
+ //# sourceMappingURL=capabilities.js.map