heyio 1.13.0 → 3.0.0

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 (327) hide show
  1. package/dist/api/middleware/auth.d.ts +14 -0
  2. package/dist/api/middleware/auth.d.ts.map +1 -0
  3. package/dist/api/middleware/auth.js +66 -0
  4. package/dist/api/middleware/auth.js.map +1 -0
  5. package/dist/api/notifications.d.ts +14 -0
  6. package/dist/api/notifications.d.ts.map +1 -0
  7. package/dist/api/notifications.js +112 -0
  8. package/dist/api/notifications.js.map +1 -0
  9. package/dist/api/routes/activity.d.ts +3 -0
  10. package/dist/api/routes/activity.d.ts.map +1 -0
  11. package/dist/api/routes/activity.js +28 -0
  12. package/dist/api/routes/activity.js.map +1 -0
  13. package/dist/api/routes/attachments.d.ts +3 -0
  14. package/dist/api/routes/attachments.d.ts.map +1 -0
  15. package/dist/api/routes/attachments.js +83 -0
  16. package/dist/api/routes/attachments.js.map +1 -0
  17. package/dist/api/routes/config.d.ts +3 -0
  18. package/dist/api/routes/config.d.ts.map +1 -0
  19. package/dist/api/routes/config.js +106 -0
  20. package/dist/api/routes/config.js.map +1 -0
  21. package/dist/api/routes/conversations.d.ts +3 -0
  22. package/dist/api/routes/conversations.d.ts.map +1 -0
  23. package/dist/api/routes/conversations.js +69 -0
  24. package/dist/api/routes/conversations.js.map +1 -0
  25. package/dist/api/routes/health.d.ts +3 -0
  26. package/dist/api/routes/health.d.ts.map +1 -0
  27. package/dist/api/routes/health.js +16 -0
  28. package/dist/api/routes/health.js.map +1 -0
  29. package/dist/api/routes/inbox.d.ts +3 -0
  30. package/dist/api/routes/inbox.d.ts.map +1 -0
  31. package/dist/api/routes/inbox.js +88 -0
  32. package/dist/api/routes/inbox.js.map +1 -0
  33. package/dist/api/routes/schedules.d.ts +3 -0
  34. package/dist/api/routes/schedules.d.ts.map +1 -0
  35. package/dist/api/routes/schedules.js +96 -0
  36. package/dist/api/routes/schedules.js.map +1 -0
  37. package/dist/api/routes/skills.d.ts +2 -0
  38. package/dist/api/routes/skills.d.ts.map +1 -0
  39. package/dist/api/routes/skills.js +85 -0
  40. package/dist/api/routes/skills.js.map +1 -0
  41. package/dist/api/routes/squads.d.ts +3 -0
  42. package/dist/api/routes/squads.d.ts.map +1 -0
  43. package/dist/api/routes/squads.js +129 -0
  44. package/dist/api/routes/squads.js.map +1 -0
  45. package/dist/api/routes/usage.d.ts +3 -0
  46. package/dist/api/routes/usage.d.ts.map +1 -0
  47. package/dist/api/routes/usage.js +55 -0
  48. package/dist/api/routes/usage.js.map +1 -0
  49. package/dist/api/routes/wiki.d.ts +2 -0
  50. package/dist/api/routes/wiki.d.ts.map +1 -0
  51. package/dist/api/routes/wiki.js +43 -0
  52. package/dist/api/routes/wiki.js.map +1 -0
  53. package/dist/api/server.d.ts +7 -0
  54. package/dist/api/server.d.ts.map +1 -0
  55. package/dist/api/server.js +136 -634
  56. package/dist/api/server.js.map +1 -0
  57. package/dist/config.d.ts +3 -0
  58. package/dist/config.d.ts.map +1 -0
  59. package/dist/config.js +2 -91
  60. package/dist/config.js.map +1 -0
  61. package/dist/copilot/client.d.ts +5 -0
  62. package/dist/copilot/client.d.ts.map +1 -0
  63. package/dist/copilot/client.js +19 -11
  64. package/dist/copilot/client.js.map +1 -0
  65. package/dist/copilot/health-monitor.d.ts +14 -0
  66. package/dist/copilot/health-monitor.d.ts.map +1 -0
  67. package/dist/copilot/health-monitor.js +70 -0
  68. package/dist/copilot/health-monitor.js.map +1 -0
  69. package/dist/copilot/orchestrator.d.ts +5 -0
  70. package/dist/copilot/orchestrator.d.ts.map +1 -0
  71. package/dist/copilot/orchestrator.js +127 -123
  72. package/dist/copilot/orchestrator.js.map +1 -0
  73. package/dist/copilot/tools.d.ts +49 -0
  74. package/dist/copilot/tools.d.ts.map +1 -0
  75. package/dist/copilot/tools.js +545 -321
  76. package/dist/copilot/tools.js.map +1 -0
  77. package/dist/index.d.ts +3 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.js +82 -26
  80. package/dist/index.js.map +1 -0
  81. package/dist/logging/logger.d.ts +6 -0
  82. package/dist/logging/logger.d.ts.map +1 -0
  83. package/dist/logging/logger.js +21 -0
  84. package/dist/logging/logger.js.map +1 -0
  85. package/dist/models/index.d.ts +6 -0
  86. package/dist/models/index.d.ts.map +1 -0
  87. package/dist/models/index.js +4 -0
  88. package/dist/models/index.js.map +1 -0
  89. package/dist/models/pricing.d.ts +25 -0
  90. package/dist/models/pricing.d.ts.map +1 -0
  91. package/dist/models/pricing.js +96 -0
  92. package/dist/models/pricing.js.map +1 -0
  93. package/dist/models/registry.d.ts +34 -0
  94. package/dist/models/registry.d.ts.map +1 -0
  95. package/dist/models/registry.js +109 -0
  96. package/dist/models/registry.js.map +1 -0
  97. package/dist/models/token-tracker.d.ts +40 -0
  98. package/dist/models/token-tracker.d.ts.map +1 -0
  99. package/dist/models/token-tracker.js +102 -0
  100. package/dist/models/token-tracker.js.map +1 -0
  101. package/dist/scheduler/engine.d.ts +9 -0
  102. package/dist/scheduler/engine.d.ts.map +1 -0
  103. package/dist/scheduler/engine.js +127 -0
  104. package/dist/scheduler/engine.js.map +1 -0
  105. package/dist/skills/index.d.ts +3 -0
  106. package/dist/skills/index.d.ts.map +1 -0
  107. package/dist/skills/index.js +2 -0
  108. package/dist/skills/index.js.map +1 -0
  109. package/dist/skills/store.d.ts +52 -0
  110. package/dist/skills/store.d.ts.map +1 -0
  111. package/dist/skills/store.js +148 -0
  112. package/dist/skills/store.js.map +1 -0
  113. package/dist/squad/agent.d.ts +46 -0
  114. package/dist/squad/agent.d.ts.map +1 -0
  115. package/dist/squad/agent.js +261 -0
  116. package/dist/squad/agent.js.map +1 -0
  117. package/dist/squad/autonomy.d.ts +16 -0
  118. package/dist/squad/autonomy.d.ts.map +1 -0
  119. package/dist/squad/autonomy.js +63 -0
  120. package/dist/squad/autonomy.js.map +1 -0
  121. package/dist/squad/event-bus.d.ts +22 -0
  122. package/dist/squad/event-bus.d.ts.map +1 -0
  123. package/dist/squad/event-bus.js +56 -0
  124. package/dist/squad/event-bus.js.map +1 -0
  125. package/dist/squad/execution/index.d.ts +12 -0
  126. package/dist/squad/execution/index.d.ts.map +1 -0
  127. package/dist/squad/execution/index.js +7 -0
  128. package/dist/squad/execution/index.js.map +1 -0
  129. package/dist/squad/execution/instance.d.ts +40 -0
  130. package/dist/squad/execution/instance.d.ts.map +1 -0
  131. package/dist/squad/execution/instance.js +138 -0
  132. package/dist/squad/execution/instance.js.map +1 -0
  133. package/dist/squad/execution/meeting.d.ts +25 -0
  134. package/dist/squad/execution/meeting.d.ts.map +1 -0
  135. package/dist/squad/execution/meeting.js +140 -0
  136. package/dist/squad/execution/meeting.js.map +1 -0
  137. package/dist/squad/execution/pr.d.ts +15 -0
  138. package/dist/squad/execution/pr.d.ts.map +1 -0
  139. package/dist/squad/execution/pr.js +93 -0
  140. package/dist/squad/execution/pr.js.map +1 -0
  141. package/dist/squad/execution/runner.d.ts +22 -0
  142. package/dist/squad/execution/runner.d.ts.map +1 -0
  143. package/dist/squad/execution/runner.js +68 -0
  144. package/dist/squad/execution/runner.js.map +1 -0
  145. package/dist/squad/execution/tasks.d.ts +11 -0
  146. package/dist/squad/execution/tasks.d.ts.map +1 -0
  147. package/dist/squad/execution/tasks.js +85 -0
  148. package/dist/squad/execution/tasks.js.map +1 -0
  149. package/dist/squad/execution/worktree.d.ts +26 -0
  150. package/dist/squad/execution/worktree.d.ts.map +1 -0
  151. package/dist/squad/execution/worktree.js +111 -0
  152. package/dist/squad/execution/worktree.js.map +1 -0
  153. package/dist/squad/hiring.d.ts +32 -0
  154. package/dist/squad/hiring.d.ts.map +1 -0
  155. package/dist/squad/hiring.js +200 -0
  156. package/dist/squad/hiring.js.map +1 -0
  157. package/dist/squad/index.d.ts +8 -0
  158. package/dist/squad/index.d.ts.map +1 -0
  159. package/dist/squad/index.js +6 -0
  160. package/dist/squad/index.js.map +1 -0
  161. package/dist/squad/manager.d.ts +48 -0
  162. package/dist/squad/manager.d.ts.map +1 -0
  163. package/dist/squad/manager.js +274 -0
  164. package/dist/squad/manager.js.map +1 -0
  165. package/dist/squad/name-generator.d.ts +16 -0
  166. package/dist/squad/name-generator.d.ts.map +1 -0
  167. package/dist/squad/name-generator.js +113 -0
  168. package/dist/squad/name-generator.js.map +1 -0
  169. package/dist/squad/roles/templates.d.ts +5 -0
  170. package/dist/squad/roles/templates.d.ts.map +1 -0
  171. package/dist/squad/roles/templates.js +102 -0
  172. package/dist/squad/roles/templates.js.map +1 -0
  173. package/dist/squad/skill-parser.d.ts +36 -0
  174. package/dist/squad/skill-parser.d.ts.map +1 -0
  175. package/dist/squad/skill-parser.js +83 -0
  176. package/dist/squad/skill-parser.js.map +1 -0
  177. package/dist/squad/source-resolver.d.ts +20 -0
  178. package/dist/squad/source-resolver.d.ts.map +1 -0
  179. package/dist/squad/source-resolver.js +52 -0
  180. package/dist/squad/source-resolver.js.map +1 -0
  181. package/dist/store/activity.d.ts +43 -0
  182. package/dist/store/activity.d.ts.map +1 -0
  183. package/dist/store/activity.js +131 -0
  184. package/dist/store/activity.js.map +1 -0
  185. package/dist/store/db.d.ts +5 -0
  186. package/dist/store/db.d.ts.map +1 -0
  187. package/dist/store/db.js +209 -248
  188. package/dist/store/db.js.map +1 -0
  189. package/dist/store/inbox.d.ts +53 -0
  190. package/dist/store/inbox.d.ts.map +1 -0
  191. package/dist/store/inbox.js +151 -0
  192. package/dist/store/inbox.js.map +1 -0
  193. package/dist/store/schedules.d.ts +53 -0
  194. package/dist/store/schedules.d.ts.map +1 -0
  195. package/dist/store/schedules.js +149 -54
  196. package/dist/store/schedules.js.map +1 -0
  197. package/dist/wiki/index.d.ts +3 -0
  198. package/dist/wiki/index.d.ts.map +1 -0
  199. package/dist/wiki/index.js +2 -0
  200. package/dist/wiki/index.js.map +1 -0
  201. package/dist/wiki/store.d.ts +49 -0
  202. package/dist/wiki/store.d.ts.map +1 -0
  203. package/dist/wiki/store.js +115 -0
  204. package/dist/wiki/store.js.map +1 -0
  205. package/package.json +52 -59
  206. package/src/api/middleware/auth.ts +76 -0
  207. package/src/api/notifications.ts +122 -0
  208. package/src/api/routes/activity.ts +29 -0
  209. package/src/api/routes/attachments.ts +93 -0
  210. package/src/api/routes/config.ts +115 -0
  211. package/src/api/routes/conversations.ts +87 -0
  212. package/src/api/routes/health.ts +18 -0
  213. package/src/api/routes/inbox.ts +98 -0
  214. package/src/api/routes/schedules.ts +121 -0
  215. package/src/api/routes/skills.ts +105 -0
  216. package/src/api/routes/squads.ts +145 -0
  217. package/src/api/routes/usage.ts +57 -0
  218. package/src/api/routes/wiki.ts +49 -0
  219. package/src/api/server.ts +186 -0
  220. package/src/config.ts +3 -0
  221. package/src/copilot/client.ts +42 -0
  222. package/src/copilot/health-monitor.ts +85 -0
  223. package/src/copilot/orchestrator.ts +222 -0
  224. package/src/copilot/tools.ts +707 -0
  225. package/src/index.ts +112 -0
  226. package/src/logging/logger.ts +26 -0
  227. package/src/models/index.ts +11 -0
  228. package/src/models/pricing.ts +121 -0
  229. package/src/models/registry.ts +131 -0
  230. package/src/models/token-tracker.ts +151 -0
  231. package/src/scheduler/engine.ts +146 -0
  232. package/src/skills/index.ts +13 -0
  233. package/src/skills/store.ts +188 -0
  234. package/src/squad/agent.ts +326 -0
  235. package/src/squad/autonomy.ts +78 -0
  236. package/src/squad/event-bus.ts +71 -0
  237. package/src/squad/execution/index.ts +17 -0
  238. package/src/squad/execution/instance.ts +186 -0
  239. package/src/squad/execution/meeting.ts +191 -0
  240. package/src/squad/execution/pr.ts +127 -0
  241. package/src/squad/execution/runner.ts +97 -0
  242. package/src/squad/execution/tasks.ts +111 -0
  243. package/src/squad/execution/worktree.ts +138 -0
  244. package/src/squad/hiring.ts +222 -0
  245. package/src/squad/index.ts +17 -0
  246. package/src/squad/manager.ts +337 -0
  247. package/src/squad/name-generator.ts +135 -0
  248. package/src/squad/roles/templates.ts +104 -0
  249. package/src/squad/skill-parser.ts +120 -0
  250. package/src/squad/source-resolver.ts +57 -0
  251. package/src/store/activity.ts +176 -0
  252. package/src/store/db.ts +237 -0
  253. package/src/store/inbox.ts +199 -0
  254. package/src/store/schedules.ts +199 -0
  255. package/src/wiki/index.ts +12 -0
  256. package/src/wiki/store.ts +139 -0
  257. package/tsconfig.json +9 -0
  258. package/LICENSE +0 -21
  259. package/README.md +0 -333
  260. package/dist/api/auth.js +0 -46
  261. package/dist/chat/attachments.js +0 -112
  262. package/dist/copilot/agents.js +0 -309
  263. package/dist/copilot/ceremonies.js +0 -174
  264. package/dist/copilot/gh-token.js +0 -64
  265. package/dist/copilot/io-scheduler.js +0 -79
  266. package/dist/copilot/model-router.js +0 -114
  267. package/dist/copilot/scheduler.js +0 -88
  268. package/dist/copilot/skills.js +0 -252
  269. package/dist/copilot/specialist-runner.js +0 -191
  270. package/dist/copilot/squad-tools.js +0 -258
  271. package/dist/copilot/system-message.js +0 -86
  272. package/dist/copilot/token-tracker.js +0 -98
  273. package/dist/copilot/trigger-schedule.js +0 -33
  274. package/dist/daemon.js +0 -67
  275. package/dist/logging.js +0 -27
  276. package/dist/mcp/config.js +0 -29
  277. package/dist/mcp/index.js +0 -3
  278. package/dist/mcp/registry.js +0 -42
  279. package/dist/notify.js +0 -25
  280. package/dist/paths.js +0 -17
  281. package/dist/setup.js +0 -35
  282. package/dist/store/agent-events.js +0 -19
  283. package/dist/store/audit-log.js +0 -71
  284. package/dist/store/conversations.js +0 -164
  285. package/dist/store/feed.js +0 -44
  286. package/dist/store/instances.js +0 -75
  287. package/dist/store/squad-colors.js +0 -23
  288. package/dist/store/squads.js +0 -60
  289. package/dist/store/tasks.js +0 -78
  290. package/dist/store/token-usage.js +0 -94
  291. package/dist/telegram/bot.js +0 -41
  292. package/dist/telegram/handlers.js +0 -42
  293. package/dist/watchdog.js +0 -37
  294. package/dist/wiki/backlinks.js +0 -51
  295. package/dist/wiki/fs.js +0 -108
  296. package/dist/wiki/search.js +0 -47
  297. package/web-dist/assets/AuditLogView-BzfjNXBT.js +0 -6
  298. package/web-dist/assets/ChatView-BdMukPKG.js +0 -1
  299. package/web-dist/assets/FeedView-BfPIabGr.js +0 -6
  300. package/web-dist/assets/HistoryView-BmEEk3Rs.js +0 -1
  301. package/web-dist/assets/LoginView-D7LrkeX7.js +0 -1
  302. package/web-dist/assets/McpView-BAP_ah3T.js +0 -1
  303. package/web-dist/assets/SchedulesView-CAtsUPCZ.js +0 -6
  304. package/web-dist/assets/SettingsView-BovjWZDa.js +0 -1
  305. package/web-dist/assets/SkillsView-DQSMM5LN.js +0 -16
  306. package/web-dist/assets/SquadDetailView-DBscu0m2.js +0 -26
  307. package/web-dist/assets/SquadHealthView-D686BuQo.js +0 -11
  308. package/web-dist/assets/SquadsView-AzMht2NJ.js +0 -6
  309. package/web-dist/assets/ToggleSwitch.vue_vue_type_script_setup_true_lang-DtShZAjW.js +0 -1
  310. package/web-dist/assets/UsageView-DiVn97aI.js +0 -16
  311. package/web-dist/assets/WikiView-Cn7KipkZ.js +0 -26
  312. package/web-dist/assets/api-D4mHJ3u0.js +0 -1
  313. package/web-dist/assets/arrow-left-D_qUNUWW.js +0 -6
  314. package/web-dist/assets/git-branch-DOM-orcl.js +0 -6
  315. package/web-dist/assets/index-Bo83B1LR.css +0 -1
  316. package/web-dist/assets/index-ELvnkQjd.js +0 -273
  317. package/web-dist/assets/pencil-CFsi7ufI.js +0 -6
  318. package/web-dist/assets/plus-BAzlGFd_.js +0 -6
  319. package/web-dist/assets/save-BmgCYJ1g.js +0 -6
  320. package/web-dist/assets/search-CS9zSIeW.js +0 -6
  321. package/web-dist/assets/squad-colors-B8B_Y-lz.js +0 -1
  322. package/web-dist/assets/trash-2-DLveUEsd.js +0 -6
  323. package/web-dist/assets/triangle-alert-lj4I30rL.js +0 -6
  324. package/web-dist/assets/x-CjXR97Fa.js +0 -6
  325. package/web-dist/favicon.svg +0 -10
  326. package/web-dist/index.html +0 -14
  327. package/web-dist/logo.svg +0 -10
