@saadnvd1/agent-os 0.3.700 → 0.3.715

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 (185) hide show
  1. package/README.md +1 -0
  2. package/app/api/bus/groups/route.ts +44 -0
  3. package/app/api/bus/spawn/route.ts +12 -1
  4. package/app/api/claims/[id]/route.ts +20 -0
  5. package/app/api/claims/check/route.ts +23 -0
  6. package/app/api/claims/check.test.ts +113 -0
  7. package/app/api/claims/exchange/route.ts +42 -0
  8. package/app/api/claims/outside.test.ts +90 -0
  9. package/app/api/claims/route.test.ts +193 -0
  10. package/app/api/claims/route.ts +73 -0
  11. package/app/api/hosts/[id]/route.ts +9 -1
  12. package/app/api/peer/unlink/route.ts +17 -0
  13. package/app/api/peers/[hostId]/audit/route.ts +14 -0
  14. package/app/api/peers/[hostId]/route.ts +20 -0
  15. package/app/api/peers/gate.test.ts +64 -1
  16. package/app/api/peers/pending/route.test.ts +37 -0
  17. package/app/api/peers/pending/route.ts +11 -4
  18. package/app/api/session-groups/[id]/restore/route.ts +11 -0
  19. package/app/api/session-groups/[id]/route.ts +25 -0
  20. package/app/api/session-groups/order/route.ts +15 -0
  21. package/app/api/session-groups/route.ts +21 -0
  22. package/app/api/sessions/[id]/fork/route.ts +3 -0
  23. package/app/api/sessions/[id]/group/route.ts +18 -0
  24. package/app/api/sessions/[id]/route.ts +14 -4
  25. package/app/api/sessions/[id]/summarize/route.ts +2 -0
  26. package/app/api/sessions/claims.test.ts +122 -0
  27. package/app/api/sessions/group/route.ts +17 -0
  28. package/app/api/sessions/route.ts +15 -14
  29. package/app/page.tsx +5 -0
  30. package/components/Claims/ClaimFiles.tsx +38 -0
  31. package/components/Claims/ClaimRow.tsx +82 -0
  32. package/components/Claims/ClaimsSheet.tsx +176 -0
  33. package/components/Claims/OverlapPill.tsx +31 -0
  34. package/components/Claims/StartClaimsNotice.tsx +70 -0
  35. package/components/Claims/claims-ui.test.ts +161 -0
  36. package/components/Claims/format.ts +57 -0
  37. package/components/Claims/index.ts +3 -0
  38. package/components/Draft/DraftPanel.tsx +40 -2
  39. package/components/Hosts/AccountMachines.tsx +32 -18
  40. package/components/Hosts/HostRow.tsx +155 -14
  41. package/components/Hosts/IncomingLinkSheet.tsx +28 -10
  42. package/components/Hosts/PeerActivitySheet.tsx +111 -0
  43. package/components/SessionList/GroupShelves.tsx +195 -0
  44. package/components/SessionList/MoveToGroupMenu.tsx +105 -0
  45. package/components/SessionList/RowSubtitle.tsx +7 -1
  46. package/components/SessionList/SelectionToolbar.tsx +52 -1
  47. package/components/SessionList/SessionRow.tsx +1 -0
  48. package/components/SessionList/SessionRowMenu.tsx +17 -0
  49. package/components/SessionList/SessionShelves.tsx +5 -0
  50. package/components/SessionList/SidebarBody.tsx +6 -0
  51. package/components/SessionList/SidebarContextMenu.test.ts +104 -0
  52. package/components/SessionList/SidebarContextMenu.tsx +59 -0
  53. package/components/SessionList/SidebarHeader.tsx +5 -0
  54. package/components/SessionList/WorkspaceSwitcher.tsx +23 -6
  55. package/components/SessionList/index.tsx +18 -14
  56. package/components/SessionList/useSidebarData.ts +10 -0
  57. package/components/ui/notice.tsx +46 -0
  58. package/components/ui/status-pill.tsx +39 -0
  59. package/data/claims/index.ts +2 -0
  60. package/data/claims/keys.ts +5 -0
  61. package/data/claims/queries.ts +47 -0
  62. package/data/peers/keys.ts +1 -0
  63. package/data/peers/queries.ts +31 -0
  64. package/data/push/topics.ts +4 -0
  65. package/data/session-groups/index.ts +156 -0
  66. package/data/sessions/index.ts +0 -1
  67. package/data/sessions/pin.ts +2 -6
  68. package/data/sessions/queries.ts +10 -29
  69. package/data/sessions/shelf.ts +2 -6
  70. package/data/tasks/index.ts +2 -0
  71. package/hooks/useSessions.ts +0 -12
  72. package/lib/__fixtures__/peer-rpc.ts +65 -33
  73. package/lib/agents/spawn.ts +4 -0
  74. package/lib/bus/index.ts +8 -0
  75. package/lib/claims/collectLocal.ts +121 -0
  76. package/lib/claims/describe.ts +41 -0
  77. package/lib/claims/exchange.ts +91 -0
  78. package/lib/claims/goal.ts +45 -0
  79. package/lib/claims/index.ts +10 -0
  80. package/lib/claims/loop.ts +51 -0
  81. package/lib/claims/machine.ts +21 -0
  82. package/lib/claims/mine.ts +43 -0
  83. package/lib/claims/notifyOverlaps.ts +101 -0
  84. package/lib/claims/onMerged.ts +85 -0
  85. package/lib/claims/outside.ts +36 -0
  86. package/lib/claims/overlap.ts +87 -0
  87. package/lib/claims/overlapCache.ts +86 -0
  88. package/lib/claims/overlapText.ts +36 -0
  89. package/lib/claims/peers.ts +56 -0
  90. package/lib/claims/startCheck.ts +100 -0
  91. package/lib/claims/startWarning.ts +29 -0
  92. package/lib/claims/store.ts +366 -0
  93. package/lib/claims/types.ts +102 -0
  94. package/lib/claims/view.ts +80 -0
  95. package/lib/claims/yield.ts +24 -0
  96. package/lib/db/changes.ts +6 -0
  97. package/lib/db/migrations/20261020T1400_work_claims.ts +35 -0
  98. package/lib/db/migrations/20261020T1515_peer_unlinked.ts +22 -0
  99. package/lib/db/migrations/20261020T1700_clean_connect_names.ts +18 -0
  100. package/lib/db/migrations/20261020T1800_session_groups.ts +49 -0
  101. package/lib/db/migrations/20261020T1900_task_queue_after_claim.ts +13 -0
  102. package/lib/db/migrations/20261020T2000_claim_notices.ts +20 -0
  103. package/lib/db/migrations/20261020T2100_claims_via_host.ts +21 -0
  104. package/lib/db/migrations/20261020T2200_work_claims_watch.ts +10 -0
  105. package/lib/db/queries.ts +0 -40
  106. package/lib/db/session-parts/columns.ts +1 -0
  107. package/lib/db/types.ts +16 -8
  108. package/lib/doctor/checks.ts +64 -1
  109. package/lib/git-remote.ts +43 -0
  110. package/lib/hosts/index.ts +10 -1
  111. package/lib/orchestration.ts +2 -0
  112. package/lib/orchestrator/act.ts +54 -4
  113. package/lib/orchestrator/brief.ts +2 -1
  114. package/lib/orchestrator/claim-wait.ts +71 -0
  115. package/lib/orchestrator/conditions.ts +28 -1
  116. package/lib/orchestrator/describe.ts +6 -1
  117. package/lib/orchestrator/facts.ts +5 -0
  118. package/lib/orchestrator/serve.ts +37 -2
  119. package/lib/orchestrator/tool-names.ts +1 -0
  120. package/lib/orchestrator/tool-schemas.ts +31 -1
  121. package/lib/orchestrator/tools.ts +3 -1
  122. package/lib/orchestrator/watcher.ts +19 -1
  123. package/lib/peer/account.ts +74 -2
  124. package/lib/peer/allowlist.ts +1 -1
  125. package/lib/peer/client.ts +26 -1
  126. package/lib/peer/link-cli.ts +19 -4
  127. package/lib/peer/links.ts +117 -5
  128. package/lib/peer/machines.ts +14 -2
  129. package/lib/peer/name.ts +32 -0
  130. package/lib/peer/pairing.ts +34 -5
  131. package/lib/peer/pin.ts +10 -3
  132. package/lib/peer/reasons.ts +7 -0
  133. package/lib/peer/revoke.ts +75 -0
  134. package/lib/peer/rpc-server.ts +53 -5
  135. package/lib/peer/unlink.ts +62 -0
  136. package/lib/peer/unlinked-proof.ts +44 -0
  137. package/lib/projects.ts +5 -2
  138. package/lib/security/demo.ts +7 -0
  139. package/lib/session-groups/assignSessions.ts +81 -0
  140. package/lib/session-groups/cli.ts +61 -0
  141. package/lib/session-groups/createGroup.ts +28 -0
  142. package/lib/session-groups/index.ts +21 -0
  143. package/lib/session-groups/removeGroup.ts +36 -0
  144. package/lib/session-groups/reorderGroups.ts +31 -0
  145. package/lib/session-groups/resolveGroup.ts +19 -0
  146. package/lib/session-groups/route.ts +32 -0
  147. package/lib/session-groups/store.ts +85 -0
  148. package/lib/session-groups/types.ts +25 -0
  149. package/lib/session-groups/updateGroup.ts +35 -0
  150. package/lib/session-groups/workspace.ts +21 -0
  151. package/lib/sessions/launch.ts +5 -2
  152. package/lib/sidebar/rollup.ts +1 -0
  153. package/lib/sidebar/row-menu.ts +2 -0
  154. package/lib/sidebar/shelves.ts +90 -15
  155. package/lib/sidebar/visible-order.ts +5 -0
  156. package/lib/tasks/hold-checks.ts +3 -1
  157. package/lib/tasks/holds.ts +3 -0
  158. package/lib/tasks/index.ts +5 -0
  159. package/lib/tasks/queue-rows.ts +8 -1
  160. package/lib/tasks/queue-start.ts +1 -0
  161. package/lib/tasks/queue-types.ts +9 -1
  162. package/lib/tasks/queue.ts +15 -5
  163. package/lib/tasks/schedule-types.ts +1 -0
  164. package/lib/test-temp.ts +19 -3
  165. package/lib/workspaces.ts +11 -3
  166. package/lib/worktree-sweep/testTemp.ts +23 -106
  167. package/package.json +1 -1
  168. package/scripts/agent-os +1 -1
  169. package/scripts/autodeploy +2 -0
  170. package/scripts/autodeploy.test.ts +31 -1
  171. package/scripts/claim-hook.sh +31 -0
  172. package/scripts/claim-hook.test.ts +230 -0
  173. package/scripts/lib/cli-links.sh +36 -0
  174. package/scripts/lib/commands.sh +3 -0
  175. package/scripts/lib/machine.sh +27 -2
  176. package/scripts/lib/machine.test.ts +25 -3
  177. package/scripts/sync-cli-links +7 -0
  178. package/scripts/sync-cli-links.test.ts +69 -0
  179. package/server.ts +3 -0
  180. package/stores/claimsUi.ts +22 -0
  181. package/app/api/groups/[...path]/route.ts +0 -136
  182. package/app/api/groups/route.ts +0 -93
  183. package/data/groups/index.ts +0 -1
  184. package/data/groups/mutations.ts +0 -95
  185. package/hooks/useGroups.ts +0 -37
