crow-central-agency 0.27.13 → 0.27.15

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 (67) hide show
  1. package/dist/_shared/constants/markdown-constants.js +2 -0
  2. package/dist/_shared/index.js +3 -1
  3. package/dist/_shared/schemas/agent-task.schema.js +4 -0
  4. package/dist/_shared/schemas/agent.schema.js +1 -3
  5. package/dist/_shared/schemas/message-source.schema.js +5 -1
  6. package/dist/_shared/schemas/schedule.schema.js +51 -0
  7. package/dist/_shared/schemas/session-history.schema.js +6 -0
  8. package/dist/bootstrap.js +9 -4
  9. package/dist/config/constants.js +2 -0
  10. package/dist/config/env.js +13 -1
  11. package/dist/connectors/connector-manager.js +7 -2
  12. package/dist/feed/simply-feed-manager.js +6 -1
  13. package/dist/public/assets/{abnfDiagram-N423BO3Z-BTzNytBQ.js → abnfDiagram-N423BO3Z-CU140Yav.js} +1 -1
  14. package/dist/public/assets/{architectureDiagram-T3A2C74G-BYApDxgU.js → architectureDiagram-T3A2C74G-DReYF096.js} +1 -1
  15. package/dist/public/assets/{chunk-5RXB4S5H-Fp-R9qL4.js → chunk-5RXB4S5H-BZ0ixv_E.js} +1 -1
  16. package/dist/public/assets/{chunk-6Q2QTUOP-CX0EHawl.js → chunk-6Q2QTUOP-DFiMjxDw.js} +1 -1
  17. package/dist/public/assets/{chunk-GF5L2VYU-BOGXfgbr.js → chunk-GF5L2VYU-CpKWu_KQ.js} +1 -1
  18. package/dist/public/assets/{chunk-JQJVKLGR-DsukIx_C.js → chunk-JQJVKLGR-CmpH1irT.js} +1 -1
  19. package/dist/public/assets/{classDiagram-JCYQIIEL-DRZ3R-Kd.js → classDiagram-JCYQIIEL-CAT7ppaQ.js} +1 -1
  20. package/dist/public/assets/{classDiagram-v2-OCEON4UE-DRZ3R-Kd.js → classDiagram-v2-OCEON4UE-CAT7ppaQ.js} +1 -1
  21. package/dist/public/assets/{cynefinDiagram-MW4NZA55-D7X9A9vx.js → cynefinDiagram-MW4NZA55--eLZ_1al.js} +1 -1
  22. package/dist/public/assets/{dagre-VZM6K2ZE-IhDESsRv.js → dagre-VZM6K2ZE-DN_jLiOk.js} +1 -1
  23. package/dist/public/assets/{diagram-7IWD3JNH-y_FbgptT.js → diagram-7IWD3JNH-CA7g8KIg.js} +1 -1
  24. package/dist/public/assets/{diagram-LBJQPF4R-BPrP4-xG.js → diagram-LBJQPF4R-U1Vx5_-s.js} +1 -1
  25. package/dist/public/assets/{diagram-Q27KOJAE-D_5e2qW2.js → diagram-Q27KOJAE-Dx6s2DzP.js} +1 -1
  26. package/dist/public/assets/{diagram-UB23O5K3-BlLbX7K5.js → diagram-UB23O5K3-b0BnXUtU.js} +1 -1
  27. package/dist/public/assets/{ebnfDiagram-BXEA7PRR-BmG7DXeJ.js → ebnfDiagram-BXEA7PRR-C95Bwx8t.js} +1 -1
  28. package/dist/public/assets/{erDiagram-JOGREHBK-CjwzbHIW.js → erDiagram-JOGREHBK-DK4B0aAF.js} +1 -1
  29. package/dist/public/assets/{flowDiagram-UKHOOZJN-IgtDW7k1.js → flowDiagram-UKHOOZJN-BZk42EDr.js} +1 -1
  30. package/dist/public/assets/{index-BkQmIm3H.js → index-DCds53oP.js} +64 -64
  31. package/dist/public/assets/index-HE5YVzwx.css +1 -0
  32. package/dist/public/assets/{infoDiagram-6WML65LV-DVKIsMBj.js → infoDiagram-6WML65LV-FmxDfVvb.js} +1 -1
  33. package/dist/public/assets/{ishikawaDiagram-WSZJBQD7-CZ3CpgJY.js → ishikawaDiagram-WSZJBQD7-D2dz6TfW.js} +1 -1
  34. package/dist/public/assets/{kanban-definition-27J2QSJJ-CRTkmIYm.js → kanban-definition-27J2QSJJ-YFF_1ZCM.js} +1 -1
  35. package/dist/public/assets/{mindmap-definition-FAOFIHXS-LpdmnoNx.js → mindmap-definition-FAOFIHXS-DgYHEOpF.js} +1 -1
  36. package/dist/public/assets/{pegDiagram-VL7TDLO6-DZqIFDrD.js → pegDiagram-VL7TDLO6-BB9FgiwR.js} +1 -1
  37. package/dist/public/assets/{pieDiagram-7S7Q4E2Y-DsNzVyqU.js → pieDiagram-7S7Q4E2Y-Dfg-fUYa.js} +1 -1
  38. package/dist/public/assets/{railroadDiagram-AXF67PYL-BE9wpeuN.js → railroadDiagram-AXF67PYL-DOuTSk1T.js} +1 -1
  39. package/dist/public/assets/{requirementDiagram-LRYGKXZP-DKoDwzBv.js → requirementDiagram-LRYGKXZP-kqFVGZ4d.js} +1 -1
  40. package/dist/public/assets/{sequenceDiagram-SI44F4Z6-DZdbV6_M.js → sequenceDiagram-SI44F4Z6-PQSpBgnT.js} +1 -1
  41. package/dist/public/assets/{stateDiagram-OKZ733FA-DBHguF_b.js → stateDiagram-OKZ733FA-DX9ego1o.js} +1 -1
  42. package/dist/public/assets/{stateDiagram-v2-UEYNNEHI-DavTfwOw.js → stateDiagram-v2-UEYNNEHI-DuGxInxi.js} +1 -1
  43. package/dist/public/assets/{swimlanes-SLNWSIFB-CeSF2wS9.js → swimlanes-SLNWSIFB-DGT-jeQq.js} +1 -1
  44. package/dist/public/assets/{swimlanesDiagram-ULZ7WXOC-761wH2FA.js → swimlanesDiagram-ULZ7WXOC-CPAX0wH6.js} +1 -1
  45. package/dist/public/assets/{timeline-definition-Z64GVDOM-DlWVuVTj.js → timeline-definition-Z64GVDOM-DCVM8Joc.js} +1 -1
  46. package/dist/public/assets/{vennDiagram-T6HMQDX7-D3-_cCYz.js → vennDiagram-T6HMQDX7-C-Ysnzed.js} +1 -1
  47. package/dist/public/assets/{wardleyDiagram-T6FBY63Y-2wtzfT5s.js → wardleyDiagram-T6FBY63Y-2DJXqb1q.js} +1 -1
  48. package/dist/public/assets/{xychartDiagram-ELKLHX3M-tAtfWXaV.js → xychartDiagram-ELKLHX3M-CrfJfB_d.js} +1 -1
  49. package/dist/public/index.html +2 -2
  50. package/dist/routes/agent.routes.js +17 -2
  51. package/dist/routes/schedule.routes.js +64 -0
  52. package/dist/routines/agent-schedule-routine.js +44 -0
  53. package/dist/routines/inter-agent-task-routine.js +4 -1
  54. package/dist/routines/routine-manager.js +10 -5
  55. package/dist/runner/agent-runner.js +37 -13
  56. package/dist/runner/github-copilot-stream-processor.js +3 -2
  57. package/dist/runner/tool-activity-parser-utils.js +10 -0
  58. package/dist/services/agent-registry.js +29 -4
  59. package/dist/services/crow-scheduler.js +31 -77
  60. package/dist/services/runtime/agent-runtime-manager.js +14 -3
  61. package/dist/services/runtime/session-history.js +9 -10
  62. package/dist/services/schedule-manager.js +228 -0
  63. package/dist/services/schedule-manager.types.js +2 -0
  64. package/dist/services/session/github-copilot-session-transformer.js +2 -1
  65. package/package.json +5 -5
  66. package/dist/public/assets/index-swT9N_8Z.css +0 -1
  67. package/dist/routines/agent-loop-routine.js +0 -32
