wizards 0.2.8 → 0.2.10

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 (60) hide show
  1. package/apps/runtime/dist/agents/project-assistant.js +16 -2
  2. package/apps/runtime/dist/agents/website.js +48 -10
  3. package/apps/runtime/dist/app.js +2 -0
  4. package/apps/runtime/dist/db/control-schema.js +18 -1
  5. package/apps/runtime/dist/db/migrations/control/0007_common_the_hand.sql +15 -0
  6. package/apps/runtime/dist/db/migrations/control/meta/0007_snapshot.json +460 -0
  7. package/apps/runtime/dist/db/migrations/control/meta/_journal.json +7 -0
  8. package/apps/runtime/dist/db/migrations/tenant/0006_hard_war_machine.sql +30 -0
  9. package/apps/runtime/dist/db/migrations/tenant/meta/0006_snapshot.json +1696 -0
  10. package/apps/runtime/dist/db/migrations/tenant/meta/_journal.json +7 -0
  11. package/apps/runtime/dist/db/schema.js +12 -6
  12. package/apps/runtime/dist/engine/steps.js +3 -0
  13. package/apps/runtime/dist/env.js +2 -0
  14. package/apps/runtime/dist/index.js +2 -0
  15. package/apps/runtime/dist/plugins/events.js +37 -14
  16. package/apps/runtime/dist/plugins/jobs.js +64 -0
  17. package/apps/runtime/dist/plugins/loader.js +67 -4
  18. package/apps/runtime/dist/plugins/public.js +31 -0
  19. package/apps/runtime/dist/plugins/registry.js +5 -0
  20. package/apps/runtime/dist/routes/plugin-public.js +59 -0
  21. package/apps/runtime/dist/routes/plugins.js +1 -1
  22. package/apps/runtime/dist/routes/studio.js +3 -0
  23. package/apps/runtime/dist/services/project-files.js +4 -0
  24. package/apps/runtime/dist/services/project-index.js +69 -9
  25. package/apps/runtime/dist/services/projects.js +7 -1
  26. package/apps/runtime/dist/services/spaces.js +2 -0
  27. package/apps/runtime/dist/tools/index.js +3 -2
  28. package/apps/runtime/dist/tools/plugin.js +89 -17
  29. package/apps/runtime/dist/tools/project.js +39 -31
  30. package/apps/web/dist/assets/Account-6cwwWOU3.js +1 -0
  31. package/apps/web/dist/assets/{ChangelogDialog-BNQ9yup8.js → ChangelogDialog-DewAXwoQ.js} +1 -1
  32. package/apps/web/dist/assets/{ChatPanel-CtE1wcUD.js → ChatPanel-CCNgem_v.js} +1 -1
  33. package/apps/web/dist/assets/{EditorPage-CAxamSak.js → EditorPage-DqVuS-JG.js} +2 -2
  34. package/apps/web/dist/assets/{FlowPreview-B3IxmikV.js → FlowPreview-BAVCgsXg.js} +1 -1
  35. package/apps/web/dist/assets/{Harness-Bo-kwm1H.js → Harness-BZCoZ4Z1.js} +1 -1
  36. package/apps/web/dist/assets/{HomePage-BdIa2zcg.js → HomePage-BsuuOXbB.js} +1 -1
  37. package/apps/web/dist/assets/{ImportWizard-DMea5ZH1.js → ImportWizard-BG28_HzC.js} +1 -1
  38. package/apps/web/dist/assets/{LocalRuntime-DFswQjxc.js → LocalRuntime-DyJJVozN.js} +1 -1
  39. package/apps/web/dist/assets/{NewWizardPage-Cnb6UYme.js → NewWizardPage-8B-d3T4k.js} +2 -2
  40. package/apps/web/dist/assets/ProjectPage-CkO8ndix.js +2 -0
  41. package/apps/web/dist/assets/{PublicRunner-CIHEMLlN.js → PublicRunner-DF960weZ.js} +1 -1
  42. package/apps/web/dist/assets/{RunnerView-COKGppwq.js → RunnerView-Z3VVOwVR.js} +1 -1
  43. package/apps/web/dist/assets/SettingsPage-BOYAZS08.js +1 -0
  44. package/apps/web/dist/assets/{SetupPage-Bk4qXYZV.js → SetupPage-Cl4Yc7A2.js} +1 -1
  45. package/apps/web/dist/assets/{SharePage-ChEtCkhn.js → SharePage-BFRWRmOF.js} +1 -1
  46. package/apps/web/dist/assets/changelog-DhleQ4p1.js +1 -0
  47. package/apps/web/dist/assets/{esm-Rtjq9ReB.js → esm-CLbOcpCO.js} +1 -1
  48. package/apps/web/dist/assets/index-Bl5vhqT3.js +10 -0
  49. package/apps/web/dist/assets/{meta-MVWkLr9H.js → meta-DxGh33r8.js} +1 -1
  50. package/apps/web/dist/assets/{outputs-s8BpXH6V.js → outputs-BDP8UsZT.js} +1 -1
  51. package/apps/web/dist/index.html +1 -1
  52. package/node_modules/@engenty-wizards/plugin-sdk/dist/index.d.ts +183 -0
  53. package/node_modules/@engenty-wizards/plugin-sdk/dist/studio.d.ts +48 -3
  54. package/node_modules/@engenty-wizards/shared/dist/projects.d.ts +7 -1
  55. package/package.json +1 -1
  56. package/apps/web/dist/assets/Account-YJEQEo5k.js +0 -1
  57. package/apps/web/dist/assets/ProjectPage-CR_FIUya.js +0 -2
  58. package/apps/web/dist/assets/SettingsPage-BqAogRSI.js +0 -1
  59. package/apps/web/dist/assets/changelog-C03GWYid.js +0 -1
  60. package/apps/web/dist/assets/index-BAQ2e4is.js +0 -10
