@harness-control/protocol 0.4.8 → 0.4.10

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.
File without changes
@@ -0,0 +1,46 @@
1
+ import { z } from "zod";
2
+ export declare const hcpConversationRequestPayloadSchema: z.ZodObject<{
3
+ session_id: z.ZodString;
4
+ operation: z.ZodDiscriminatedUnion<[z.ZodObject<{
5
+ kind: z.ZodLiteral<"read">;
6
+ }, z.core.$strict>, z.ZodObject<{
7
+ kind: z.ZodLiteral<"rollback">;
8
+ num_turns: z.ZodNumber;
9
+ expected_history_hash: z.ZodString;
10
+ }, z.core.$strict>, z.ZodObject<{
11
+ kind: z.ZodLiteral<"retire">;
12
+ }, z.core.$strict>], "kind">;
13
+ }, z.core.$strict>;
14
+ export declare const nativeConversationHistorySchema: z.ZodObject<{
15
+ history_hash: z.ZodString;
16
+ turn_count: z.ZodNumber;
17
+ truncated: z.ZodBoolean;
18
+ turns: z.ZodArray<z.ZodObject<{
19
+ id: z.ZodString;
20
+ status: z.ZodString;
21
+ items: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
22
+ }, z.core.$strict>>;
23
+ }, z.core.$strict>;
24
+ export declare const hcpConversationResultPayloadSchema: z.ZodObject<{
25
+ command_id: z.ZodString;
26
+ session_id: z.ZodString;
27
+ operation: z.ZodEnum<{
28
+ read: "read";
29
+ rollback: "rollback";
30
+ retire: "retire";
31
+ }>;
32
+ filesystem_undo: z.ZodLiteral<false>;
33
+ history: z.ZodOptional<z.ZodObject<{
34
+ history_hash: z.ZodString;
35
+ turn_count: z.ZodNumber;
36
+ truncated: z.ZodBoolean;
37
+ turns: z.ZodArray<z.ZodObject<{
38
+ id: z.ZodString;
39
+ status: z.ZodString;
40
+ items: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
41
+ }, z.core.$strict>>;
42
+ }, z.core.$strict>>;
43
+ }, z.core.$strict>;
44
+ export type HcpConversationRequestPayload = z.infer<typeof hcpConversationRequestPayloadSchema>;
45
+ export type HcpConversationResultPayload = z.infer<typeof hcpConversationResultPayloadSchema>;
46
+ //# sourceMappingURL=conversation.d.ts.map
@@ -0,0 +1,12 @@
1
+ import { z } from "zod";
2
+ export const hcpConversationRequestPayloadSchema = z.object({ session_id: z.string().min(1).max(512),
3
+ operation: z.discriminatedUnion("kind", [z.object({ kind: z.literal("read") }).strict(),
4
+ z.object({ kind: z.literal("rollback"), num_turns: z.number().int().min(1).max(100), expected_history_hash: z.string().regex(/^[a-f0-9]{64}$/) }).strict(),
5
+ z.object({ kind: z.literal("retire") }).strict()]) }).strict();
6
+ export const nativeConversationHistorySchema = z.object({ history_hash: z.string().regex(/^[a-f0-9]{64}$/),
7
+ turn_count: z.number().int().nonnegative(), truncated: z.boolean(),
8
+ turns: z.array(z.object({ id: z.string(), status: z.string(), items: z.array(z.record(z.string(), z.json())) }).strict()).max(100) }).strict();
9
+ export const hcpConversationResultPayloadSchema = z.object({ command_id: z.string().min(1), session_id: z.string().min(1),
10
+ operation: z.enum(["read", "rollback", "retire"]), filesystem_undo: z.literal(false),
11
+ history: nativeConversationHistorySchema.optional() }).strict();
12
+ //# sourceMappingURL=conversation.js.map
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { type HcpAccountsReadPayload, type HcpAccountsSnapshotPayload } from "./accounts.js";
2
2
  export * from "./accounts.js";
3
+ import { type HcpConversationRequestPayload, type HcpConversationResultPayload } from "./conversation.js";
4
+ export * from "./conversation.js";
3
5
  import { z } from "zod";
4
6
  export declare const HCP_VERSION: "hcp.v0";
5
7
  export declare const HCP_METADATA_MAX_ENCODED_BYTES: number;
@@ -7,11 +9,11 @@ export declare const HCP_PAYLOAD_MAX_ENCODED_BYTES: number;
7
9
  export declare const HCP_MESSAGE_MAX_ENCODED_BYTES: number;
8
10
  export type HcpVersion = typeof HCP_VERSION;
9
11
  export declare const HOST_LIFECYCLE_MESSAGE_TYPES: readonly ["host.accounts.read", "host.accounts.snapshot", "host.hello", "host.accepted", "host.rejected", "host.heartbeat", "host.capabilities.updated", "host.replay.unavailable", "host.workspaces.request", "host.workspaces.result"];
10
- export declare const CONTROL_PLANE_COMMAND_MESSAGE_TYPES: readonly ["harness.session.start", "harness.session.snapshot.request", "harness.turn.send", "harness.turn.cancel", "harness.session.stop", "harness.approval.respond", "harness.input.respond", "tool_servers.detach"];
12
+ export declare const CONTROL_PLANE_COMMAND_MESSAGE_TYPES: readonly ["harness.session.start", "harness.conversation.request", "harness.session.snapshot.request", "harness.turn.send", "harness.turn.cancel", "harness.session.stop", "harness.approval.respond", "harness.input.respond", "tool_servers.detach"];
11
13
  export declare const COMMAND_ACK_MESSAGE_TYPES: readonly ["hcp.command.ack", "hcp.command.nack"];
12
14
  export declare const LOCAL_ACTION_MESSAGE_TYPES: readonly ["local.action.request", "local.action.response", "local.action.error"];
13
15
  export declare const RUNTIME_EVENT_MESSAGE_TYPES: readonly ["harness.event"];