@@ -0,0 +1,199 @@
1
+ import { CronExpressionParser } from 'cron-parser';
2
+ import { createChildLogger } from '../logging/logger.js';
3
+ import { getDatabase } from './db.js';
4
+
5
+ const logger = () => createChildLogger('schedules-store');
6
+
7
+ export type ScheduleTargetType = 'squad' | 'orchestrator';
8
+
9
+ export interface Schedule {
10
+ id: string;
11
+ name: string;
12
+ targetType: ScheduleTargetType;
13
+ targetId: string | null;
14
+ cron: string;
15
+ prompt: string;
16
+ enabled: boolean;
17
+ lastRun: string | null;
18
+ nextRun: string | null;
19
+ createdAt: string;
20
+ }
21
+
22
+ /**
23
+ * Calculate the next run time from a cron expression.
24
+ */
25
+ export function calculateNextRun(cron: string, from?: Date): Date {
26
+ const interval = CronExpressionParser.parse(cron, { currentDate: from ?? new Date() });
27
+ return interval.next().toDate();
28
+ }
29
+
30
+ /**
31
+ * Create a new schedule.
32
+ */
33
+ export async function createSchedule(params: {
34
+ name: string;
35
+ targetType: ScheduleTargetType;
36
+ targetId?: string;
37
+ cron: string;
38
+ prompt: string;
39
+ enabled?: boolean;
40
+ }): Promise<Schedule> {
41
+ const db = getDatabase();
42
+ const id = crypto.randomUUID();
43
+ const enabled = params.enabled ?? true;
44
+ const nextRun = enabled ? calculateNextRun(params.cron).toISOString() : null;
45
+
46
+ await db.execute({
47
+ sql: `INSERT INTO schedules (id, name, target_type, target_id, cron, prompt, enabled, next_run)
48
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
49
+ args: [
50
+ id,
51
+ params.name,
52
+ params.targetType,
53
+ params.targetId ?? null,
54
+ params.cron,
55
+ params.prompt,
56
+ enabled ? 1 : 0,
57
+ nextRun,
58
+ ],
59
+ });
60
+
61
+ logger().info({ id, name: params.name, cron: params.cron }, 'Schedule created');
62
+
63
+ return {
64
+ id,
65
+ name: params.name,
66
+ targetType: params.targetType,
67
+ targetId: params.targetId ?? null,
68
+ cron: params.cron,
69
+ prompt: params.prompt,
70
+ enabled,
71
+ lastRun: null,
72
+ nextRun,
73
+ createdAt: new Date().toISOString(),
74
+ };
75
+ }
76
+
77
+ /**
78
+ * List all schedules with optional enabled filter.
79
+ */
80
+ export async function listSchedules(enabledOnly?: boolean): Promise<Schedule[]> {
81
+ const db = getDatabase();
82
+ const sql = enabledOnly
83
+ ? 'SELECT * FROM schedules WHERE enabled = 1 ORDER BY next_run ASC'
84
+ : 'SELECT * FROM schedules ORDER BY created_at DESC';
85
+ const result = await db.execute(sql);
86
+ return result.rows.map(rowToSchedule);
87
+ }
88
+
89
+ /**
90
+ * Get a single schedule by ID.
91
+ */
92
+ export async function getSchedule(id: string): Promise<Schedule | null> {
93
+ const db = getDatabase();
94
+ const result = await db.execute({ sql: 'SELECT * FROM schedules WHERE id = ?', args: [id] });
95
+ if (result.rows.length === 0) return null;
96
+ return rowToSchedule(result.rows[0]);
97
+ }
98
+
99
+ /**
100
+ * Update a schedule (partial update).
101
+ */
102
+ export async function updateSchedule(
103
+ id: string,
104
+ updates: Partial<Pick<Schedule, 'name' | 'cron' | 'prompt' | 'enabled'>>,
105
+ ): Promise<void> {
106
+ const db = getDatabase();
107
+ const sets: string[] = [];
108
+ const args: (string | number | null)[] = [];
109
+
110
+ if (updates.name !== undefined) {
111
+ sets.push('name = ?');
112
+ args.push(updates.name);
113
+ }
114
+ if (updates.cron !== undefined) {
115
+ sets.push('cron = ?');
116
+ args.push(updates.cron);
117
+ // Recalculate next_run
118
+ sets.push('next_run = ?');
119
+ args.push(calculateNextRun(updates.cron).toISOString());
120
+ }
121
+ if (updates.prompt !== undefined) {
122
+ sets.push('prompt = ?');
123
+ args.push(updates.prompt);
124
+ }
125
+ if (updates.enabled !== undefined) {
126
+ sets.push('enabled = ?');
127
+ args.push(updates.enabled ? 1 : 0);
128
+ if (updates.enabled && !updates.cron) {
129
+ // Need to recalculate next_run from existing cron
130
+ const existing = await getSchedule(id);
131
+ if (existing) {
132
+ sets.push('next_run = ?');
133
+ args.push(calculateNextRun(existing.cron).toISOString());
134
+ }
135
+ }
136
+ if (!updates.enabled) {
137
+ sets.push('next_run = ?');
138
+ args.push(null);
139
+ }
140
+ }
141
+
142
+ if (sets.length === 0) return;
143
+ args.push(id);
144
+
145
+ await db.execute({
146
+ sql: `UPDATE schedules SET ${sets.join(', ')} WHERE id = ?`,
147
+ args,
148
+ });
149
+ }
150
+
151
+ /**
152
+ * Delete a schedule.
153
+ */
154
+ export async function deleteSchedule(id: string): Promise<void> {
155
+ const db = getDatabase();
156
+ await db.execute({ sql: 'DELETE FROM schedules WHERE id = ?', args: [id] });
157
+ }
158
+
159
+ /**
160
+ * Mark a schedule as fired (update last_run and next_run).
161
+ */
162
+ export async function markScheduleFired(id: string, cron: string): Promise<void> {
163
+ const db = getDatabase();
164
+ const now = new Date().toISOString();
165
+ const nextRun = calculateNextRun(cron).toISOString();
166
+
167
+ await db.execute({
168
+ sql: 'UPDATE schedules SET last_run = ?, next_run = ? WHERE id = ?',
169
+ args: [now, nextRun, id],
170
+ });
171
+ }
172
+
173
+ /**
174
+ * Get all schedules that are due to fire (next_run <= now and enabled).
175
+ */
176
+ export async function getDueSchedules(): Promise<Schedule[]> {
177
+ const db = getDatabase();
178
+ const now = new Date().toISOString();
179
+ const result = await db.execute({
180
+ sql: 'SELECT * FROM schedules WHERE enabled = 1 AND next_run IS NOT NULL AND next_run <= ?',
181
+ args: [now],
182
+ });
183
+ return result.rows.map(rowToSchedule);
184
+ }
185
+
186
+ function rowToSchedule(row: Record<string, unknown>): Schedule {
187
+ return {
188
+ id: row.id as string,
189
+ name: row.name as string,
190
+ targetType: row.target_type as ScheduleTargetType,
191
+ targetId: row.target_id as string | null,
192
+ cron: row.cron as string,
193
+ prompt: row.prompt as string,
194
+ enabled: (row.enabled as number) === 1,
195
+ lastRun: row.last_run as string | null,
196
+ nextRun: row.next_run as string | null,
197
+ createdAt: row.created_at as string,
198
+ };
199
+ }
@@ -0,0 +1,12 @@
1
+ export {
2
+ initWiki,
3
+ ensureSquadWiki,
4
+ listWikiPages,
5
+ readWikiPage,
6
+ writeWikiPage,
7
+ searchWiki,
8
+ getSquadScopes,
9
+ getOrchestratorScopes,
10
+ getPageListing,
11
+ } from './store.js';
12
+ export type { WikiScope, WikiPage, WikiSearchResult } from './store.js';
@@ -0,0 +1,139 @@
1
+ import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { createChildLogger } from '../logging/logger.js';
4
+
5
+ const logger = () => createChildLogger('wiki');
6
+
7
+ export type WikiScope = 'io' | 'shared' | string; // string = squad name
8
+
9
+ export interface WikiPage {
10
+ scope: string;
11
+ name: string;
12
+ content: string;
13
+ }
14
+
15
+ export interface WikiSearchResult {
16
+ scope: string;
17
+ name: string;
18
+ matches: string[];
19
+ }
20
+
21
+ let wikiRoot = '';
22
+
23
+ /**
24
+ * Initialize the wiki directory structure.
25
+ */
26
+ export function initWiki(dataDir: string): void {
27
+ wikiRoot = join(dataDir, 'wiki');
28
+ mkdirSync(join(wikiRoot, 'io'), { recursive: true });
29
+ mkdirSync(join(wikiRoot, 'shared'), { recursive: true });
30
+ mkdirSync(join(wikiRoot, 'squads'), { recursive: true });
31
+ logger().info({ wikiRoot }, 'Wiki initialized');
32
+ }
33
+
34
+ /**
35
+ * Ensure a squad wiki folder exists.
36
+ */
37
+ export function ensureSquadWiki(squadName: string): void {
38
+ const dir = join(wikiRoot, 'squads', squadName);
39
+ mkdirSync(dir, { recursive: true });
40
+ }
41
+
42
+ function scopeDir(scope: WikiScope): string {
43
+ if (scope === 'io') return join(wikiRoot, 'io');
44
+ if (scope === 'shared') return join(wikiRoot, 'shared');
45
+ return join(wikiRoot, 'squads', scope);
46
+ }
47
+
48
+ /**
49
+ * List all page names in a scope.
50
+ */
51
+ export function listWikiPages(scope: WikiScope): string[] {
52
+ const dir = scopeDir(scope);
53
+ if (!existsSync(dir)) return [];
54
+ return readdirSync(dir)
55
+ .filter((f) => f.endsWith('.md'))
56
+ .map((f) => f.replace(/\.md$/, ''));
57
+ }
58
+
59
+ /**
60
+ * Read a wiki page. Returns null if it doesn't exist.
61
+ */
62
+ export function readWikiPage(scope: WikiScope, pageName: string): WikiPage | null {
63
+ const filePath = join(scopeDir(scope), `${pageName}.md`);
64
+ if (!existsSync(filePath)) return null;
65
+ const content = readFileSync(filePath, 'utf-8');
66
+ return { scope, name: pageName, content };
67
+ }
68
+
69
+ /**
70
+ * Write (create or overwrite) a wiki page.
71
+ */
72
+ export function writeWikiPage(scope: WikiScope, pageName: string, content: string): WikiPage {
73
+ const dir = scopeDir(scope);
74
+ mkdirSync(dir, { recursive: true });
75
+ const filePath = join(dir, `${pageName}.md`);
76
+ writeFileSync(filePath, content, 'utf-8');
77
+ logger().info({ scope, pageName }, 'Wiki page written');
78
+ return { scope, name: pageName, content };
79
+ }
80
+
81
+ /**
82
+ * Search wiki pages by keyword across one or more scopes.
83
+ * Returns matching pages with context lines.
84
+ */
85
+ export function searchWiki(keyword: string, scopes: WikiScope[]): WikiSearchResult[] {
86
+ const results: WikiSearchResult[] = [];
87
+ const lower = keyword.toLowerCase();
88
+
89
+ for (const scope of scopes) {
90
+ const pages = listWikiPages(scope);
91
+ for (const pageName of pages) {
92
+ const page = readWikiPage(scope, pageName);
93
+ if (!page) continue;
94
+
95
+ const lines = page.content.split('\n');
96
+ const matches: string[] = [];
97
+ for (const line of lines) {
98
+ if (line.toLowerCase().includes(lower)) {
99
+ matches.push(line.trim());
100
+ }
101
+ }
102
+
103
+ if (matches.length > 0) {
104
+ results.push({ scope, name: pageName, matches: matches.slice(0, 5) });
105
+ }
106
+ }
107
+ }
108
+
109
+ return results;
110
+ }
111
+
112
+ /**
113
+ * Get accessible scopes for a squad agent.
114
+ */
115
+ export function getSquadScopes(squadName: string): WikiScope[] {
116
+ return ['shared', squadName];
117
+ }
118
+
119
+ /**
120
+ * Get accessible scopes for the orchestrator.
121
+ */
122
+ export function getOrchestratorScopes(): WikiScope[] {
123
+ return ['io', 'shared'];
124
+ }
125
+
126
+ /**
127
+ * Get a summary of available pages for injection into system prompts.
128
+ */
129
+ export function getPageListing(scopes: WikiScope[]): string {
130
+ const sections: string[] = [];
131
+ for (const scope of scopes) {
132
+ const pages = listWikiPages(scope);
133
+ if (pages.length > 0) {
134
+ const label = scope === 'io' ? 'IO' : scope === 'shared' ? 'Shared' : `Squad (${scope})`;
135
+ sections.push(`${label}: ${pages.join(', ')}`);
136
+ }
137
+ }
138
+ return sections.length > 0 ? sections.join('\n') : '(no wiki pages yet)';
139
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src"
6
+ },
7
+ "include": ["src/**/*"],
8
+ "references": [{ "path": "../shared" }]
9
+ }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Michael Jolley
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.