loopable-cli 0.1.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 (133) hide show
  1. package/.output/nitro.json +17 -0
  2. package/.output/public/apple-touch-icon.png +0 -0
  3. package/.output/public/assets/_connectorId-BWjYn5tm.js +1 -0
  4. package/.output/public/assets/_loopId-Ds4RkyEc.js +1 -0
  5. package/.output/public/assets/_taskId-BOzICXDf.js +1 -0
  6. package/.output/public/assets/alert-Bn9-Zm0l.js +1 -0
  7. package/.output/public/assets/arrow-left-BF9juV9T.js +1 -0
  8. package/.output/public/assets/arrow-right-CzqvnOY1.js +1 -0
  9. package/.output/public/assets/button-HCY6DCY-.js +1 -0
  10. package/.output/public/assets/connection-status-CYZB8kLy.js +1 -0
  11. package/.output/public/assets/connector-icon-BZ_MUJV_.js +1 -0
  12. package/.output/public/assets/connectors-BvzttfSu.js +1 -0
  13. package/.output/public/assets/connectors-DdJNwRN_.js +1 -0
  14. package/.output/public/assets/external-link-D46X-bXa.js +1 -0
  15. package/.output/public/assets/gaps-D-I6xiDc.js +1 -0
  16. package/.output/public/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  17. package/.output/public/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  18. package/.output/public/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  19. package/.output/public/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  20. package/.output/public/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  21. package/.output/public/assets/inbox-BUUu9xxE.js +1 -0
  22. package/.output/public/assets/index-ztzex0FN.js +10 -0
  23. package/.output/public/assets/loader-CcBl2u8m.js +1 -0
  24. package/.output/public/assets/loop-form-dB3CLcZb.js +1 -0
  25. package/.output/public/assets/loops-DRunQrxL.js +1 -0
  26. package/.output/public/assets/loops-oSdqMd29.js +1 -0
  27. package/.output/public/assets/manifests-DNMqf7Vi.js +7 -0
  28. package/.output/public/assets/new-uyFxVjuB.js +1 -0
  29. package/.output/public/assets/preload-helper-ORbuV86A.js +3 -0
  30. package/.output/public/assets/runners-DSU3r5Ww.js +1 -0
  31. package/.output/public/assets/setting-fields-ixkpdBb-.js +3 -0
  32. package/.output/public/assets/styles-DZL5V1o7.css +2 -0
  33. package/.output/public/assets/switch-d5ummmHY.js +1 -0
  34. package/.output/public/assets/task-list-BpOStt9v.js +1 -0
  35. package/.output/public/assets/tasks-B8MsKgic.js +1 -0
  36. package/.output/public/assets/trash-2-D6u6NpzO.js +1 -0
  37. package/.output/public/favicon.svg +9 -0
  38. package/.output/server/_chunks/ssr-renderer.mjs +26 -0
  39. package/.output/server/_connectorId-8nb5yOzG.mjs +421 -0
  40. package/.output/server/_libs/@base-ui/react+[...].mjs +12841 -0
  41. package/.output/server/_libs/@tanstack/react-router+[...].mjs +14349 -0
  42. package/.output/server/_libs/class-variance-authority+clsx.mjs +69 -0
  43. package/.output/server/_libs/dijkstrajs.mjs +118 -0
  44. package/.output/server/_libs/drizzle-orm.mjs +4349 -0
  45. package/.output/server/_libs/h3+rou3+srvx.mjs +1361 -0
  46. package/.output/server/_libs/lucide-react.mjs +911 -0
  47. package/.output/server/_libs/next-themes.mjs +53 -0
  48. package/.output/server/_libs/pngjs.mjs +1680 -0
  49. package/.output/server/_libs/qrcode.mjs +2583 -0
  50. package/.output/server/_libs/sonner.mjs +955 -0
  51. package/.output/server/_libs/tailwind-merge.mjs +3380 -0
  52. package/.output/server/_libs/tanstack__history.mjs +341 -0
  53. package/.output/server/_libs/ufo.mjs +64 -0
  54. package/.output/server/_loopId-BsUL1SeL.mjs +272 -0
  55. package/.output/server/_runtime.mjs +35 -0
  56. package/.output/server/_ssr/access-zIl15o8y.mjs +42 -0
  57. package/.output/server/_ssr/agents-Btql102J.mjs +657 -0
  58. package/.output/server/_ssr/agents-DAOZPgO2.mjs +76 -0
  59. package/.output/server/_ssr/alert-NEiOCTOl.mjs +37 -0
  60. package/.output/server/_ssr/callback-CUINvl7M.mjs +62 -0
  61. package/.output/server/_ssr/client-CKkOfh-s.mjs +335 -0
  62. package/.output/server/_ssr/connection-status-Bi5peUAk.mjs +31 -0
  63. package/.output/server/_ssr/connections-qnw2GVlP.mjs +2542 -0
  64. package/.output/server/_ssr/connector-icon-DZXQLLFo.mjs +37 -0
  65. package/.output/server/_ssr/connectors-BHNwuIMj.mjs +106 -0
  66. package/.output/server/_ssr/connectors-C28g0i4c.mjs +83 -0
  67. package/.output/server/_ssr/createServerRpc-DPDrnFdH.mjs +12 -0
  68. package/.output/server/_ssr/empty-plugin-adapters-BJ4m9L8g.mjs +5 -0
  69. package/.output/server/_ssr/gaps-RAFSXLZf.mjs +53 -0
  70. package/.output/server/_ssr/inbox-k5zHergU.mjs +35 -0
  71. package/.output/server/_ssr/loop-form-DlObSewZ.mjs +412 -0
  72. package/.output/server/_ssr/loops-APFcP0y6.mjs +311 -0
  73. package/.output/server/_ssr/loops-xt2Bn7_q.mjs +222 -0
  74. package/.output/server/_ssr/new-DfKyd2Wa.mjs +169 -0
  75. package/.output/server/_ssr/router-3WmpE5b_.mjs +1553 -0
  76. package/.output/server/_ssr/runners-By-mwc3F.mjs +32 -0
  77. package/.output/server/_ssr/runners-DI_NxpHC.mjs +116 -0
  78. package/.output/server/_ssr/runners-DtXs4Q8a.mjs +106 -0
  79. package/.output/server/_ssr/secrets-Hqti-niS.mjs +199 -0
  80. package/.output/server/_ssr/setting-fields-8vKFj4df.mjs +92 -0
  81. package/.output/server/_ssr/ssr.mjs +6605 -0
  82. package/.output/server/_ssr/start-Bdc2GJUI.mjs +51 -0
  83. package/.output/server/_ssr/switch-ReNglgH6.mjs +18 -0
  84. package/.output/server/_ssr/task-list-CUITIqkb.mjs +186 -0
  85. package/.output/server/_ssr/tasks-SAjNovX6.mjs +110 -0
  86. package/.output/server/_ssr/tasks-vcoodp_D.mjs +533 -0
  87. package/.output/server/_tanstack-start-manifest_v-C0cP5F0M.mjs +125 -0
  88. package/.output/server/_taskId-CXS3lod0.mjs +249 -0
  89. package/.output/server/index.mjs +541 -0
  90. package/README.md +81 -0
  91. package/dist/cli.mjs +165 -0
  92. package/dist/dispatcher.mjs +9871 -0
  93. package/dist/runner.mjs +657 -0
  94. package/drizzle/0000_cold_demogoblin.sql +29 -0
  95. package/drizzle/0001_fancy_blonde_phantom.sql +13 -0
  96. package/drizzle/0002_spooky_smiling_tiger.sql +16 -0
  97. package/drizzle/0003_small_golden_guardian.sql +25 -0
  98. package/drizzle/0004_wonderful_thunderbolts.sql +39 -0
  99. package/drizzle/0005_named_workflows.sql +7 -0
  100. package/drizzle/0006_signals.sql +18 -0
  101. package/drizzle/0007_review_comments.sql +1 -0
  102. package/drizzle/0008_held_signals.sql +1 -0
  103. package/drizzle/0009_work_item_ref.sql +58 -0
  104. package/drizzle/0010_signal_payload.sql +2 -0
  105. package/drizzle/0011_rule_poll_cursor.sql +1 -0
  106. package/drizzle/0012_loops.sql +63 -0
  107. package/drizzle/0013_loop_owns_action_and_prompt.sql +154 -0
  108. package/drizzle/0014_loop_poll_every.sql +4 -0
  109. package/drizzle/0015_machines.sql +10 -0
  110. package/drizzle/0016_task_machine.sql +1 -0
  111. package/drizzle/0017_loop_machine.sql +1 -0
  112. package/drizzle/0018_runners.sql +1 -0
  113. package/drizzle/0019_task_runner.sql +1 -0
  114. package/drizzle/0020_loop_runner.sql +1 -0
  115. package/drizzle/0021_drop_runner_kind.sql +1 -0
  116. package/drizzle/0022_drop_loop_runner.sql +1 -0
  117. package/drizzle/0023_shared_host.sql +6 -0
  118. package/drizzle/meta/0000_snapshot.json +206 -0
  119. package/drizzle/meta/0001_snapshot.json +284 -0
  120. package/drizzle/meta/0002_snapshot.json +390 -0
  121. package/drizzle/meta/0003_snapshot.json +566 -0
  122. package/drizzle/meta/0004_snapshot.json +633 -0
  123. package/drizzle/meta/0005_snapshot.json +626 -0
  124. package/drizzle/meta/0006_snapshot.json +752 -0
  125. package/drizzle/meta/0007_snapshot.json +759 -0
  126. package/drizzle/meta/0008_snapshot.json +766 -0
  127. package/drizzle/meta/0009_snapshot.json +752 -0
  128. package/drizzle/meta/0010_snapshot.json +766 -0
  129. package/drizzle/meta/0011_snapshot.json +773 -0
  130. package/drizzle/meta/0012_snapshot.json +773 -0
  131. package/drizzle/meta/0013_snapshot.json +817 -0
  132. package/drizzle/meta/_journal.json +174 -0
  133. package/package.json +88 -0