14
- export declare const SESSION_SNAPSHOT_MESSAGE_TYPES: readonly ["harness.session.snapshot"];
16
+ export declare const SESSION_SNAPSHOT_MESSAGE_TYPES: readonly ["harness.session.snapshot", "harness.conversation.result"];
15
17
  export declare const KNOWN_HCP_EVENT_TYPES: readonly ["session.started", "session.configured", "session.state.changed", "session.exited", "thread.started", "thread.state.changed", "thread.metadata.updated", "thread.token_usage.updated", "thread.realtime.started", "thread.realtime.item_added", "thread.realtime.audio_delta", "thread.realtime.error", "thread.realtime.closed", "auth.status", "account.updated", "account.rate_limits.updated", "turn.started", "turn.completed", "turn.failed", "turn.aborted", "turn.cancelled", "turn.plan.updated", "turn.proposed.delta", "turn.proposed.completed", "turn.diff.updated", "item.started", "item.updated", "item.completed", "content.delta", "reasoning.delta", "command.started", "command.completed", "local_capability.lease.created", "local_capability.lease.revoked", "local_capability.lease.expired", "local_capability.action.started", "local_capability.action.completed", "local_capability.action.failed", "file_change.started", "file_change.completed", "mcp_tool.started", "mcp_tool.completed", "mcp.status.updated", "mcp.oauth.completed", "approval.requested", "approval.resolved", "input.requested", "input.resolved", "request.opened", "request.resolved", "user_input.requested", "user_input.resolved", "task.started", "task.progress", "task.completed", "hook.started", "hook.progress", "hook.completed", "tool.progress", "tool.summary", "model.rerouted", "config.warning", "deprecation.notice", "files.persisted", "workspace.preflight.completed", "usage.updated", "runtime.warning", "runtime.error"];
16
18
  export type HostLifecycleMessageType = (typeof HOST_LIFECYCLE_MESSAGE_TYPES)[number];
17
19
  export type ControlPlaneCommandMessageType = (typeof CONTROL_PLANE_COMMAND_MESSAGE_TYPES)[number];
@@ -117,12 +119,16 @@ export type HarnessModel = {
117
119
  is_default?: boolean;
118
120
  capabilities: {
119
121
  option_descriptors: HarnessOptionDescriptor[];
122
+ image_input?: boolean;
120
123
  };
121
124
  };
122
125
  export type HarnessExecutionCapabilities = {
123
126
  streaming: boolean;
124
127
  multi_turn: boolean;
125
128
  session_continuation: boolean;
129
+ plan_mode?: boolean;
130
+ native_history?: boolean;
131
+ conversation_rollback?: boolean;
126
132
  sandbox_modes: Array<"read_only" | "workspace_write" | "danger_full_access">;
127
133
  approval_policies: Array<"ask" | "auto_edits" | "full_access">;
128
134
  };
@@ -281,6 +287,13 @@ export type HcpSessionStartPayload = {
281
287
  workspace_preflight?: WorkspacePreflight;
282
288
  local_capability_lease?: LocalCapabilityLease;
283
289
  mcp_servers: McpServerAttachment[];
290
+ first_turn?: {
291
+ turn_id: string;
292
+ input: string;
293
+ not_after: string;
294
+ mode?: "execute" | "plan";
295
+ images?: HcpImageInput[];
296
+ };
284
297
  };
285
298
  export type HcpSessionSnapshotRequestPayload = {
286
299
  session_id: string;
@@ -289,6 +302,8 @@ export type HcpTurnSendPayload = {
289
302
  session_id: string;
290
303
  turn_id: string;
291
304
  input: string;
305
+ mode?: "execute" | "plan";
306
+ images?: HcpImageInput[];
292
307
  model_selection?: HarnessModelSelection;
293
308
  };
294
309
  export type HcpTurnCancelPayload = {
@@ -774,6 +789,7 @@ export declare const harnessModelSchema: z.ZodObject<{
774
789
  current_value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean, z.ZodNumber]>>;
775
790
  prompt_injected_values: z.ZodOptional<z.ZodArray<z.ZodString>>;
776
791
  }, z.core.$strict>>;
792
+ image_input: z.ZodOptional<z.ZodBoolean>;
777
793
  }, z.core.$strict>;
778
794
  }, z.core.$strict>;
779
795
  export declare const harnessProviderSnapshotSchema: z.ZodObject<{
@@ -781,6 +797,9 @@ export declare const harnessProviderSnapshotSchema: z.ZodObject<{
781
797
  streaming: z.ZodBoolean;
782
798
  multi_turn: z.ZodBoolean;
783
799
  session_continuation: z.ZodBoolean;
800
+ plan_mode: z.ZodOptional<z.ZodBoolean>;
801
+ native_history: z.ZodOptional<z.ZodBoolean>;
802
+ conversation_rollback: z.ZodOptional<z.ZodBoolean>;
784
803
  sandbox_modes: z.ZodArray<z.ZodEnum<{
785
804
  read_only: "read_only";
786
805
  workspace_write: "workspace_write";
@@ -846,6 +865,7 @@ export declare const harnessProviderSnapshotSchema: z.ZodObject<{
846
865
  current_value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean, z.ZodNumber]>>;
847
866
  prompt_injected_values: z.ZodOptional<z.ZodArray<z.ZodString>>;
848
867
  }, z.core.$strict>>;
868
+ image_input: z.ZodOptional<z.ZodBoolean>;
849
869
  }, z.core.$strict>;
850
870
  }, z.core.$strict>>;
851
871
  hidden_models: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -962,6 +982,9 @@ export declare const hcpHostCapabilitiesUpdatedPayloadSchema: z.ZodObject<{
962
982
  streaming: z.ZodBoolean;
963
983
  multi_turn: z.ZodBoolean;
964
984
  session_continuation: z.ZodBoolean;
985
+ plan_mode: z.ZodOptional<z.ZodBoolean>;
986
+ native_history: z.ZodOptional<z.ZodBoolean>;
987
+ conversation_rollback: z.ZodOptional<z.ZodBoolean>;
965
988
  sandbox_modes: z.ZodArray<z.ZodEnum<{
966
989
  read_only: "read_only";
967
990
  workspace_write: "workspace_write";
@@ -1027,6 +1050,7 @@ export declare const hcpHostCapabilitiesUpdatedPayloadSchema: z.ZodObject<{
1027
1050
  current_value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean, z.ZodNumber]>>;
1028
1051
  prompt_injected_values: z.ZodOptional<z.ZodArray<z.ZodString>>;
1029
1052
  }, z.core.$strict>>;
1053
+ image_input: z.ZodOptional<z.ZodBoolean>;
1030
1054
  }, z.core.$strict>;
1031
1055
  }, z.core.$strict>>;
1032
1056
  hidden_models: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -1253,6 +1277,18 @@ export declare const mcpServerAttachmentSchema: z.ZodDiscriminatedUnion<[z.ZodOb
1253
1277
  allowed_tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
1254
1278
  denied_tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
1255
1279
  }, z.core.$strict>], "transport">;
