@vinihcrosa/lumem-os 0.4.0 → 0.6.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.
- package/bin/lumem.mjs +46 -3
- package/dist/server/main.mjs +11659 -7544
- package/dist/web/assets/{codemirror-setup-u52h1pHp.js → codemirror-setup-JaVFPDhT.js} +1 -1
- package/dist/web/assets/index-BvSMeFFu.css +32 -0
- package/dist/web/assets/index-DML0Esam.js +101 -0
- package/dist/web/index.html +2 -2
- package/drizzle/0014_tarefa_como_entidade.sql +33 -0
- package/drizzle/0015_quadro_de_sete_colunas.sql +33 -0
- package/drizzle/0016_ordem_na_coluna.sql +13 -0
- package/drizzle/0017_relogio_do_encalhe.sql +10 -0
- package/drizzle/0018_tetos_do_workspace.sql +26 -0
- package/drizzle/0019_comentario_de_tarefa.sql +15 -0
- package/drizzle/0020_esteira_tentativa_e_autonomia.sql +51 -0
- package/drizzle/0021_catalogo_de_agentes.sql +27 -0
- package/drizzle/0022_interruptor_da_esteira.sql +30 -0
- package/drizzle/0023_prompt_preparado.sql +49 -0
- package/drizzle/0024_motivo_do_bloqueio.sql +1 -0
- package/drizzle/0025_aviso_uma_vez.sql +1 -0
- package/drizzle/0026_pr_mesclada_sempre_remove.sql +1 -0
- package/drizzle/0027_issue_como_identidade.sql +6 -0
- package/drizzle/0028_marcos_no_tracker.sql +1 -0
- package/drizzle/0029_parecer_do_revisor.sql +22 -0
- package/drizzle/0030_papel_da_sessao_e_vaivem.sql +56 -0
- package/drizzle/0031_recibo_do_parecer.sql +14 -0
- package/drizzle/0032_turno_do_consumo.sql +1 -0
- package/drizzle/meta/0014_snapshot.json +1895 -0
- package/drizzle/meta/0015_snapshot.json +1895 -0
- package/drizzle/meta/0016_snapshot.json +1912 -0
- package/drizzle/meta/0017_snapshot.json +1920 -0
- package/drizzle/meta/0018_snapshot.json +1945 -0
- package/drizzle/meta/0019_snapshot.json +2039 -0
- package/drizzle/meta/0020_snapshot.json +2063 -0
- package/drizzle/meta/0021_snapshot.json +2249 -0
- package/drizzle/meta/0022_snapshot.json +2273 -0
- package/drizzle/meta/0023_snapshot.json +2291 -0
- package/drizzle/meta/0024_snapshot.json +2298 -0
- package/drizzle/meta/0025_snapshot.json +2305 -0
- package/drizzle/meta/0026_snapshot.json +2313 -0
- package/drizzle/meta/0027_snapshot.json +2357 -0
- package/drizzle/meta/0028_snapshot.json +2365 -0
- package/drizzle/meta/0029_snapshot.json +2506 -0
- package/drizzle/meta/0030_snapshot.json +2525 -0
- package/drizzle/meta/0031_snapshot.json +2623 -0
- package/drizzle/meta/0032_snapshot.json +2631 -0
- package/drizzle/meta/_journal.json +133 -0
- package/package.json +1 -1
- package/dist/web/assets/index-CrtHjcbU.js +0 -101
- package/dist/web/assets/index-DliBP3a7.css +0 -32
package/dist/web/index.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Lumem-OS</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-DML0Esam.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BvSMeFFu.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="root"></div>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
CREATE TABLE `task` (
|
|
2
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
3
|
+
`workspace_id` text NOT NULL,
|
|
4
|
+
`project_id` text NOT NULL,
|
|
5
|
+
`title` text NOT NULL,
|
|
6
|
+
`body` text DEFAULT '' NOT NULL,
|
|
7
|
+
`status` text DEFAULT 'open' NOT NULL,
|
|
8
|
+
`created_by` text DEFAULT 'human' NOT NULL,
|
|
9
|
+
`created_by_session` text,
|
|
10
|
+
`worktree_id` text,
|
|
11
|
+
`links` text DEFAULT '[]' NOT NULL,
|
|
12
|
+
`reason` text,
|
|
13
|
+
`closed_at` integer,
|
|
14
|
+
`created_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
15
|
+
`updated_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
16
|
+
FOREIGN KEY (`workspace_id`) REFERENCES `workspace`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
17
|
+
FOREIGN KEY (`project_id`) REFERENCES `project`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
18
|
+
FOREIGN KEY (`worktree_id`) REFERENCES `worktree`(`id`) ON UPDATE no action ON DELETE set null,
|
|
19
|
+
CONSTRAINT "task_status" CHECK("task"."status" IN ('proposed', 'open', 'in_progress', 'review', 'done', 'dropped')),
|
|
20
|
+
CONSTRAINT "task_created_by" CHECK("task"."created_by" IN ('human', 'agent')),
|
|
21
|
+
CONSTRAINT "task_agent_provenance" CHECK(("task"."created_by" = 'agent' AND "task"."created_by_session" IS NOT NULL)
|
|
22
|
+
OR ("task"."created_by" = 'human' AND "task"."created_by_session" IS NULL)),
|
|
23
|
+
CONSTRAINT "task_closed_at" CHECK(("task"."status" IN ('done', 'dropped') AND "task"."closed_at" IS NOT NULL)
|
|
24
|
+
OR ("task"."status" NOT IN ('done', 'dropped') AND "task"."closed_at" IS NULL))
|
|
25
|
+
);
|
|
26
|
+
--> statement-breakpoint
|
|
27
|
+
CREATE INDEX `task_by_workspace` ON `task` (`workspace_id`,`status`);--> statement-breakpoint
|
|
28
|
+
CREATE INDEX `task_by_project` ON `task` (`project_id`);--> statement-breakpoint
|
|
29
|
+
-- `ON DELETE set null` escrito à mão: o `drizzle-kit` perde a ação do FK no
|
|
30
|
+
-- caminho de ALTER TABLE, e sem ela a coluna nasceria NO ACTION — ou seja,
|
|
31
|
+
-- apagar uma tarefa ficaria bloqueado por qualquer sessão que a serviu, que é
|
|
32
|
+
-- o oposto do que o schema declara.
|
|
33
|
+
ALTER TABLE `session` ADD `task_id` text REFERENCES `task`(`id`) ON UPDATE no action ON DELETE set null;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
PRAGMA foreign_keys=OFF;--> statement-breakpoint
|
|
2
|
+
CREATE TABLE `__new_task` (
|
|
3
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
4
|
+
`workspace_id` text NOT NULL,
|
|
5
|
+
`project_id` text NOT NULL,
|
|
6
|
+
`title` text NOT NULL,
|
|
7
|
+
`body` text DEFAULT '' NOT NULL,
|
|
8
|
+
`status` text DEFAULT 'open' NOT NULL,
|
|
9
|
+
`created_by` text DEFAULT 'human' NOT NULL,
|
|
10
|
+
`created_by_session` text,
|
|
11
|
+
`worktree_id` text,
|
|
12
|
+
`links` text DEFAULT '[]' NOT NULL,
|
|
13
|
+
`reason` text,
|
|
14
|
+
`closed_at` integer,
|
|
15
|
+
`created_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
16
|
+
`updated_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
17
|
+
FOREIGN KEY (`workspace_id`) REFERENCES `workspace`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
18
|
+
FOREIGN KEY (`project_id`) REFERENCES `project`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
19
|
+
FOREIGN KEY (`worktree_id`) REFERENCES `worktree`(`id`) ON UPDATE no action ON DELETE set null,
|
|
20
|
+
CONSTRAINT "task_status" CHECK("__new_task"."status" IN ('proposed', 'backlog', 'open', 'in_progress', 'review', 'testing', 'ready_to_merge', 'done', 'dropped')),
|
|
21
|
+
CONSTRAINT "task_created_by" CHECK("__new_task"."created_by" IN ('human', 'agent')),
|
|
22
|
+
CONSTRAINT "task_agent_provenance" CHECK(("__new_task"."created_by" = 'agent' AND "__new_task"."created_by_session" IS NOT NULL)
|
|
23
|
+
OR ("__new_task"."created_by" = 'human' AND "__new_task"."created_by_session" IS NULL)),
|
|
24
|
+
CONSTRAINT "task_closed_at" CHECK(("__new_task"."status" IN ('done', 'dropped') AND "__new_task"."closed_at" IS NOT NULL)
|
|
25
|
+
OR ("__new_task"."status" NOT IN ('done', 'dropped') AND "__new_task"."closed_at" IS NULL))
|
|
26
|
+
);
|
|
27
|
+
--> statement-breakpoint
|
|
28
|
+
INSERT INTO `__new_task`("id", "workspace_id", "project_id", "title", "body", "status", "created_by", "created_by_session", "worktree_id", "links", "reason", "closed_at", "created_at", "updated_at") SELECT "id", "workspace_id", "project_id", "title", "body", "status", "created_by", "created_by_session", "worktree_id", "links", "reason", "closed_at", "created_at", "updated_at" FROM `task`;--> statement-breakpoint
|
|
29
|
+
DROP TABLE `task`;--> statement-breakpoint
|
|
30
|
+
ALTER TABLE `__new_task` RENAME TO `task`;--> statement-breakpoint
|
|
31
|
+
PRAGMA foreign_keys=ON;--> statement-breakpoint
|
|
32
|
+
CREATE INDEX `task_by_workspace` ON `task` (`workspace_id`,`status`);--> statement-breakpoint
|
|
33
|
+
CREATE INDEX `task_by_project` ON `task` (`project_id`);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
ALTER TABLE `task` ADD `position` integer DEFAULT 0 NOT NULL;--> statement-breakpoint
|
|
2
|
+
CREATE INDEX `task_by_position` ON `task` (`workspace_id`,`status`,`position`);--> statement-breakpoint
|
|
3
|
+
-- Backfill escrito à mão: o `drizzle-kit` só sabe o DEFAULT, e com todas as
|
|
4
|
+
-- linhas em zero a coluna do quadro nasceria numa ordem que o SQLite escolhe.
|
|
5
|
+
-- Ordem de chegada é a que o §4.3 declara para quem nunca arrastou, e
|
|
6
|
+
-- `created_at` é o único registro dela que existe.
|
|
7
|
+
UPDATE `task` SET `position` = (
|
|
8
|
+
SELECT COUNT(*) FROM `task` AS `earlier`
|
|
9
|
+
WHERE `earlier`.`workspace_id` = `task`.`workspace_id`
|
|
10
|
+
AND `earlier`.`status` = `task`.`status`
|
|
11
|
+
AND (`earlier`.`created_at` < `task`.`created_at`
|
|
12
|
+
OR (`earlier`.`created_at` = `task`.`created_at` AND `earlier`.`id` < `task`.`id`))
|
|
13
|
+
);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
ALTER TABLE `task` ADD `status_changed_at` integer DEFAULT 0 NOT NULL;--> statement-breakpoint
|
|
2
|
+
-- Backfill à mão, e o `DEFAULT 0` acima é o motivo: o SQLite recusa
|
|
3
|
+
-- `ADD COLUMN` com default não-constante, então não dá para carimbar *agora* na
|
|
4
|
+
-- própria coluna — e carimbar *agora* seria errado de qualquer jeito. Toda
|
|
5
|
+
-- tarefa que já estava parada acordaria da migração dizendo "há 0 s", apagando
|
|
6
|
+
-- exatamente o encalhe que a coluna existe para mostrar. `updated_at` é o
|
|
7
|
+
-- melhor registro de quando alguém mexeu nela pela última vez: um limite
|
|
8
|
+
-- superior da verdade, que erra para o lado seguro — nunca inventa encalhe que
|
|
9
|
+
-- não houve.
|
|
10
|
+
UPDATE `task` SET `status_changed_at` = `updated_at`;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
PRAGMA foreign_keys=OFF;--> statement-breakpoint
|
|
2
|
+
CREATE TABLE `__new_workspace` (
|
|
3
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
4
|
+
`name` text NOT NULL,
|
|
5
|
+
`default_lumem_mode` text DEFAULT 'ask' NOT NULL,
|
|
6
|
+
`budget_cost_per_task` real,
|
|
7
|
+
`budget_cost_per_day` real,
|
|
8
|
+
`budget_turns_per_session` integer,
|
|
9
|
+
`created_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
10
|
+
`updated_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
11
|
+
CONSTRAINT "workspace_default_lumem_mode" CHECK("__new_workspace"."default_lumem_mode" IN ('ask', 'auto')),
|
|
12
|
+
CONSTRAINT "workspace_budget_not_negative" CHECK(("__new_workspace"."budget_cost_per_task" IS NULL OR "__new_workspace"."budget_cost_per_task" >= 0)
|
|
13
|
+
AND ("__new_workspace"."budget_cost_per_day" IS NULL OR "__new_workspace"."budget_cost_per_day" >= 0)
|
|
14
|
+
AND ("__new_workspace"."budget_turns_per_session" IS NULL OR "__new_workspace"."budget_turns_per_session" >= 0))
|
|
15
|
+
);
|
|
16
|
+
--> statement-breakpoint
|
|
17
|
+
-- A lista de colunas do SELECT foi reescrita à mão, e é a mesma armadilha que o
|
|
18
|
+
-- `0001` pagou: o `drizzle-kit` gera o SELECT com as colunas da tabela **nova**,
|
|
19
|
+
-- lendo da **velha** — `SELECT "budget_cost_per_task" FROM workspace` num banco
|
|
20
|
+
-- onde essa coluna, por definição, ainda não existe. Copia-se o que havia; as
|
|
21
|
+
-- três novas ficam `NULL`, que é o valor que quer dizer **sem teto**.
|
|
22
|
+
INSERT INTO `__new_workspace`("id", "name", "default_lumem_mode", "created_at", "updated_at") SELECT "id", "name", "default_lumem_mode", "created_at", "updated_at" FROM `workspace`;--> statement-breakpoint
|
|
23
|
+
DROP TABLE `workspace`;--> statement-breakpoint
|
|
24
|
+
ALTER TABLE `__new_workspace` RENAME TO `workspace`;--> statement-breakpoint
|
|
25
|
+
PRAGMA foreign_keys=ON;--> statement-breakpoint
|
|
26
|
+
CREATE UNIQUE INDEX `workspace_name_unique` ON `workspace` (`name`);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
CREATE TABLE `task_comment` (
|
|
2
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
3
|
+
`task_id` text NOT NULL,
|
|
4
|
+
`body` text NOT NULL,
|
|
5
|
+
`created_by` text DEFAULT 'human' NOT NULL,
|
|
6
|
+
`created_by_session` text,
|
|
7
|
+
`created_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
8
|
+
`updated_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
9
|
+
FOREIGN KEY (`task_id`) REFERENCES `task`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
10
|
+
CONSTRAINT "task_comment_created_by" CHECK("task_comment"."created_by" IN ('human', 'agent')),
|
|
11
|
+
CONSTRAINT "task_comment_provenance" CHECK(("task_comment"."created_by" = 'agent' AND "task_comment"."created_by_session" IS NOT NULL)
|
|
12
|
+
OR ("task_comment"."created_by" = 'human' AND "task_comment"."created_by_session" IS NULL))
|
|
13
|
+
);
|
|
14
|
+
--> statement-breakpoint
|
|
15
|
+
CREATE INDEX `task_comment_by_task` ON `task_comment` (`task_id`,`created_at`);
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
PRAGMA foreign_keys=OFF;--> statement-breakpoint
|
|
2
|
+
CREATE TABLE `__new_task` (
|
|
3
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
4
|
+
`workspace_id` text NOT NULL,
|
|
5
|
+
`project_id` text NOT NULL,
|
|
6
|
+
`title` text NOT NULL,
|
|
7
|
+
`body` text DEFAULT '' NOT NULL,
|
|
8
|
+
`status` text DEFAULT 'open' NOT NULL,
|
|
9
|
+
`created_by` text DEFAULT 'human' NOT NULL,
|
|
10
|
+
`created_by_session` text,
|
|
11
|
+
`worktree_id` text,
|
|
12
|
+
`position` integer DEFAULT 0 NOT NULL,
|
|
13
|
+
`links` text DEFAULT '[]' NOT NULL,
|
|
14
|
+
`reason` text,
|
|
15
|
+
`attempts` integer DEFAULT 0 NOT NULL,
|
|
16
|
+
`autonomy` text DEFAULT 'inherit' NOT NULL,
|
|
17
|
+
`status_changed_at` integer DEFAULT 0 NOT NULL,
|
|
18
|
+
`closed_at` integer,
|
|
19
|
+
`created_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
20
|
+
`updated_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
21
|
+
FOREIGN KEY (`workspace_id`) REFERENCES `workspace`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
22
|
+
FOREIGN KEY (`project_id`) REFERENCES `project`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
23
|
+
FOREIGN KEY (`worktree_id`) REFERENCES `worktree`(`id`) ON UPDATE no action ON DELETE set null,
|
|
24
|
+
CONSTRAINT "task_status" CHECK("__new_task"."status" IN ('proposed', 'backlog', 'open', 'in_progress', 'review', 'testing', 'ready_to_merge', 'done', 'dropped')),
|
|
25
|
+
CONSTRAINT "task_created_by" CHECK("__new_task"."created_by" IN ('human', 'agent')),
|
|
26
|
+
CONSTRAINT "task_autonomy" CHECK("__new_task"."autonomy" IN ('inherit', 'off')),
|
|
27
|
+
CONSTRAINT "task_attempts_not_negative" CHECK("__new_task"."attempts" >= 0),
|
|
28
|
+
CONSTRAINT "task_agent_provenance" CHECK(("__new_task"."created_by" = 'agent' AND "__new_task"."created_by_session" IS NOT NULL)
|
|
29
|
+
OR ("__new_task"."created_by" = 'human' AND "__new_task"."created_by_session" IS NULL)),
|
|
30
|
+
CONSTRAINT "task_closed_at" CHECK(("__new_task"."status" IN ('done', 'dropped') AND "__new_task"."closed_at" IS NOT NULL)
|
|
31
|
+
OR ("__new_task"."status" NOT IN ('done', 'dropped') AND "__new_task"."closed_at" IS NULL))
|
|
32
|
+
);
|
|
33
|
+
--> statement-breakpoint
|
|
34
|
+
-- A lista de colunas foi reescrita à mão, e é a TERCEIRA vez neste repositório:
|
|
35
|
+
-- o `drizzle-kit` gera o SELECT com as colunas da tabela **nova**, lendo da
|
|
36
|
+
-- **velha** — `SELECT "attempts", "autonomy" FROM task` num banco onde elas, por
|
|
37
|
+
-- definição, ainda não existem. O `0001` pagou por isso, o `0018` pagou cinco
|
|
38
|
+
-- migrações depois, e a lição já está no `testing.md`: **leia o SELECT de toda
|
|
39
|
+
-- migração gerada**. Nenhum teste que começa de banco vazio pega.
|
|
40
|
+
--
|
|
41
|
+
-- Copia-se o que havia. As duas novas ficam no DEFAULT: `attempts = 0`, que é a
|
|
42
|
+
-- verdade sobre toda tarefa que existia antes de a esteira existir, e
|
|
43
|
+
-- `autonomy = 'inherit'`, que não liga nada — o interruptor do workspace nasce
|
|
44
|
+
-- em `manual`.
|
|
45
|
+
INSERT INTO `__new_task`("id", "workspace_id", "project_id", "title", "body", "status", "created_by", "created_by_session", "worktree_id", "position", "links", "reason", "status_changed_at", "closed_at", "created_at", "updated_at") SELECT "id", "workspace_id", "project_id", "title", "body", "status", "created_by", "created_by_session", "worktree_id", "position", "links", "reason", "status_changed_at", "closed_at", "created_at", "updated_at" FROM `task`;--> statement-breakpoint
|
|
46
|
+
DROP TABLE `task`;--> statement-breakpoint
|
|
47
|
+
ALTER TABLE `__new_task` RENAME TO `task`;--> statement-breakpoint
|
|
48
|
+
PRAGMA foreign_keys=ON;--> statement-breakpoint
|
|
49
|
+
CREATE INDEX `task_by_workspace` ON `task` (`workspace_id`,`status`);--> statement-breakpoint
|
|
50
|
+
CREATE INDEX `task_by_position` ON `task` (`workspace_id`,`status`,`position`);--> statement-breakpoint
|
|
51
|
+
CREATE INDEX `task_by_project` ON `task` (`project_id`);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
CREATE TABLE `named_agent` (
|
|
2
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
3
|
+
`workspace_id` text NOT NULL,
|
|
4
|
+
`name` text NOT NULL,
|
|
5
|
+
`adapter` text NOT NULL,
|
|
6
|
+
`model` text,
|
|
7
|
+
`instructions` text DEFAULT '' NOT NULL,
|
|
8
|
+
`created_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
9
|
+
`updated_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
10
|
+
FOREIGN KEY (`workspace_id`) REFERENCES `workspace`(`id`) ON UPDATE no action ON DELETE restrict
|
|
11
|
+
);
|
|
12
|
+
--> statement-breakpoint
|
|
13
|
+
CREATE UNIQUE INDEX `named_agent_name_in_workspace` ON `named_agent` (`workspace_id`,`name`);--> statement-breakpoint
|
|
14
|
+
CREATE TABLE `role_binding` (
|
|
15
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
16
|
+
`scope_type` text NOT NULL,
|
|
17
|
+
`scope_id` text NOT NULL,
|
|
18
|
+
`role` text NOT NULL,
|
|
19
|
+
`agent_id` text NOT NULL,
|
|
20
|
+
`created_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
21
|
+
`updated_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
22
|
+
FOREIGN KEY (`agent_id`) REFERENCES `named_agent`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
23
|
+
CONSTRAINT "role_binding_scope_type" CHECK("role_binding"."scope_type" IN ('workspace', 'project', 'task')),
|
|
24
|
+
CONSTRAINT "role_binding_role" CHECK("role_binding"."role" IN ('implementador', 'revisor', 'testador'))
|
|
25
|
+
);
|
|
26
|
+
--> statement-breakpoint
|
|
27
|
+
CREATE UNIQUE INDEX `role_binding_one_per_scope` ON `role_binding` (`scope_type`,`scope_id`,`role`);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
PRAGMA foreign_keys=OFF;--> statement-breakpoint
|
|
2
|
+
CREATE TABLE `__new_workspace` (
|
|
3
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
4
|
+
`name` text NOT NULL,
|
|
5
|
+
`default_lumem_mode` text DEFAULT 'ask' NOT NULL,
|
|
6
|
+
`budget_cost_per_task` real,
|
|
7
|
+
`budget_cost_per_day` real,
|
|
8
|
+
`budget_turns_per_session` integer,
|
|
9
|
+
`autonomy` text DEFAULT 'manual' NOT NULL,
|
|
10
|
+
`autonomy_max_parallel` integer DEFAULT 2 NOT NULL,
|
|
11
|
+
`created_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
12
|
+
`updated_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
13
|
+
CONSTRAINT "workspace_default_lumem_mode" CHECK("__new_workspace"."default_lumem_mode" IN ('ask', 'auto')),
|
|
14
|
+
CONSTRAINT "workspace_autonomy" CHECK("__new_workspace"."autonomy" IN ('manual', 'assistido', 'autonomo')),
|
|
15
|
+
CONSTRAINT "workspace_autonomy_max_parallel" CHECK("__new_workspace"."autonomy_max_parallel" >= 0),
|
|
16
|
+
CONSTRAINT "workspace_budget_not_negative" CHECK(("__new_workspace"."budget_cost_per_task" IS NULL OR "__new_workspace"."budget_cost_per_task" >= 0)
|
|
17
|
+
AND ("__new_workspace"."budget_cost_per_day" IS NULL OR "__new_workspace"."budget_cost_per_day" >= 0)
|
|
18
|
+
AND ("__new_workspace"."budget_turns_per_session" IS NULL OR "__new_workspace"."budget_turns_per_session" >= 0))
|
|
19
|
+
);
|
|
20
|
+
--> statement-breakpoint
|
|
21
|
+
-- Reescrita à mão pela QUARTA vez: o `drizzle-kit` gera o SELECT com as colunas
|
|
22
|
+
-- da tabela nova lendo da velha, e `SELECT "autonomy" FROM workspace` não existe
|
|
23
|
+
-- num banco anterior a esta migração. O `0001`, o `0018` e o `0020` pagaram pelo
|
|
24
|
+
-- mesmo. Copia-se o que havia; as duas novas ficam no DEFAULT — `manual`, que é
|
|
25
|
+
-- o Lumem de hoje, e `2`, que é o número que a folha do Open Design desenha.
|
|
26
|
+
INSERT INTO `__new_workspace`("id", "name", "default_lumem_mode", "budget_cost_per_task", "budget_cost_per_day", "budget_turns_per_session", "created_at", "updated_at") SELECT "id", "name", "default_lumem_mode", "budget_cost_per_task", "budget_cost_per_day", "budget_turns_per_session", "created_at", "updated_at" FROM `workspace`;--> statement-breakpoint
|
|
27
|
+
DROP TABLE `workspace`;--> statement-breakpoint
|
|
28
|
+
ALTER TABLE `__new_workspace` RENAME TO `workspace`;--> statement-breakpoint
|
|
29
|
+
PRAGMA foreign_keys=ON;--> statement-breakpoint
|
|
30
|
+
CREATE UNIQUE INDEX `workspace_name_unique` ON `workspace` (`name`);
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
PRAGMA foreign_keys=OFF;--> statement-breakpoint
|
|
2
|
+
CREATE TABLE `__new_task` (
|
|
3
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
4
|
+
`workspace_id` text NOT NULL,
|
|
5
|
+
`project_id` text NOT NULL,
|
|
6
|
+
`title` text NOT NULL,
|
|
7
|
+
`body` text DEFAULT '' NOT NULL,
|
|
8
|
+
`status` text DEFAULT 'open' NOT NULL,
|
|
9
|
+
`created_by` text DEFAULT 'human' NOT NULL,
|
|
10
|
+
`created_by_session` text,
|
|
11
|
+
`worktree_id` text,
|
|
12
|
+
`position` integer DEFAULT 0 NOT NULL,
|
|
13
|
+
`links` text DEFAULT '[]' NOT NULL,
|
|
14
|
+
`reason` text,
|
|
15
|
+
`attempts` integer DEFAULT 0 NOT NULL,
|
|
16
|
+
`autonomy` text DEFAULT 'inherit' NOT NULL,
|
|
17
|
+
`prepared_prompt` text,
|
|
18
|
+
`prepared_role` text,
|
|
19
|
+
`status_changed_at` integer DEFAULT 0 NOT NULL,
|
|
20
|
+
`closed_at` integer,
|
|
21
|
+
`created_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
22
|
+
`updated_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
23
|
+
FOREIGN KEY (`workspace_id`) REFERENCES `workspace`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
24
|
+
FOREIGN KEY (`project_id`) REFERENCES `project`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
25
|
+
FOREIGN KEY (`worktree_id`) REFERENCES `worktree`(`id`) ON UPDATE no action ON DELETE set null,
|
|
26
|
+
CONSTRAINT "task_status" CHECK("__new_task"."status" IN ('proposed', 'backlog', 'open', 'in_progress', 'review', 'testing', 'ready_to_merge', 'done', 'dropped')),
|
|
27
|
+
CONSTRAINT "task_created_by" CHECK("__new_task"."created_by" IN ('human', 'agent')),
|
|
28
|
+
CONSTRAINT "task_autonomy" CHECK("__new_task"."autonomy" IN ('inherit', 'off')),
|
|
29
|
+
CONSTRAINT "task_attempts_not_negative" CHECK("__new_task"."attempts" >= 0),
|
|
30
|
+
CONSTRAINT "task_prepared_pair" CHECK(("__new_task"."prepared_prompt" IS NULL AND "__new_task"."prepared_role" IS NULL)
|
|
31
|
+
OR ("__new_task"."prepared_prompt" IS NOT NULL AND "__new_task"."prepared_role" IS NOT NULL)),
|
|
32
|
+
CONSTRAINT "task_agent_provenance" CHECK(("__new_task"."created_by" = 'agent' AND "__new_task"."created_by_session" IS NOT NULL)
|
|
33
|
+
OR ("__new_task"."created_by" = 'human' AND "__new_task"."created_by_session" IS NULL)),
|
|
34
|
+
CONSTRAINT "task_closed_at" CHECK(("__new_task"."status" IN ('done', 'dropped') AND "__new_task"."closed_at" IS NOT NULL)
|
|
35
|
+
OR ("__new_task"."status" NOT IN ('done', 'dropped') AND "__new_task"."closed_at" IS NULL))
|
|
36
|
+
);
|
|
37
|
+
--> statement-breakpoint
|
|
38
|
+
-- Quinta vez, e a lição já tem endereço no `testing.md`: o `drizzle-kit` gera o
|
|
39
|
+
-- SELECT com as colunas da tabela nova lendo da velha. Aqui as duas que não
|
|
40
|
+
-- existem ainda são `prepared_prompt` e `prepared_role`; as duas ficam `NULL`,
|
|
41
|
+
-- que quer dizer *nada preparado* — a verdade sobre toda tarefa anterior ao
|
|
42
|
+
-- degrau `assistido`.
|
|
43
|
+
INSERT INTO `__new_task`("id", "workspace_id", "project_id", "title", "body", "status", "created_by", "created_by_session", "worktree_id", "position", "links", "reason", "attempts", "autonomy", "status_changed_at", "closed_at", "created_at", "updated_at") SELECT "id", "workspace_id", "project_id", "title", "body", "status", "created_by", "created_by_session", "worktree_id", "position", "links", "reason", "attempts", "autonomy", "status_changed_at", "closed_at", "created_at", "updated_at" FROM `task`;--> statement-breakpoint
|
|
44
|
+
DROP TABLE `task`;--> statement-breakpoint
|
|
45
|
+
ALTER TABLE `__new_task` RENAME TO `task`;--> statement-breakpoint
|
|
46
|
+
PRAGMA foreign_keys=ON;--> statement-breakpoint
|
|
47
|
+
CREATE INDEX `task_by_workspace` ON `task` (`workspace_id`,`status`);--> statement-breakpoint
|
|
48
|
+
CREATE INDEX `task_by_position` ON `task` (`workspace_id`,`status`,`position`);--> statement-breakpoint
|
|
49
|
+
CREATE INDEX `task_by_project` ON `task` (`project_id`);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE `task` ADD `blocked_reason` text;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE `task` ADD `notified_at` integer;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE `workspace` ADD `merged_always_removes` integer DEFAULT false NOT NULL;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
ALTER TABLE `task` ADD `external_source` text;--> statement-breakpoint
|
|
2
|
+
ALTER TABLE `task` ADD `external_id` text;--> statement-breakpoint
|
|
3
|
+
ALTER TABLE `task` ADD `external_state` text;--> statement-breakpoint
|
|
4
|
+
ALTER TABLE `task` ADD `external_assignee` text;--> statement-breakpoint
|
|
5
|
+
ALTER TABLE `task` ADD `external_body_hash` text;--> statement-breakpoint
|
|
6
|
+
CREATE UNIQUE INDEX `task_external_in_workspace` ON `task` (`workspace_id`,`external_source`,`external_id`);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE `task` ADD `external_marks` text DEFAULT '[]' NOT NULL;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
CREATE TABLE `task_finding` (
|
|
2
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
3
|
+
`task_id` text NOT NULL,
|
|
4
|
+
`found_by_session` text NOT NULL,
|
|
5
|
+
`role` text NOT NULL,
|
|
6
|
+
`bucket` text NOT NULL,
|
|
7
|
+
`title` text NOT NULL,
|
|
8
|
+
`detail` text DEFAULT '' NOT NULL,
|
|
9
|
+
`command` text,
|
|
10
|
+
`expected` text,
|
|
11
|
+
`verification` text DEFAULT 'pending' NOT NULL,
|
|
12
|
+
`output` text,
|
|
13
|
+
`created_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
14
|
+
`updated_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
15
|
+
FOREIGN KEY (`task_id`) REFERENCES `task`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
16
|
+
CONSTRAINT "task_finding_bucket" CHECK("task_finding"."bucket" IN ('blocks', 'notes')),
|
|
17
|
+
CONSTRAINT "task_finding_verification" CHECK("task_finding"."verification" IN ('pending', 'reproduced', 'refuted', 'skipped')),
|
|
18
|
+
CONSTRAINT "task_finding_reproduction" CHECK(("task_finding"."bucket" = 'blocks' AND "task_finding"."command" IS NOT NULL)
|
|
19
|
+
OR ("task_finding"."bucket" = 'notes' AND "task_finding"."command" IS NULL))
|
|
20
|
+
);
|
|
21
|
+
--> statement-breakpoint
|
|
22
|
+
CREATE INDEX `task_finding_by_task` ON `task_finding` (`task_id`,`created_at`);
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
ALTER TABLE `session` ADD `task_role` text;--> statement-breakpoint
|
|
2
|
+
PRAGMA foreign_keys=OFF;--> statement-breakpoint
|
|
3
|
+
CREATE TABLE `__new_task` (
|
|
4
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
5
|
+
`workspace_id` text NOT NULL,
|
|
6
|
+
`project_id` text NOT NULL,
|
|
7
|
+
`title` text NOT NULL,
|
|
8
|
+
`body` text DEFAULT '' NOT NULL,
|
|
9
|
+
`status` text DEFAULT 'open' NOT NULL,
|
|
10
|
+
`created_by` text DEFAULT 'human' NOT NULL,
|
|
11
|
+
`created_by_session` text,
|
|
12
|
+
`worktree_id` text,
|
|
13
|
+
`position` integer DEFAULT 0 NOT NULL,
|
|
14
|
+
`links` text DEFAULT '[]' NOT NULL,
|
|
15
|
+
`reason` text,
|
|
16
|
+
`attempts` integer DEFAULT 0 NOT NULL,
|
|
17
|
+
`bounces` integer DEFAULT 0 NOT NULL,
|
|
18
|
+
`autonomy` text DEFAULT 'inherit' NOT NULL,
|
|
19
|
+
`prepared_prompt` text,
|
|
20
|
+
`prepared_role` text,
|
|
21
|
+
`blocked_reason` text,
|
|
22
|
+
`notified_at` integer,
|
|
23
|
+
`external_source` text,
|
|
24
|
+
`external_id` text,
|
|
25
|
+
`external_state` text,
|
|
26
|
+
`external_assignee` text,
|
|
27
|
+
`external_body_hash` text,
|
|
28
|
+
`external_marks` text DEFAULT '[]' NOT NULL,
|
|
29
|
+
`status_changed_at` integer DEFAULT 0 NOT NULL,
|
|
30
|
+
`closed_at` integer,
|
|
31
|
+
`created_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
32
|
+
`updated_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
33
|
+
FOREIGN KEY (`workspace_id`) REFERENCES `workspace`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
34
|
+
FOREIGN KEY (`project_id`) REFERENCES `project`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
35
|
+
FOREIGN KEY (`worktree_id`) REFERENCES `worktree`(`id`) ON UPDATE no action ON DELETE set null,
|
|
36
|
+
CONSTRAINT "task_status" CHECK("__new_task"."status" IN ('proposed', 'backlog', 'open', 'in_progress', 'review', 'testing', 'ready_to_merge', 'done', 'dropped')),
|
|
37
|
+
CONSTRAINT "task_created_by" CHECK("__new_task"."created_by" IN ('human', 'agent')),
|
|
38
|
+
CONSTRAINT "task_autonomy" CHECK("__new_task"."autonomy" IN ('inherit', 'off')),
|
|
39
|
+
CONSTRAINT "task_attempts_not_negative" CHECK("__new_task"."attempts" >= 0),
|
|
40
|
+
CONSTRAINT "task_bounces_not_negative" CHECK("__new_task"."bounces" >= 0),
|
|
41
|
+
CONSTRAINT "task_prepared_pair" CHECK(("__new_task"."prepared_prompt" IS NULL AND "__new_task"."prepared_role" IS NULL)
|
|
42
|
+
OR ("__new_task"."prepared_prompt" IS NOT NULL AND "__new_task"."prepared_role" IS NOT NULL)),
|
|
43
|
+
CONSTRAINT "task_agent_provenance" CHECK(("__new_task"."created_by" = 'agent' AND "__new_task"."created_by_session" IS NOT NULL)
|
|
44
|
+
OR ("__new_task"."created_by" = 'human' AND "__new_task"."created_by_session" IS NULL)),
|
|
45
|
+
CONSTRAINT "task_closed_at" CHECK(("__new_task"."status" IN ('done', 'dropped') AND "__new_task"."closed_at" IS NOT NULL)
|
|
46
|
+
OR ("__new_task"."status" NOT IN ('done', 'dropped') AND "__new_task"."closed_at" IS NULL))
|
|
47
|
+
);
|
|
48
|
+
--> statement-breakpoint
|
|
49
|
+
INSERT INTO `__new_task`("id", "workspace_id", "project_id", "title", "body", "status", "created_by", "created_by_session", "worktree_id", "position", "links", "reason", "attempts", "bounces", "autonomy", "prepared_prompt", "prepared_role", "blocked_reason", "notified_at", "external_source", "external_id", "external_state", "external_assignee", "external_body_hash", "external_marks", "status_changed_at", "closed_at", "created_at", "updated_at") SELECT "id", "workspace_id", "project_id", "title", "body", "status", "created_by", "created_by_session", "worktree_id", "position", "links", "reason", "attempts", 0, "autonomy", "prepared_prompt", "prepared_role", "blocked_reason", "notified_at", "external_source", "external_id", "external_state", "external_assignee", "external_body_hash", "external_marks", "status_changed_at", "closed_at", "created_at", "updated_at" FROM `task`;--> statement-breakpoint
|
|
50
|
+
DROP TABLE `task`;--> statement-breakpoint
|
|
51
|
+
ALTER TABLE `__new_task` RENAME TO `task`;--> statement-breakpoint
|
|
52
|
+
PRAGMA foreign_keys=ON;--> statement-breakpoint
|
|
53
|
+
CREATE INDEX `task_by_workspace` ON `task` (`workspace_id`,`status`);--> statement-breakpoint
|
|
54
|
+
CREATE INDEX `task_by_position` ON `task` (`workspace_id`,`status`,`position`);--> statement-breakpoint
|
|
55
|
+
CREATE INDEX `task_by_project` ON `task` (`project_id`);--> statement-breakpoint
|
|
56
|
+
CREATE UNIQUE INDEX `task_external_in_workspace` ON `task` (`workspace_id`,`external_source`,`external_id`);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
CREATE TABLE `task_review` (
|
|
2
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
3
|
+
`task_id` text NOT NULL,
|
|
4
|
+
`by_session` text NOT NULL,
|
|
5
|
+
`role` text NOT NULL,
|
|
6
|
+
`blocks` integer DEFAULT 0 NOT NULL,
|
|
7
|
+
`notes` integer DEFAULT 0 NOT NULL,
|
|
8
|
+
`created_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
9
|
+
`updated_at` integer DEFAULT (unixepoch('subsec') * 1000) NOT NULL,
|
|
10
|
+
FOREIGN KEY (`task_id`) REFERENCES `task`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
11
|
+
CONSTRAINT "task_review_counts_not_negative" CHECK("task_review"."blocks" >= 0 AND "task_review"."notes" >= 0)
|
|
12
|
+
);
|
|
13
|
+
--> statement-breakpoint
|
|
14
|
+
CREATE INDEX `task_review_by_session` ON `task_review` (`by_session`,`created_at`);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE `session_usage` ADD `turn` integer DEFAULT 0 NOT NULL;
|