@@ -8,7 +8,9 @@ import { ServiceError } from "../services/errors.js";
8
8
  import { addProjectFile, projectFileContent, projectFiles, updateProjectFile, } from "../services/project-files.js";
9
9
  import { documentText } from "../services/project-index.js";
10
10
  import { brandColorSchema, ownedProject, updateProject } from "../services/projects.js";
11
+ import { currentTenant } from "../tenants/tenant.js";
11
12
  import { safeFetch } from "../tools/net-guard.js";
13
+ import { assistantToolsOf } from "../tools/plugin.js";
12
14
  import { readWebsite } from "./website.js";
13
15
  const MAX_STEPS = 24;
14
16
  const SYSTEM = `You help the admin of "engenty wizards" set up a SPACE: what every wizard of the space draws on — who they are (title, about), the brand (logos, colours), assets (images, graphics, videos), documents, and facts (label → value: address, VAT id, phone, opening hours — anything).
@@ -294,10 +296,22 @@ function buildTools(input, resolved, wrote) {
294
296
  export async function runProjectAssistant(input) {
295
297
  let changed = false;
296
298
  const resolved = await textModel("high");
297
- const tools = buildTools(input, resolved, () => {
299
+ const wrote = () => {
298
300
  changed = true;
299
301
  input.onChanged?.();
300
- });
302
+ };
303
+ const tools = buildTools(input, resolved, wrote);
304
+ // What the tenant's plugins let the assistant do besides: a source of knowledge, say.
305
+ const project = await ownedProject(input.userId, input.projectId);
306
+ Object.assign(tools, await assistantToolsOf({
307
+ tenantId: currentTenant(),
308
+ space: { id: project.id, name: project.name },
309
+ userId: input.userId,
310
+ signal: input.signal ?? new AbortController().signal,
311
+ emit: (message) => input.onActivity?.(message),
312
+ changed: wrote,
313
+ card: (card) => input.onCard?.(card),
314
+ }));
301
315
  attachTools(resolved, tools);
302
316
  const agent = new Agent({
303
317
  id: "project-assistant",
@@ -96,7 +96,8 @@ async function rendered(url) {
96
96
  return null;
97
97
  }
98
98
  }
99
- export async function readWebsite(raw, signal) {
99
+ /** A page's HTML, drawn in a browser when it has hardly any text without its scripts. */
100
+ async function loadPage(raw, signal) {
100
101
  const res = await safeFetch(/^https?:\/\//i.test(raw) ? raw : `https://${raw}`, {