1280
+ export declare const HARNESS_IMAGE_MAX_BYTES: number;
1281
+ export declare const HARNESS_IMAGE_MIME_TYPES: readonly ["image/gif", "image/jpeg", "image/png", "image/webp"];
1282
+ export declare const hcpImageInputSchema: z.ZodObject<{
1283
+ mime_type: z.ZodEnum<{
1284
+ "image/gif": "image/gif";
1285
+ "image/jpeg": "image/jpeg";
1286
+ "image/png": "image/png";
1287
+ "image/webp": "image/webp";
1288
+ }>;
1289
+ data_base64: z.ZodString;
1290
+ }, z.core.$strict>;
1291
+ export type HcpImageInput = z.infer<typeof hcpImageInputSchema>;
1256
1292
  export declare const hcpSessionStartPayloadSchema: z.ZodObject<{
1257
1293
  session_id: z.ZodString;
1258
1294
  workspace_id: z.ZodString;
@@ -1344,6 +1380,24 @@ export declare const hcpSessionStartPayloadSchema: z.ZodObject<{
1344
1380
  allowed_tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
1345
1381
  denied_tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
1346
1382
  }, z.core.$strict>], "transport">>;
1383
+ first_turn: z.ZodOptional<z.ZodObject<{
1384
+ turn_id: z.ZodString;
1385
+ input: z.ZodString;
1386
+ not_after: z.ZodString;
1387
+ mode: z.ZodOptional<z.ZodEnum<{
1388
+ execute: "execute";
1389
+ plan: "plan";
1390
+ }>>;
1391
+ images: z.ZodOptional<z.ZodArray<z.ZodObject<{
1392
+ mime_type: z.ZodEnum<{
1393
+ "image/gif": "image/gif";
1394
+ "image/jpeg": "image/jpeg";
1395
+ "image/png": "image/png";
1396
+ "image/webp": "image/webp";
1397
+ }>;
1398
+ data_base64: z.ZodString;
1399
+ }, z.core.$strict>>>;
1400
+ }, z.core.$strict>>;
1347
1401
  }, z.core.$strict>;
1348
1402
  export declare const hcpSessionSnapshotRequestPayloadSchema: z.ZodObject<{
1349
1403
  session_id: z.ZodString;
@@ -1352,6 +1406,19 @@ export declare const hcpTurnSendPayloadSchema: z.ZodObject<{
1352
1406
  session_id: z.ZodString;
1353
1407
  turn_id: z.ZodString;
1354
1408
  input: z.ZodString;
1409
+ mode: z.ZodOptional<z.ZodEnum<{
1410
+ execute: "execute";
1411
+ plan: "plan";
1412
+ }>>;
1413
+ images: z.ZodOptional<z.ZodArray<z.ZodObject<{
1414
+ mime_type: z.ZodEnum<{
1415
+ "image/gif": "image/gif";
1416
+ "image/jpeg": "image/jpeg";
1417
+ "image/png": "image/png";
1418
+ "image/webp": "image/webp";
1419
+ }>;
1420
+ data_base64: z.ZodString;
1421
+ }, z.core.$strict>>>;
1355
1422
  model_selection: z.ZodOptional<z.ZodObject<{
1356
1423
  model: z.ZodString;
1357
1424
  options: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -3397,6 +3464,9 @@ export declare const hcpHostCapabilitiesUpdatedMessageSchema: z.ZodObject<{
3397
3464
  streaming: z.ZodBoolean;
3398
3465
  multi_turn: z.ZodBoolean;
3399
3466
  session_continuation: z.ZodBoolean;
3467
+ plan_mode: z.ZodOptional<z.ZodBoolean>;
3468
+ native_history: z.ZodOptional<z.ZodBoolean>;
3469
+ conversation_rollback: z.ZodOptional<z.ZodBoolean>;
3400
3470
  sandbox_modes: z.ZodArray<z.ZodEnum<{
3401
3471
  read_only: "read_only";
3402
3472
  workspace_write: "workspace_write";
@@ -3462,6 +3532,7 @@ export declare const hcpHostCapabilitiesUpdatedMessageSchema: z.ZodObject<{
3462
3532
  current_value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean, z.ZodNumber]>>;
3463
3533
  prompt_injected_values: z.ZodOptional<z.ZodArray<z.ZodString>>;
3464
3534
  }, z.core.$strict>>;
3535
+ image_input: z.ZodOptional<z.ZodBoolean>;
3465
3536
  }, z.core.$strict>;
3466
3537
  }, z.core.$strict>>;
3467
3538
  hidden_models: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -3629,6 +3700,24 @@ export declare const hcpSessionStartMessageSchema: z.ZodObject<{
3629
3700
  allowed_tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
3630
3701
  denied_tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
3631
3702
  }, z.core.$strict>], "transport">>;
3703
+ first_turn: z.ZodOptional<z.ZodObject<{
3704
+ turn_id: z.ZodString;
3705
+ input: z.ZodString;
3706
+ not_after: z.ZodString;
3707
+ mode: z.ZodOptional<z.ZodEnum<{
3708
+ execute: "execute";
3709
+ plan: "plan";
3710
+ }>>;
3711
+ images: z.ZodOptional<z.ZodArray<z.ZodObject<{
3712
+ mime_type: z.ZodEnum<{
3713
+ "image/gif": "image/gif";
3714
+ "image/jpeg": "image/jpeg";
3715
+ "image/png": "image/png";
3716
+ "image/webp": "image/webp";
3717
+ }>;
3718
+ data_base64: z.ZodString;
3719
+ }, z.core.$strict>>>;
3720
+ }, z.core.$strict>>;
3632
3721
  }, z.core.$strict>;
3633
3722
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
3634
3723
  }, z.core.$strict>;
