pikibun 0.20.0 → 0.22.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/README.md +15 -6
- package/dist/chunks/{chunk-BVKSJ7PV.js → chunk-KOZ2NZL7.js} +4590 -3062
- package/dist/chunks/{cli-W7LFSBCE.js → cli-OGQRYOKN.js} +2523 -1644
- package/dist/cli.js +114 -5
- package/dist/migrations/postgres/0038_workspace_attachments.sql +11 -0
- package/dist/migrations/postgres/0039_extensions.sql +54 -0
- package/dist/migrations/postgres/0040_child_session_settings.sql +12 -0
- package/dist/migrations/postgres/0040_host_builtin_extensions.sql +5 -0
- package/dist/migrations/postgres/0040_notifications.sql +47 -0
- package/dist/migrations/postgres/0041_piki_extensions.sql +32 -0
- package/dist/migrations/postgres/0042_default_extensions.sql +23 -0
- package/dist/migrations/postgres/0043_host_required_extensions.sql +6 -0
- package/dist/migrations/sqlite/0045_workspace_attachments.sql +9 -0
- package/dist/migrations/sqlite/0046_extensions.sql +52 -0
- package/dist/migrations/sqlite/0047_child_session_settings.sql +10 -0
- package/dist/migrations/sqlite/0047_host_builtin_extensions.sql +3 -0
- package/dist/migrations/sqlite/0047_notifications.sql +45 -0
- package/dist/migrations/sqlite/0048_piki_extensions.sql +30 -0
- package/dist/migrations/sqlite/0049_default_extensions.sql +22 -0
- package/dist/migrations/sqlite/0050_host_required_extensions.sql +4 -0
- package/dist/web/assets/index-BdJ_-50H.js +62 -0
- package/dist/web/assets/{index-CnOXvi_D.js → index-ClW_3YVo.js} +1 -1
- package/dist/web/assets/index-DR-JFaOB.css +1 -0
- package/dist/web/index.html +2 -2
- package/dist/web/sw.js +61 -0
- package/npm-shrinkwrap.json +3 -2
- package/package.json +2 -1
- package/dist/web/assets/index-BTJ7REap.css +0 -1
- package/dist/web/assets/index-D8LT-Xr6.js +0 -58
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ConnectorSetupError,
|
|
3
|
+
ExtensionSourceError,
|
|
4
|
+
ExtensionStore,
|
|
3
5
|
RepositoryCache,
|
|
4
6
|
connectMain,
|
|
5
|
-
defaultStateDir
|
|
6
|
-
|
|
7
|
+
defaultStateDir,
|
|
8
|
+
loadInstalled,
|
|
9
|
+
parseExtensionSource
|
|
10
|
+
} from "./chunks/chunk-KOZ2NZL7.js";
|
|
7
11
|
|
|
8
12
|
// ../../apps/runner/src/cache-cli.ts
|
|
9
13
|
import { join, relative, resolve } from "node:path";
|
|
@@ -61,10 +65,113 @@ async function cacheMain(args2) {
|
|
|
61
65
|
`);
|
|
62
66
|
}
|
|
63
67
|
|
|
68
|
+
// ../../apps/runner/src/extensions-cli.ts
|
|
69
|
+
import { resolve as resolve2 } from "node:path";
|
|
70
|
+
import { parseArgs as parseArgs2 } from "node:util";
|
|
71
|
+
var HELP2 = `Usage: pikibun extensions <command> [options]
|
|
72
|
+
|
|
73
|
+
Pi extensions for the sessions on this host. A workspace chooses which ones its sessions use (Settings > Workspaces >
|
|
74
|
+
the workspace > Extensions in Pikibun); a session runs with those this host has at the same version. The host's owner
|
|
75
|
+
can also install them from Pikibun (Settings > Hosts > this host > Extensions). They run in the connector, as this
|
|
76
|
+
machine's user, outside the sandbox: install only code you trust.
|
|
77
|
+
|
|
78
|
+
Commands:
|
|
79
|
+
add SOURCE Install an extension, pinned:
|
|
80
|
+
npm:<package>@<exact version> e.g. npm:@ollama/pi-web-search@0.0.5
|
|
81
|
+
git:<https URL>@<full commit> e.g. git:github.com/acme/search@<40-character commit>
|
|
82
|
+
PATH a dev extension: a .ts/.js file or a package directory,
|
|
83
|
+
loaded in place, in your own sessions on this host only
|
|
84
|
+
list Load Pikibun's own and the installed extensions and show what each offers, ignores, or why it
|
|
85
|
+
doesn't load
|
|
86
|
+
remove NAME Uninstall one: its source as listed, a package name, or a dev extension's path
|
|
87
|
+
|
|
88
|
+
Options:
|
|
89
|
+
--state-dir PATH Connector state (default ~/.local/share/pikibun/connector)
|
|
90
|
+
--allow-scripts For add: let npm run the package's install scripts (off by default)
|
|
91
|
+
--help Show this help
|
|
92
|
+
|
|
93
|
+
Pikibun's built-in extensions (piki:gh, piki:glab, piki:azure-cli) come with the connector: they run the GitHub, GitLab
|
|
94
|
+
or Azure CLI installed and signed in on this host, where a workspace uses them. Nothing to install.
|
|
95
|
+
|
|
96
|
+
A running connector picks up changes made here when it next reconnects; restart it to use them at once.
|
|
97
|
+
`;
|
|
98
|
+
async function extensionsMain(args2) {
|
|
99
|
+
const { values, positionals } = parseArgs2({ args: args2, strict: true, allowPositionals: true, options: {
|
|
100
|
+
help: { type: "boolean" },
|
|
101
|
+
"state-dir": { type: "string" },
|
|
102
|
+
"allow-scripts": { type: "boolean" }
|
|
103
|
+
} });
|
|
104
|
+
const [command2, ...rest] = positionals;
|
|
105
|
+
if (values.help || command2 === void 0) {
|
|
106
|
+
process.stdout.write(HELP2);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const store = ExtensionStore.forStateDir(resolve2(values["state-dir"] ?? defaultStateDir()));
|
|
110
|
+
try {
|
|
111
|
+
if (command2 === "add" && rest.length === 1) {
|
|
112
|
+
const installed = await store.add(parseExtensionSource(rest[0]), { allowScripts: values["allow-scripts"] });
|
|
113
|
+
process.stdout.write(`Installed ${installed.source}.
|
|
114
|
+
`);
|
|
115
|
+
print((await loadInstalled(store)).filter((item) => item.summary.source === installed.source));
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (values["allow-scripts"]) throw new ConnectorSetupError("--allow-scripts applies to add only.");
|
|
119
|
+
if (command2 === "list" && !rest.length) {
|
|
120
|
+
const loaded = await loadInstalled(store);
|
|
121
|
+
if (!loaded.some((item) => !item.factories)) process.stdout.write(`No extensions installed in ${store.directory}.
|
|
122
|
+
`);
|
|
123
|
+
print(loaded);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (command2 === "remove" && rest.length === 1) {
|
|
127
|
+
const removed = await store.remove(rest[0]);
|
|
128
|
+
process.stdout.write(`Removed ${removed.source}.
|
|
129
|
+
`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
} catch (error) {
|
|
133
|
+
if (error instanceof ExtensionSourceError) throw new ConnectorSetupError(error.message);
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
throw new ConnectorSetupError(`Unknown extensions command: ${positionals.join(" ")}. Run "pikibun extensions --help".`);
|
|
137
|
+
}
|
|
138
|
+
function print(loaded) {
|
|
139
|
+
for (const { summary } of loaded) {
|
|
140
|
+
process.stdout.write(`${summary.source}${summary.dev ? " (dev: your own sessions on this host)" : summary.source.startsWith("piki:") ? " (built into the connector)" : ""}
|
|
141
|
+
`);
|
|
142
|
+
if (summary.description) process.stdout.write(` ${summary.description}
|
|
143
|
+
`);
|
|
144
|
+
if (summary.error) {
|
|
145
|
+
process.stdout.write(` Doesn't load: ${summary.error}
|
|
146
|
+
`);
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
for (const module of summary.modules) {
|
|
150
|
+
process.stdout.write(` ${module.path}
|
|
151
|
+
`);
|
|
152
|
+
if (module.error) {
|
|
153
|
+
process.stdout.write(` Doesn't load: ${module.error}
|
|
154
|
+
`);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (module.tools.length) process.stdout.write(` Tools: ${module.tools.map((tool) => tool.name).join(", ")}
|
|
158
|
+
`);
|
|
159
|
+
if (module.events.length) process.stdout.write(` Events: ${module.events.join(", ")}
|
|
160
|
+
`);
|
|
161
|
+
if (module.flags.length) process.stdout.write(` Settings: ${module.flags.map((flag) => flag.name).join(", ")}
|
|
162
|
+
`);
|
|
163
|
+
if (module.noops.length) process.stdout.write(` Does nothing here: ${module.noops.join(", ")}
|
|
164
|
+
`);
|
|
165
|
+
if (module.ignored.length) process.stdout.write(` Not supported: ${module.ignored.join(", ")}
|
|
166
|
+
`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
64
171
|
// package.json
|
|
65
172
|
var package_default = {
|
|
66
173
|
name: "pikibun",
|
|
67
|
-
version: "0.
|
|
174
|
+
version: "0.22.0",
|
|
68
175
|
description: "Connect your Linux or WSL2 Pi host to a Pikibun workspace, or run Pikibun on your own computer.",
|
|
69
176
|
license: "MIT",
|
|
70
177
|
homepage: "https://pikibun.com",
|
|
@@ -82,6 +189,7 @@ var package_default = {
|
|
|
82
189
|
dependencies: {
|
|
83
190
|
"@earendil-works/chord": "1.4.0",
|
|
84
191
|
"@earendil-works/pi-ai": "1.4.0",
|
|
192
|
+
"@earendil-works/pi-codemode": "1.4.0",
|
|
85
193
|
"@earendil-works/pi-coding-agent": "1.4.0",
|
|
86
194
|
"@earendil-works/pi-durable": "1.4.0",
|
|
87
195
|
"@hono/node-server": "1.19.11",
|
|
@@ -105,6 +213,7 @@ Commands:
|
|
|
105
213
|
serve Run Pikibun on this computer, for yourself with it as the host,
|
|
106
214
|
or shared with others (--share)
|
|
107
215
|
cache List or prune this host's repository cache
|
|
216
|
+
extensions Add, list or remove this host's extensions
|
|
108
217
|
|
|
109
218
|
Options:
|
|
110
219
|
--help Show this help
|
|
@@ -113,8 +222,8 @@ Options:
|
|
|
113
222
|
Run "pikibun connect --help" or "pikibun serve --help" for their options.
|
|
114
223
|
`;
|
|
115
224
|
var [command, ...args] = process.argv.slice(2);
|
|
116
|
-
var serveMain = async (args2) => (await import("./chunks/cli-
|
|
117
|
-
var run = command === "connect" ? connectMain : command === "cache" ? cacheMain : command === "serve" ? serveMain : void 0;
|
|
225
|
+
var serveMain = async (args2) => (await import("./chunks/cli-OGQRYOKN.js")).serveMain(args2);
|
|
226
|
+
var run = command === "connect" ? connectMain : command === "cache" ? cacheMain : command === "extensions" ? extensionsMain : command === "serve" ? serveMain : void 0;
|
|
118
227
|
if (run) {
|
|
119
228
|
run(args).catch((error) => {
|
|
120
229
|
process.stderr.write(error instanceof ConnectorSetupError ? `${error.message}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
-- Postgres translation of sqlite/0045_workspace_attachments.sql.
|
|
2
|
+
|
|
3
|
+
-- Files attached to messages (apps/server/src/file-uploads.ts).
|
|
4
|
+
-- A workspace's attachment settings, as its owners and admins chose them; no row: the defaults (10 MiB a file).
|
|
5
|
+
-- max_file_bytes: the largest file a message here may carry, uploaded into the session's worktree.
|
|
6
|
+
CREATE TABLE workspace_attachment_settings (
|
|
7
|
+
workspace_id TEXT PRIMARY KEY REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
8
|
+
max_file_bytes BIGINT NOT NULL CHECK (max_file_bytes BETWEEN 1048576 AND 52428800),
|
|
9
|
+
updated_by TEXT NOT NULL REFERENCES users(id),
|
|
10
|
+
updated_at TEXT NOT NULL
|
|
11
|
+
);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
-- Postgres translation of sqlite/0046_extensions.sql.
|
|
2
|
+
|
|
3
|
+
-- Extensions (docs/design/host-extensions.md, apps/server/src/extensions.ts).
|
|
4
|
+
-- The Pi extensions a workspace's sessions use, one version of each package, in order; its owners and admins choose them.
|
|
5
|
+
-- package_key is npm:<name> or git:<url>; source pins the version (npm:<name>@<version>, git:<url>@<commit>).
|
|
6
|
+
CREATE TABLE workspace_extensions (
|
|
7
|
+
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
8
|
+
package_key TEXT NOT NULL,
|
|
9
|
+
source TEXT NOT NULL,
|
|
10
|
+
position BIGINT NOT NULL,
|
|
11
|
+
enabled BIGINT NOT NULL DEFAULT 1 CHECK (enabled IN (0, 1)),
|
|
12
|
+
tools_mode TEXT NOT NULL DEFAULT 'approval' CHECK (tools_mode IN ('approval', 'automatic')),
|
|
13
|
+
settings_json TEXT NOT NULL DEFAULT '{}',
|
|
14
|
+
updated_by TEXT NOT NULL REFERENCES users(id),
|
|
15
|
+
updated_at TEXT NOT NULL,
|
|
16
|
+
PRIMARY KEY (workspace_id, package_key)
|
|
17
|
+
);
|
|
18
|
+
-- What each host last reported it has installed (HostExtensionsReport), on each sync of its connector.
|
|
19
|
+
CREATE TABLE connector_extensions (
|
|
20
|
+
connector_id TEXT PRIMARY KEY REFERENCES connectors(id) ON DELETE CASCADE,
|
|
21
|
+
report_json TEXT NOT NULL,
|
|
22
|
+
reported_at TEXT NOT NULL
|
|
23
|
+
);
|
|
24
|
+
-- The host owner's own extension settings; no row: the defaults. automatic_tools 1 lets workspaces run extension tools
|
|
25
|
+
-- without approval on this host, where they set an extension's tools to automatic.
|
|
26
|
+
CREATE TABLE connector_extension_settings (
|
|
27
|
+
connector_id TEXT PRIMARY KEY REFERENCES connectors(id) ON DELETE CASCADE,
|
|
28
|
+
automatic_tools BIGINT NOT NULL DEFAULT 0 CHECK (automatic_tools IN (0, 1)),
|
|
29
|
+
updated_by TEXT NOT NULL REFERENCES users(id),
|
|
30
|
+
updated_at TEXT NOT NULL
|
|
31
|
+
);
|
|
32
|
+
-- Installs and removals the host's owner asked for in Pikibun; its connector carries them out when it next syncs and
|
|
33
|
+
-- reports how they went.
|
|
34
|
+
CREATE TABLE connector_extension_requests (
|
|
35
|
+
id TEXT PRIMARY KEY,
|
|
36
|
+
connector_id TEXT NOT NULL REFERENCES connectors(id) ON DELETE CASCADE,
|
|
37
|
+
action TEXT NOT NULL CHECK (action IN ('install', 'remove')),
|
|
38
|
+
source TEXT NOT NULL,
|
|
39
|
+
requested_by TEXT NOT NULL REFERENCES users(id),
|
|
40
|
+
requested_at TEXT NOT NULL,
|
|
41
|
+
status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'done', 'failed')),
|
|
42
|
+
error TEXT,
|
|
43
|
+
finished_at TEXT
|
|
44
|
+
);
|
|
45
|
+
CREATE INDEX connector_extension_requests_pending ON connector_extension_requests (connector_id, status, requested_at);
|
|
46
|
+
-- Another member's extension tool call a host said ran automatically, which the control plane couldn't confirm the first
|
|
47
|
+
-- time it saw it (the workspace didn't run that extension's tools automatically on that host): shown as a plain record,
|
|
48
|
+
-- never reviewed, even once the setting allows it.
|
|
49
|
+
CREATE TABLE approval_unconfirmed_automatic (
|
|
50
|
+
session_id TEXT NOT NULL REFERENCES sessions(id),
|
|
51
|
+
approval_id TEXT NOT NULL,
|
|
52
|
+
created_at TEXT NOT NULL,
|
|
53
|
+
PRIMARY KEY (session_id, approval_id)
|
|
54
|
+
);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-- Postgres translation of sqlite/0047_child_session_settings.sql.
|
|
2
|
+
|
|
3
|
+
-- Sessions started by an agent (apps/server/src/cross-session.ts, docs/design/cross-session.md).
|
|
4
|
+
-- A workspace's settings for them, as its owners and admins chose them; no row: the defaults (on).
|
|
5
|
+
-- child_models 1: an agent that starts a session for a sub-task may choose the model and reasoning level it runs on.
|
|
6
|
+
-- 0: every such session runs on its parent's current model and reasoning level.
|
|
7
|
+
CREATE TABLE workspace_child_session_settings (
|
|
8
|
+
workspace_id TEXT PRIMARY KEY REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
9
|
+
child_models BIGINT NOT NULL DEFAULT 1 CHECK (child_models IN (0, 1)),
|
|
10
|
+
updated_by TEXT NOT NULL REFERENCES users(id),
|
|
11
|
+
updated_at TEXT NOT NULL
|
|
12
|
+
);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
-- Postgres translation of sqlite/0047_host_builtin_extensions.sql.
|
|
2
|
+
|
|
3
|
+
-- Pi's built-in extensions every session on a host runs with, as its owner and admins set it in Pikibun
|
|
4
|
+
-- (HostConfig.builtinExtensions in packages/shared/src/host-config.ts): their names, as a JSON array. '[]' runs none.
|
|
5
|
+
ALTER TABLE connector_configs ADD COLUMN builtin_extensions_json TEXT NOT NULL DEFAULT '[]';
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
-- Postgres translation of sqlite/0047_notifications.sql.
|
|
2
|
+
|
|
3
|
+
-- Notifications (docs/notifications.md, apps/server/src/notifications.ts).
|
|
4
|
+
-- Which notifications each person gets; no row: the defaults (everything on, with session titles).
|
|
5
|
+
CREATE TABLE notification_preferences (
|
|
6
|
+
user_id TEXT PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
|
7
|
+
approvals BIGINT NOT NULL DEFAULT 1 CHECK (approvals IN (0, 1)),
|
|
8
|
+
finished BIGINT NOT NULL DEFAULT 1 CHECK (finished IN (0, 1)),
|
|
9
|
+
failed BIGINT NOT NULL DEFAULT 1 CHECK (failed IN (0, 1)),
|
|
10
|
+
details BIGINT NOT NULL DEFAULT 1 CHECK (details IN (0, 1)),
|
|
11
|
+
updated_at TEXT NOT NULL
|
|
12
|
+
);
|
|
13
|
+
-- The devices that get a person's notifications: a browser's Web Push subscription (endpoint, p256dh and auth keys) or
|
|
14
|
+
-- the app's Expo push token (in endpoint). Each belongs to the sign-in that registered it, and goes with it: signing
|
|
15
|
+
-- out, or signing an app out from the web, stops its notifications.
|
|
16
|
+
CREATE TABLE notification_devices (
|
|
17
|
+
id TEXT PRIMARY KEY,
|
|
18
|
+
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
19
|
+
auth_token_hash TEXT NOT NULL REFERENCES auth_sessions(token_hash) ON DELETE CASCADE,
|
|
20
|
+
kind TEXT NOT NULL CHECK (kind IN ('web', 'expo')),
|
|
21
|
+
endpoint TEXT NOT NULL UNIQUE,
|
|
22
|
+
p256dh TEXT,
|
|
23
|
+
auth TEXT,
|
|
24
|
+
name TEXT,
|
|
25
|
+
created_at TEXT NOT NULL,
|
|
26
|
+
CHECK ((kind = 'web') = (p256dh IS NOT NULL AND auth IS NOT NULL))
|
|
27
|
+
);
|
|
28
|
+
CREATE INDEX notification_devices_user ON notification_devices(user_id);
|
|
29
|
+
CREATE INDEX notification_devices_auth ON notification_devices(auth_token_hash);
|
|
30
|
+
-- Each person's recent notifications, which open web pages and desktop windows poll (GET /api/notifications/feed).
|
|
31
|
+
-- Ids sort in the order they were made; rows older than a day are removed as new ones come.
|
|
32
|
+
CREATE TABLE notifications (
|
|
33
|
+
id TEXT PRIMARY KEY,
|
|
34
|
+
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
35
|
+
session_id TEXT REFERENCES sessions(id) ON DELETE CASCADE,
|
|
36
|
+
kind TEXT NOT NULL CHECK (kind IN ('approval', 'finished', 'failed', 'test')),
|
|
37
|
+
title TEXT NOT NULL,
|
|
38
|
+
body TEXT NOT NULL,
|
|
39
|
+
created_at TEXT NOT NULL
|
|
40
|
+
);
|
|
41
|
+
CREATE INDEX notifications_user ON notifications(user_id, id);
|
|
42
|
+
-- Keys the server makes for itself once; the Web Push (VAPID) key pair, its private half sealed with VAULT_KEY.
|
|
43
|
+
CREATE TABLE server_keys (
|
|
44
|
+
name TEXT PRIMARY KEY,
|
|
45
|
+
value TEXT NOT NULL,
|
|
46
|
+
created_at TEXT NOT NULL
|
|
47
|
+
);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
-- Postgres translation of sqlite/0048_piki_extensions.sql.
|
|
2
|
+
|
|
3
|
+
-- Pikibun extensions (docs/design/piki-extensions.md, apps/server/src/extensions.ts).
|
|
4
|
+
-- piki:<name> sources come with the connector; their package_key is the source itself. A workspace that binds its
|
|
5
|
+
-- first repository on GitHub (github.com or Enterprise Server), GitLab or Azure DevOps gets the extension of that forge's
|
|
6
|
+
-- command-line tool (gh, glab, az): its tools wait for approval, and owners and admins turn it off or remove it like any
|
|
7
|
+
-- other. Workspaces that already have such a repository get it here, as their owner, unless they use 32 extensions.
|
|
8
|
+
INSERT INTO workspace_extensions (workspace_id, package_key, source, position, enabled, tools_mode, settings_json, updated_by, updated_at)
|
|
9
|
+
SELECT w.id, 'piki:gh', 'piki:gh', COALESCE((SELECT MAX(e.position) FROM workspace_extensions e WHERE e.workspace_id = w.id), 0) + 1, 1, 'approval', '{}', w.owner_id,
|
|
10
|
+
to_char(clock_timestamp() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"')
|
|
11
|
+
FROM workspaces w
|
|
12
|
+
WHERE EXISTS (SELECT 1 FROM workspace_repositories r WHERE r.workspace_id = w.id AND r.provider IN ('github', 'github-enterprise'))
|
|
13
|
+
AND NOT EXISTS (SELECT 1 FROM workspace_extensions e WHERE e.workspace_id = w.id AND e.package_key = 'piki:gh')
|
|
14
|
+
AND (SELECT COUNT(*) FROM workspace_extensions e WHERE e.workspace_id = w.id) < 32;
|
|
15
|
+
INSERT INTO workspace_extensions (workspace_id, package_key, source, position, enabled, tools_mode, settings_json, updated_by, updated_at)
|
|
16
|
+
SELECT w.id, 'piki:glab', 'piki:glab', COALESCE((SELECT MAX(e.position) FROM workspace_extensions e WHERE e.workspace_id = w.id), 0) + 1, 1, 'approval', '{}', w.owner_id,
|
|
17
|
+
to_char(clock_timestamp() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"')
|
|
18
|
+
FROM workspaces w
|
|
19
|
+
WHERE EXISTS (SELECT 1 FROM workspace_repositories r WHERE r.workspace_id = w.id AND r.provider IN ('gitlab'))
|
|
20
|
+
AND NOT EXISTS (SELECT 1 FROM workspace_extensions e WHERE e.workspace_id = w.id AND e.package_key = 'piki:glab')
|
|
21
|
+
AND (SELECT COUNT(*) FROM workspace_extensions e WHERE e.workspace_id = w.id) < 32;
|
|
22
|
+
INSERT INTO workspace_extensions (workspace_id, package_key, source, position, enabled, tools_mode, settings_json, updated_by, updated_at)
|
|
23
|
+
SELECT w.id, 'piki:azure-cli', 'piki:azure-cli', COALESCE((SELECT MAX(e.position) FROM workspace_extensions e WHERE e.workspace_id = w.id), 0) + 1, 1, 'approval', '{}', w.owner_id,
|
|
24
|
+
to_char(clock_timestamp() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"')
|
|
25
|
+
FROM workspaces w
|
|
26
|
+
WHERE EXISTS (SELECT 1 FROM workspace_repositories r WHERE r.workspace_id = w.id AND r.provider IN ('azure-devops'))
|
|
27
|
+
AND NOT EXISTS (SELECT 1 FROM workspace_extensions e WHERE e.workspace_id = w.id AND e.package_key = 'piki:azure-cli')
|
|
28
|
+
AND (SELECT COUNT(*) FROM workspace_extensions e WHERE e.workspace_id = w.id) < 32;
|
|
29
|
+
-- Pi's built-in extensions a host's configuration turns on are named pi:<name> (packages/shared/src/host-config.ts),
|
|
30
|
+
-- beside Pikibun's own piki:<name>; configurations saved before named them bare. Reads accept those too.
|
|
31
|
+
UPDATE connector_configs SET builtin_extensions_json = REPLACE(builtin_extensions_json, '"codemode"', '"pi:codemode"')
|
|
32
|
+
WHERE builtin_extensions_json LIKE '%"codemode"%';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
-- Postgres translation of sqlite/0049_default_extensions.sql.
|
|
2
|
+
-- Popular Pi extensions for every existing workspace (docs/extensions.md), turned off and with tools on approval, after
|
|
3
|
+
-- the ones it has: its owners and admins turn on the ones they want. New workspaces get the same ones when they are
|
|
4
|
+
-- created (defaultWorkspaceExtensions in packages/shared/src/host-extensions.ts, which lists the same sources). A
|
|
5
|
+
-- workspace that already uses a package, any version of it, keeps its own; one at the limit of 32 gets no more.
|
|
6
|
+
INSERT INTO workspace_extensions (workspace_id, package_key, source, position, enabled, tools_mode, settings_json, updated_by, updated_at)
|
|
7
|
+
SELECT w.id, 'npm:pi-web-access', 'npm:pi-web-access@0.46.0', (SELECT COALESCE(MAX(e.position), 0) + 1 FROM workspace_extensions e WHERE e.workspace_id = w.id),
|
|
8
|
+
0, 'approval', '{}', w.owner_id, to_char(now() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"')
|
|
9
|
+
FROM workspaces w
|
|
10
|
+
WHERE (SELECT COUNT(*) FROM workspace_extensions e WHERE e.workspace_id = w.id) < 32
|
|
11
|
+
ON CONFLICT (workspace_id, package_key) DO NOTHING;
|
|
12
|
+
INSERT INTO workspace_extensions (workspace_id, package_key, source, position, enabled, tools_mode, settings_json, updated_by, updated_at)
|
|
13
|
+
SELECT w.id, 'npm:pi-web-search', 'npm:pi-web-search@1.7.0', (SELECT COALESCE(MAX(e.position), 0) + 1 FROM workspace_extensions e WHERE e.workspace_id = w.id),
|
|
14
|
+
0, 'approval', '{}', w.owner_id, to_char(now() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"')
|
|
15
|
+
FROM workspaces w
|
|
16
|
+
WHERE (SELECT COUNT(*) FROM workspace_extensions e WHERE e.workspace_id = w.id) < 32
|
|
17
|
+
ON CONFLICT (workspace_id, package_key) DO NOTHING;
|
|
18
|
+
INSERT INTO workspace_extensions (workspace_id, package_key, source, position, enabled, tools_mode, settings_json, updated_by, updated_at)
|
|
19
|
+
SELECT w.id, 'npm:cc-safety-net', 'npm:cc-safety-net@2.7.2', (SELECT COALESCE(MAX(e.position), 0) + 1 FROM workspace_extensions e WHERE e.workspace_id = w.id),
|
|
20
|
+
0, 'approval', '{}', w.owner_id, to_char(now() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"')
|
|
21
|
+
FROM workspaces w
|
|
22
|
+
WHERE (SELECT COUNT(*) FROM workspace_extensions e WHERE e.workspace_id = w.id) < 32
|
|
23
|
+
ON CONFLICT (workspace_id, package_key) DO NOTHING;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
-- Postgres translation of sqlite/0050_host_required_extensions.sql.
|
|
2
|
+
|
|
3
|
+
-- The extensions a host's owner requires of every session on it, whatever its workspace chose (HostConfig.requiredExtensions
|
|
4
|
+
-- in packages/shared/src/host-config.ts): each one's source and settings, as JSON, in the order sessions run them.
|
|
5
|
+
-- '[]' requires none.
|
|
6
|
+
ALTER TABLE connector_configs ADD COLUMN required_extensions_json TEXT NOT NULL DEFAULT '[]';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
-- Files attached to messages (apps/server/src/file-uploads.ts).
|
|
2
|
+
-- A workspace's attachment settings, as its owners and admins chose them; no row: the defaults (10 MiB a file).
|
|
3
|
+
-- max_file_bytes: the largest file a message here may carry, uploaded into the session's worktree.
|
|
4
|
+
CREATE TABLE workspace_attachment_settings (
|
|
5
|
+
workspace_id TEXT PRIMARY KEY REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
6
|
+
max_file_bytes INTEGER NOT NULL CHECK (max_file_bytes BETWEEN 1048576 AND 52428800),
|
|
7
|
+
updated_by TEXT NOT NULL REFERENCES users(id),
|
|
8
|
+
updated_at TEXT NOT NULL
|
|
9
|
+
);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
-- Extensions (docs/design/host-extensions.md, apps/server/src/extensions.ts).
|
|
2
|
+
-- The Pi extensions a workspace's sessions use, one version of each package, in order; its owners and admins choose them.
|
|
3
|
+
-- package_key is npm:<name> or git:<url>; source pins the version (npm:<name>@<version>, git:<url>@<commit>).
|
|
4
|
+
CREATE TABLE workspace_extensions (
|
|
5
|
+
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
6
|
+
package_key TEXT NOT NULL,
|
|
7
|
+
source TEXT NOT NULL,
|
|
8
|
+
position INTEGER NOT NULL,
|
|
9
|
+
enabled INTEGER NOT NULL DEFAULT 1 CHECK (enabled IN (0, 1)),
|
|
10
|
+
tools_mode TEXT NOT NULL DEFAULT 'approval' CHECK (tools_mode IN ('approval', 'automatic')),
|
|
11
|
+
settings_json TEXT NOT NULL DEFAULT '{}',
|
|
12
|
+
updated_by TEXT NOT NULL REFERENCES users(id),
|
|
13
|
+
updated_at TEXT NOT NULL,
|
|
14
|
+
PRIMARY KEY (workspace_id, package_key)
|
|
15
|
+
);
|
|
16
|
+
-- What each host last reported it has installed (HostExtensionsReport), on each sync of its connector.
|
|
17
|
+
CREATE TABLE connector_extensions (
|
|
18
|
+
connector_id TEXT PRIMARY KEY REFERENCES connectors(id) ON DELETE CASCADE,
|
|
19
|
+
report_json TEXT NOT NULL,
|
|
20
|
+
reported_at TEXT NOT NULL
|
|
21
|
+
);
|
|
22
|
+
-- The host owner's own extension settings; no row: the defaults. automatic_tools 1 lets workspaces run extension tools
|
|
23
|
+
-- without approval on this host, where they set an extension's tools to automatic.
|
|
24
|
+
CREATE TABLE connector_extension_settings (
|
|
25
|
+
connector_id TEXT PRIMARY KEY REFERENCES connectors(id) ON DELETE CASCADE,
|
|
26
|
+
automatic_tools INTEGER NOT NULL DEFAULT 0 CHECK (automatic_tools IN (0, 1)),
|
|
27
|
+
updated_by TEXT NOT NULL REFERENCES users(id),
|
|
28
|
+
updated_at TEXT NOT NULL
|
|
29
|
+
);
|
|
30
|
+
-- Installs and removals the host's owner asked for in Pikibun; its connector carries them out when it next syncs and
|
|
31
|
+
-- reports how they went.
|
|
32
|
+
CREATE TABLE connector_extension_requests (
|
|
33
|
+
id TEXT PRIMARY KEY,
|
|
34
|
+
connector_id TEXT NOT NULL REFERENCES connectors(id) ON DELETE CASCADE,
|
|
35
|
+
action TEXT NOT NULL CHECK (action IN ('install', 'remove')),
|
|
36
|
+
source TEXT NOT NULL,
|
|
37
|
+
requested_by TEXT NOT NULL REFERENCES users(id),
|
|
38
|
+
requested_at TEXT NOT NULL,
|
|
39
|
+
status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'done', 'failed')),
|
|
40
|
+
error TEXT,
|
|
41
|
+
finished_at TEXT
|
|
42
|
+
);
|
|
43
|
+
CREATE INDEX connector_extension_requests_pending ON connector_extension_requests (connector_id, status, requested_at);
|
|
44
|
+
-- Another member's extension tool call a host said ran automatically, which the control plane couldn't confirm the first
|
|
45
|
+
-- time it saw it (the workspace didn't run that extension's tools automatically on that host): shown as a plain record,
|
|
46
|
+
-- never reviewed, even once the setting allows it.
|
|
47
|
+
CREATE TABLE approval_unconfirmed_automatic (
|
|
48
|
+
session_id TEXT NOT NULL REFERENCES sessions(id),
|
|
49
|
+
approval_id TEXT NOT NULL,
|
|
50
|
+
created_at TEXT NOT NULL,
|
|
51
|
+
PRIMARY KEY (session_id, approval_id)
|
|
52
|
+
);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
-- Sessions started by an agent (apps/server/src/cross-session.ts, docs/design/cross-session.md).
|
|
2
|
+
-- A workspace's settings for them, as its owners and admins chose them; no row: the defaults (on).
|
|
3
|
+
-- child_models 1: an agent that starts a session for a sub-task may choose the model and reasoning level it runs on.
|
|
4
|
+
-- 0: every such session runs on its parent's current model and reasoning level.
|
|
5
|
+
CREATE TABLE workspace_child_session_settings (
|
|
6
|
+
workspace_id TEXT PRIMARY KEY REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
7
|
+
child_models INTEGER NOT NULL DEFAULT 1 CHECK (child_models IN (0, 1)),
|
|
8
|
+
updated_by TEXT NOT NULL REFERENCES users(id),
|
|
9
|
+
updated_at TEXT NOT NULL
|
|
10
|
+
);
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
-- Pi's built-in extensions every session on a host runs with, as its owner and admins set it in Pikibun
|
|
2
|
+
-- (HostConfig.builtinExtensions in packages/shared/src/host-config.ts): their names, as a JSON array. '[]' runs none.
|
|
3
|
+
ALTER TABLE connector_configs ADD COLUMN builtin_extensions_json TEXT NOT NULL DEFAULT '[]';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
-- Notifications (docs/notifications.md, apps/server/src/notifications.ts).
|
|
2
|
+
-- Which notifications each person gets; no row: the defaults (everything on, with session titles).
|
|
3
|
+
CREATE TABLE notification_preferences (
|
|
4
|
+
user_id TEXT PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
|
5
|
+
approvals INTEGER NOT NULL DEFAULT 1 CHECK (approvals IN (0, 1)),
|
|
6
|
+
finished INTEGER NOT NULL DEFAULT 1 CHECK (finished IN (0, 1)),
|
|
7
|
+
failed INTEGER NOT NULL DEFAULT 1 CHECK (failed IN (0, 1)),
|
|
8
|
+
details INTEGER NOT NULL DEFAULT 1 CHECK (details IN (0, 1)),
|
|
9
|
+
updated_at TEXT NOT NULL
|
|
10
|
+
);
|
|
11
|
+
-- The devices that get a person's notifications: a browser's Web Push subscription (endpoint, p256dh and auth keys) or
|
|
12
|
+
-- the app's Expo push token (in endpoint). Each belongs to the sign-in that registered it, and goes with it: signing
|
|
13
|
+
-- out, or signing an app out from the web, stops its notifications.
|
|
14
|
+
CREATE TABLE notification_devices (
|
|
15
|
+
id TEXT PRIMARY KEY,
|
|
16
|
+
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
17
|
+
auth_token_hash TEXT NOT NULL REFERENCES auth_sessions(token_hash) ON DELETE CASCADE,
|
|
18
|
+
kind TEXT NOT NULL CHECK (kind IN ('web', 'expo')),
|
|
19
|
+
endpoint TEXT NOT NULL UNIQUE,
|
|
20
|
+
p256dh TEXT,
|
|
21
|
+
auth TEXT,
|
|
22
|
+
name TEXT,
|
|
23
|
+
created_at TEXT NOT NULL,
|
|
24
|
+
CHECK ((kind = 'web') = (p256dh IS NOT NULL AND auth IS NOT NULL))
|
|
25
|
+
);
|
|
26
|
+
CREATE INDEX notification_devices_user ON notification_devices(user_id);
|
|
27
|
+
CREATE INDEX notification_devices_auth ON notification_devices(auth_token_hash);
|
|
28
|
+
-- Each person's recent notifications, which open web pages and desktop windows poll (GET /api/notifications/feed).
|
|
29
|
+
-- Ids sort in the order they were made; rows older than a day are removed as new ones come.
|
|
30
|
+
CREATE TABLE notifications (
|
|
31
|
+
id TEXT PRIMARY KEY,
|
|
32
|
+
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
33
|
+
session_id TEXT REFERENCES sessions(id) ON DELETE CASCADE,
|
|
34
|
+
kind TEXT NOT NULL CHECK (kind IN ('approval', 'finished', 'failed', 'test')),
|
|
35
|
+
title TEXT NOT NULL,
|
|
36
|
+
body TEXT NOT NULL,
|
|
37
|
+
created_at TEXT NOT NULL
|
|
38
|
+
);
|
|
39
|
+
CREATE INDEX notifications_user ON notifications(user_id, id);
|
|
40
|
+
-- Keys the server makes for itself once; the Web Push (VAPID) key pair, its private half sealed with VAULT_KEY.
|
|
41
|
+
CREATE TABLE server_keys (
|
|
42
|
+
name TEXT PRIMARY KEY,
|
|
43
|
+
value TEXT NOT NULL,
|
|
44
|
+
created_at TEXT NOT NULL
|
|
45
|
+
);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
-- Pikibun extensions (docs/design/piki-extensions.md, apps/server/src/extensions.ts).
|
|
2
|
+
-- piki:<name> sources come with the connector; their package_key is the source itself. A workspace that binds its
|
|
3
|
+
-- first repository on GitHub (github.com or Enterprise Server), GitLab or Azure DevOps gets the extension of that forge's
|
|
4
|
+
-- command-line tool (gh, glab, az): its tools wait for approval, and owners and admins turn it off or remove it like any
|
|
5
|
+
-- other. Workspaces that already have such a repository get it here, as their owner, unless they use 32 extensions.
|
|
6
|
+
INSERT INTO workspace_extensions (workspace_id, package_key, source, position, enabled, tools_mode, settings_json, updated_by, updated_at)
|
|
7
|
+
SELECT w.id, 'piki:gh', 'piki:gh', COALESCE((SELECT MAX(e.position) FROM workspace_extensions e WHERE e.workspace_id = w.id), 0) + 1, 1, 'approval', '{}', w.owner_id,
|
|
8
|
+
strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
9
|
+
FROM workspaces w
|
|
10
|
+
WHERE EXISTS (SELECT 1 FROM workspace_repositories r WHERE r.workspace_id = w.id AND r.provider IN ('github', 'github-enterprise'))
|
|
11
|
+
AND NOT EXISTS (SELECT 1 FROM workspace_extensions e WHERE e.workspace_id = w.id AND e.package_key = 'piki:gh')
|
|
12
|
+
AND (SELECT COUNT(*) FROM workspace_extensions e WHERE e.workspace_id = w.id) < 32;
|
|
13
|
+
INSERT INTO workspace_extensions (workspace_id, package_key, source, position, enabled, tools_mode, settings_json, updated_by, updated_at)
|
|
14
|
+
SELECT w.id, 'piki:glab', 'piki:glab', COALESCE((SELECT MAX(e.position) FROM workspace_extensions e WHERE e.workspace_id = w.id), 0) + 1, 1, 'approval', '{}', w.owner_id,
|
|
15
|
+
strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
16
|
+
FROM workspaces w
|
|
17
|
+
WHERE EXISTS (SELECT 1 FROM workspace_repositories r WHERE r.workspace_id = w.id AND r.provider IN ('gitlab'))
|
|
18
|
+
AND NOT EXISTS (SELECT 1 FROM workspace_extensions e WHERE e.workspace_id = w.id AND e.package_key = 'piki:glab')
|
|
19
|
+
AND (SELECT COUNT(*) FROM workspace_extensions e WHERE e.workspace_id = w.id) < 32;
|
|
20
|
+
INSERT INTO workspace_extensions (workspace_id, package_key, source, position, enabled, tools_mode, settings_json, updated_by, updated_at)
|
|
21
|
+
SELECT w.id, 'piki:azure-cli', 'piki:azure-cli', COALESCE((SELECT MAX(e.position) FROM workspace_extensions e WHERE e.workspace_id = w.id), 0) + 1, 1, 'approval', '{}', w.owner_id,
|
|
22
|
+
strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
23
|
+
FROM workspaces w
|
|
24
|
+
WHERE EXISTS (SELECT 1 FROM workspace_repositories r WHERE r.workspace_id = w.id AND r.provider IN ('azure-devops'))
|
|
25
|
+
AND NOT EXISTS (SELECT 1 FROM workspace_extensions e WHERE e.workspace_id = w.id AND e.package_key = 'piki:azure-cli')
|
|
26
|
+
AND (SELECT COUNT(*) FROM workspace_extensions e WHERE e.workspace_id = w.id) < 32;
|
|
27
|
+
-- Pi's built-in extensions a host's configuration turns on are named pi:<name> (packages/shared/src/host-config.ts),
|
|
28
|
+
-- beside Pikibun's own piki:<name>; configurations saved before named them bare. Reads accept those too.
|
|
29
|
+
UPDATE connector_configs SET builtin_extensions_json = REPLACE(builtin_extensions_json, '"codemode"', '"pi:codemode"')
|
|
30
|
+
WHERE builtin_extensions_json LIKE '%"codemode"%';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
-- Popular Pi extensions for every existing workspace (docs/extensions.md), turned off and with tools on approval, after
|
|
2
|
+
-- the ones it has: its owners and admins turn on the ones they want. New workspaces get the same ones when they are
|
|
3
|
+
-- created (defaultWorkspaceExtensions in packages/shared/src/host-extensions.ts, which lists the same sources). A
|
|
4
|
+
-- workspace that already uses a package, any version of it, keeps its own; one at the limit of 32 gets no more.
|
|
5
|
+
INSERT INTO workspace_extensions (workspace_id, package_key, source, position, enabled, tools_mode, settings_json, updated_by, updated_at)
|
|
6
|
+
SELECT w.id, 'npm:pi-web-access', 'npm:pi-web-access@0.46.0', (SELECT COALESCE(MAX(e.position), 0) + 1 FROM workspace_extensions e WHERE e.workspace_id = w.id),
|
|
7
|
+
0, 'approval', '{}', w.owner_id, strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
8
|
+
FROM workspaces w
|
|
9
|
+
WHERE (SELECT COUNT(*) FROM workspace_extensions e WHERE e.workspace_id = w.id) < 32
|
|
10
|
+
ON CONFLICT (workspace_id, package_key) DO NOTHING;
|
|
11
|
+
INSERT INTO workspace_extensions (workspace_id, package_key, source, position, enabled, tools_mode, settings_json, updated_by, updated_at)
|
|
12
|
+
SELECT w.id, 'npm:pi-web-search', 'npm:pi-web-search@1.7.0', (SELECT COALESCE(MAX(e.position), 0) + 1 FROM workspace_extensions e WHERE e.workspace_id = w.id),
|
|
13
|
+
0, 'approval', '{}', w.owner_id, strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
14
|
+
FROM workspaces w
|
|
15
|
+
WHERE (SELECT COUNT(*) FROM workspace_extensions e WHERE e.workspace_id = w.id) < 32
|
|
16
|
+
ON CONFLICT (workspace_id, package_key) DO NOTHING;
|
|
17
|
+
INSERT INTO workspace_extensions (workspace_id, package_key, source, position, enabled, tools_mode, settings_json, updated_by, updated_at)
|
|
18
|
+
SELECT w.id, 'npm:cc-safety-net', 'npm:cc-safety-net@2.7.2', (SELECT COALESCE(MAX(e.position), 0) + 1 FROM workspace_extensions e WHERE e.workspace_id = w.id),
|
|
19
|
+
0, 'approval', '{}', w.owner_id, strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
20
|
+
FROM workspaces w
|
|
21
|
+
WHERE (SELECT COUNT(*) FROM workspace_extensions e WHERE e.workspace_id = w.id) < 32
|
|
22
|
+
ON CONFLICT (workspace_id, package_key) DO NOTHING;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
-- The extensions a host's owner requires of every session on it, whatever its workspace chose (HostConfig.requiredExtensions
|
|
2
|
+
-- in packages/shared/src/host-config.ts): each one's source and settings, as JSON, in the order sessions run them.
|
|
3
|
+
-- '[]' requires none.
|
|
4
|
+
ALTER TABLE connector_configs ADD COLUMN required_extensions_json TEXT NOT NULL DEFAULT '[]';
|