@@ -0,0 +1,16 @@
1
+ CREATE TABLE `rules` (
2
+ `id` text PRIMARY KEY NOT NULL,
3
+ `name` text NOT NULL,
4
+ `enabled` integer DEFAULT true NOT NULL,
5
+ `priority` integer NOT NULL,
6
+ `connector_id` text NOT NULL,
7
+ `event_id` text NOT NULL,
8
+ `conditions` text DEFAULT '{}' NOT NULL,
9
+ `instruction` text NOT NULL,
10
+ `agent_id` text,
11
+ `action_id` text NOT NULL,
12
+ `created_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
13
+ `updated_at` integer DEFAULT (unixepoch() * 1000) NOT NULL
14
+ );
15
+ --> statement-breakpoint
16
+ CREATE INDEX `rules_priority_idx` ON `rules` (`priority`);
@@ -0,0 +1,25 @@
1
+ CREATE TABLE `tasks` (
2
+ `id` text PRIMARY KEY NOT NULL,
3
+ `rule_id` text NOT NULL,
4
+ `connector_id` text NOT NULL,
5
+ `state` text DEFAULT 'queued' NOT NULL,
6
+ `source_url` text NOT NULL,
7
+ `source_kind` text NOT NULL,
8
+ `source_repo` text NOT NULL,
9
+ `source_number` integer NOT NULL,
10
+ `source_title` text NOT NULL,
11
+ `dry_run` integer DEFAULT false NOT NULL,
12
+ `agent_id` text,
13
+ `agent_command` text,
14
+ `output` text,
15
+ `action_id` text NOT NULL,
16
+ `result_url` text,
17
+ `error` text,
18
+ `duration_ms` integer,
19
+ `created_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
20
+ `updated_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
21
+ FOREIGN KEY (`rule_id`) REFERENCES `rules`(`id`) ON UPDATE no action ON DELETE cascade
22
+ );
23
+ --> statement-breakpoint
24
+ CREATE INDEX `tasks_rule_idx` ON `tasks` (`rule_id`);--> statement-breakpoint
25
+ CREATE INDEX `tasks_created_idx` ON `tasks` (`created_at`);
@@ -0,0 +1,39 @@
1
+ PRAGMA foreign_keys=OFF;--> statement-breakpoint
2
+ CREATE TABLE `__new_tasks` (
3
+ `id` text PRIMARY KEY NOT NULL,
4
+ `rule_id` text NOT NULL,
5
+ `connector_id` text NOT NULL,
6
+ `state` text DEFAULT 'queued' NOT NULL,
7
+ `source_url` text NOT NULL,
8
+ `source_kind` text NOT NULL,
9
+ `source_repo` text NOT NULL,
10
+ `source_number` integer NOT NULL,
11
+ `source_title` text,
12
+ `dry_run` integer DEFAULT false NOT NULL,
13
+ `agent_id` text,
14
+ `agent_command` text,
15
+ `output` text,
16
+ `action_id` text NOT NULL,
17
+ `result_url` text,
18
+ `error` text,
19
+ `log_path` text,
20
+ `attempts` integer DEFAULT 0 NOT NULL,
21
+ `run_after` integer DEFAULT (unixepoch() * 1000) NOT NULL,
22
+ `lease_until` integer,
23
+ `cancel_requested` integer DEFAULT false NOT NULL,
24
+ `dedupe_key` text,
25
+ `duration_ms` integer,
26
+ `created_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
27
+ `started_at` integer,
28
+ `updated_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
29
+ FOREIGN KEY (`rule_id`) REFERENCES `rules`(`id`) ON UPDATE no action ON DELETE cascade
30
+ );
31
+ --> statement-breakpoint
32
+ INSERT INTO `__new_tasks`("id", "rule_id", "connector_id", "state", "source_url", "source_kind", "source_repo", "source_number", "source_title", "dry_run", "agent_id", "agent_command", "output", "action_id", "result_url", "error", "log_path", "attempts", "run_after", "lease_until", "cancel_requested", "dedupe_key", "duration_ms", "created_at", "started_at", "updated_at") SELECT "id", "rule_id", "connector_id", "state", "source_url", "source_kind", "source_repo", "source_number", "source_title", "dry_run", "agent_id", "agent_command", "output", "action_id", "result_url", "error", NULL, 0, "created_at", NULL, 0, NULL, "duration_ms", "created_at", "created_at", "updated_at" FROM `tasks`;--> statement-breakpoint
33
+ DROP TABLE `tasks`;--> statement-breakpoint
34
+ ALTER TABLE `__new_tasks` RENAME TO `tasks`;--> statement-breakpoint
35
+ PRAGMA foreign_keys=ON;--> statement-breakpoint
36
+ CREATE INDEX `tasks_rule_idx` ON `tasks` (`rule_id`);--> statement-breakpoint
37
+ CREATE INDEX `tasks_created_idx` ON `tasks` (`created_at`);--> statement-breakpoint
38
+ CREATE INDEX `tasks_claim_idx` ON `tasks` (`state`,`run_after`);--> statement-breakpoint
39
+ CREATE UNIQUE INDEX `tasks_dedupe_idx` ON `tasks` (`dedupe_key`);
@@ -0,0 +1,7 @@
1
+ ALTER TABLE `rules` RENAME COLUMN `event_id` TO `workflow_id`;--> statement-breakpoint
2
+ ALTER TABLE `rules` RENAME COLUMN `conditions` TO `settings`;--> statement-breakpoint
3
+ ALTER TABLE `rules` ADD `guidance` text;--> statement-breakpoint
4
+ UPDATE `rules` SET `workflow_id` = CASE `workflow_id` WHEN 'pull_request.review_requested_of_me' THEN 'github.review_requested' WHEN 'issue.assigned_to_me' THEN 'github.issue_assigned' ELSE `workflow_id` END;--> statement-breakpoint
5
+ UPDATE `rules` SET `guidance` = CASE WHEN `instruction` IN ('Review this pull request. Focus on correctness, security and missing tests. Point at specific lines, and say plainly when something looks fine.', 'Write a short implementation plan for this issue: what to change, in which files, and what to watch out for. Do not write the code.', 'Read the review comments and draft a reply. Say what you would change and why, and push back politely where the comment is mistaken.', 'Work out why the checks failed. Explain the cause in a few sentences and suggest the smallest fix. Quote the part of the log that matters.') THEN NULL ELSE `instruction` END;--> statement-breakpoint
6
+ ALTER TABLE `rules` DROP COLUMN `instruction`;--> statement-breakpoint
7
+ ALTER TABLE `rules` DROP COLUMN `action_id`;
@@ -0,0 +1,18 @@
1
+ CREATE TABLE `signals` (
2
+ `rule_id` text NOT NULL,
3
+ `key` text NOT NULL,
4
+ `outcome` text NOT NULL,
5
+ `source_kind` text NOT NULL,
6
+ `source_repo` text NOT NULL,
7
+ `source_number` integer NOT NULL,
8
+ `source_title` text NOT NULL,
9
+ `source_url` text NOT NULL,
10
+ `task_id` text,
11
+ `seen_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
12
+ PRIMARY KEY(`rule_id`, `key`),
13
+ FOREIGN KEY (`rule_id`) REFERENCES `rules`(`id`) ON UPDATE no action ON DELETE cascade
14
+ );
15
+ --> statement-breakpoint
16
+ CREATE INDEX `signals_outcome_idx` ON `signals` (`rule_id`,`outcome`);--> statement-breakpoint
17
+ ALTER TABLE `rules` ADD `polled_at` integer;--> statement-breakpoint
18
+ ALTER TABLE `rules` ADD `poll_error` text;
@@ -0,0 +1 @@
1
+ ALTER TABLE `tasks` ADD `comments` text;
@@ -0,0 +1 @@
1
+ ALTER TABLE `signals` ADD `hold` text;
@@ -0,0 +1,58 @@
1
+ PRAGMA foreign_keys=OFF;--> statement-breakpoint
2
+ CREATE TABLE `__new_tasks` (
3
+ `id` text PRIMARY KEY NOT NULL,
4
+ `rule_id` text NOT NULL,
5
+ `connector_id` text NOT NULL,
6
+ `state` text DEFAULT 'queued' NOT NULL,
7
+ `source_url` text NOT NULL,
8
+ `source_kind` text NOT NULL,
9
+ `source_ref` text NOT NULL,
10
+ `source_title` text,
11
+ `dry_run` integer DEFAULT false NOT NULL,
12
+ `agent_id` text,
13
+ `agent_command` text,
14
+ `output` text,
15
+ `comments` text,
16
+ `action_id` text NOT NULL,
17
+ `result_url` text,
18
+ `error` text,
19
+ `log_path` text,
20
+ `attempts` integer DEFAULT 0 NOT NULL,
21
+ `run_after` integer DEFAULT (unixepoch() * 1000) NOT NULL,
22
+ `lease_until` integer,
23
+ `cancel_requested` integer DEFAULT false NOT NULL,
24
+ `dedupe_key` text,
25
+ `duration_ms` integer,
26
+ `created_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
27
+ `started_at` integer,
28
+ `updated_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
29
+ FOREIGN KEY (`rule_id`) REFERENCES `rules`(`id`) ON UPDATE no action ON DELETE cascade
30
+ );--> statement-breakpoint
31
+ INSERT INTO `__new_tasks` (`id`, `rule_id`, `connector_id`, `state`, `source_url`, `source_kind`, `source_ref`, `source_title`, `dry_run`, `agent_id`, `agent_command`, `output`, `comments`, `action_id`, `result_url`, `error`, `log_path`, `attempts`, `run_after`, `lease_until`, `cancel_requested`, `dedupe_key`, `duration_ms`, `created_at`, `started_at`, `updated_at`)
32
+ SELECT `id`, `rule_id`, `connector_id`, `state`, `source_url`, `source_kind`, `source_repo` || '#' || `source_number`, `source_title`, `dry_run`, `agent_id`, `agent_command`, `output`, `comments`, `action_id`, `result_url`, `error`, `log_path`, `attempts`, `run_after`, `lease_until`, `cancel_requested`, `dedupe_key`, `duration_ms`, `created_at`, `started_at`, `updated_at` FROM `tasks`;--> statement-breakpoint
33
+ DROP TABLE `tasks`;--> statement-breakpoint
34
+ ALTER TABLE `__new_tasks` RENAME TO `tasks`;--> statement-breakpoint
35
+ CREATE INDEX `tasks_rule_idx` ON `tasks` (`rule_id`);--> statement-breakpoint
36
+ CREATE INDEX `tasks_created_idx` ON `tasks` (`created_at`);--> statement-breakpoint
37
+ CREATE INDEX `tasks_claim_idx` ON `tasks` (`state`,`run_after`);--> statement-breakpoint
38
+ CREATE UNIQUE INDEX `tasks_dedupe_idx` ON `tasks` (`dedupe_key`);--> statement-breakpoint
39
+ CREATE TABLE `__new_signals` (
40
+ `rule_id` text NOT NULL,
41
+ `key` text NOT NULL,
42
+ `outcome` text NOT NULL,
43
+ `source_kind` text NOT NULL,
44
+ `source_ref` text NOT NULL,
45
+ `source_title` text NOT NULL,
46
+ `source_url` text NOT NULL,
47
+ `hold` text,
48
+ `task_id` text,
49
+ `seen_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
50
+ PRIMARY KEY(`rule_id`, `key`),
51
+ FOREIGN KEY (`rule_id`) REFERENCES `rules`(`id`) ON UPDATE no action ON DELETE cascade
52
+ );--> statement-breakpoint
53
+ INSERT INTO `__new_signals` (`rule_id`, `key`, `outcome`, `source_kind`, `source_ref`, `source_title`, `source_url`, `hold`, `task_id`, `seen_at`)
54
+ SELECT `rule_id`, `key`, `outcome`, `source_kind`, `source_repo` || '#' || `source_number`, `source_title`, `source_url`, `hold`, `task_id`, `seen_at` FROM `signals`;--> statement-breakpoint
55
+ DROP TABLE `signals`;--> statement-breakpoint
56
+ ALTER TABLE `__new_signals` RENAME TO `signals`;--> statement-breakpoint
57
+ CREATE INDEX `signals_outcome_idx` ON `signals` (`rule_id`,`outcome`);--> statement-breakpoint
58
+ PRAGMA foreign_keys=ON;
@@ -0,0 +1,2 @@
1
+ ALTER TABLE `signals` ADD `source_payload` text;--> statement-breakpoint
2
+ ALTER TABLE `tasks` ADD `source_payload` text;
@@ -0,0 +1 @@
1
+ ALTER TABLE `rules` ADD `poll_cursor` text;
@@ -0,0 +1,63 @@
1
+ PRAGMA foreign_keys=OFF;--> statement-breakpoint
2
+ ALTER TABLE `rules` RENAME TO `loops`;--> statement-breakpoint
3
+ DROP INDEX IF EXISTS `rules_priority_idx`;--> statement-breakpoint
4
+ CREATE INDEX `loops_priority_idx` ON `loops` (`priority`);--> statement-breakpoint
5
+ CREATE TABLE `__new_tasks` (
6
+ `id` text PRIMARY KEY NOT NULL,
7
+ `loop_id` text NOT NULL,
8
+ `connector_id` text NOT NULL,
9
+ `state` text DEFAULT 'queued' NOT NULL,
10
+ `source_url` text NOT NULL,
11
+ `source_kind` text NOT NULL,
12
+ `source_ref` text NOT NULL,
13
+ `source_payload` text,
14
+ `source_title` text,
15
+ `dry_run` integer DEFAULT false NOT NULL,
16
+ `agent_id` text,
17
+ `agent_command` text,
18
+ `output` text,
19
+ `comments` text,
20
+ `action_id` text NOT NULL,
21
+ `result_url` text,
22
+ `error` text,
23
+ `log_path` text,
24
+ `attempts` integer DEFAULT 0 NOT NULL,
25
+ `run_after` integer DEFAULT (unixepoch() * 1000) NOT NULL,
26
+ `lease_until` integer,
27
+ `cancel_requested` integer DEFAULT false NOT NULL,
28
+ `dedupe_key` text,
29
+ `duration_ms` integer,
30
+ `created_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
31
+ `started_at` integer,
32
+ `updated_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
33
+ FOREIGN KEY (`loop_id`) REFERENCES `loops`(`id`) ON UPDATE no action ON DELETE cascade
34
+ );--> statement-breakpoint
35
+ INSERT INTO `__new_tasks` (`id`, `loop_id`, `connector_id`, `state`, `source_url`, `source_kind`, `source_ref`, `source_payload`, `source_title`, `dry_run`, `agent_id`, `agent_command`, `output`, `comments`, `action_id`, `result_url`, `error`, `log_path`, `attempts`, `run_after`, `lease_until`, `cancel_requested`, `dedupe_key`, `duration_ms`, `created_at`, `started_at`, `updated_at`)
36
+ SELECT `id`, `rule_id`, `connector_id`, `state`, `source_url`, `source_kind`, `source_ref`, `source_payload`, `source_title`, `dry_run`, `agent_id`, `agent_command`, `output`, `comments`, `action_id`, `result_url`, `error`, `log_path`, `attempts`, `run_after`, `lease_until`, `cancel_requested`, `dedupe_key`, `duration_ms`, `created_at`, `started_at`, `updated_at` FROM `tasks`;--> statement-breakpoint
37
+ DROP TABLE `tasks`;--> statement-breakpoint
38
+ ALTER TABLE `__new_tasks` RENAME TO `tasks`;--> statement-breakpoint
39
+ CREATE INDEX `tasks_loop_idx` ON `tasks` (`loop_id`);--> statement-breakpoint
40
+ CREATE INDEX `tasks_created_idx` ON `tasks` (`created_at`);--> statement-breakpoint
41
+ CREATE INDEX `tasks_claim_idx` ON `tasks` (`state`,`run_after`);--> statement-breakpoint
42
+ CREATE UNIQUE INDEX `tasks_dedupe_idx` ON `tasks` (`dedupe_key`);--> statement-breakpoint
43
+ CREATE TABLE `__new_signals` (
44
+ `loop_id` text NOT NULL,
45
+ `key` text NOT NULL,
46
+ `outcome` text NOT NULL,
47
+ `source_kind` text NOT NULL,
48
+ `source_ref` text NOT NULL,
49
+ `source_payload` text,
50
+ `source_title` text NOT NULL,
51
+ `source_url` text NOT NULL,
52
+ `hold` text,
53
+ `task_id` text,
54
+ `seen_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
55
+ PRIMARY KEY(`loop_id`, `key`),
56
+ FOREIGN KEY (`loop_id`) REFERENCES `loops`(`id`) ON UPDATE no action ON DELETE cascade
57
+ );--> statement-breakpoint
58
+ INSERT INTO `__new_signals` (`loop_id`, `key`, `outcome`, `source_kind`, `source_ref`, `source_payload`, `source_title`, `source_url`, `hold`, `task_id`, `seen_at`)
59
+ SELECT `rule_id`, `key`, `outcome`, `source_kind`, `source_ref`, `source_payload`, `source_title`, `source_url`, `hold`, `task_id`, `seen_at` FROM `signals`;--> statement-breakpoint
60
+ DROP TABLE `signals`;--> statement-breakpoint
61
+ ALTER TABLE `__new_signals` RENAME TO `signals`;--> statement-breakpoint
62
+ CREATE INDEX `signals_outcome_idx` ON `signals` (`loop_id`,`outcome`);--> statement-breakpoint
63
+ PRAGMA foreign_keys=ON;
@@ -0,0 +1,154 @@
1
+ -- Hand-written. The generated version was `ADD COLUMN ... NOT NULL` with no
2
+ -- default, four times over, which SQLite refuses outright.
3
+ --
4
+ -- Rebuilding `loops` is the awkward part, because `tasks` and `signals`
5
+ -- reference it with ON DELETE CASCADE and this connection runs with foreign
6
+ -- keys on. Two things that look like they would help do not:
7
+ --
8
+ -- PRAGMA foreign_keys=OFF does nothing inside a transaction, and every
9
+ -- migration runs inside one.
10
+ -- PRAGMA legacy_alter_table does take effect, but with foreign keys on the
11
+ -- rename rewrites referencing tables regardless.
12
+ --
13
+ -- So the order below is the point. `loops` is moved aside, the new one is
14
+ -- built beside it, and then the two children are rebuilt pointing at the new
15
+ -- table. Only once nothing refers to the old one is it dropped, and there is
16
+ -- nothing left for the cascade to take. Every rename happens while both
17
+ -- tables exist, so the schema is never left referring to something absent.
18
+ --
19
+ -- The prompts are written out in full rather than read from the manifests,
20
+ -- because that is what copying means: each loop is given the words its
21
+ -- workflow was asking on the day this ran, and a later release rewording a
22
+ -- prompt leaves it alone. This text is deliberately frozen. It is a record,
23
+ -- not a duplicate to be kept in step.
24
+ ALTER TABLE `loops` RENAME TO `__old_loops`;--> statement-breakpoint
25
+ CREATE TABLE `loops` (
26
+ `id` text PRIMARY KEY NOT NULL,
27
+ `name` text NOT NULL,
28
+ `enabled` integer DEFAULT true NOT NULL,
29
+ `priority` integer NOT NULL,
30
+ `connector_id` text NOT NULL,
31
+ `workflow_id` text NOT NULL,
32
+ `settings` text DEFAULT '{}' NOT NULL,
33
+ `prompt` text NOT NULL,
34
+ `guidance` text,
35
+ `agent_id` text,
36
+ `action_connector_id` text NOT NULL,
37
+ `action_id` text NOT NULL,
38
+ `action_target` text DEFAULT '{}' NOT NULL,
39
+ `polled_at` integer,
40
+ `poll_error` text,
41
+ `poll_cursor` text,
42
+ `created_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
43
+ `updated_at` integer DEFAULT (unixepoch() * 1000) NOT NULL
44
+ );--> statement-breakpoint
45
+ INSERT INTO `loops` (`id`, `name`, `enabled`, `priority`, `connector_id`, `workflow_id`, `settings`, `prompt`, `guidance`, `agent_id`, `action_connector_id`, `action_id`, `action_target`, `polled_at`, `poll_error`, `poll_cursor`, `created_at`, `updated_at`)
46
+ SELECT `id`, `name`, `enabled`, `priority`, `connector_id`, `workflow_id`, `settings`,
47
+ CASE `workflow_id`
48
+ WHEN 'github.review_requested' THEN 'Review this pull request the way an experienced engineer on this team would.
49
+
50
+ Look for correctness bugs, security problems, races, unhandled errors, and
51
+ changes that quietly break existing behaviour. Check whether the change is
52
+ tested, and say plainly when it is not.
53
+
54
+ Point at specific files and lines rather than describing the change back to
55
+ its author. Say when something is done well; a review that lists only faults
56
+ reads as hostile. Skip anything a linter or formatter already enforces, and
57
+ do not restate what the diff obviously does.
58
+
59
+ Where you cannot see enough of the code to judge something, say so instead of
60
+ guessing.'
61
+ WHEN 'github.issue_assigned' THEN 'Write a short implementation plan for this issue.
62
+
63
+ Say what should change, in which files where you can tell, and what to watch
64
+ out for. Stay inside what the issue actually supports: if it is too vague to
65
+ plan, say what is missing rather than inventing the requirements.
66
+
67
+ Do not write the implementation.'
68
+ WHEN 'wechat.ask' THEN 'Someone has sent you a message. Do what it asks, working in this directory,
69
+ and then answer them.
70
+
71
+ You are answering into a chat on a phone. Be brief: a couple of short
72
+ paragraphs at most, no headings, no bullet lists unless you are genuinely
73
+ listing things. Plain sentences.
74
+
75
+ If the message asks a question about this code, read enough of it to answer
76
+ properly rather than guessing. If it asks for a change, make the change and
77
+ say in one line what you did. If the message is too vague to act on, say what
78
+ you need to know instead of assuming.'
79
+ ELSE ''
80
+ END,
81
+ `guidance`, `agent_id`,
82
+ `connector_id`,
83
+ CASE `workflow_id`
84
+ WHEN 'github.review_requested' THEN 'github.submit_review'
85
+ WHEN 'github.issue_assigned' THEN 'github.post_issue_comment'
86
+ WHEN 'wechat.ask' THEN 'wechat.reply'
87
+ ELSE ''
88
+ END,
89
+ '{}',
90
+ `polled_at`, `poll_error`, `poll_cursor`, `created_at`, `updated_at` FROM `__old_loops`;--> statement-breakpoint
91
+ CREATE TABLE `__new_tasks` (
92
+ `id` text PRIMARY KEY NOT NULL,
93
+ `loop_id` text NOT NULL,
94
+ `connector_id` text NOT NULL,
95
+ `state` text DEFAULT 'queued' NOT NULL,
96
+ `source_url` text NOT NULL,
97
+ `source_kind` text NOT NULL,
98
+ `source_ref` text NOT NULL,
99
+ `source_payload` text,
100
+ `source_title` text,
101
+ `dry_run` integer DEFAULT false NOT NULL,
102
+ `agent_id` text,
103
+ `agent_command` text,
104
+ `output` text,
105
+ `comments` text,
106
+ `action_connector_id` text NOT NULL,
107
+ `action_id` text NOT NULL,
108
+ `action_target` text DEFAULT '{}' NOT NULL,
109
+ `result_url` text,
110
+ `error` text,
111
+ `log_path` text,
112
+ `attempts` integer DEFAULT 0 NOT NULL,
113
+ `run_after` integer DEFAULT (unixepoch() * 1000) NOT NULL,
114
+ `lease_until` integer,
115
+ `cancel_requested` integer DEFAULT false NOT NULL,
116
+ `dedupe_key` text,
117
+ `duration_ms` integer,
118
+ `created_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
119
+ `started_at` integer,
120
+ `updated_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
121
+ FOREIGN KEY (`loop_id`) REFERENCES `loops`(`id`) ON UPDATE no action ON DELETE cascade
122
+ );--> statement-breakpoint
123
+ INSERT INTO `__new_tasks` (`id`, `loop_id`, `connector_id`, `state`, `source_url`, `source_kind`, `source_ref`, `source_payload`, `source_title`, `dry_run`, `agent_id`, `agent_command`, `output`, `comments`, `action_connector_id`, `action_id`, `action_target`, `result_url`, `error`, `log_path`, `attempts`, `run_after`, `lease_until`, `cancel_requested`, `dedupe_key`, `duration_ms`, `created_at`, `started_at`, `updated_at`)
124
+ SELECT `id`, `loop_id`, `connector_id`, `state`, `source_url`, `source_kind`, `source_ref`, `source_payload`, `source_title`, `dry_run`, `agent_id`, `agent_command`, `output`, `comments`, `connector_id`, `action_id`, '{}', `result_url`, `error`, `log_path`, `attempts`, `run_after`, `lease_until`, `cancel_requested`, `dedupe_key`, `duration_ms`, `created_at`, `started_at`, `updated_at` FROM `tasks`;--> statement-breakpoint
125
+ DROP TABLE `tasks`;--> statement-breakpoint
126
+ ALTER TABLE `__new_tasks` RENAME TO `tasks`;--> statement-breakpoint
127
+ CREATE INDEX `tasks_loop_idx` ON `tasks` (`loop_id`);--> statement-breakpoint
128
+ CREATE INDEX `tasks_created_idx` ON `tasks` (`created_at`);--> statement-breakpoint
129
+ CREATE INDEX `tasks_claim_idx` ON `tasks` (`state`,`run_after`);--> statement-breakpoint
130
+ CREATE UNIQUE INDEX `tasks_dedupe_idx` ON `tasks` (`dedupe_key`);--> statement-breakpoint
131
+ CREATE TABLE `__new_signals` (
132
+ `loop_id` text NOT NULL,
133
+ `key` text NOT NULL,
134
+ `outcome` text NOT NULL,
135
+ `source_kind` text NOT NULL,
136
+ `source_ref` text NOT NULL,
137
+ `source_payload` text,
138
+ `source_title` text NOT NULL,
139
+ `source_url` text NOT NULL,
140
+ `hold` text,
141
+ `task_id` text,
142
+ `seen_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
143
+ PRIMARY KEY(`loop_id`, `key`),
144
+ FOREIGN KEY (`loop_id`) REFERENCES `loops`(`id`) ON UPDATE no action ON DELETE cascade
145
+ );--> statement-breakpoint
146
+ INSERT INTO `__new_signals` (`loop_id`, `key`, `outcome`, `source_kind`, `source_ref`, `source_payload`, `source_title`, `source_url`, `hold`, `task_id`, `seen_at`)
147
+ SELECT `loop_id`, `key`, `outcome`, `source_kind`, `source_ref`, `source_payload`, `source_title`, `source_url`, `hold`, `task_id`, `seen_at` FROM `signals`;--> statement-breakpoint
148
+ DROP TABLE `signals`;--> statement-breakpoint
149
+ ALTER TABLE `__new_signals` RENAME TO `signals`;--> statement-breakpoint
150
+ CREATE INDEX `signals_outcome_idx` ON `signals` (`loop_id`,`outcome`);--> statement-breakpoint
151
+ DROP TABLE `__old_loops`;--> statement-breakpoint
152
+ -- Last, because an index belongs to its table and this one followed `loops`
153
+ -- when it was renamed aside. The name is only free again once that is gone.
154
+ CREATE INDEX `loops_priority_idx` ON `loops` (`priority`);
@@ -0,0 +1,4 @@
1
+ -- Nullable and with no default, so this is the one shape of ADD COLUMN SQLite
2
+ -- takes without rebuilding the table. Null keeps every existing loop looking
3
+ -- as often as the engine does, which is what they all did before.
4
+ ALTER TABLE `loops` ADD `poll_every_ms` integer;
@@ -0,0 +1,10 @@
1
+ CREATE TABLE `machines` (
2
+ `id` text PRIMARY KEY NOT NULL,
3
+ `name` text NOT NULL,
4
+ `hostname` text NOT NULL,
5
+ `kind` text NOT NULL DEFAULT 'joined',
6
+ `status` text NOT NULL DEFAULT 'offline',
7
+ `inventory` text NOT NULL DEFAULT '[]',
8
+ `last_seen_at` integer,
9
+ `created_at` integer NOT NULL DEFAULT (unixepoch() * 1000)
10
+ );
@@ -0,0 +1 @@
1
+ ALTER TABLE `tasks` ADD `machine_id` text;
@@ -0,0 +1 @@
1
+ ALTER TABLE `loops` ADD `machine_id` text;
@@ -0,0 +1 @@
1
+ ALTER TABLE `machines` RENAME TO `runners`;
@@ -0,0 +1 @@
1
+ ALTER TABLE `tasks` RENAME COLUMN `machine_id` TO `runner_id`;
@@ -0,0 +1 @@
1
+ ALTER TABLE `loops` RENAME COLUMN `machine_id` TO `runner_id`;
@@ -0,0 +1 @@
1
+ ALTER TABLE `runners` DROP COLUMN `kind`;
@@ -0,0 +1 @@
1
+ ALTER TABLE `loops` DROP COLUMN `runner_id`;
@@ -0,0 +1,6 @@
1
+ ALTER TABLE `tasks` ADD `log_text` text DEFAULT '' NOT NULL;
2
+ CREATE TABLE `secrets` (
3
+ `key` text PRIMARY KEY NOT NULL,
4
+ `value` text NOT NULL,
5
+ `updated_at` integer DEFAULT (unixepoch() * 1000) NOT NULL
6
+ );
@@ -0,0 +1,206 @@
1
+ {
2
+ "version": "6",
3
+ "dialect": "sqlite",
4
+ "id": "34cd696f-e205-40f4-ac7a-b1dc1a60c19e",
5
+ "prevId": "00000000-0000-0000-0000-000000000000",
6
+ "tables": {
7
+ "auth_attempts": {
8
+ "name": "auth_attempts",
9
+ "columns": {
10
+ "state": {
11
+ "name": "state",
12
+ "type": "text",
13
+ "primaryKey": true,
14
+ "notNull": true,
15
+ "autoincrement": false
16
+ },
17
+ "connector_id": {
18
+ "name": "connector_id",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": true,
22
+ "autoincrement": false
23
+ },
24
+ "verifier": {
25
+ "name": "verifier",
26
+ "type": "text",
27
+ "primaryKey": false,
28
+ "notNull": true,
29
+ "autoincrement": false
30
+ },
31
+ "redirect_uri": {
32
+ "name": "redirect_uri",
33
+ "type": "text",
34
+ "primaryKey": false,
35
+ "notNull": true,
36
+ "autoincrement": false
37
+ },
38
+ "return_to": {
39
+ "name": "return_to",
40
+ "type": "text",
41
+ "primaryKey": false,
42
+ "notNull": false,
43
+ "autoincrement": false
44
+ },
45
+ "expires_at": {
46
+ "name": "expires_at",
47
+ "type": "integer",
48
+ "primaryKey": false,
49
+ "notNull": true,
50
+ "autoincrement": false
51
+ },
52
+ "created_at": {
53
+ "name": "created_at",
54
+ "type": "integer",
55
+ "primaryKey": false,
56
+ "notNull": true,
57
+ "autoincrement": false,
58
+ "default": "(unixepoch() * 1000)"
59
+ }
60
+ },
61
+ "indexes": {},
62
+ "foreignKeys": {},
63
+ "compositePrimaryKeys": {},
64
+ "uniqueConstraints": {},
65
+ "checkConstraints": {}
66
+ },
67
+ "connections": {
68
+ "name": "connections",
69
+ "columns": {
70
+ "id": {
71
+ "name": "id",
72
+ "type": "text",
73
+ "primaryKey": true,
74
+ "notNull": true,
75
+ "autoincrement": false
76
+ },
77
+ "connector_id": {
78
+ "name": "connector_id",
79
+ "type": "text",
80
+ "primaryKey": false,
81
+ "notNull": true,
82
+ "autoincrement": false
83
+ },
84
+ "status": {
85
+ "name": "status",
86
+ "type": "text",
87
+ "primaryKey": false,
88
+ "notNull": true,
89
+ "autoincrement": false,
90
+ "default": "'connected'"
91
+ },
92
+ "account_id": {
93
+ "name": "account_id",
94
+ "type": "text",
95
+ "primaryKey": false,
96
+ "notNull": true,
97
+ "autoincrement": false
98
+ },
99
+ "account_label": {
100
+ "name": "account_label",
101
+ "type": "text",
102
+ "primaryKey": false,
103
+ "notNull": true,
104
+ "autoincrement": false
105
+ },
106
+ "account_url": {
107
+ "name": "account_url",
108
+ "type": "text",
109
+ "primaryKey": false,
110
+ "notNull": false,
111
+ "autoincrement": false
112
+ },
113
+ "avatar_url": {
114
+ "name": "avatar_url",
115
+ "type": "text",
116
+ "primaryKey": false,
117
+ "notNull": false,
118
+ "autoincrement": false
119
+ },
120
+ "scopes": {
121
+ "name": "scopes",
122
+ "type": "text",
123
+ "primaryKey": false,
124
+ "notNull": false,
125
+ "autoincrement": false
126
+ },
127
+ "settings": {
128
+ "name": "settings",
129
+ "type": "text",
130
+ "primaryKey": false,
131
+ "notNull": true,
132
+ "autoincrement": false,
133
+ "default": "'{}'"
134
+ },
135
+ "cursor": {
136
+ "name": "cursor",
137
+ "type": "text",
138
+ "primaryKey": false,
139
+ "notNull": false,
140
+ "autoincrement": false
141
+ },
142
+ "last_synced_at": {
143
+ "name": "last_synced_at",
144
+ "type": "integer",
145
+ "primaryKey": false,
146
+ "notNull": false,
147
+ "autoincrement": false
148
+ },
149
+ "last_error": {
150
+ "name": "last_error",
151
+ "type": "text",
152
+ "primaryKey": false,
153
+ "notNull": false,
154
+ "autoincrement": false
155
+ },
156
+ "created_at": {
157
+ "name": "created_at",
158
+ "type": "integer",
159
+ "primaryKey": false,
160
+ "notNull": true,
161
+ "autoincrement": false,
162
+ "default": "(unixepoch() * 1000)"
163
+ },
164
+ "updated_at": {
165
+ "name": "updated_at",
166
+ "type": "integer",
167
+ "primaryKey": false,
168
+ "notNull": true,
169
+ "autoincrement": false,
170
+ "default": "(unixepoch() * 1000)"
171
+ }
172
+ },
173
+ "indexes": {
174
+ "connections_account_unique": {
175
+ "name": "connections_account_unique",
176
+ "columns": [
177
+ "connector_id",
178
+ "account_id"
179
+ ],
180
+ "isUnique": true
181
+ },
182
+ "connections_connector_idx": {
183
+ "name": "connections_connector_idx",
184
+ "columns": [
185
+ "connector_id"
186
+ ],
187
+ "isUnique": false
188
+ }
189
+ },
190
+ "foreignKeys": {},
191
+ "compositePrimaryKeys": {},
192
+ "uniqueConstraints": {},
193
+ "checkConstraints": {}
194
+ }
195
+ },
196
+ "views": {},
197
+ "enums": {},
198
+ "_meta": {
199
+ "schemas": {},
200
+ "tables": {},
201
+ "columns": {}
202
+ },
203
+ "internal": {
204
+ "indexes": {}
205
+ }
206
+ }