@@ -3721,6 +3810,19 @@ export declare const hcpTurnSendMessageSchema: z.ZodObject<{
3721
3810
  session_id: z.ZodString;
3722
3811
  turn_id: z.ZodString;
3723
3812
  input: z.ZodString;
3813
+ mode: z.ZodOptional<z.ZodEnum<{
3814
+ execute: "execute";
3815
+ plan: "plan";
3816
+ }>>;
3817
+ images: z.ZodOptional<z.ZodArray<z.ZodObject<{
3818
+ mime_type: z.ZodEnum<{
3819
+ "image/gif": "image/gif";
3820
+ "image/jpeg": "image/jpeg";
3821
+ "image/png": "image/png";
3822
+ "image/webp": "image/webp";
3823
+ }>;
3824
+ data_base64: z.ZodString;
3825
+ }, z.core.$strict>>>;
3724
3826
  model_selection: z.ZodOptional<z.ZodObject<{
3725
3827
  model: z.ZodString;
3726
3828
  options: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -5028,7 +5130,97 @@ export declare const hcpAccountsSnapshotMessageSchema: z.ZodObject<{
5028
5130
  }, z.core.$strict>;
5029
5131
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
5030
5132
  }, z.core.$strict>;
5133
+ export declare const hcpConversationRequestMessageSchema: z.ZodObject<{
5134
+ id: z.ZodString;
5135
+ type: z.ZodLiteral<"harness.conversation.request">;
5136
+ version: z.ZodLiteral<"hcp.v0">;
5137
+ sent_at: z.ZodString;
5138
+ payload: z.ZodObject<{
5139
+ session_id: z.ZodString;
5140
+ operation: z.ZodDiscriminatedUnion<[z.ZodObject<{
5141
+ kind: z.ZodLiteral<"read">;
5142
+ }, z.core.$strict>, z.ZodObject<{
5143
+ kind: z.ZodLiteral<"rollback">;
5144
+ num_turns: z.ZodNumber;
5145
+ expected_history_hash: z.ZodString;
5146
+ }, z.core.$strict>, z.ZodObject<{
5147
+ kind: z.ZodLiteral<"retire">;
5148
+ }, z.core.$strict>], "kind">;
5149
+ }, z.core.$strict>;
5150
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
5151
+ }, z.core.$strict>;
5152
+ export declare const hcpConversationResultMessageSchema: z.ZodObject<{
5153
+ id: z.ZodString;
5154
+ type: z.ZodLiteral<"harness.conversation.result">;
5155
+ version: z.ZodLiteral<"hcp.v0">;
5156
+ sent_at: z.ZodString;
5157
+ payload: z.ZodObject<{
5158
+ command_id: z.ZodString;
5159
+ session_id: z.ZodString;
5160
+ operation: z.ZodEnum<{
5161
+ read: "read";
5162
+ rollback: "rollback";
5163
+ retire: "retire";
5164
+ }>;
5165
+ filesystem_undo: z.ZodLiteral<false>;
5166
+ history: z.ZodOptional<z.ZodObject<{
5167
+ history_hash: z.ZodString;
5168
+ turn_count: z.ZodNumber;
5169
+ truncated: z.ZodBoolean;
5170
+ turns: z.ZodArray<z.ZodObject<{
5171
+ id: z.ZodString;
5172
+ status: z.ZodString;
5173
+ items: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
5174
+ }, z.core.$strict>>;
5175
+ }, z.core.$strict>>;
5176
+ }, z.core.$strict>;
5177
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
5178
+ }, z.core.$strict>;
5031
5179
  export declare const hcpMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
5180
+ id: z.ZodString;
5181
+ type: z.ZodLiteral<"harness.conversation.request">;
5182
+ version: z.ZodLiteral<"hcp.v0">;
5183
+ sent_at: z.ZodString;
5184
+ payload: z.ZodObject<{
5185
+ session_id: z.ZodString;
5186
+ operation: z.ZodDiscriminatedUnion<[z.ZodObject<{
5187
+ kind: z.ZodLiteral<"read">;
5188
+ }, z.core.$strict>, z.ZodObject<{
5189
+ kind: z.ZodLiteral<"rollback">;
5190
+ num_turns: z.ZodNumber;
5191
+ expected_history_hash: z.ZodString;
5192
+ }, z.core.$strict>, z.ZodObject<{
5193
+ kind: z.ZodLiteral<"retire">;
5194
+ }, z.core.$strict>], "kind">;
5195
+ }, z.core.$strict>;
5196
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
5197
+ }, z.core.$strict>, z.ZodObject<{
5198
+ id: z.ZodString;
5199
+ type: z.ZodLiteral<"harness.conversation.result">;
5200
+ version: z.ZodLiteral<"hcp.v0">;
5201
+ sent_at: z.ZodString;
5202
+ payload: z.ZodObject<{
5203
+ command_id: z.ZodString;
5204
+ session_id: z.ZodString;
5205
+ operation: z.ZodEnum<{
5206
+ read: "read";
5207
+ rollback: "rollback";
5208
+ retire: "retire";
5209
+ }>;
5210
+ filesystem_undo: z.ZodLiteral<false>;
5211
+ history: z.ZodOptional<z.ZodObject<{
5212
+ history_hash: z.ZodString;
5213
+ turn_count: z.ZodNumber;
5214
+ truncated: z.ZodBoolean;
5215
+ turns: z.ZodArray<z.ZodObject<{
5216
+ id: z.ZodString;
5217
+ status: z.ZodString;
5218
+ items: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
5219
+ }, z.core.$strict>>;
5220
+ }, z.core.$strict>>;
5221
+ }, z.core.$strict>;
5222
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
5223
+ }, z.core.$strict>, z.ZodObject<{
5032
5224
  id: z.ZodString;
5033
5225
  type: z.ZodLiteral<"host.accounts.read">;
5034
5226
  version: z.ZodLiteral<"hcp.v0">;
@@ -5255,6 +5447,9 @@ export declare const hcpMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
5255
5447
  streaming: z.ZodBoolean;
5256
5448
  multi_turn: z.ZodBoolean;
5257
5449
  session_continuation: z.ZodBoolean;
5450
+ plan_mode: z.ZodOptional<z.ZodBoolean>;
5451
+ native_history: z.ZodOptional<z.ZodBoolean>;
5452
+ conversation_rollback: z.ZodOptional<z.ZodBoolean>;
5258
5453
  sandbox_modes: z.ZodArray<z.ZodEnum<{
5259
5454
  read_only: "read_only";
5260
5455
  workspace_write: "workspace_write";
@@ -5320,6 +5515,7 @@ export declare const hcpMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
5320
5515
  current_value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean, z.ZodNumber]>>;
5321
5516
  prompt_injected_values: z.ZodOptional<z.ZodArray<z.ZodString>>;
5322
5517
  }, z.core.$strict>>;
5518
+ image_input: z.ZodOptional<z.ZodBoolean>;
5323
5519
  }, z.core.$strict>;
5324
5520
  }, z.core.$strict>>;
5325
5521
  hidden_models: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -5485,6 +5681,24 @@ export declare const hcpMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
5485
5681
  allowed_tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
5486
5682
  denied_tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
5487
5683
  }, z.core.$strict>], "transport">>;
5684
+ first_turn: z.ZodOptional<z.ZodObject<{
5685
+ turn_id: z.ZodString;
5686
+ input: z.ZodString;
5687
+ not_after: z.ZodString;
5688
+ mode: z.ZodOptional<z.ZodEnum<{
5689
+ execute: "execute";
5690
+ plan: "plan";
5691
+ }>>;
5692
+ images: z.ZodOptional<z.ZodArray<z.ZodObject<{
5693
+ mime_type: z.ZodEnum<{
5694
+ "image/gif": "image/gif";
5695
+ "image/jpeg": "image/jpeg";
5696
+ "image/png": "image/png";
5697
+ "image/webp": "image/webp";
5698
+ }>;
5699
+ data_base64: z.ZodString;
5700
+ }, z.core.$strict>>>;
5701
+ }, z.core.$strict>>;
5488
5702
  }, z.core.$strict>;
