@otto-code/protocol 0.5.5 → 0.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/messages.js CHANGED
@@ -917,6 +917,30 @@ export const ProjectRemoveRequestSchema = z.object({
917
917
  projectId: z.string(),
918
918
  requestId: z.string(),
919
919
  });
920
+ // An unordered pair of linked projects. The daemon stores the pair in a
921
+ // canonical order, but clients treat it as undirected: a link between A and B
922
+ // permits opening files across both projects. See the gated-multi-root project.
923
+ export const ProjectLinkSchema = z.object({
924
+ projectAId: z.string(),
925
+ projectBId: z.string(),
926
+ });
927
+ export const ProjectLinksListRequestSchema = z.object({
928
+ type: z.literal("project.links.list.request"),
929
+ requestId: z.string(),
930
+ });
931
+ export const ProjectLinksSetRequestSchema = z.object({
932
+ type: z.literal("project.links.set.request"),
933
+ // Order is irrelevant; the daemon canonicalizes. Linking is idempotent.
934
+ projectId: z.string(),
935
+ otherProjectId: z.string(),
936
+ requestId: z.string(),
937
+ });
938
+ export const ProjectLinksUnsetRequestSchema = z.object({
939
+ type: z.literal("project.links.unset.request"),
940
+ projectId: z.string(),
941
+ otherProjectId: z.string(),
942
+ requestId: z.string(),
943
+ });
920
944
  export const WorkspaceTitleSetRequestSchema = z.object({
921
945
  type: z.literal("workspace.title.set.request"),
922
946
  workspaceId: z.string(),
@@ -1546,6 +1570,71 @@ export const AgentBackgroundTaskClearResponseMessageSchema = z.object({
1546
1570
  type: z.literal("agent.background_task.clear.response"),
1547
1571
  payload: AgentActionResponsePayloadSchema,
1548
1572
  });
1573
+ // A suggested task an agent surfaced via the `spawn_task` tool (Claude Desktop
1574
+ // parity). Renders as a chip in the parent agent's session; the user starts it
1575
+ // (new worktree / local / this session) or dismisses it. The `prompt` is
1576
+ // deliberately NOT part of this wire shape — it stays server-side and is only
1577
+ // used when the task is started ("not shown directly" in Claude Desktop).
1578
+ // COMPAT(suggestedTasks): added in v0.5.6, drop the gate when daemon floor >= v0.5.6.
1579
+ export const SuggestedTaskStateSchema = z.enum(["pending", "started", "dismissed"]);
1580
+ export const SuggestedTaskInfoSchema = z.object({
1581
+ taskId: z.string(),
1582
+ parentAgentId: z.string(),
1583
+ title: z.string(),
1584
+ tldr: z.string(),
1585
+ cwd: z.string().optional(),
1586
+ state: SuggestedTaskStateSchema,
1587
+ createdAt: z.string(),
1588
+ updatedAt: z.string(),
1589
+ });
1590
+ // Pushed with the full current set of pending suggested tasks for a parent
1591
+ // agent whenever any of them changes (spawn/start/dismiss) — same full-list
1592
+ // reconciliation shape as BackgroundShellTasksChangedSchema.
1593
+ export const SuggestedTasksChangedSchema = z.object({
1594
+ type: z.literal("suggested_tasks_changed"),
1595
+ payload: z.object({
1596
+ parentAgentId: z.string(),
1597
+ tasks: z.array(SuggestedTaskInfoSchema),
1598
+ }),
1599
+ });
1600
+ // Aggregate outcome for a start/dismiss over one or more tasks. `succeeded`/
1601
+ // `failed` count the tasks acted on so the client can report "Started 3 tasks";
1602
+ // `error` collects any per-task failure messages (the failed tasks' chips stay).
1603
+ const SuggestedTaskActionResponsePayloadSchema = z.object({
1604
+ requestId: z.string(),
1605
+ parentAgentId: z.string(),
1606
+ accepted: z.boolean(),
1607
+ succeeded: z.number(),
1608
+ failed: z.number(),
1609
+ error: z.string().nullable(),
1610
+ });
1611
+ // Start one or more suggested tasks, applying the SAME mode to each — no
1612
+ // combining. `worktree` spins a new worktree-backed workspace per task, `local`
1613
+ // a new session in the same repo/cwd per task, `in_session` steers the parent
1614
+ // agent with the task prompt. The daemon resolves the parent agent's brain
1615
+ // (provider/model/personality) so a started task continues the suggesting agent.
1616
+ export const TasksSuggestedStartModeSchema = z.enum(["worktree", "local", "in_session"]);
1617
+ export const TasksSuggestedStartRequestMessageSchema = z.object({
1618
+ type: z.literal("tasks.suggested.start.request"),
1619
+ parentAgentId: z.string(),
1620
+ taskIds: z.array(z.string()),
1621
+ mode: TasksSuggestedStartModeSchema,
1622
+ requestId: z.string(),
1623
+ });
1624
+ export const TasksSuggestedStartResponseMessageSchema = z.object({
1625
+ type: z.literal("tasks.suggested.start.response"),
1626
+ payload: SuggestedTaskActionResponsePayloadSchema,
1627
+ });
1628
+ export const TasksSuggestedDismissRequestMessageSchema = z.object({
1629
+ type: z.literal("tasks.suggested.dismiss.request"),
1630
+ parentAgentId: z.string(),
1631
+ taskIds: z.array(z.string()),
1632
+ requestId: z.string(),
1633
+ });
1634
+ export const TasksSuggestedDismissResponseMessageSchema = z.object({
1635
+ type: z.literal("tasks.suggested.dismiss.response"),
1636
+ payload: SuggestedTaskActionResponsePayloadSchema,
1637
+ });
1549
1638
  // Switch a running agent to an Agent Personality (or clear with null). The
1550
1639
  // daemon re-resolves the id against the roster + the agent's cwd provider
1551
1640
  // snapshot and applies the full personality live — system prompt, identity
@@ -1606,6 +1695,39 @@ export const ProjectRemoveResponseSchema = z.object({
1606
1695
  type: z.literal("project.remove.response"),
1607
1696
  payload: ProjectRemoveResponsePayloadSchema,
1608
1697
  });
1698
+ export const ProjectLinksListResponsePayloadSchema = z.object({
1699
+ requestId: z.string(),
1700
+ links: z.array(ProjectLinkSchema).default([]),
1701
+ error: z.string().nullable(),
1702
+ });
1703
+ export const ProjectLinksListResponseSchema = z.object({
1704
+ type: z.literal("project.links.list.response"),
1705
+ payload: ProjectLinksListResponsePayloadSchema,
1706
+ });
1707
+ export const ProjectLinksMutationResponsePayloadSchema = z.object({
1708
+ requestId: z.string(),
1709
+ accepted: z.boolean(),
1710
+ // The full link set after the mutation, so the client refreshes in one hop.
1711
+ links: z.array(ProjectLinkSchema).default([]),
1712
+ error: z.string().nullable(),
1713
+ });
1714
+ export const ProjectLinksSetResponseSchema = z.object({
1715
+ type: z.literal("project.links.set.response"),
1716
+ payload: ProjectLinksMutationResponsePayloadSchema,
1717
+ });
1718
+ export const ProjectLinksUnsetResponseSchema = z.object({
1719
+ type: z.literal("project.links.unset.response"),
1720
+ payload: ProjectLinksMutationResponsePayloadSchema,
1721
+ });
1722
+ // Pushed to the session whenever the link set changes (mutation or cascade on
1723
+ // project removal) so open UIs re-evaluate cross-project access without polling.
1724
+ export const ProjectLinksChangedPayloadSchema = z.object({
1725
+ links: z.array(ProjectLinkSchema).default([]),
1726
+ });
1727
+ export const ProjectLinksChangedSchema = z.object({
1728
+ type: z.literal("project.links.changed"),
1729
+ payload: ProjectLinksChangedPayloadSchema,
1730
+ });
1609
1731
  export const WorkspaceTitleSetResponsePayloadSchema = z.object({
1610
1732
  requestId: z.string(),
1611
1733
  workspaceId: z.string(),
@@ -1818,6 +1940,10 @@ export const CheckoutGitRollbackRequestSchema = z.object({
1818
1940
  cwd: z.string(),
1819
1941
  // Repo-relative paths whose uncommitted changes should be discarded.
1820
1942
  paths: z.array(z.string()),
1943
+ // Set after the user confirms rolling back while agents are running in this
1944
+ // workspace; without it the daemon refuses with kind "agents_running", since
1945
+ // discarding a live agent's uncommitted edits mid-run can destroy its work.
1946
+ allowWithRunningAgents: z.boolean().optional(),
1821
1947
  requestId: z.string(),
1822
1948
  });
1823
1949
  export const CheckoutMergeRequestSchema = z.object({
@@ -2457,6 +2583,9 @@ export const SessionInboundMessageSchema = z.discriminatedUnion("type", [
2457
2583
  UpdateAgentRequestMessageSchema,
2458
2584
  ProjectRenameRequestSchema,
2459
2585
  ProjectRemoveRequestSchema,
2586
+ ProjectLinksListRequestSchema,
2587
+ ProjectLinksSetRequestSchema,
2588
+ ProjectLinksUnsetRequestSchema,
2460
2589
  WorkspaceTitleSetRequestSchema,
2461
2590
  SetVoiceModeMessageSchema,
2462
2591
  SendAgentMessageRequestSchema,
@@ -2503,6 +2632,8 @@ export const SessionInboundMessageSchema = z.discriminatedUnion("type", [
2503
2632
  AgentSubagentStopRequestMessageSchema,
2504
2633
  AgentBackgroundTaskStopRequestMessageSchema,
2505
2634
  AgentBackgroundTaskClearRequestMessageSchema,
2635
+ TasksSuggestedStartRequestMessageSchema,
2636
+ TasksSuggestedDismissRequestMessageSchema,
2506
2637
  AgentPersonalitySetRequestMessageSchema,
2507
2638
  AgentRewindRequestMessageSchema,
2508
2639
  AgentPermissionResponseMessageSchema,
@@ -2796,6 +2927,8 @@ export const ServerInfoStatusPayloadSchema = z
2796
2927
  observedSubagents: z.boolean().optional(),
2797
2928
  // COMPAT(backgroundShellTasks): added in v0.5.3, drop the gate when daemon floor >= v0.5.3.
2798
2929
  backgroundShellTasks: z.boolean().optional(),
2930
+ // COMPAT(suggestedTasks): added in v0.5.6, drop the gate when daemon floor >= v0.5.6.
2931
+ suggestedTasks: z.boolean().optional(),
2799
2932
  // COMPAT(textEditor): added in v0.4.4, drop the gate when daemon floor >= v0.4.4.
2800
2933
  textEditor: z.boolean().optional(),
2801
2934
  // COMPAT(projectSearch): added in v0.4.4, drop the gate when daemon floor >= v0.4.4.
@@ -2832,6 +2965,8 @@ export const ServerInfoStatusPayloadSchema = z
2832
2965
  activityStats: z.boolean().optional(),
2833
2966
  // COMPAT(runsClear): added in v0.5.3, drop the gate when daemon floor >= v0.5.3.
2834
2967
  runsClear: z.boolean().optional(),
2968
+ // COMPAT(projectLinks): added in v0.5.6, drop the gate when daemon floor >= v0.5.6.
2969
+ projectLinks: z.boolean().optional(),
2835
2970
  })
2836
2971
  .optional(),
2837
2972
  })
@@ -3951,6 +4086,13 @@ export const CheckoutGitRollbackErrorSchema = z.discriminatedUnion("kind", [
3951
4086
  kind: z.literal("git_failed"),
3952
4087
  detail: z.string(),
3953
4088
  }),
4089
+ // Refused because agents are running in this workspace; discarding their
4090
+ // uncommitted edits mid-run risks destroying work. The client re-sends with
4091
+ // allowWithRunningAgents after confirming, mirroring the commit flow.
4092
+ z.object({
4093
+ kind: z.literal("agents_running"),
4094
+ agents: z.array(CheckoutGitCommitRunningAgentSchema),
4095
+ }),
3954
4096
  ]);
3955
4097
  export const CheckoutGitRollbackResponseSchema = z.object({
3956
4098
  type: z.literal("checkout.git.rollback.response"),
@@ -4989,11 +5131,18 @@ export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [
4989
5131
  AgentBackgroundTaskStopResponseMessageSchema,
4990
5132
  AgentBackgroundTaskClearResponseMessageSchema,
4991
5133
  BackgroundShellTasksChangedSchema,
5134
+ TasksSuggestedStartResponseMessageSchema,
5135
+ TasksSuggestedDismissResponseMessageSchema,
5136
+ SuggestedTasksChangedSchema,
4992
5137
  AgentPersonalitySetResponseMessageSchema,
4993
5138
  AgentRewindResponseMessageSchema,
4994
5139
  UpdateAgentResponseMessageSchema,
4995
5140
  ProjectRenameResponseSchema,
4996
5141
  ProjectRemoveResponseSchema,
5142
+ ProjectLinksListResponseSchema,
5143
+ ProjectLinksSetResponseSchema,
5144
+ ProjectLinksUnsetResponseSchema,
5145
+ ProjectLinksChangedSchema,
4997
5146
  WorkspaceTitleSetResponseSchema,
4998
5147
  WaitForFinishResponseMessageSchema,
4999
5148
  AgentPermissionRequestMessageSchema,
@@ -3851,6 +3851,45 @@ export declare const WSOutboundMessageSchema: {
3851
3851
  archivedAt: import("zod").ZodOptional<import("zod").ZodString>;
3852
3852
  }, import("zod/v4/core").$strip>>;
3853
3853
  }, import("zod/v4/core").$strip>;
3854
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
3855
+ type: import("zod").ZodLiteral<"tasks.suggested.start.response">;
3856
+ payload: import("zod").ZodObject<{
3857
+ requestId: import("zod").ZodString;
3858
+ parentAgentId: import("zod").ZodString;
3859
+ accepted: import("zod").ZodBoolean;
3860
+ succeeded: import("zod").ZodNumber;
3861
+ failed: import("zod").ZodNumber;
3862
+ error: import("zod").ZodNullable<import("zod").ZodString>;
3863
+ }, import("zod/v4/core").$strip>;
3864
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
3865
+ type: import("zod").ZodLiteral<"tasks.suggested.dismiss.response">;
3866
+ payload: import("zod").ZodObject<{
3867
+ requestId: import("zod").ZodString;
3868
+ parentAgentId: import("zod").ZodString;
3869
+ accepted: import("zod").ZodBoolean;
3870
+ succeeded: import("zod").ZodNumber;
3871
+ failed: import("zod").ZodNumber;
3872
+ error: import("zod").ZodNullable<import("zod").ZodString>;
3873
+ }, import("zod/v4/core").$strip>;
3874
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
3875
+ type: import("zod").ZodLiteral<"suggested_tasks_changed">;
3876
+ payload: import("zod").ZodObject<{
3877
+ parentAgentId: import("zod").ZodString;
3878
+ tasks: import("zod").ZodArray<import("zod").ZodObject<{
3879
+ taskId: import("zod").ZodString;
3880
+ parentAgentId: import("zod").ZodString;
3881
+ title: import("zod").ZodString;
3882
+ tldr: import("zod").ZodString;
3883
+ cwd: import("zod").ZodOptional<import("zod").ZodString>;
3884
+ state: import("zod").ZodEnum<{
3885
+ pending: "pending";
3886
+ dismissed: "dismissed";
3887
+ started: "started";
3888
+ }>;
3889
+ createdAt: import("zod").ZodString;
3890
+ updatedAt: import("zod").ZodString;
3891
+ }, import("zod/v4/core").$strip>>;
3892
+ }, import("zod/v4/core").$strip>;
3854
3893
  }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
3855
3894
  type: import("zod").ZodLiteral<"agent.personality.set.response">;
3856
3895
  payload: import("zod").ZodObject<{
@@ -3895,6 +3934,46 @@ export declare const WSOutboundMessageSchema: {
3895
3934
  removedWorkspaceIds: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodString>>;
3896
3935
  error: import("zod").ZodNullable<import("zod").ZodString>;
3897
3936
  }, import("zod/v4/core").$strip>;
3937
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
3938
+ type: import("zod").ZodLiteral<"project.links.list.response">;
3939
+ payload: import("zod").ZodObject<{
3940
+ requestId: import("zod").ZodString;
3941
+ links: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodObject<{
3942
+ projectAId: import("zod").ZodString;
3943
+ projectBId: import("zod").ZodString;
3944
+ }, import("zod/v4/core").$strip>>>;
3945
+ error: import("zod").ZodNullable<import("zod").ZodString>;
3946
+ }, import("zod/v4/core").$strip>;
3947
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
3948
+ type: import("zod").ZodLiteral<"project.links.set.response">;
3949
+ payload: import("zod").ZodObject<{
3950
+ requestId: import("zod").ZodString;
3951
+ accepted: import("zod").ZodBoolean;
3952
+ links: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodObject<{
3953
+ projectAId: import("zod").ZodString;
3954
+ projectBId: import("zod").ZodString;
3955
+ }, import("zod/v4/core").$strip>>>;
3956
+ error: import("zod").ZodNullable<import("zod").ZodString>;
3957
+ }, import("zod/v4/core").$strip>;
3958
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
3959
+ type: import("zod").ZodLiteral<"project.links.unset.response">;
3960
+ payload: import("zod").ZodObject<{
3961
+ requestId: import("zod").ZodString;
3962
+ accepted: import("zod").ZodBoolean;
3963
+ links: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodObject<{
3964
+ projectAId: import("zod").ZodString;
3965
+ projectBId: import("zod").ZodString;
3966
+ }, import("zod/v4/core").$strip>>>;
3967
+ error: import("zod").ZodNullable<import("zod").ZodString>;
3968
+ }, import("zod/v4/core").$strip>;
3969
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
3970
+ type: import("zod").ZodLiteral<"project.links.changed">;
3971
+ payload: import("zod").ZodObject<{
3972
+ links: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodObject<{
3973
+ projectAId: import("zod").ZodString;
3974
+ projectBId: import("zod").ZodString;
3975
+ }, import("zod/v4/core").$strip>>>;
3976
+ }, import("zod/v4/core").$strip>;
3898
3977
  }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
3899
3978
  type: import("zod").ZodLiteral<"workspace.title.set.response">;
3900
3979
  payload: import("zod").ZodObject<{
@@ -4449,6 +4528,12 @@ export declare const WSOutboundMessageSchema: {
4449
4528
  }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
4450
4529
  kind: import("zod").ZodLiteral<"git_failed">;
4451
4530
  detail: import("zod").ZodString;
4531
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
4532
+ kind: import("zod").ZodLiteral<"agents_running">;
4533
+ agents: import("zod").ZodArray<import("zod").ZodObject<{
4534
+ id: import("zod").ZodString;
4535
+ title: import("zod").ZodNullable<import("zod").ZodString>;
4536
+ }, import("zod/v4/core").$strip>>;
4452
4537
  }, import("zod/v4/core").$strip>], "kind">>;
4453
4538
  requestId: import("zod").ZodString;
4454
4539
  }, import("zod/v4/core").$strip>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@otto-code/protocol",
3
- "version": "0.5.5",
3
+ "version": "0.5.7",
4
4
  "description": "Otto shared protocol schemas and wire types",
5
5
  "files": [
6
6
  "dist",