101
102
  headers: UA,
102
103
  signal: AbortSignal.any([AbortSignal.timeout(20_000), ...(signal ? [signal] : [])]),
@@ -107,11 +108,52 @@ export async function readWebsite(raw, signal) {
107
108
  if (res.ok && htmlToMarkdown(html).replace(/\s+/g, " ").length < 500) {
108
109
  html = ((await rendered(base)) ?? html).slice(0, 1_500_000);
109
110
  }
110
- const tags = (name) => [...html.matchAll(new RegExp(`<${name}\\b[^>]*>`, "gi"))].map((m) => m[0]);
111
- const meta = (key) => {
112
- const tag = tags("meta").find((t) => [attr(t, "name"), attr(t, "property")].some((v) => v.toLowerCase() === key));
113
- return tag ? attr(tag, "content") : "";
111
+ return { res, base, html };
112
+ }
113
+ const tagsOf = (html, name) => [...html.matchAll(new RegExp(`<${name}\\b[^>]*>`, "gi"))].map((m) => m[0]);
114
+ /** A `<meta>` by its name or property. */
115
+ function metaOf(html, key) {
116
+ const tag = tagsOf(html, "meta").find((t) => [attr(t, "name"), attr(t, "property")].some((v) => v.toLowerCase() === key));
117
+ return tag ? attr(tag, "content") : "";
118
+ }
119
+ const titleOf = (html) => html
120
+ .match(/<title[^>]*>([\s\S]*?)<\/title>/i)?.[1]
121
+ .replace(/\s+/g, " ")
122
+ .trim() ?? "";
123
+ /** The text of a link, as a reader sees it. */
124
+ const linkText = (inner) => inner
125
+ .replace(/<[^>]+>/g, " ")
126
+ .replace(/\s+/g, " ")
127
+ .trim()
128
+ .slice(0, 120);
129
+ /**
130
+ * A page for a plugin (`server.web.read`): its whole text as Markdown and every link, as against
131
+ * `readWebsite`, which picks what the assistant needs of a company's site.
132
+ */
133
+ export async function readPage(raw, signal) {
134
+ const { res, base, html } = await loadPage(raw, signal);
135
+ const links = [];
136
+ for (const m of html.matchAll(/<a\b([^>]*)>([\s\S]*?)<\/a>/gi)) {
137
+ const url = absolute(attr(`<a ${m[1]}>`, "href"), base)?.replace(/#.*$/, "");
138
+ if (url && !links.some((l) => l.url === url) && links.length < 2000) {
139
+ links.push({ url, text: linkText(m[2]) });
140
+ }
141
+ }
142
+ return {
143
+ url: base,
144
+ status: res.status,
145
+ etag: res.headers.get("etag"),
146
+ lastModified: res.headers.get("last-modified"),
147
+ title: titleOf(html),
148
+ description: metaOf(html, "description") || metaOf(html, "og:description"),
149
+ text: htmlToMarkdown(html).slice(0, 400_000),
150
+ links,
114
151
  };
152
+ }
153
+ export async function readWebsite(raw, signal) {
154
+ const { res, base, html } = await loadPage(raw, signal);
155
+ const tags = (name) => tagsOf(html, name);
156
+ const meta = (key) => metaOf(html, key);
115
157
  const logos = [];
116
158
  const addLogo = (href, hint) => {
117
159
  const url = absolute(href, base);
@@ -165,11 +207,7 @@ export async function readWebsite(raw, signal) {
165
207
  const links = [];
166
208
  for (const m of html.matchAll(/<a\b([^>]*)>([\s\S]*?)<\/a>/gi)) {
167
209
  const url = absolute(attr(`<a ${m[1]}>`, "href"), base);
168
- const text = m[2]
169
- .replace(/<[^>]+>/g, " ")
170
- .replace(/\s+/g, " ")
171
- .trim()
172
- .slice(0, 60);
210
+ const text = linkText(m[2]).slice(0, 60);
173
211
  if (url &&
174
212
  new URL(url).hostname === host &&
175
213
  /impressum|imprint|kontakt|contact|about|ueber|über|team|legal|unternehmen|company/i.test(`${url} ${text}`) &&
@@ -19,6 +19,7 @@ import { PLUGIN_NAME, pluginArchive, pluginMarketplace } from "./plugin.js";
19
19
  import { apiRoutes } from "./routes/api.js";
20
20
  import { internalRoutes } from "./routes/internal.js";
21
21
  import { marketplaceStudio } from "./routes/marketplace.js";
22
+ import { publicPluginRoutes } from "./routes/plugin-public.js";
22
23
  import { pluginRoutes } from "./routes/plugins.js";
23
24
  import { connectCallback, publicRoutes, runRoutes, shareRoutes } from "./routes/runs.js";
24
25
  import { studio } from "./routes/studio.js";
@@ -180,6 +181,7 @@ app.route("/api/studio/plugins", pluginRoutes);
180
181
  app.route("/api/studio", studio);
181
182
  app.route("/api/v1", apiRoutes);
182
183
  app.route("/api/internal", internalRoutes);
184
+ app.route("/api/public/plugins", publicPluginRoutes);
183
185
  app.route("/api/public", publicRoutes);
184
186
  app.route("/api/runs", runRoutes);
185
187
  app.route("/api/shares", shareRoutes);
@@ -1,5 +1,5 @@
1
1
  import { sql } from "drizzle-orm";
2
- import { index, integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
2
+ import { index, integer, primaryKey, sqliteTable, text, uniqueIndex, } from "drizzle-orm/sqlite-core";
3
3
  const now = sql `(unixepoch() * 1000)`;
4
4
  const createdAt = () => integer("created_at", { mode: "timestamp_ms" }).notNull().default(now);
5
5
  // The control database: what the runtime must know before it can open a tenant's database,
@@ -77,3 +77,20 @@ export const marketplaceCache = sqliteTable("marketplace_cache", {
77
77
  entry: text("entry", { mode: "json" }).$type().notNull(),
78
78
  fetchedAt: integer("fetched_at", { mode: "timestamp_ms" }).notNull().default(now),
79
79
  });
80
+ /** When a plugin's job (`server.every`) last ran for a tenant: the next turn counts from it. */
81
+ export const pluginJob = sqliteTable("plugin_job", {
82
+ tenantId: text("tenant_id").notNull(),
83
+ plugin: text("plugin").notNull(),
84
+ name: text("name").notNull(),
85
+ lastRunAt: integer("last_run_at", { mode: "timestamp_ms" }).notNull(),
86
+ }, (t) => [primaryKey({ columns: [t.tenantId, t.plugin, t.name] })]);
87
+ /**
88
+ * The part of a plugin's public address (`server.publicUrl`) that names the tenant, without
89
+ * giving its id away: `/api/public/plugins/<plugin>/<ref>/…`.
90
+ */
91
+ export const pluginAddress = sqliteTable("plugin_address", {
92
+ ref: text("ref").primaryKey(),
93
+ tenantId: text("tenant_id").notNull(),
94
+ plugin: text("plugin").notNull(),
95
+ createdAt: createdAt(),
96
+ }, (t) => [uniqueIndex("plugin_address_tenant").on(t.tenantId, t.plugin)]);
@@ -0,0 +1,15 @@
1
+ CREATE TABLE `plugin_address` (
2
+ `ref` text PRIMARY KEY NOT NULL,
3
+ `tenant_id` text NOT NULL,
4
+ `plugin` text NOT NULL,
5
+ `created_at` integer DEFAULT (unixepoch() * 1000) NOT NULL
6
+ );
7
+ --> statement-breakpoint
8
+ CREATE UNIQUE INDEX `plugin_address_tenant` ON `plugin_address` (`tenant_id`,`plugin`);--> statement-breakpoint
9
+ CREATE TABLE `plugin_job` (
10
+ `tenant_id` text NOT NULL,
11
+ `plugin` text NOT NULL,
12
+ `name` text NOT NULL,
13
+ `last_run_at` integer NOT NULL,
14
+ PRIMARY KEY(`tenant_id`, `plugin`, `name`)
15
+ );
@@ -0,0 +1,460 @@
1
+ {
2
+ "version": "6",
3
+ "dialect": "sqlite",
4
+ "id": "7a54af3d-5213-4e30-8216-8e80102ae5f6",
5
+ "prevId": "c8fcba8d-5f73-449f-ba49-ee238c45f94b",
6
+ "tables": {
7
+ "link": {
8
+ "name": "link",
9
+ "columns": {
10
+ "token": {
11
+ "name": "token",
12
+ "type": "text",
13
+ "primaryKey": true,
14
+ "notNull": true,
15
+ "autoincrement": false
16
+ },
17
+ "tenant_id": {
18
+ "name": "tenant_id",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": true,
22
+ "autoincrement": false
23
+ },
24
+ "kind": {
25
+ "name": "kind",
26
+ "type": "text",
27
+ "primaryKey": false,
28
+ "notNull": true,
29
+ "autoincrement": false
30
+ },
31
+ "ref": {
32
+ "name": "ref",
33
+ "type": "text",
34
+ "primaryKey": false,
35
+ "notNull": true,
36
+ "autoincrement": false
37
+ },
38
+ "created_at": {
39
+ "name": "created_at",
40
+ "type": "integer",
41
+ "primaryKey": false,
42
+ "notNull": true,
43
+ "autoincrement": false,
44
+ "default": "(unixepoch() * 1000)"
45
+ }
46
+ },
47
+ "indexes": {
48
+ "link_tenant": {
49
+ "name": "link_tenant",
50
+ "columns": [
51
+ "tenant_id"
52
+ ],
53
+ "isUnique": false
54
+ },
55
+ "link_ref": {
56
+ "name": "link_ref",
57
+ "columns": [
58
+ "kind",
59
+ "ref"
60
+ ],
61
+ "isUnique": false
62
+ }
63
+ },
64
+ "foreignKeys": {},
65
+ "compositePrimaryKeys": {},
66
+ "uniqueConstraints": {},
67
+ "checkConstraints": {}
68
+ },
69
+ "marketplace_cache": {
70
+ "name": "marketplace_cache",
71
+ "columns": {
72
+ "id": {
73
+ "name": "id",
74
+ "type": "text",
75
+ "primaryKey": true,
76
+ "notNull": true,
77
+ "autoincrement": false
78
+ },
79
+ "hash": {
80
+ "name": "hash",
81
+ "type": "text",
82
+ "primaryKey": false,
83
+ "notNull": true,
84
+ "autoincrement": false
85
+ },
86
+ "entry": {
87
+ "name": "entry",
88
+ "type": "text",
89
+ "primaryKey": false,
90
+ "notNull": true,
91
+ "autoincrement": false
92
+ },
93
+ "fetched_at": {
94
+ "name": "fetched_at",
95
+ "type": "integer",
96
+ "primaryKey": false,
97
+ "notNull": true,
98
+ "autoincrement": false,
99
+ "default": "(unixepoch() * 1000)"
100
+ }
101
+ },
102
+ "indexes": {},
103
+ "foreignKeys": {},
104
+ "compositePrimaryKeys": {},
105
+ "uniqueConstraints": {},
106
+ "checkConstraints": {}
107
+ },
108
+ "plugin_address": {
109
+ "name": "plugin_address",
110
+ "columns": {
111
+ "ref": {
112
+ "name": "ref",
113
+ "type": "text",
114
+ "primaryKey": true,
115
+ "notNull": true,
116
+ "autoincrement": false
117
+ },
118
+ "tenant_id": {
119
+ "name": "tenant_id",
120
+ "type": "text",
121
+ "primaryKey": false,
122
+ "notNull": true,
123
+ "autoincrement": false
124
+ },
125
+ "plugin": {
126
+ "name": "plugin",
127
+ "type": "text",
128
+ "primaryKey": false,
129
+ "notNull": true,
130
+ "autoincrement": false
131
+ },
132
+ "created_at": {
133
+ "name": "created_at",
134
+ "type": "integer",
135
+ "primaryKey": false,
136
+ "notNull": true,
137
+ "autoincrement": false,
138
+ "default": "(unixepoch() * 1000)"
139
+ }
140
+ },
141
+ "indexes": {
142
+ "plugin_address_tenant": {
143
+ "name": "plugin_address_tenant",
144
+ "columns": [
145
+ "tenant_id",
146
+ "plugin"
147
+ ],
148
+ "isUnique": true
149
+ }
150
+ },
151
+ "foreignKeys": {},
152
+ "compositePrimaryKeys": {},
153
+ "uniqueConstraints": {},
154
+ "checkConstraints": {}
155
+ },
156
+ "plugin_job": {
157
+ "name": "plugin_job",
158
+ "columns": {
159
+ "tenant_id": {
160
+ "name": "tenant_id",
161
+ "type": "text",
162
+ "primaryKey": false,
163
+ "notNull": true,
164
+ "autoincrement": false
165
+ },
166
+ "plugin": {
167
+ "name": "plugin",
168
+ "type": "text",
169
+ "primaryKey": false,
170
+ "notNull": true,
171
+ "autoincrement": false
172
+ },
173
+ "name": {
174
+ "name": "name",
175
+ "type": "text",
176
+ "primaryKey": false,
177
+ "notNull": true,
178
+ "autoincrement": false
179
+ },
180
+ "last_run_at": {
181
+ "name": "last_run_at",
182
+ "type": "integer",
183
+ "primaryKey": false,
184
+ "notNull": true,
185
+ "autoincrement": false
186
+ }
187
+ },
188
+ "indexes": {},
189
+ "foreignKeys": {},
190
+ "compositePrimaryKeys": {
191
+ "plugin_job_tenant_id_plugin_name_pk": {
192
+ "columns": [
193
+ "tenant_id",
194
+ "plugin",
195
+ "name"
196
+ ],
197
+ "name": "plugin_job_tenant_id_plugin_name_pk"
198
+ }
199
+ },
200
+ "uniqueConstraints": {},
201
+ "checkConstraints": {}
202
+ },
203
+ "run_index": {
204
+ "name": "run_index",
205
+ "columns": {
206
+ "run_id": {
207
+ "name": "run_id",
208
+ "type": "text",
209
+ "primaryKey": true,
210
+ "notNull": true,
211
+ "autoincrement": false
212
+ },
213
+ "tenant_id": {
214
+ "name": "tenant_id",
215
+ "type": "text",
216
+ "primaryKey": false,
217
+ "notNull": true,
218
+ "autoincrement": false
219
+ },
220
+ "visitor_id": {
221
+ "name": "visitor_id",
222
+ "type": "text",
223
+ "primaryKey": false,
224
+ "notNull": false,
225
+ "autoincrement": false
226
+ },
227
+ "ip_hash": {
228
+ "name": "ip_hash",
229
+ "type": "text",
230
+ "primaryKey": false,
231
+ "notNull": false,
232
+ "autoincrement": false
233
+ },
234
+ "active": {
235
+ "name": "active",
236
+ "type": "integer",
237
+ "primaryKey": false,
238
+ "notNull": true,
239
+ "autoincrement": false,
240
+ "default": false
241
+ },
242
+ "push": {
243
+ "name": "push",
244
+ "type": "text",
245
+ "primaryKey": false,
246
+ "notNull": false,
247
+ "autoincrement": false
248
+ },
249
+ "created_at": {
250
+ "name": "created_at",
251
+ "type": "integer",
252
+ "primaryKey": false,
253
+ "notNull": true,
254
+ "autoincrement": false,
255
+ "default": "(unixepoch() * 1000)"
256
+ }
257
+ },
258
+ "indexes": {
259
+ "run_index_visitor": {
260
+ "name": "run_index_visitor",
261
+ "columns": [
262
+ "visitor_id",
263
+ "created_at"
264
+ ],
265
+ "isUnique": false
266
+ },
267
+ "run_index_ip": {
268
+ "name": "run_index_ip",
269
+ "columns": [
270
+ "ip_hash",
271
+ "created_at"
272
+ ],
273
+ "isUnique": false
274
+ },
275
+ "run_index_active": {
276
+ "name": "run_index_active",
277
+ "columns": [
278
+ "active",
279
+ "tenant_id"
280
+ ],
281
+ "isUnique": false
282
+ }
283
+ },
284
+ "foreignKeys": {},
285
+ "compositePrimaryKeys": {},
286
+ "uniqueConstraints": {},
287
+ "checkConstraints": {}
288
+ },
289
+ "session": {
290
+ "name": "session",
291
+ "columns": {
292
+ "id": {
293
+ "name": "id",
294
+ "type": "text",
295
+ "primaryKey": true,
296
+ "notNull": true,
297
+ "autoincrement": false
298
+ },
299
+ "user_id": {
300
+ "name": "user_id",
301
+ "type": "text",
302
+ "primaryKey": false,
303
+ "notNull": true,
304
+ "autoincrement": false
305
+ },
306
+ "tenant_id": {
307
+ "name": "tenant_id",
308
+ "type": "text",
309
+ "primaryKey": false,
310
+ "notNull": true,
311
+ "autoincrement": false
312
+ },
313
+ "role": {
314
+ "name": "role",
315
+ "type": "text",
316
+ "primaryKey": false,
317
+ "notNull": true,
318
+ "autoincrement": false
319
+ },
320
+ "name": {
321
+ "name": "name",
322
+ "type": "text",
323
+ "primaryKey": false,
324
+ "notNull": true,
325
+ "autoincrement": false
326
+ },
327
+ "email": {
328
+ "name": "email",
329
+ "type": "text",
330
+ "primaryKey": false,
331
+ "notNull": true,
332
+ "autoincrement": false
333
+ },
334
+ "image": {
335
+ "name": "image",
336
+ "type": "text",
337
+ "primaryKey": false,
338
+ "notNull": false,
339
+ "autoincrement": false
340
+ },
341
+ "refresh_token": {
342
+ "name": "refresh_token",
343
+ "type": "text",
344
+ "primaryKey": false,
345
+ "notNull": false,
346
+ "autoincrement": false
347
+ },
348
+ "claims_expire_at": {
349
+ "name": "claims_expire_at",
350
+ "type": "integer",
351
+ "primaryKey": false,
352
+ "notNull": true,
353
+ "autoincrement": false
354
+ },
355
+ "expires_at": {
356
+ "name": "expires_at",
357
+ "type": "integer",
358
+ "primaryKey": false,
359
+ "notNull": true,
360
+ "autoincrement": false
361
+ },
362
+ "created_at": {
363
+ "name": "created_at",
364
+ "type": "integer",
365
+ "primaryKey": false,
366
+ "notNull": true,
367
+ "autoincrement": false,
368
+ "default": "(unixepoch() * 1000)"
369
+ }
370
+ },
371
+ "indexes": {
372
+ "session_expires": {
373
+ "name": "session_expires",
374
+ "columns": [
375
+ "expires_at"
376
+ ],
377
+ "isUnique": false
378
+ }
379
+ },
380
+ "foreignKeys": {},
381
+ "compositePrimaryKeys": {},
382
+ "uniqueConstraints": {},
383
+ "checkConstraints": {}
384
+ },
385
+ "setting": {
386
+ "name": "setting",
387
+ "columns": {
388
+ "key": {
389
+ "name": "key",
390
+ "type": "text",
391
+ "primaryKey": true,
392
+ "notNull": true,
393
+ "autoincrement": false
394
+ },
395
+ "value": {
396
+ "name": "value",
397
+ "type": "text",
398
+ "primaryKey": false,
399
+ "notNull": true,
400
+ "autoincrement": false
401
+ }
402
+ },
403
+ "indexes": {},
404
+ "foreignKeys": {},
405
+ "compositePrimaryKeys": {},
406
+ "uniqueConstraints": {},
407
+ "checkConstraints": {}
408
+ },
409
+ "tenant": {
410
+ "name": "tenant",
411
+ "columns": {
412
+ "id": {
413
+ "name": "id",
414
+ "type": "text",
415
+ "primaryKey": true,
416
+ "notNull": true,
417
+ "autoincrement": false
418
+ },
419
+ "status": {
420
+ "name": "status",
421
+ "type": "text",
422
+ "primaryKey": false,
423
+ "notNull": true,
424
+ "autoincrement": false,
425
+ "default": "'active'"
426
+ },
427
+ "db_url": {
428
+ "name": "db_url",
429
+ "type": "text",
430
+ "primaryKey": false,
431
+ "notNull": false,
432
+ "autoincrement": false
433
+ },
434
+ "created_at": {
435
+ "name": "created_at",
436
+ "type": "integer",
437
+ "primaryKey": false,
438
+ "notNull": true,
439
+ "autoincrement": false,
440
+ "default": "(unixepoch() * 1000)"
441
+ }
442
+ },
443
+ "indexes": {},
444
+ "foreignKeys": {},
445
+ "compositePrimaryKeys": {},
446
+ "uniqueConstraints": {},
447
+ "checkConstraints": {}
448
+ }
449
+ },
450
+ "views": {},
451
+ "enums": {},
452
+ "_meta": {
453
+ "schemas": {},
454
+ "tables": {},
455
+ "columns": {}
456
+ },
457
+ "internal": {
458
+ "indexes": {}
459
+ }
460
+ }
@@ -50,6 +50,13 @@
50
50
  "when": 1791230810434,
51
51
  "tag": "0006_sleepy_mojo",
52
52
  "breakpoints": true
53
+ },
54
+ {
55
+ "idx": 7,
56
+ "version": "6",
57
+ "when": 1791283092370,
58
+ "tag": "0007_common_the_hand",
59
+ "breakpoints": true
53
60
  }
54
61
  ]
55
62
  }
@@ -0,0 +1,30 @@
1
+ PRAGMA foreign_keys=OFF;--> statement-breakpoint
2
+ CREATE TABLE `__new_project_chunk` (
3
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
4
+ `project_id` text NOT NULL,
5
+ `file_id` text,
6
+ `plugin` text,
7
+ `ref` text,
8
+ `title` text,
9
+ `link` text,
10
+ `idx` integer NOT NULL,
11
+ `text` text NOT NULL,
12
+ `embedding` blob,
13
+ `model` text,
14
+ FOREIGN KEY (`project_id`) REFERENCES `project`(`id`) ON UPDATE no action ON DELETE cascade,
15
+ FOREIGN KEY (`file_id`) REFERENCES `project_file`(`id`) ON UPDATE no action ON DELETE cascade
16
+ );
17
+ --> statement-breakpoint
18
+ INSERT INTO `__new_project_chunk`("id", "project_id", "file_id", "idx", "text", "embedding", "model") SELECT "id", "project_id", "file_id", "idx", "text", "embedding", "model" FROM `project_chunk`;--> statement-breakpoint
19
+ DROP TABLE `project_chunk`;--> statement-breakpoint
20
+ ALTER TABLE `__new_project_chunk` RENAME TO `project_chunk`;--> statement-breakpoint
21
+ PRAGMA foreign_keys=ON;--> statement-breakpoint
22
+ CREATE INDEX `project_chunk_project` ON `project_chunk` (`project_id`,`model`);--> statement-breakpoint
23
+ CREATE INDEX `project_chunk_file` ON `project_chunk` (`file_id`);--> statement-breakpoint
24
+ CREATE INDEX `project_chunk_ref` ON `project_chunk` (`project_id`,`plugin`,`ref`);--> statement-breakpoint
25
+ CREATE TRIGGER `project_chunk_ai` AFTER INSERT ON `project_chunk` BEGIN
26
+ INSERT INTO `project_chunk_fts`(rowid, `text`) VALUES (new.id, new.text);
27
+ END;--> statement-breakpoint
28
+ CREATE TRIGGER `project_chunk_ad` AFTER DELETE ON `project_chunk` BEGIN
29
+ INSERT INTO `project_chunk_fts`(`project_chunk_fts`, rowid, `text`) VALUES ('delete', old.id, old.text);
30
+ END;