5489
5703
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
5490
5704
  }, z.core.$strict>, z.ZodObject<{
@@ -5574,6 +5788,19 @@ export declare const hcpMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
5574
5788
  session_id: z.ZodString;
5575
5789
  turn_id: z.ZodString;
5576
5790
  input: z.ZodString;
5791
+ mode: z.ZodOptional<z.ZodEnum<{
5792
+ execute: "execute";
5793
+ plan: "plan";
5794
+ }>>;
5795
+ images: z.ZodOptional<z.ZodArray<z.ZodObject<{
5796
+ mime_type: z.ZodEnum<{
5797
+ "image/gif": "image/gif";
5798
+ "image/jpeg": "image/jpeg";
5799
+ "image/png": "image/png";
5800
+ "image/webp": "image/webp";
5801
+ }>;
5802
+ data_base64: z.ZodString;
5803
+ }, z.core.$strict>>>;
5577
5804
  model_selection: z.ZodOptional<z.ZodObject<{
5578
5805
  model: z.ZodString;
5579
5806
  options: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -6763,7 +6990,7 @@ export type LocalActionRequestMessage = HcpEnvelope<"local.action.request", Loca
6763
6990
  export type LocalActionResponseMessage = HcpEnvelope<"local.action.response", LocalActionResponsePayload>;
6764
6991
  export type LocalActionErrorMessage = HcpEnvelope<"local.action.error", LocalActionErrorPayload>;
6765
6992
  export type HcpHarnessEventMessage = HcpEnvelope<"harness.event", HcpHarnessEventPayload>;
6766
- export type HcpMessage = HcpEnvelope<"host.accounts.read", HcpAccountsReadPayload> | HcpEnvelope<"host.accounts.snapshot", HcpAccountsSnapshotPayload> | HcpEnvelope<"host.workspaces.request", HcpWorkspacesRequestPayload> | HcpEnvelope<"host.workspaces.result", HcpWorkspacesResultPayload> | HcpCommandAckMessage | HcpCommandNackMessage | HcpHostHelloMessage | HcpHostAcceptedMessage | HcpHostRejectedMessage | HcpHostHeartbeatMessage | HcpHostCapabilitiesUpdatedMessage | HcpHostReplayUnavailableMessage | HcpSessionStartMessage | HcpSessionSnapshotRequestMessage | HcpSessionSnapshotMessage | HcpTurnSendMessage | HcpTurnCancelMessage | HcpSessionStopMessage | HcpApprovalRespondMessage | HcpInputRespondMessage | ToolServersDetachMessage | LocalActionRequestMessage | LocalActionResponseMessage | LocalActionErrorMessage | HcpHarnessEventMessage;
6993
+ export type HcpMessage = HcpEnvelope<"host.accounts.read", HcpAccountsReadPayload> | HcpEnvelope<"host.accounts.snapshot", HcpAccountsSnapshotPayload> | HcpEnvelope<"host.workspaces.request", HcpWorkspacesRequestPayload> | HcpEnvelope<"host.workspaces.result", HcpWorkspacesResultPayload> | HcpCommandAckMessage | HcpCommandNackMessage | HcpHostHelloMessage | HcpHostAcceptedMessage | HcpHostRejectedMessage | HcpHostHeartbeatMessage | HcpHostCapabilitiesUpdatedMessage | HcpHostReplayUnavailableMessage | HcpSessionStartMessage | HcpSessionSnapshotRequestMessage | HcpSessionSnapshotMessage | HcpTurnSendMessage | HcpTurnCancelMessage | HcpSessionStopMessage | HcpApprovalRespondMessage | HcpInputRespondMessage | ToolServersDetachMessage | LocalActionRequestMessage | LocalActionResponseMessage | LocalActionErrorMessage | HcpEnvelope<"harness.conversation.request", HcpConversationRequestPayload> | HcpEnvelope<"harness.conversation.result", HcpConversationResultPayload> | HcpHarnessEventMessage;
6767
6994
  export type HcpKnownMessageType = HcpMessage["type"];
6768
6995
  export declare function parseHcpEnvelope(input: unknown): HcpEnvelope<string, unknown>;
6769
6996
  export declare function parseHcpMessage(input: unknown): HcpMessage;
@@ -6789,4 +7016,5 @@ export declare function parseHcpHarnessEventPayload(input: unknown): HcpHarnessE
6789
7016
  export { HcpSessionEventReducer, type HcpEventApplyResult, type HcpSnapshotApplyResult, } from "./session-reducer.js";
6790
7017
  export * from "./pairing.js";
6791
7018
  export * from "./mcp-review.js";
7019
+ export * from "./native-review.js";
6792
7020
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import { hcpAccountsReadPayloadSchema, hcpAccountsSnapshotPayloadSchema } from "./accounts.js";
2
2
  export * from "./accounts.js";
3
+ import { hcpConversationRequestPayloadSchema, hcpConversationResultPayloadSchema } from "./conversation.js";
4
+ export * from "./conversation.js";
3
5
  import { z } from "zod";
4
6
  export const HCP_VERSION = "hcp.v0";
5
7
  export const HCP_METADATA_MAX_ENCODED_BYTES = 16 * 1024;
@@ -19,6 +21,7 @@ export const HOST_LIFECYCLE_MESSAGE_TYPES = [
19
21
  ];
20
22
  export const CONTROL_PLANE_COMMAND_MESSAGE_TYPES = [
21
23
  "harness.session.start",
24
+ "harness.conversation.request",
22
25
  "harness.session.snapshot.request",
23
26
  "harness.turn.send",
24
27
  "harness.turn.cancel",
@@ -34,7 +37,7 @@ export const LOCAL_ACTION_MESSAGE_TYPES = [
34
37
  "local.action.error",
35
38
  ];
36
39
  export const RUNTIME_EVENT_MESSAGE_TYPES = ["harness.event"];
37
- export const SESSION_SNAPSHOT_MESSAGE_TYPES = ["harness.session.snapshot"];
40
+ export const SESSION_SNAPSHOT_MESSAGE_TYPES = ["harness.session.snapshot", "harness.conversation.result"];
38
41
  export const KNOWN_HCP_EVENT_TYPES = [
39
42
  "session.started",
40
43
  "session.configured",
@@ -260,6 +263,7 @@ export const harnessModelSchema = z
260
263
  capabilities: z
261
264
  .object({
262
265
  option_descriptors: z.array(harnessOptionDescriptorSchema),
266
+ image_input: z.boolean().optional(),
263
267
  })
264
268
  .strict(),
265
269
  })
@@ -270,6 +274,9 @@ export const harnessProviderSnapshotSchema = z
270
274
  streaming: z.boolean(),
271
275
  multi_turn: z.boolean(),
272
276
  session_continuation: z.boolean(),
277
+ plan_mode: z.boolean().optional(),
278
+ native_history: z.boolean().optional(),
279
+ conversation_rollback: z.boolean().optional(),
273
280
  sandbox_modes: z.array(z.enum(["read_only", "workspace_write", "danger_full_access"])),
274
281
  approval_policies: z.array(z.enum(["ask", "auto_edits", "full_access"])),
275
282
  }).strict().optional(),