@@ -1,136 +0,0 @@
1
- import { NextResponse } from "next/server";
2
- import { db, queries, type Group } from "@/lib/db";
3
-
4
- // GET /api/groups/[...path] - Get a single group
5
- export async function GET(
6
- request: Request,
7
- { params }: { params: Promise<{ path: string[] }> }
8
- ) {
9
- const { path: pathParts } = await params;
10
- const path = pathParts.join("/");
11
-
12
- try {
13
- const group = queries.getGroup(db).get(path) as Group | undefined;
14
-
15
- if (!group) {
16
- return NextResponse.json({ error: "Group not found" }, { status: 404 });
17
- }
18
-
19
- return NextResponse.json({
20
- group: { ...group, expanded: Boolean(group.expanded) },
21
- });
22
- } catch (error) {
23
- console.error("Error fetching group:", error);
24
- return NextResponse.json(
25
- { error: "Failed to fetch group" },
26
- { status: 500 }
27
- );
28
- }
29
- }
30
-
31
- // PATCH /api/groups/[...path] - Update group (name, expanded, order)
32
- export async function PATCH(
33
- request: Request,
34
- { params }: { params: Promise<{ path: string[] }> }
35
- ) {
36
- const { path: pathParts } = await params;
37
- const path = pathParts.join("/");
38
-
39
- try {
40
- const body = await request.json();
41
- const { name, expanded, sort_order } = body;
42
-
43
- // Check if group exists
44
- const group = queries.getGroup(db).get(path) as Group | undefined;
45
- if (!group) {
46
- return NextResponse.json({ error: "Group not found" }, { status: 404 });
47
- }
48
-
49
- // Protect default group from being renamed
50
- if (path === "sessions" && name !== undefined && name !== "Sessions") {
51
- return NextResponse.json(
52
- { error: "Cannot rename the default group" },
53
- { status: 400 }
54
- );
55
- }
56
-
57
- // Update name
58
- if (name !== undefined) {
59
- queries.updateGroupName(db).run(name, path);
60
- }
61
-
62
- // Update expanded state
63
- if (expanded !== undefined) {
64
- queries.updateGroupExpanded(db).run(expanded ? 1 : 0, path);
65
- }
66
-
67
- // Update sort order
68
- if (sort_order !== undefined) {
69
- queries.updateGroupOrder(db).run(sort_order, path);
70
- }
71
-
72
- const updatedGroup = queries.getGroup(db).get(path) as Group;
73
- return NextResponse.json({
74
- group: { ...updatedGroup, expanded: Boolean(updatedGroup.expanded) },
75
- });
76
- } catch (error) {
77
- console.error("Error updating group:", error);
78
- return NextResponse.json(
79
- { error: "Failed to update group" },
80
- { status: 500 }
81
- );
82
- }
83
- }
84
-
85
- // DELETE /api/groups/[...path] - Delete group (moves sessions to parent or default)
86
- export async function DELETE(
87
- request: Request,
88
- { params }: { params: Promise<{ path: string[] }> }
89
- ) {
90
- const { path: pathParts } = await params;
91
- const path = pathParts.join("/");
92
-
93
- try {
94
- // Protect default group
95
- if (path === "sessions") {
96
- return NextResponse.json(
97
- { error: "Cannot delete the default group" },
98
- { status: 400 }
99
- );
100
- }
101
-
102
- // Check if group exists
103
- const group = queries.getGroup(db).get(path) as Group | undefined;
104
- if (!group) {
105
- return NextResponse.json({ error: "Group not found" }, { status: 404 });
106
- }
107
-
108
- // Find parent group or use default
109
- const pathParts2 = path.split("/");
110
- pathParts2.pop();
111
- const parentPath =
112
- pathParts2.length > 0 ? pathParts2.join("/") : "sessions";
113
-
114
- // Move all sessions in this group to parent
115
- queries.moveSessionsToGroup(db).run(parentPath, path);
116
-
117
- // Also move sessions from any subgroups
118
- const allGroups = queries.getAllGroups(db).all() as Group[];
119
- const subgroups = allGroups.filter((g) => g.path.startsWith(path + "/"));
120
- for (const subgroup of subgroups) {
121
- queries.moveSessionsToGroup(db).run(parentPath, subgroup.path);
122
- queries.deleteGroup(db).run(subgroup.path);
123
- }
124
-
125
- // Delete the group
126
- queries.deleteGroup(db).run(path);
127
-
128
- return NextResponse.json({ success: true, movedTo: parentPath });
129
- } catch (error) {
130
- console.error("Error deleting group:", error);
131
- return NextResponse.json(
132
- { error: "Failed to delete group" },
133
- { status: 500 }
134
- );
135
- }
136
- }
@@ -1,93 +0,0 @@
1
- import { NextResponse } from "next/server";
2
- import { db, queries, type Group } from "@/lib/db";
3
-
4
- // GET /api/groups - List all groups
5
- export async function GET() {
6
- try {
7
- const groups = queries.getAllGroups(db).all() as Group[];
8
-
9
- // Convert expanded from 0/1 to boolean
10
- const formattedGroups = groups.map((g) => ({
11
- ...g,
12
- expanded: Boolean(g.expanded),
13
- }));
14
-
15
- return NextResponse.json({ groups: formattedGroups });
16
- } catch (error) {
17
- console.error("Error fetching groups:", error);
18
- return NextResponse.json(
19
- { error: "Failed to fetch groups" },
20
- { status: 500 }
21
- );
22
- }
23
- }
24
-
25
- // POST /api/groups - Create a new group
26
- export async function POST(request: Request) {
27
- try {
28
- const body = await request.json();
29
- const { name, parentPath } = body;
30
-
31
- if (!name || typeof name !== "string") {
32
- return NextResponse.json({ error: "Name is required" }, { status: 400 });
33
- }
34
-
35
- // Sanitize name to create path
36
- const sanitizedName = name
37
- .toLowerCase()
38
- .replace(/[^a-z0-9-]/g, "-")
39
- .replace(/-+/g, "-")
40
- .replace(/^-|-$/g, "");
41
-
42
- if (!sanitizedName) {
43
- return NextResponse.json(
44
- { error: "Invalid group name" },
45
- { status: 400 }
46
- );
47
- }
48
-
49
- // Build full path
50
- const path = parentPath ? `${parentPath}/${sanitizedName}` : sanitizedName;
51
-
52
- // Check if group already exists
53
- const existing = queries.getGroup(db).get(path) as Group | undefined;
54
- if (existing) {
55
- return NextResponse.json(
56
- { error: "Group already exists", group: existing },
57
- { status: 409 }
58
- );
59
- }
60
-
61
- // If parent path specified, ensure parent exists
62
- if (parentPath) {
63
- const parent = queries.getGroup(db).get(parentPath) as Group | undefined;
64
- if (!parent) {
65
- return NextResponse.json(
66
- { error: "Parent group does not exist" },
67
- { status: 400 }
68
- );
69
- }
70
- }
71
-
72
- // Get max sort order for new group
73
- const groups = queries.getAllGroups(db).all() as Group[];
74
- const maxOrder = groups.reduce((max, g) => Math.max(max, g.sort_order), 0);
75
-
76
- // Create the group
77
- queries.createGroup(db).run(path, name, maxOrder + 1);
78
-
79
- const newGroup = queries.getGroup(db).get(path) as Group;
80
- return NextResponse.json(
81
- {
82
- group: { ...newGroup, expanded: Boolean(newGroup.expanded) },
83
- },
84
- { status: 201 }
85
- );
86
- } catch (error) {
87
- console.error("Error creating group:", error);
88
- return NextResponse.json(
89
- { error: "Failed to create group" },
90
- { status: 500 }
91
- );
92
- }
93
- }
@@ -1 +0,0 @@
1
- export { useToggleGroup, useCreateGroup, useDeleteGroup } from "./mutations";
@@ -1,95 +0,0 @@
1
- import { useMutation, useQueryClient } from "@tanstack/react-query";
2
- import { sessionKeys } from "../sessions/keys";
3
-
4
- export function useToggleGroup() {
5
- const queryClient = useQueryClient();
6
-
7
- return useMutation({
8
- mutationFn: async ({
9
- path,
10
- expanded,
11
- }: {
12
- path: string;
13
- expanded: boolean;
14
- }) => {
15
- const res = await fetch(`/api/groups/${encodeURIComponent(path)}`, {
16
- method: "PATCH",
17
- headers: { "Content-Type": "application/json" },
18
- body: JSON.stringify({ expanded }),
19
- });
20
- if (!res.ok) throw new Error("Failed to toggle group");
21
- return res.json();
22
- },
23
- onMutate: async ({ path, expanded }) => {
24
- await queryClient.cancelQueries({ queryKey: sessionKeys.list() });
25
- const previous = queryClient.getQueryData(sessionKeys.list());
26
- queryClient.setQueryData(
27
- sessionKeys.list(),
28
- (
29
- old:
30
- | {
31
- sessions: unknown[];
32
- groups: Array<{ path: string; expanded: boolean }>;
33
- }
34
- | undefined
35
- ) =>
36
- old
37
- ? {
38
- ...old,
39
- groups: old.groups.map((g) =>
40
- g.path === path ? { ...g, expanded } : g
41
- ),
42
- }
43
- : old
44
- );
45
- return { previous };
46
- },
47
- onError: (_, __, context) => {
48
- if (context?.previous) {
49
- queryClient.setQueryData(sessionKeys.list(), context.previous);
50
- }
51
- },
52
- });
53
- }
54
-
55
- export function useCreateGroup() {
56
- const queryClient = useQueryClient();
57
-
58
- return useMutation({
59
- mutationFn: async ({
60
- name,
61
- parentPath,
62
- }: {
63
- name: string;
64
- parentPath?: string;
65
- }) => {
66
- const res = await fetch("/api/groups", {
67
- method: "POST",
68
- headers: { "Content-Type": "application/json" },
69
- body: JSON.stringify({ name, parentPath }),
70
- });
71
- if (!res.ok) throw new Error("Failed to create group");
72
- return res.json();
73
- },
74
- onSuccess: () => {
75
- queryClient.invalidateQueries({ queryKey: sessionKeys.list() });
76
- },
77
- });
78
- }
79
-
80
- export function useDeleteGroup() {
81
- const queryClient = useQueryClient();
82
-
83
- return useMutation({
84
- mutationFn: async (path: string) => {
85
- const res = await fetch(`/api/groups/${encodeURIComponent(path)}`, {
86
- method: "DELETE",
87
- });
88
- if (!res.ok) throw new Error("Failed to delete group");
89
- return res.json();
90
- },
91
- onSuccess: () => {
92
- queryClient.invalidateQueries({ queryKey: sessionKeys.list() });
93
- },
94
- });
95
- }
@@ -1,37 +0,0 @@
1
- import { useCallback } from "react";
2
- import { useToggleGroup, useCreateGroup, useDeleteGroup } from "@/data/groups";
3
-
4
- export function useGroups() {
5
- const toggleMutation = useToggleGroup();
6
- const createMutation = useCreateGroup();
7
- const deleteMutation = useDeleteGroup();
8
-
9
- const toggleGroup = useCallback(
10
- async (path: string, expanded: boolean) => {
11
- await toggleMutation.mutateAsync({ path, expanded });
12
- },
13
- [toggleMutation]
14
- );
15
-
16
- const createGroup = useCallback(
17
- async (name: string, parentPath?: string) => {
18
- await createMutation.mutateAsync({ name, parentPath });
19
- },
20
- [createMutation]
21
- );
22
-
23
- const deleteGroup = useCallback(
24
- async (path: string) => {
25
- if (!confirm("Delete this group? Sessions will be moved to parent."))
26
- return;
27
- await deleteMutation.mutateAsync(path);
28
- },
29
- [deleteMutation]
30
- );
31
-
32
- return {
33
- toggleGroup,
34
- createGroup,
35
- deleteGroup,
36
- };
37
- }