@@ -0,0 +1,2 @@
1
+ export const HTMLVIEW_FENCE_LANG = "htmlview";
2
+ //# sourceMappingURL=markdown-constants.js.map
@@ -1,5 +1,7 @@
1
+ export { HTMLVIEW_FENCE_LANG } from "./constants/markdown-constants.js";
1
2
  export { CLAUDE_MODELS, GITHUB_COPILOT_MODELS, CLAUDE_CODE_MODEL_OPTIONS, ModelOptionSchema, REASONING_EFFORT, ReasoningEffortSchema, THINKING_MODE, CLAUDE_DEFAULT_MODEL, COPILOT_DEFAULT_MODEL, CLAUDE_AUTO_COMPACT_TOKENS_MIN, CLAUDE_AUTO_COMPACT_TOKENS_MAX, COPILOT_AUTO_COMPACT_UTILIZATION_MAX, AgentIdSchema, AgentConfigSchema, AgentConfigTemplateSchema, CreateAgentInputSchema, UpdateAgentInputSchema, ToolConfigSchema, PermissionModeSchema, SettingSourceSchema, DiscoveredSkillSchema, LoopConfigSchema, ConfiguredFeedSchema, MAX_LOOP_TIMES, PERMISSION_MODE, SETTING_SOURCE, DEFAULT_SETTING_SOURCES, TOOL_MODE, CLAUDE_CODE_TOOL, GITHUB_COPILOT_TOOL, DEFAULT_CLAUDE_CODE_AVAILABLE_TOOLS, DEFAULT_GITHUB_COPILOT_AVAILABLE_TOOLS, DEFAULT_AVAILABLE_TOOLS_BY_TYPE, SUBAGENT_TOOL_NAME, AGENT_TYPE, AgentTypeSchema, DEFAULT_AGENT_TYPE, AGENT_NAME_MAX_LENGTH, } from "./schemas/agent.schema.js";