@@ -489,6 +496,11 @@ export const mcpServerAttachmentSchema = z.discriminatedUnion("transport", [
489
496
  streamableHttpMcpServerAttachmentSchema,
490
497
  runnerStdioMcpProfileAttachmentSchema,
491
498
  ]);
499
+ export const HARNESS_IMAGE_MAX_BYTES = 384 * 1024;
500
+ export const HARNESS_IMAGE_MIME_TYPES = ["image/gif", "image/jpeg", "image/png", "image/webp"];
501
+ export const hcpImageInputSchema = z.object({ mime_type: z.enum(HARNESS_IMAGE_MIME_TYPES),
502
+ data_base64: z.string().min(4).max(HARNESS_IMAGE_MAX_BYTES * 4 / 3).regex(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/) }).strict();
503
+ const harnessImagesSchema = z.array(hcpImageInputSchema).min(1).max(4).refine(images => images.reduce((bytes, image) => bytes + image.data_base64.length, 0) <= HARNESS_IMAGE_MAX_BYTES * 4 / 3, "Image aggregate exceeds the transport limit.");
492
504
  export const hcpSessionStartPayloadSchema = z
493
505
  .object({
494
506
  session_id: nonEmptyStringSchema,
@@ -504,6 +516,13 @@ export const hcpSessionStartPayloadSchema = z
504
516
  workspace_preflight: workspacePreflightSchema.optional(),
505
517
  local_capability_lease: localCapabilityLeaseSchema.optional(),
506
518
  mcp_servers: z.array(mcpServerAttachmentSchema),
519
+ first_turn: z.object({
520
+ turn_id: nonEmptyStringSchema,
521
+ input: z.string(),
522
+ not_after: timestampSchema,
523
+ mode: z.enum(["execute", "plan"]).optional(),
524
+ images: harnessImagesSchema.optional(),
525
+ }).strict().optional(),
507
526
  })
508
527
  .strict();
509
528
  export const hcpSessionSnapshotRequestPayloadSchema = z
@@ -516,6 +535,8 @@ export const hcpTurnSendPayloadSchema = z
516
535
  session_id: nonEmptyStringSchema,
517
536
  turn_id: nonEmptyStringSchema,
518
537
  input: z.string(),
538
+ mode: z.enum(["execute", "plan"]).optional(),
539
+ images: harnessImagesSchema.optional(),
519
540
  model_selection: harnessModelSelectionSchema.optional(),
520
541
  })
521
542
  .strict();
@@ -1309,6 +1330,7 @@ const sessionEventDataSchema = z
1309
1330
  exit_code: z.number().int().optional(),
1310
1331
  model_selection: harnessModelSelectionSchema.optional(),
1311
1332
  mcp_server_count: z.number().int().nonnegative().optional(),
1333
+ native_conversation_ready: z.literal(true).optional(),
1312
1334
  local_capabilities: z.array(nonEmptyStringSchema).optional(),
1313
1335
  message: z.string().optional(),
1314
1336
  })
