@controlflow-ai/daemon 0.1.2 → 0.1.3

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 (61) hide show
  1. package/README.md +54 -6
  2. package/package.json +3 -1
  3. package/src/agent-avatar.ts +30 -0
  4. package/src/agent-key.ts +28 -0
  5. package/src/agent-permissions.ts +359 -0
  6. package/src/agent-runtime.ts +795 -28
  7. package/src/agent-workspace.ts +183 -0
  8. package/src/app.ts +1970 -79
  9. package/src/args.ts +54 -7
  10. package/src/cli.ts +873 -14
  11. package/src/client.ts +472 -10
  12. package/src/coco.ts +9 -40
  13. package/src/codex.ts +33 -5
  14. package/src/config.ts +28 -4
  15. package/src/console.ts +230 -20
  16. package/src/daemon-client.ts +116 -3
  17. package/src/daemon.ts +936 -98
  18. package/src/db.ts +3128 -122
  19. package/src/delivery-ws.ts +269 -0
  20. package/src/format.ts +4 -1
  21. package/src/lark/cli.ts +3 -3
  22. package/src/lark/event-router.ts +60 -4
  23. package/src/lark/inbound-events.ts +156 -3
  24. package/src/lark/server-integration.ts +659 -111
  25. package/src/lark/ws-daemon.ts +136 -10
  26. package/src/local-api.ts +545 -15
  27. package/src/local-auth.ts +33 -1
  28. package/src/message-attachments.ts +71 -0
  29. package/src/messaging-cli.ts +741 -0
  30. package/src/messaging-status.ts +669 -0
  31. package/src/migrations/024_agents_model.ts +10 -0
  32. package/src/migrations/025_room_archive.ts +44 -0
  33. package/src/migrations/026_project_archive.ts +44 -0
  34. package/src/migrations/027_agent_permission_profiles.ts +16 -0
  35. package/src/migrations/028_lark_websocket_restart_state.ts +16 -0
  36. package/src/migrations/029_held_message_drafts.ts +32 -0
  37. package/src/migrations/030_agent_room_read_state.ts +25 -0
  38. package/src/migrations/031_room_tasks.ts +29 -0
  39. package/src/migrations/032_room_reminders.ts +29 -0
  40. package/src/migrations/033_room_saved_messages.ts +25 -0
  41. package/src/migrations/034_agent_activity_events.ts +27 -0
  42. package/src/migrations/035_agent_avatars.ts +17 -0
  43. package/src/migrations/036_project_agent_defaults.ts +21 -0
  44. package/src/migrations/037_message_attachments.ts +36 -0
  45. package/src/migrations/038_agent_activity_room_scope.ts +64 -0
  46. package/src/migrations/039_message_attachments_path.ts +34 -0
  47. package/src/migrations/040_message_attachments_file_schema.ts +80 -0
  48. package/src/migrations/041_room_system_events.ts +30 -0
  49. package/src/migrations/042_message_attachment_file_kind.ts +52 -0
  50. package/src/migrations/043_room_mode_skill_registry.ts +92 -0
  51. package/src/migrations/044_workflow_runtime.ts +69 -0
  52. package/src/migrations/045_skill_repository_ownership.ts +64 -0
  53. package/src/migrations.ts +69 -1
  54. package/src/neeko.ts +40 -4
  55. package/src/runtime-env.ts +179 -0
  56. package/src/runtime-registry.ts +83 -13
  57. package/src/server.ts +244 -4
  58. package/src/token-file.ts +13 -6
  59. package/src/types.ts +362 -0
  60. package/src/workflow-runtime.ts +275 -0
  61. package/src/web.ts +0 -904
@@ -1,7 +1,7 @@
1
1
  import { defaultDaemonToken, defaultDaemonUrl } from './config.js';
2
2
  import { localHeaders } from './local-auth.js';
3
- import type { AgentRoomSubscriptionMode, AgentRun, ApiResponse, Chat, Message, RoomChannel, RoomParticipant, RunAction } from './types.js';
4
- import type { CreateArtifactRequest, SendRequest } from './client.js';
3
+ import type { AgentRoomSubscriptionMode, AgentRun, ApiResponse, Chat, HeldMessageDraft, Message, RoomChannel, RoomParticipant, RoomReminder, RoomSavedMessage, RoomTask, RoomTaskStatus, RunAction } from './types.js';
4
+ import type { ClaimRoomTaskRequest, CreateArtifactRequest, CreateHandoffRoomRequest, CreateRoomReminderRequest, CreateRoomSavedMessageRequest, CreateRoomTasksRequest, HeldDraftResolutionResult, ListHeldDraftsRequest, ListRoomRemindersRequest, ListRoomSavedMessagesRequest, SendMessageResult, SendRequest } from './client.js';
5
5
 