2
3
  export { SchedulerTimeSchema, DAY_OF_WEEK, DayOfWeekSchema, TimeModeSchema, TIME_MODE, } from "./schemas/scheduler.schema.js";
4
+ export { SCHEDULE_NAME_MAX_LENGTH, MAX_SCHEDULE_TIMES, ScheduleSchema, CreateScheduleInputSchema, UpdateScheduleInputSchema, } from "./schemas/schedule.schema.js";
3
5
  export { createApiSuccessSchema, ApiErrorSchema, } from "./schemas/api-response.schema.js";
4
6
  export { SessionUsageSchema, BranchPointSchema, SessionHistorySchema, PendingPermissionInfoSchema, PendingInstructionReminderSchema, AgentRuntimeStateSchema, AgentActivitySchema, AGENT_ACTIVITY_TYPE, AGENT_STATUS, MAX_INPUT_HISTORY, MAX_SESSION_HISTORY, } from "./schemas/agent-runtime-state.schema.js";
5
7
  export { ClientMessageSchema, ServerMessageSchema, SendMessageSchema, InjectMessageSchema, PermissionResponseWsSchema, ResolveQuestionWsSchema, CommandMessageSchema, AgentTextWsMessageSchema, AgentActivityWsMessageSchema, AgentResultWsMessageSchema, AgentStatusWsMessageSchema, AgentCreatedWsMessageSchema, AgentUpdatedWsMessageSchema, AgentDeletedWsMessageSchema, AgentUsageWsMessageSchema, PermissionRequestWsMessageSchema, PermissionCancelledWsMessageSchema, QuestionRequestWsMessageSchema, QuestionResolvedWsMessageSchema, ErrorWsMessageSchema, AgentMessageWsMessageSchema, AgentToolProgressWsMessageSchema, TaskAddedWsMessageSchema, TaskUpdatedWsMessageSchema, TaskAssignedWsMessageSchema, TaskStateChangedWsMessageSchema, TaskDeletedWsMessageSchema, CircleCreatedWsMessageSchema, CircleUpdatedWsMessageSchema, CircleDeletedWsMessageSchema, RelationshipCreatedWsMessageSchema, RelationshipDeletedWsMessageSchema, FragmentCreatedWsMessageSchema, FragmentUpdatedWsMessageSchema, FragmentDeletedWsMessageSchema, AgentBuilderDraftUpdatedWsMessageSchema, AgentSessionsUpdatedWsMessageSchema, isAgentServerMessage, isAgentLifecycleServerMessage, CLIENT_MESSAGE_TYPE, SERVER_MESSAGE_TYPE, } from "./schemas/websocket.schema.js";