@@ -1833,7 +1855,10 @@ export const hcpWorkspacesRequestMessageSchema = hcpTypedEnvelopeSchema("host.wo
1833
1855
  export const hcpWorkspacesResultMessageSchema = hcpTypedEnvelopeSchema("host.workspaces.result", hcpWorkspacesResultPayloadSchema);
1834
1856
  export const hcpAccountsReadMessageSchema = hcpTypedEnvelopeSchema("host.accounts.read", hcpAccountsReadPayloadSchema);
1835
1857
  export const hcpAccountsSnapshotMessageSchema = hcpTypedEnvelopeSchema("host.accounts.snapshot", hcpAccountsSnapshotPayloadSchema);
1858
+ export const hcpConversationRequestMessageSchema = hcpTypedEnvelopeSchema("harness.conversation.request", hcpConversationRequestPayloadSchema);
1859
+ export const hcpConversationResultMessageSchema = hcpTypedEnvelopeSchema("harness.conversation.result", hcpConversationResultPayloadSchema);
1836
1860
  export const hcpMessageSchema = z.discriminatedUnion("type", [
1861
+ hcpConversationRequestMessageSchema, hcpConversationResultMessageSchema,
1837
1862
  hcpAccountsReadMessageSchema,
1838
1863
  hcpAccountsSnapshotMessageSchema,
1839
1864
  hcpWorkspacesRequestMessageSchema,
@@ -1934,4 +1959,5 @@ export function parseHcpHarnessEventPayload(input) {
1934
1959
  export { HcpSessionEventReducer, } from "./session-reducer.js";
1935
1960
  export * from "./pairing.js";
1936
1961
  export * from "./mcp-review.js";
1962
+ export * from "./native-review.js";
1937
1963
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,15 @@
1
+ import { z } from "zod";
2
+ export declare const NATIVE_REVIEW_MAX_ACTION_BYTES: number;
3
+ /** Credential-free presentation; the executable request remains owned by its native adapter. */
4
+ export declare const nativeReviewActionSchema: z.ZodObject<{
5
+ kind: z.ZodLiteral<"native_operation">;
6
+ operation: z.ZodEnum<{
7
+ command: "command";
8
+ file_change: "file_change";
9
+ }>;
10
+ details: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
11
+ }, z.core.$strict>;
12
+ export type NativeReviewAction = z.infer<typeof nativeReviewActionSchema>;
13
+ export declare function nativeReviewActionBytes(json: string): Uint8Array;
14
+ export declare function hashNativeReviewAction(json: string): Promise<string>;
15
+ //# sourceMappingURL=native-review.d.ts.map
@@ -0,0 +1,19 @@
1
+ import { z } from "zod";
2
+ export const NATIVE_REVIEW_MAX_ACTION_BYTES = 48 * 1024;
3
+ /** Credential-free presentation; the executable request remains owned by its native adapter. */
4
+ export const nativeReviewActionSchema = z.object({
5
+ kind: z.literal("native_operation"), operation: z.enum(["command", "file_change"]),
6
+ details: z.record(z.string(), z.json()),
7
+ }).strict();
8
+ export function nativeReviewActionBytes(json) {
9
+ const bytes = new TextEncoder().encode(json);
10
+ if (!bytes.length || bytes.length > NATIVE_REVIEW_MAX_ACTION_BYTES)
11
+ throw new Error("Native review action exceeds its UTF-8 limit.");
12
+ nativeReviewActionSchema.parse(JSON.parse(json));
13
+ return bytes;
14
+ }
15
+ export async function hashNativeReviewAction(json) {
16
+ const bytes = nativeReviewActionBytes(json);
17
+ return [...new Uint8Array(await crypto.subtle.digest("SHA-256", Uint8Array.from(bytes)))].map(byte => byte.toString(16).padStart(2, "0")).join("");
18
+ }
19
+ //# sourceMappingURL=native-review.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harness-control/protocol",
3
- "version": "0.4.8",
3
+ "version": "0.4.10",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,238 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "oneOf": [
4
+ {
5
+ "type": "object",
6
+ "properties": {
7
+ "id": {
8
+ "type": "string",
9
+ "minLength": 1
10
+ },
11
+ "type": {
12
+ "type": "string",
13
+ "const": "harness.conversation.request"
14
+ },
15
+ "version": {
16
+ "type": "string",
17
+ "const": "hcp.v0"
18
+ },
19
+ "sent_at": {
20
+ "type": "string",
21
+ "format": "date-time",
22
+ "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
23
+ },
24
+ "payload": {
25
+ "type": "object",
26
+ "properties": {
27
+ "session_id": {
28
+ "type": "string",
29
+ "minLength": 1,
30
+ "maxLength": 512
31
+ },
32
+ "operation": {
33
+ "oneOf": [
34
+ {
35
+ "type": "object",
36
+ "properties": {
37
+ "kind": {
38
+ "type": "string",
39
+ "const": "read"
40
+ }
41
+ },
42
+ "required": [
43
+ "kind"
44
+ ],
45
+ "additionalProperties": false
46
+ },
47
+ {
48
+ "type": "object",
49
+ "properties": {
50
+ "kind": {
51
+ "type": "string",
52
+ "const": "rollback"
53
+ },
54
+ "num_turns": {
55
+ "type": "integer",
56
+ "minimum": 1,
57
+ "maximum": 100
58
+ },
59
+ "expected_history_hash": {
60
+ "type": "string",
61
+ "pattern": "^[a-f0-9]{64}$"
62
+ }
63
+ },
64
+ "required": [
65
+ "kind",
66
+ "num_turns",
67
+ "expected_history_hash"
68
+ ],
69
+ "additionalProperties": false
70
+ },
71
+ {
72
+ "type": "object",
73
+ "properties": {
74
+ "kind": {
75
+ "type": "string",
76
+ "const": "retire"
77
+ }
78
+ },
79
+ "required": [
80
+ "kind"
81
+ ],
82
+ "additionalProperties": false
83
+ }
84
+ ]
85
+ }
86
+ },
87
+ "required": [
88
+ "session_id",
89
+ "operation"
90
+ ],
91
+ "additionalProperties": false
92
+ },
93
+ "metadata": {
94
+ "type": "object",
95
+ "propertyNames": {
96
+ "type": "string"
97
+ },
98
+ "additionalProperties": {}
99
+ }
100
+ },
101
+ "required": [
102
+ "id",
103
+ "type",
104
+ "version",
105
+ "sent_at",
106
+ "payload"
107
+ ],
108
+ "additionalProperties": false
109
+ },
110
+ {
111
+ "type": "object",
112
+ "properties": {
113
+ "id": {
114
+ "type": "string",
115
+ "minLength": 1
116
+ },
117
+ "type": {
118
+ "type": "string",
119
+ "const": "harness.conversation.result"
120
+ },
121
+ "version": {
122
+ "type": "string",
123
+ "const": "hcp.v0"
124
+ },
125
+ "sent_at": {
126
+ "type": "string",
127
+ "format": "date-time",
128
+ "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
129
+ },
130
+ "payload": {
131
+ "type": "object",
132
+ "properties": {
133
+ "command_id": {
134
+ "type": "string",
135
+ "minLength": 1
136
+ },
137
+ "session_id": {
138
+ "type": "string",
139
+ "minLength": 1
140
+ },
141
+ "operation": {
142
+ "type": "string",
143
+ "enum": [
144
+ "read",
145
+ "rollback",
146
+ "retire"
147
+ ]
148
+ },
149
+ "filesystem_undo": {
150
+ "type": "boolean",
151
+ "const": false
152
+ },
153
+ "history": {
154
+ "type": "object",
155
+ "properties": {
156
+ "history_hash": {
157
+ "type": "string",
158
+ "pattern": "^[a-f0-9]{64}$"
159
+ },
160
+ "turn_count": {
161
+ "type": "integer",
162
+ "minimum": 0,
163
+ "maximum": 9007199254740991
164
+ },
165
+ "truncated": {
166
+ "type": "boolean"
167
+ },
168
+ "turns": {
169
+ "maxItems": 100,
170
+ "type": "array",
171
+ "items": {
172
+ "type": "object",
173
+ "properties": {
174
+ "id": {
175
+ "type": "string"
176
+ },
177
+ "status": {
178
+ "type": "string"
179
+ },
180
+ "items": {
181
+ "type": "array",
182
+ "items": {
183
+ "type": "object",
184
+ "propertyNames": {
185
+ "type": "string"
186
+ },
187
+ "additionalProperties": {
188
+ "$ref": "#/$defs/__schema0"
189
+ }
190
+ }
191
+ }
192
+ },
193
+ "required": [
194
+ "id",
195
+ "status",
196
+ "items"
197
+ ],
198
+ "additionalProperties": false
199
+ }
200
+ }
201
+ },
202
+ "required": [
203
+ "history_hash",
204
+ "turn_count",
205
+ "truncated",
206
+ "turns"
207
+ ],
208
+ "additionalProperties": false
209
+ }
210
+ },
211
+ "required": [
212
+ "command_id",
213
+ "session_id",
214
+ "operation",
215
+ "filesystem_undo"
216
+ ],
217
+ "additionalProperties": false
218
+ },
219
+ "metadata": {
220
+ "type": "object",
221
+ "propertyNames": {
222
+ "type": "string"
223
+ },
224
+ "additionalProperties": {}
225
+ }
226
+ },
227
+ "required": [
228
+ "id",
229
+ "type",
230
+ "version",
231
+ "sent_at",
232
+ "payload"
233
+ ],
234
+ "additionalProperties": false
235
+ },
4
236
  {
5
237
  "type": "object",
6
238
  "properties": {
@@ -1168,6 +1400,15 @@
1168
1400
  "session_continuation": {
1169
1401
  "type": "boolean"
1170
1402
  },
1403
+ "plan_mode": {
1404
+ "type": "boolean"
1405
+ },
1406
+ "native_history": {
1407
+ "type": "boolean"
1408
+ },
1409
+ "conversation_rollback": {
1410
+ "type": "boolean"
1411
+ },
1171
1412
  "sandbox_modes": {
1172
1413
  "type": "array",
1173
1414
  "items": {
@@ -1387,6 +1628,9 @@
1387
1628
  ],
1388
1629
  "additionalProperties": false
1389
1630
  }
1631
+ },
1632
+ "image_input": {
1633
+ "type": "boolean"
1390
1634
  }
1391
1635
  },
1392
1636
  "required": [
@@ -2166,6 +2410,66 @@
2166
2410
  }
2167
2411
  ]
2168
2412
  }
2413
+ },
2414
+ "first_turn": {
2415
+ "type": "object",
2416
+ "properties": {
2417
+ "turn_id": {
2418
+ "type": "string",
2419
+ "minLength": 1
2420
+ },
2421
+ "input": {
2422
+ "type": "string"
2423
+ },
2424
+ "not_after": {
2425
+ "type": "string",
2426
+ "format": "date-time",
2427
+ "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
2428
+ },
2429
+ "mode": {
2430
+ "type": "string",
2431
+ "enum": [
2432
+ "execute",
2433
+ "plan"
2434
+ ]
2435
+ },
2436
+ "images": {
2437
+ "minItems": 1,
2438
+ "maxItems": 4,
2439
+ "type": "array",
2440
+ "items": {
2441
+ "type": "object",
2442
+ "properties": {
2443
+ "mime_type": {
2444
+ "type": "string",
2445
+ "enum": [
2446
+ "image/gif",
2447
+ "image/jpeg",
2448
+ "image/png",
2449
+ "image/webp"
2450
+ ]
2451
+ },
2452
+ "data_base64": {
2453
+ "type": "string",
2454
+ "minLength": 4,
2455
+ "maxLength": 524288,
2456
+ "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"
2457
+ }
2458
+ },
2459
+ "required": [
2460
+ "mime_type",
2461
+ "data_base64"
2462
+ ],
2463
+ "additionalProperties": false
2464
+ }
2465
+ }
2466
+ },
2467
+ "required": [
2468
+ "turn_id",
2469
+ "input",
2470
+ "not_after"
2471
+ ],
2472
+ "additionalProperties": false
2169
2473
  }
2170
2474
  },
2171
2475
  "required": [
@@ -2609,6 +2913,43 @@
2609
2913
  "input": {
2610
2914
  "type": "string"
2611
2915
  },
2916
+ "mode": {
2917
+ "type": "string",
2918
+ "enum": [
2919
+ "execute",
2920
+ "plan"
2921
+ ]
2922
+ },
2923
+ "images": {
2924
+ "minItems": 1,
2925
+ "maxItems": 4,
2926
+ "type": "array",
2927
+ "items": {
2928
+ "type": "object",
2929
+ "properties": {
2930
+ "mime_type": {
2931
+ "type": "string",
2932
+ "enum": [
2933
+ "image/gif",
2934
+ "image/jpeg",
2935
+ "image/png",
2936
+ "image/webp"
2937
+ ]
2938
+ },
2939
+ "data_base64": {
2940
+ "type": "string",
2941
+ "minLength": 4,
2942
+ "maxLength": 524288,
2943
+ "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"
2944
+ }
2945
+ },
2946
+ "required": [
2947
+ "mime_type",
2948
+ "data_base64"
2949
+ ],
2950
+ "additionalProperties": false
2951
+ }
2952
+ },
2612
2953
  "model_selection": {
2613
2954
  "type": "object",
2614
2955
  "properties": {
@@ -7959,6 +8300,10 @@
7959
8300
  "minimum": 0,
7960
8301
  "maximum": 9007199254740991
7961
8302
  },
8303
+ "native_conversation_ready": {
8304
+ "type": "boolean",
8305
+ "const": true
8306
+ },
7962
8307
  "local_capabilities": {
7963
8308
  "type": "array",
7964
8309
  "items": {
@@ -8153,6 +8498,10 @@
8153
8498
  "minimum": 0,
8154
8499
  "maximum": 9007199254740991
8155
8500
  },
8501
+ "native_conversation_ready": {
8502
+ "type": "boolean",
8503
+ "const": true
8504
+ },
8156
8505
  "local_capabilities": {
8157
8506
  "type": "array",
8158
8507
  "items": {
@@ -8347,6 +8696,10 @@
8347
8696
  "minimum": 0,
8348
8697
  "maximum": 9007199254740991
8349
8698
  },
8699
+ "native_conversation_ready": {
8700
+ "type": "boolean",
8701
+ "const": true
8702
+ },
8350
8703
  "local_capabilities": {
8351
8704
  "type": "array",
8352
8705
  "items": {
@@ -8541,6 +8894,10 @@
8541
8894
  "minimum": 0,
8542
8895
  "maximum": 9007199254740991
8543
8896
  },
8897
+ "native_conversation_ready": {
8898
+ "type": "boolean",
8899
+ "const": true
8900
+ },
8544
8901
  "local_capabilities": {
8545
8902
  "type": "array",
8546
8903
  "items": {
@@ -18962,6 +19319,39 @@
18962
19319
  "additionalProperties": false
18963
19320
  }
18964
19321
  ],
19322
+ "$defs": {
19323
+ "__schema0": {
19324
+ "anyOf": [
19325
+ {
19326
+ "type": "string"
19327
+ },
19328
+ {
19329
+ "type": "number"
19330
+ },
19331
+ {
19332
+ "type": "boolean"
19333
+ },
19334
+ {
19335
+ "type": "null"
19336
+ },
19337
+ {
19338
+ "type": "array",
19339
+ "items": {
19340
+ "$ref": "#/$defs/__schema0"
19341
+ }
19342
+ },
19343
+ {
19344
+ "type": "object",
19345
+ "propertyNames": {
19346
+ "type": "string"
19347
+ },
19348
+ "additionalProperties": {
19349
+ "$ref": "#/$defs/__schema0"
19350
+ }
19351
+ }
19352
+ ]
19353
+ }
19354
+ },
18965
19355
  "$id": "https://schemas.harness-control.local/hcp.v0/message.schema.json",
18966
19356
  "title": "HCP protocol message",
18967
19357
  "description": "Structural JSON Schema for known hcp.v0 protocol messages. Runtime parsers enforce additional cross-field invariants such as lease-to-attribution equality."