6
6
  export class DaemonClient {
7
7
  readonly baseUrl: string;
@@ -17,10 +17,41 @@ export class DaemonClient {
17
17
  }
18
18
 
19
19
  async sendMessage(input: SendRequest): Promise<Message> {
20
- const data = await this.post<{ message: Message }>('/local/messages', input);
20
+ const data = await this.sendMessageResult(input);
21
+ if (!data.message) throw new Error('message was held as a draft');
21
22
  return data.message;
22
23
  }
23
24
 
25
+ async sendMessageResult(input: SendRequest): Promise<SendMessageResult> {
26
+ return this.post<SendMessageResult>('/local/messages', input);
27
+ }
28
+
29
+ async listHeldDrafts(input: ListHeldDraftsRequest = {}): Promise<HeldMessageDraft[]> {
30
+ const params = new URLSearchParams();
31
+ if (input.agent) params.set('agent', input.agent);
32
+ if (input.room_id) params.set('room_id', input.room_id);
33
+ params.set('status', input.status ?? 'held');
34
+ params.set('limit', String(input.limit ?? 50));
35
+ const data = await this.get<{ drafts: HeldMessageDraft[] }>(`/local/held-drafts?${params}`);
36
+ return data.drafts;
37
+ }
38
+
39
+ async abandonHeldDraft(id: string): Promise<HeldDraftResolutionResult> {
40
+ return this.post<HeldDraftResolutionResult>(`/local/held-drafts/${encodeURIComponent(id)}/abandon`, {});
41
+ }
42
+
43
+ async staySilentHeldDraft(id: string): Promise<HeldDraftResolutionResult> {
44
+ return this.abandonHeldDraft(id);
45
+ }
46
+
47
+ async sendHeldDraftAnyway(id: string): Promise<HeldDraftResolutionResult> {
48
+ return this.post<HeldDraftResolutionResult>(`/local/held-drafts/${encodeURIComponent(id)}/send-anyway`, {});
49
+ }
50
+
51
+ async reviseHeldDraft(id: string, content: string): Promise<HeldDraftResolutionResult> {
52
+ return this.post<HeldDraftResolutionResult>(`/local/held-drafts/${encodeURIComponent(id)}/revise`, { content });
53
+ }
54
+
24
55
  async getMessages(params: URLSearchParams): Promise<Message[]> {
25
56
  const data = await this.get<{ messages: Message[] }>(`/local/messages?${params}`);
26
57
  return data.messages;
@@ -44,11 +75,85 @@ export class DaemonClient {
44
75
  return this.post<unknown>(`/local/rooms/${encodeURIComponent(room)}/agents`, input);
45
76
  }
46
77
 
78
+ async createHandoffRoom(input: CreateHandoffRoomRequest): Promise<{ room: Chat; message: Message | null; deliveries: unknown[]; notify: unknown }> {
79
+ return this.post<{ room: Chat; message: Message | null; deliveries: unknown[]; notify: unknown }>('/local/rooms/handoff', input);
80
+ }
81
+
47
82
  async createTopic(room: string, input: { name: string; created_by?: string | null }): Promise<RoomChannel> {
48
83
  const data = await this.post<{ channel: RoomChannel }>(`/local/rooms/${encodeURIComponent(room)}/topics`, input);
49
84
  return data.channel;
50
85
  }
51
86
 
87
+ async listRoomTasks(room: string, status: RoomTaskStatus | 'all' = 'all', limit = 50): Promise<RoomTask[]> {
88
+ const params = new URLSearchParams({ status, limit: String(limit) });
89
+ const data = await this.get<{ tasks: RoomTask[] }>(`/local/rooms/${encodeURIComponent(room)}/tasks?${params}`);
90
+ return data.tasks;
91
+ }
92
+
93
+ async createRoomTasks(room: string, input: CreateRoomTasksRequest): Promise<RoomTask[]> {
94
+ const data = await this.post<{ tasks: RoomTask[] }>(`/local/rooms/${encodeURIComponent(room)}/tasks`, input);
95
+ return data.tasks;
96
+ }
97
+
98
+ async claimRoomTask(room: string, taskNumber: number, input: ClaimRoomTaskRequest): Promise<RoomTask> {
99
+ const data = await this.post<{ task: RoomTask }>(`/local/rooms/${encodeURIComponent(room)}/tasks/${taskNumber}/claim`, input);
100
+ return data.task;
101
+ }
102
+
103
+ async unclaimRoomTask(room: string, taskNumber: number): Promise<RoomTask> {
104
+ const data = await this.post<{ task: RoomTask }>(`/local/rooms/${encodeURIComponent(room)}/tasks/${taskNumber}/unclaim`, {});
105
+ return data.task;
106
+ }
107
+
108
+ async updateRoomTaskStatus(room: string, taskNumber: number, status: RoomTaskStatus): Promise<RoomTask> {
109
+ const data = await this.patch<{ task: RoomTask }>(`/local/rooms/${encodeURIComponent(room)}/tasks/${taskNumber}`, { status });
110
+ return data.task;
111
+ }
112
+
113
+ async restartRoomAgent(room: string, agent: string): Promise<AgentRun> {
114
+ const data = await this.post<{ run: AgentRun }>(`/local/rooms/${encodeURIComponent(room)}/agents/${encodeURIComponent(agent)}/restart`, {});
115
+ return data.run;
116
+ }
117
+
118
+ async scheduleReminder(input: CreateRoomReminderRequest): Promise<RoomReminder> {
119
+ const data = await this.post<{ reminder: RoomReminder }>('/local/reminders', input);
120
+ return data.reminder;
121
+ }
122
+
123
+ async listReminders(input: ListRoomRemindersRequest = {}): Promise<RoomReminder[]> {
124
+ const params = new URLSearchParams();
125
+ params.set('status', input.status ?? 'scheduled');
126
+ if (input.created_by) params.set('created_by', input.created_by);
127
+ if (input.room_id) params.set('room_id', input.room_id);
128
+ params.set('limit', String(input.limit ?? 50));
129
+ const data = await this.get<{ reminders: RoomReminder[] }>(`/local/reminders?${params}`);
130
+ return data.reminders;
131
+ }
132
+
133
+ async cancelReminder(id: string): Promise<RoomReminder> {
134
+ const data = await this.post<{ reminder: RoomReminder }>(`/local/reminders/${encodeURIComponent(id)}/cancel`, {});
135
+ return data.reminder;
136
+ }
137
+
138
+ async saveMessage(input: CreateRoomSavedMessageRequest): Promise<RoomSavedMessage> {
139
+ const data = await this.post<{ saved_message: RoomSavedMessage }>('/local/saved-messages', input);
140
+ return data.saved_message;
141
+ }
142
+
143
+ async listSavedMessages(input: ListRoomSavedMessagesRequest = {}): Promise<RoomSavedMessage[]> {
144
+ const params = new URLSearchParams();
145
+ if (input.saved_by) params.set('saved_by', input.saved_by);
146
+ if (input.room_id) params.set('room_id', input.room_id);
147
+ params.set('limit', String(input.limit ?? 50));
148
+ const data = await this.get<{ saved_messages: RoomSavedMessage[] }>(`/local/saved-messages?${params}`);
149
+ return data.saved_messages;
150
+ }
151
+
152
+ async removeSavedMessage(id: string): Promise<RoomSavedMessage> {
153
+ const data = await this.post<{ saved_message: RoomSavedMessage }>(`/local/saved-messages/${encodeURIComponent(id)}/delete`, {});
154
+ return data.saved_message;
155
+ }
156
+
52
157
  async getMessage(id: number): Promise<Message> {
53
158
  const data = await this.get<{ message: Message }>(`/local/messages/${id}`);
54
159
  return data.message;
@@ -80,6 +185,14 @@ export class DaemonClient {
80
185
  });
81
186
  }
82
187
 
188
+ private async patch<T>(path: string, body: unknown): Promise<T> {
189
+ return this.request<T>(path, {
190
+ method: 'PATCH',
191
+ headers: { 'content-type': 'application/json', ...localHeaders(this.token) },
192
+ body: JSON.stringify(body),
193
+ });
194
+ }
195
+
83
196
  private async request<T>(path: string, init: RequestInit): Promise<T> {
84
197
  const response = await fetch(`${this.baseUrl}${path}`, init);
85
198
  const payload = await response.json() as ApiResponse<T>;