@@ -26,7 +28,7 @@ export { REFLECTION_AGENT_REF, REFLECTION_TEMP_PREFIX, REFLECTION_OP, Reflection
26
28
  export { MESSAGE_SOURCE_TYPE, MessageSourceSchema, } from "./schemas/message-source.schema.js";
27
29
  export { AGENT_COMMAND, AgentCommandSchema } from "./schemas/agent-command.schema.js";
28
30
  export { GraphNodePositionSchema, GraphNodeSchema, GraphEdgeSchema, GraphDataSchema, } from "./schemas/graph.schema.js";
29
- export { SessionHistoryNodeSchema } from "./schemas/session-history.schema.js";
31
+ export { SessionHistoryNodeSchema, RenameSessionRequestSchema, SESSION_LABEL_MAX_LENGTH, } from "./schemas/session-history.schema.js";
30
32
  export { ConnectorConnectionSchema, ConnectorInfoSchema, ConnectConnectorResponseSchema, } from "./schemas/connector.schema.js";
31
33
  export { parseRule, parseRules, formatRule, matchesSpecifier, GLOB_STAR, WORD_BOUNDARY_SUFFIX, PREFIX_STAR_SUFFIX, } from "./utils/permission-rule/rule-format.js";
32
34
  export { normalizeMcpName } from "./utils/mcp-utils.js";
@@ -22,6 +22,10 @@ const AgentSourceSchema = z.object({
22
22
  });
23
23
  const LoopSourceSchema = z.object({
24
24
  sourceType: z.literal(AGENT_TASK_SOURCE_TYPE.LOOP),
25
+ /** Set when the task originated from a top-level schedule rather than a legacy agent loop */
26
+ scheduleId: z.string().optional(),
27
+ /** Carries the schedule's new-session choice from fire time to dispatch */
28
+ newSession: z.boolean().optional(),
25
29
  });
26
30
  const ReminderSourceSchema = z.object({
27
31
  sourceType: z.literal(AGENT_TASK_SOURCE_TYPE.REMINDER),
@@ -351,6 +351,7 @@ export const AgentConfigSchema = z.object({
351
351
  mcpServerIds: z.array(z.string()).optional(),
352
352
  configuredFeeds: z.array(ConfiguredFeedSchema).optional(),
353
353
  sensorIds: z.array(z.string()).optional(),
354
+ /** @deprecated Legacy agent loop. Read only by ScheduleManager.migrateAgentLoops; no write path remains. */
354
355
  loop: LoopConfigSchema.optional(),
355
356
  discordConfig: DiscordConfigSchema.optional(),
356
357
  persistSession: z.boolean().optional(),
@@ -385,7 +386,6 @@ export const CreateAgentInputSchema = z.object({
385
386
  mcpServerIds: z.array(z.string()).optional(),
386
387
  configuredFeeds: z.array(ConfiguredFeedSchema).optional(),
387
388
  sensorIds: z.array(z.string()).optional(),
388
- loop: LoopConfigSchema.optional(),
389
389
  discordConfig: DiscordConfigSchema.optional(),
390
390
  excludeClaudeCodeSystemPrompt: z.boolean().optional(),
391
391
  enableGmailNotification: z.boolean().optional(),
@@ -411,7 +411,6 @@ export const UpdateAgentInputSchema = z.object({
411
411
  mcpServerIds: z.array(z.string()).optional(),
412
412
  configuredFeeds: z.array(ConfiguredFeedSchema).optional(),
413
413
  sensorIds: z.array(z.string()).optional(),
414
- loop: LoopConfigSchema.optional(),
415
414
  discordConfig: DiscordConfigSchema.optional(),
416
415
  isPinned: z.boolean().optional(),
417
416
  excludeClaudeCodeSystemPrompt: z.boolean().optional(),
@@ -434,7 +433,6 @@ export const AgentConfigTemplateSchema = AgentConfigSchema.pick({
434
433
  mcpServerIds: true,
435
434
  configuredFeeds: true,
436
435
  sensorIds: true,
437
- loop: true,
438
436
  }).extend({
439
437
  templateId: z.uuid(),
440
438
  templateName: z.string().min(1).max(64),
@@ -18,7 +18,11 @@ export const MessageSourceSchema = z.discriminatedUnion("sourceType", [
18
18
  z.object({ sourceType: z.literal(MESSAGE_SOURCE_TYPE.USER) }),
19
19
  z.object({ sourceType: z.literal(MESSAGE_SOURCE_TYPE.LOOP) }),
20
20
  z.object({ sourceType: z.literal(MESSAGE_SOURCE_TYPE.AGENT), agentId: z.string() }),
21
- z.object({ sourceType: z.literal(MESSAGE_SOURCE_TYPE.TASK), taskId: z.string() }),
21
+ z.object({
22
+ sourceType: z.literal(MESSAGE_SOURCE_TYPE.TASK),
23
+ taskId: z.string(),
24
+ newSession: z.boolean().optional(),
25
+ }),
22
26
  z.object({ sourceType: z.literal(MESSAGE_SOURCE_TYPE.TASK_RESULT), taskId: z.string() }),
23
27
  z.object({ sourceType: z.literal(MESSAGE_SOURCE_TYPE.RECOVERY) }),
24
28
  z.object({ sourceType: z.literal(MESSAGE_SOURCE_TYPE.NOTIFICATION) }),
@@ -0,0 +1,51 @@
1
+ import { z } from "zod";
2
+ import { DayOfWeekSchema, SchedulerTimeSchema, TIME_MODE, TimeModeSchema } from "./scheduler.schema.js";
3
+ /** Maximum length of a schedule name, enforced on the create/update input path. */
4
+ export const SCHEDULE_NAME_MAX_LENGTH = 64;
5
+ /** Maximum number of time entries allowed in a schedule */
6
+ export const MAX_SCHEDULE_TIMES = 12;
7
+ /**
8
+ * A top-level schedule owned by the scheduler subsystem.
9
+ * On fire it creates one task per target agent.
10
+ */
11
+ export const ScheduleSchema = z.object({
12
+ id: z.uuid(),
13
+ name: z.string().min(1).max(SCHEDULE_NAME_MAX_LENGTH),
14
+ message: z.string().min(1),
15
+ enabled: z.boolean().default(false),
16
+ agentIds: z.array(z.string()).default([]),
17
+ /** Empty means every day */
18
+ daysOfWeek: z.array(DayOfWeekSchema).default([]),
19
+ timeMode: TimeModeSchema.default(TIME_MODE.EVERY),
20
+ times: z.array(SchedulerTimeSchema).min(1).max(MAX_SCHEDULE_TIMES).default([{}]),
21
+ newSession: z.boolean().default(false),
22
+ createdAt: z.iso.datetime({ offset: true }),
23
+ updatedAt: z.iso.datetime({ offset: true }),
24
+ /** Epoch ms of the last fire; undefined until first fire. */
25
+ lastFiredTimestamp: z.number().optional(),
26
+ /** Set only by the legacy loop migration — provenance + idempotency guard. */
27
+ migratedFromAgentId: z.string().optional(),
28
+ });
29
+ export const CreateScheduleInputSchema = ScheduleSchema.omit({
30
+ id: true,
31
+ createdAt: true,
32
+ updatedAt: true,
33
+ lastFiredTimestamp: true,
34
+ migratedFromAgentId: true,
35
+ });
36
+ /**
37
+ * Every field optional so a partial edit (e.g. an enable/disable toggle) touches nothing else.
38
+ * Declared explicitly rather than as CreateScheduleInputSchema.partial(): partial() keeps the
39
+ * field defaults, so an absent key would parse back as its default and clobber the stored value.
40
+ */
41
+ export const UpdateScheduleInputSchema = z.object({
42
+ name: z.string().min(1).max(SCHEDULE_NAME_MAX_LENGTH).optional(),
43
+ message: z.string().min(1).optional(),
44
+ enabled: z.boolean().optional(),
45
+ agentIds: z.array(z.string()).optional(),
46
+ daysOfWeek: z.array(DayOfWeekSchema).optional(),
47
+ timeMode: TimeModeSchema.optional(),
48
+ times: z.array(SchedulerTimeSchema).min(1).max(MAX_SCHEDULE_TIMES).optional(),
49
+ newSession: z.boolean().optional(),
50
+ });
51
+ //# sourceMappingURL=schedule.schema.js.map
@@ -1,4 +1,10 @@
1
1
  import { z } from "zod";
2
+ /** Upper bound on a session label, shared by the rename request schema and the panel's input. */
3
+ export const SESSION_LABEL_MAX_LENGTH = 120;
4
+ /** Body of PATCH /api/agents/:id/sessions/:sessionId — the entry's new label. */
5
+ export const RenameSessionRequestSchema = z.object({
6
+ label: z.string().trim().min(1).max(SESSION_LABEL_MAX_LENGTH),
7
+ });
2
8
  /** One row of the pre-ordered session projection returned by GET /api/agents/:id/sessions. */
3
9
  export const SessionHistoryNodeSchema = z.object({
4
10
  sessionId: z.string(),
package/dist/bootstrap.js CHANGED
@@ -26,6 +26,7 @@ import { getSuperTasksMcpServerDefinition } from "./mcp/tasks/super-tasks-mcp-se
26
26
  import { getRemindersMcpServerDefinition } from "./mcp/reminders/reminders-mcp-server.js";
27
27
  import { FileObjectStoreProvider } from "./core/store/file-object-store-provider.js";
28
28
  import { CrowScheduler } from "./services/crow-scheduler.js";
29
+ import { ScheduleManager } from "./services/schedule-manager.js";
29
30
  import { SystemSettingsManager } from "./services/system-settings-manager.js";
30
31
  import { MessageQueueManager } from "./services/message-queue-manager.js";
31
32
  import { AgentTaskManager } from "./services/agent-task-manager.js";
@@ -45,7 +46,7 @@ import { shutdownTelemetry } from "./telemetry/setup.js";
45
46
  import { registerShutdownHandlers } from "./server/graceful-shutdown.js";
46
47
  import { createInterAgentTaskRoutine } from "./routines/inter-agent-task-routine.js";
47
48
  import { createTaskDispatchRoutine } from "./routines/task-dispatch-routine.js";
48
- import { createAgentLoopRoutine } from "./routines/agent-loop-routine.js";
49
+ import { createAgentScheduleRoutine } from "./routines/agent-schedule-routine.js";
49
50
  import { createAgentReminderRoutine } from "./routines/agent-reminder-routine.js";
50
51
  import { createFeedCleanupRoutine } from "./routines/feed-cleanup-routine.js";
51
52
  import { createFeedNewItemsRoutine } from "./routines/feed-new-items-routine.js";
@@ -66,6 +67,7 @@ import { createGmailNotificationRoutine } from "./routines/gmail-notification-ro
66
67
  import { FolderFileStoreProvider } from "./core/store/folder-file-store-provider.js";
67
68
  import { SimplyFeedManager } from "./feed/simply-feed-manager.js";
68
69
  import { registerFeedRoutes } from "./routes/feed.routes.js";
70
+ import { registerScheduleRoutes } from "./routes/schedule.routes.js";
69
71
  import { registerSystemSettingsRoutes } from "./routes/system-settings.routes.js";
70
72
  import { getFeedMcpServerDefinition } from "./mcp/feed/feed-mcp-server.js";
71
73
  import { getAudioMcpServerDefinition } from "./mcp/audio/audio-mcp-server.js";
@@ -100,6 +102,8 @@ export async function bootstrap(options) {
100
102
  await registry.initialize();
101
103
  const crowScheduler = new CrowScheduler(storeProvider, registry);
102
104
  await crowScheduler.initialize();
105
+ const scheduleManager = new ScheduleManager(storeProvider, crowScheduler, registry);
106
+ await scheduleManager.initialize();
103
107
  const taskManager = new AgentTaskManager(storeProvider, broadcaster, circleManager);
104
108
  await taskManager.initialize();
105
109
  const feedManager = new SimplyFeedManager(storeProvider, folderFileProvider, crowScheduler);
@@ -124,13 +128,13 @@ export async function bootstrap(options) {
124
128
  await runtimeManager.initialize();
125
129
  const worldBuilderDraftStore = new WorldBuilderDraftStore(storeProvider);
126
130
  const worldBuilderService = new WorldBuilderService(runtimeManager, worldBuilderDraftStore, registry, circleManager, mcpManager, broadcaster);
127
- const routineManager = new RoutineManager(registry, runtimeManager, taskManager, crowScheduler, feedManager);
131
+ const routineManager = new RoutineManager(registry, runtimeManager, taskManager, crowScheduler, scheduleManager, feedManager);
128
132
  const interAgentRoutine = createInterAgentTaskRoutine(registry, runtimeManager, taskManager);
129
133
  routineManager.addRoutine(interAgentRoutine);
130
134
  const taskDispatchRoutine = createTaskDispatchRoutine(runtimeManager);
131
135
  routineManager.addRoutine(taskDispatchRoutine);
132
- const agentLoopRoutine = createAgentLoopRoutine(taskManager);
133
- routineManager.addRoutine(agentLoopRoutine);
136
+ const agentScheduleRoutine = createAgentScheduleRoutine(taskManager);
137
+ routineManager.addRoutine(agentScheduleRoutine);
134
138
  const agentReminderRoutine = createAgentReminderRoutine(taskManager);
135
139
  routineManager.addRoutine(agentReminderRoutine);
136
140
  const feedCleanupRoutine = createFeedCleanupRoutine(registry, systemSettingsManager);
@@ -184,6 +188,7 @@ export async function bootstrap(options) {
184
188
  await registerFragmentRoutes(server, fragmentManager, registry, relationshipManager);
185
189
  await registerGraphRoutes(server, circleManager, registry, runtimeManager, fragmentManager, relationshipManager);
186
190
  await registerFeedRoutes(server, feedManager);
191
+ await registerScheduleRoutes(server, scheduleManager);
187
192
  await registerSystemSettingsRoutes(server, systemSettingsManager);
188
193
  await registerConnectorsRoutes(server, connectorManager);
189
194
  // Start listening
@@ -37,6 +37,8 @@ export const SYSTEM_AGENTS_PROJECT_DIR_NAME = "system-project";
37
37
  export const DEFAULT_PROJECT_DIR_NAME = "default-project";
38
38
  /** Object store table name for agent reminders */
39
39
  export const REMINDERS_STORE_TABLE = "reminders";
40
+ /** Object store table name for top-level schedules */
41
+ export const SCHEDULES_STORE_TABLE = "schedules";
40
42
  export const CLIENT_STORE_TABLE = "client";
41
43
  export const CLIENT_STORE_TIMEZONE_KEY = "timezone";
42
44
  export const CLIENT_STORE_LOCATION_KEY = "location";
@@ -19,6 +19,18 @@ function getBoolean(key) {
19
19
  function resolvePlacesSource(key) {
20
20
  return process.env[key]?.trim().toUpperCase() === PLACES_SOURCE.GOOGLE ? PLACES_SOURCE.GOOGLE : PLACES_SOURCE.OSM;
21
21
  }
22
+ /** A test run must never inherit the user's real data: VITEST is set per worker, NODE_ENV is not reliable. */
23
+ function resolveCrowSystemPath() {
24
+ const configured = getOptional("CROW_SYSTEM_PATH");
25
+ if (configured) {
26
+ return configured;
27
+ }
28
+ if (process.env.VITEST) {
29
+ throw new Error("CROW_SYSTEM_PATH is not set under test. Refusing to fall back to the home directory — " +
30
+ "tests must run against a temp directory they own (see vitest.setup.ts).");
31
+ }
32
+ return path.join(os.homedir(), ".crow");
33
+ }
22
34
  function readRequired(key) {
23
35
  const value = process.env[key]?.trim();
24
36
  if (!value) {
@@ -33,7 +45,7 @@ const port = getOptionalNumber("PORT") ?? 3101;
33
45
  // Default value for single-box deployment.
34
46
  const backendOrigin = `http://${host}:${port}`;
35
47
  const corsOrigins = getOptional("CORS_ORIGINS") ?? backendOrigin;
36
- const crowSysPath = getOptional("CROW_SYSTEM_PATH") ?? path.join(os.homedir(), ".crow");
48
+ const crowSysPath = resolveCrowSystemPath();
37
49
  let cachedAccessKey;
38
50
  function getAccessKey() {
39
51
  if (cachedAccessKey === undefined) {
@@ -24,8 +24,13 @@ export class ConnectorManager {
24
24
  this.connectionStore = connectionStore;
25
25
  this.agentRegistry = agentRegistry;
26
26
  this.pendingStateTtlMs = env.OAUTH_PENDING_STATE_TTL_MS ?? DEFAULT_PENDING_STATE_TTL_MS;
27
- crowScheduler.scheduleWork(PENDING_STATE_SWEEP_WORK_ID, TIME_MODE.EVERY, [{ minute: 1 }], () => {
28
- this.sweepExpiredPendingStates();
27
+ crowScheduler.scheduleWork({
28
+ id: PENDING_STATE_SWEEP_WORK_ID,
29
+ timeMode: TIME_MODE.EVERY,
30
+ times: [{ minute: 1 }],
31
+ callback: () => {
32
+ this.sweepExpiredPendingStates();
33
+ },
29
34
  });
30
35
  }
31
36
  registerConnector(connector) {
@@ -54,7 +54,12 @@ export class SimplyFeedManager extends EventBus {
54
54
  if (!this.hasTextGen) {
55
55
  log.warn("Feed text generation provider not configured — item summaries and topic-based search are disabled. Set FEED_TEXT_GENERATION_* env vars to enable.");
56
56
  }
57
- this.crowScheduler.scheduleWork(REFRESH_FEEDS_WORK_ID, TIME_MODE.EVERY, [{ minute: env.FEED_REFRESH_IN_MINUTES ?? DEFAULT_FEED_REFRESH_IN_MINUTES }], () => this.refreshAllFeeds());
57
+ this.crowScheduler.scheduleWork({
58
+ id: REFRESH_FEEDS_WORK_ID,
59
+ timeMode: TIME_MODE.EVERY,
60
+ times: [{ minute: env.FEED_REFRESH_IN_MINUTES ?? DEFAULT_FEED_REFRESH_IN_MINUTES }],
61
+ callback: () => this.refreshAllFeeds(),
62
+ });
58
63
  }
59
64
  /** Load or rebuild the search index. Wire before serving search queries. */
60
65
  async initialize() {
@@ -1 +1 @@
1
- import{m as e}from"./src-DkpnC9h-.js";import{n as t}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import"./chunk-I66GZJ75-CiiCugFd.js";import"./index-BkQmIm3H.js";import{m as n,t as r}from"./mermaid-parser.core-Dizpiz9G.js";import{n as i,r as a,t as o}from"./chunk-6Q2QTUOP-CX0EHawl.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";var c=n().RailroadAbnf.parser.LangiumParser,l=t(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=t(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=t(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=t(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=t(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=t(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=t(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:t(t=>{o.clear(),e.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(t);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new r(n);let i=n.value;e.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),e.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};
1
+ import{m as e}from"./src-DkpnC9h-.js";import{n as t}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import"./chunk-I66GZJ75-CiiCugFd.js";import"./index-DCds53oP.js";import{m as n,t as r}from"./mermaid-parser.core-Dizpiz9G.js";import{n as i,r as a,t as o}from"./chunk-6Q2QTUOP-DFiMjxDw.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";var c=n().RailroadAbnf.parser.LangiumParser,l=t(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=t(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=t(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=t(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=t(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=t(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=t(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:t(t=>{o.clear(),e.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(t);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new r(n);let i=n.value;e.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),e.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};