@myagentroam/node 0.9.119 → 0.9.121

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.
@@ -1,91 +0,0 @@
1
- export const NODE_SCHEMA_VERSION_V4 = 4;
2
- /** Last supported released schema. Fresh databases start from this baseline. */
3
- export const NODE_SCHEMA_V4 = String.raw `CREATE TABLE node_schema_migrations (
4
- version INTEGER PRIMARY KEY, applied_at INTEGER NOT NULL
5
- ) STRICT;
6
- CREATE TABLE workspaces (
7
- id TEXT PRIMARY KEY, path TEXT NOT NULL UNIQUE,
8
- kind TEXT NOT NULL CHECK (kind IN ('DIRECTORY', 'GIT_WORKSPACE')),
9
- git_summary TEXT, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL
10
- ) STRICT;
11
- CREATE TABLE agent_sessions (
12
- id TEXT PRIMARY KEY,
13
- workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
14
- runner TEXT NOT NULL CHECK (runner IN ('codex', 'claude-code', 'opencode')),
15
- pin_order INTEGER CHECK (pin_order IS NULL OR pin_order >= 0),
16
- metadata TEXT NOT NULL CHECK (json_valid(metadata))
17
- ) STRICT;
18
- CREATE TABLE terminal_sessions (
19
- id TEXT PRIMARY KEY, workspace_id TEXT REFERENCES workspaces(id) ON DELETE SET NULL,
20
- profile_id TEXT NOT NULL,
21
- state TEXT NOT NULL CHECK (state IN ('RUNNING', 'EXITED', 'CLOSED')),
22
- exit_code INTEGER, rows INTEGER NOT NULL CHECK (rows > 0 AND rows <= 1000),
23
- cols INTEGER NOT NULL CHECK (cols > 0 AND cols <= 1000),
24
- latest_sequence INTEGER NOT NULL CHECK (latest_sequence >= 0),
25
- created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL
26
- ) STRICT;
27
- CREATE TABLE runner_defaults (
28
- runner TEXT PRIMARY KEY CHECK (runner IN ('codex', 'claude-code', 'opencode')),
29
- model TEXT NOT NULL, effort TEXT NOT NULL, access TEXT NOT NULL
30
- ) STRICT;
31
- CREATE TABLE mcp_installations (
32
- target_kind TEXT NOT NULL CHECK (target_kind IN ('NODE','WORKSPACE')),
33
- target_id TEXT NOT NULL, catalog_entry_id TEXT NOT NULL, server_name TEXT NOT NULL,
34
- display_name TEXT NOT NULL, version TEXT NOT NULL,
35
- enabled INTEGER NOT NULL CHECK (enabled IN (0,1)),
36
- runtime TEXT NOT NULL CHECK (json_valid(runtime)),
37
- configuration TEXT NOT NULL CHECK (json_valid(configuration)), installed_at INTEGER NOT NULL,
38
- PRIMARY KEY (target_kind,target_id,server_name),
39
- CHECK ((target_kind='NODE' AND target_id='') OR (target_kind='WORKSPACE' AND target_id<>''))
40
- ) STRICT;`;
41
- export function assertNodeSchemaV4(database) {
42
- const required = {
43
- node_schema_migrations: ['version', 'applied_at'],
44
- workspaces: ['id', 'path', 'kind', 'git_summary', 'created_at', 'updated_at'],
45
- agent_sessions: ['id', 'workspace_id', 'runner', 'pin_order', 'metadata'],
46
- terminal_sessions: [
47
- 'id',
48
- 'workspace_id',
49
- 'profile_id',
50
- 'state',
51
- 'exit_code',
52
- 'rows',
53
- 'cols',
54
- 'latest_sequence',
55
- 'created_at',
56
- 'updated_at'
57
- ],
58
- runner_defaults: ['runner', 'model', 'effort', 'access'],
59
- mcp_installations: [
60
- 'target_kind',
61
- 'target_id',
62
- 'catalog_entry_id',
63
- 'server_name',
64
- 'display_name',
65
- 'version',
66
- 'enabled',
67
- 'runtime',
68
- 'configuration',
69
- 'installed_at'
70
- ]
71
- };
72
- for (const [table, expected] of Object.entries(required)) {
73
- const columns = database.prepare(`PRAGMA table_info(${table})`).all();
74
- const actual = columns.map((column) => column.name);
75
- // Later schema versions may add columns to this baseline table.
76
- if (expected.some((name) => !actual.includes(name)))
77
- throw new Error(`NODE_DATABASE_SCHEMA_INVALID:${table}`);
78
- }
79
- for (const table of ['agent_sessions', 'runner_defaults']) {
80
- const definition = database
81
- .prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name=?")
82
- .get(table);
83
- if (typeof definition?.sql !== 'string' || !definition.sql.includes("'opencode'"))
84
- throw new Error(`NODE_DATABASE_SCHEMA_INVALID:${table}:runner`);
85
- }
86
- const row = database
87
- .prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='mcp_installations'")
88
- .get();
89
- if (typeof row?.sql !== 'string' || !row.sql.includes("target_kind IN ('NODE','WORKSPACE')"))
90
- throw new Error('NODE_DATABASE_SCHEMA_INVALID:mcp_installations');
91
- }
@@ -1,33 +0,0 @@
1
- export const NODE_SCHEMA_VERSION_V5 = 5;
2
- /** Adds MAR Agent to every persisted Runner discriminator. */
3
- export const NODE_SCHEMA_MIGRATION_V5 = String.raw `
4
- CREATE TABLE agent_sessions_v5 (
5
- id TEXT PRIMARY KEY,
6
- workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
7
- runner TEXT NOT NULL CHECK (runner IN ('mar-agent', 'codex', 'claude-code', 'opencode')),
8
- pin_order INTEGER CHECK (pin_order IS NULL OR pin_order >= 0),
9
- metadata TEXT NOT NULL CHECK (json_valid(metadata))
10
- ) STRICT;
11
- INSERT INTO agent_sessions_v5 (id, workspace_id, runner, pin_order, metadata)
12
- SELECT id, workspace_id, runner, pin_order, metadata FROM agent_sessions;
13
- DROP TABLE agent_sessions;
14
- ALTER TABLE agent_sessions_v5 RENAME TO agent_sessions;
15
-
16
- CREATE TABLE runner_defaults_v5 (
17
- runner TEXT PRIMARY KEY CHECK (runner IN ('mar-agent', 'codex', 'claude-code', 'opencode')),
18
- model TEXT NOT NULL, effort TEXT NOT NULL, access TEXT NOT NULL
19
- ) STRICT;
20
- INSERT INTO runner_defaults_v5 (runner, model, effort, access)
21
- SELECT runner, model, effort, access FROM runner_defaults;
22
- DROP TABLE runner_defaults;
23
- ALTER TABLE runner_defaults_v5 RENAME TO runner_defaults;
24
- `;
25
- export function assertNodeSchemaV5(database) {
26
- for (const table of ['agent_sessions', 'runner_defaults']) {
27
- const definition = database
28
- .prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name=?")
29
- .get(table);
30
- if (typeof definition?.sql !== 'string' || !definition.sql.includes("'mar-agent'"))
31
- throw new Error(`NODE_DATABASE_SCHEMA_INVALID:${table}:runner`);
32
- }
33
- }
@@ -1,191 +0,0 @@
1
- export const NODE_SCHEMA_VERSION_V6 = 6;
2
- /** Adds rebuildable hosted-conversation indexes and immutable template publication metadata. */
3
- export const NODE_SCHEMA_MIGRATION_V6 = String.raw `
4
- CREATE TABLE conversation_template_versions (
5
- id TEXT PRIMARY KEY,
6
- template_id TEXT NOT NULL,
7
- version_number INTEGER NOT NULL CHECK (version_number > 0),
8
- draft_revision INTEGER NOT NULL CHECK (draft_revision > 0),
9
- status TEXT NOT NULL CHECK (status IN ('AVAILABLE','DISABLED','CORRUPTED','RETAINED')),
10
- storage_key TEXT NOT NULL UNIQUE,
11
- manifest TEXT NOT NULL CHECK (json_valid(manifest)),
12
- content_hash TEXT NOT NULL CHECK (length(content_hash) = 64),
13
- manifest_hash TEXT NOT NULL CHECK (length(manifest_hash) = 64),
14
- file_count INTEGER NOT NULL CHECK (file_count >= 0),
15
- total_bytes INTEGER NOT NULL CHECK (total_bytes >= 0),
16
- host_policy_version INTEGER NOT NULL CHECK (host_policy_version > 0),
17
- published_by_user_id INTEGER NOT NULL CHECK (published_by_user_id > 0),
18
- published_at INTEGER NOT NULL CHECK (published_at >= 0),
19
- reference_count INTEGER NOT NULL DEFAULT 0 CHECK (reference_count >= 0),
20
- UNIQUE (template_id, version_number)
21
- ) STRICT;
22
- CREATE INDEX conversation_template_versions_template_status
23
- ON conversation_template_versions(template_id, status, published_at);
24
-
25
- CREATE TABLE conversation_template_publish_jobs (
26
- id TEXT PRIMARY KEY,
27
- template_id TEXT NOT NULL,
28
- draft_revision INTEGER NOT NULL CHECK (draft_revision > 0),
29
- stage TEXT NOT NULL CHECK (
30
- stage IN ('VALIDATING','ENUMERATING','COPYING','SCANNING','MANIFEST','SEALED','REGISTERED')
31
- ),
32
- status TEXT NOT NULL CHECK (status IN ('QUEUED','RUNNING','SUCCEEDED','FAILED')),
33
- version_id TEXT REFERENCES conversation_template_versions(id) ON DELETE SET NULL,
34
- error_code TEXT,
35
- error_summary TEXT,
36
- requested_by_user_id INTEGER NOT NULL CHECK (requested_by_user_id > 0),
37
- draft TEXT NOT NULL CHECK (json_valid(draft)),
38
- created_at INTEGER NOT NULL CHECK (created_at >= 0),
39
- updated_at INTEGER NOT NULL CHECK (updated_at >= 0)
40
- ) STRICT;
41
- CREATE INDEX conversation_template_publish_jobs_template
42
- ON conversation_template_publish_jobs(template_id, created_at, id);
43
- CREATE INDEX conversation_template_publish_jobs_status
44
- ON conversation_template_publish_jobs(status, updated_at);
45
-
46
- CREATE TABLE hosted_conversations (
47
- id TEXT PRIMARY KEY,
48
- user_storage_key TEXT NOT NULL,
49
- conversation_storage_key TEXT NOT NULL,
50
- client_request_id TEXT,
51
- node_id TEXT NOT NULL,
52
- session_id TEXT NOT NULL,
53
- template_id TEXT NOT NULL,
54
- template_name TEXT NOT NULL,
55
- active_version_id TEXT NOT NULL REFERENCES conversation_template_versions(id),
56
- pending_version_id TEXT REFERENCES conversation_template_versions(id),
57
- title TEXT NOT NULL,
58
- status TEXT NOT NULL CHECK (
59
- status IN ('ACTIVE','UPGRADE_PENDING','UPGRADE_FAILED','RECOVERABLE_DELETED','DELETING')
60
- ),
61
- model_id TEXT NOT NULL,
62
- reasoning_effort TEXT,
63
- template_deleted INTEGER NOT NULL DEFAULT 0 CHECK (template_deleted IN (0,1)),
64
- recoverable_until INTEGER,
65
- used_bytes INTEGER NOT NULL DEFAULT 0 CHECK (used_bytes >= 0),
66
- max_bytes INTEGER NOT NULL CHECK (max_bytes > 0),
67
- created_at INTEGER NOT NULL CHECK (created_at >= 0),
68
- updated_at INTEGER NOT NULL CHECK (updated_at >= 0),
69
- last_activity_at INTEGER NOT NULL CHECK (last_activity_at >= 0),
70
- UNIQUE (user_storage_key, conversation_storage_key),
71
- UNIQUE (user_storage_key, client_request_id)
72
- ) STRICT;
73
- CREATE INDEX hosted_conversations_user_activity
74
- ON hosted_conversations(user_storage_key, last_activity_at DESC, id DESC);
75
- CREATE INDEX hosted_conversations_template
76
- ON hosted_conversations(template_id, status, id);
77
-
78
- CREATE TABLE conversation_files (
79
- id TEXT PRIMARY KEY,
80
- conversation_id TEXT NOT NULL REFERENCES hosted_conversations(id) ON DELETE CASCADE,
81
- category TEXT NOT NULL CHECK (category IN ('UPLOAD','WORK','OUTPUT')),
82
- relative_path TEXT NOT NULL,
83
- display_name TEXT NOT NULL,
84
- mime_type TEXT NOT NULL,
85
- size INTEGER NOT NULL CHECK (size >= 0),
86
- source TEXT NOT NULL CHECK (source IN ('USER','AGENT','SYSTEM')),
87
- turn_id TEXT,
88
- item_id TEXT,
89
- created_at INTEGER NOT NULL CHECK (created_at >= 0),
90
- updated_at INTEGER NOT NULL CHECK (updated_at >= 0),
91
- UNIQUE (conversation_id, category, relative_path)
92
- ) STRICT;
93
- CREATE INDEX conversation_files_conversation_updated
94
- ON conversation_files(conversation_id, updated_at DESC, id);
95
-
96
- CREATE TABLE hosted_conversation_messages (
97
- conversation_id TEXT NOT NULL REFERENCES hosted_conversations(id) ON DELETE CASCADE,
98
- client_message_id TEXT NOT NULL,
99
- run_id TEXT NOT NULL,
100
- status TEXT NOT NULL CHECK (status IN ('RUNNING','SUCCEEDED','FAILED','INTERRUPTED')),
101
- created_at INTEGER NOT NULL CHECK (created_at >= 0),
102
- updated_at INTEGER NOT NULL CHECK (updated_at >= 0),
103
- PRIMARY KEY (conversation_id, client_message_id)
104
- ) STRICT;
105
- `;
106
- export function assertNodeSchemaV6(database) {
107
- const required = {
108
- conversation_template_versions: [
109
- 'id',
110
- 'template_id',
111
- 'version_number',
112
- 'draft_revision',
113
- 'status',
114
- 'storage_key',
115
- 'manifest',
116
- 'content_hash',
117
- 'manifest_hash',
118
- 'file_count',
119
- 'total_bytes',
120
- 'host_policy_version',
121
- 'published_by_user_id',
122
- 'published_at',
123
- 'reference_count'
124
- ],
125
- conversation_template_publish_jobs: [
126
- 'id',
127
- 'template_id',
128
- 'draft_revision',
129
- 'stage',
130
- 'status',
131
- 'version_id',
132
- 'error_code',
133
- 'error_summary',
134
- 'requested_by_user_id',
135
- 'draft',
136
- 'created_at',
137
- 'updated_at'
138
- ],
139
- hosted_conversations: [
140
- 'id',
141
- 'user_storage_key',
142
- 'conversation_storage_key',
143
- 'client_request_id',
144
- 'node_id',
145
- 'session_id',
146
- 'template_id',
147
- 'template_name',
148
- 'active_version_id',
149
- 'pending_version_id',
150
- 'title',
151
- 'status',
152
- 'model_id',
153
- 'reasoning_effort',
154
- 'template_deleted',
155
- 'recoverable_until',
156
- 'used_bytes',
157
- 'max_bytes',
158
- 'created_at',
159
- 'updated_at',
160
- 'last_activity_at'
161
- ],
162
- conversation_files: [
163
- 'id',
164
- 'conversation_id',
165
- 'category',
166
- 'relative_path',
167
- 'display_name',
168
- 'mime_type',
169
- 'size',
170
- 'source',
171
- 'turn_id',
172
- 'item_id',
173
- 'created_at',
174
- 'updated_at'
175
- ],
176
- hosted_conversation_messages: [
177
- 'conversation_id',
178
- 'client_message_id',
179
- 'run_id',
180
- 'status',
181
- 'created_at',
182
- 'updated_at'
183
- ]
184
- };
185
- for (const [table, expected] of Object.entries(required)) {
186
- const columns = database.prepare(`PRAGMA table_info(${table})`).all();
187
- const actual = columns.map((column) => column.name);
188
- if (actual.length !== expected.length || expected.some((name) => !actual.includes(name)))
189
- throw new Error(`NODE_DATABASE_SCHEMA_INVALID:${table}`);
190
- }
191
- }
@@ -1,52 +0,0 @@
1
- export const NODE_SCHEMA_VERSION_V7 = 7;
2
- export const EMPTY_MCP_CONFIG_HASH = '4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945';
3
- /** Adds immutable MCP fingerprints and removes the retired hosted reasoning preference. */
4
- export const NODE_SCHEMA_MIGRATION_V7 = String.raw `
5
- ALTER TABLE conversation_template_versions
6
- ADD COLUMN mcp_config_hash TEXT NOT NULL DEFAULT '${EMPTY_MCP_CONFIG_HASH}'
7
- CHECK (length(mcp_config_hash) = 64);
8
- ALTER TABLE hosted_conversations DROP COLUMN reasoning_effort;
9
- CREATE TABLE conversation_files_v7 (
10
- id TEXT PRIMARY KEY,
11
- conversation_id TEXT NOT NULL REFERENCES hosted_conversations(id) ON DELETE CASCADE,
12
- category TEXT NOT NULL CHECK (category IN ('UPLOAD','OUTPUT')),
13
- relative_path TEXT NOT NULL,
14
- display_name TEXT NOT NULL,
15
- mime_type TEXT NOT NULL,
16
- size INTEGER NOT NULL CHECK (size >= 0),
17
- source TEXT NOT NULL CHECK (source IN ('USER','AGENT','SYSTEM')),
18
- turn_id TEXT,
19
- item_id TEXT,
20
- created_at INTEGER NOT NULL CHECK (created_at >= 0),
21
- updated_at INTEGER NOT NULL CHECK (updated_at >= 0),
22
- UNIQUE (conversation_id, category, relative_path)
23
- ) STRICT;
24
- INSERT INTO conversation_files_v7
25
- (id,conversation_id,category,relative_path,display_name,mime_type,size,source,
26
- turn_id,item_id,created_at,updated_at)
27
- SELECT id,conversation_id,category,relative_path,display_name,mime_type,size,source,
28
- turn_id,item_id,created_at,updated_at
29
- FROM conversation_files
30
- WHERE category IN ('UPLOAD','OUTPUT');
31
- DROP TABLE conversation_files;
32
- ALTER TABLE conversation_files_v7 RENAME TO conversation_files;
33
- CREATE INDEX conversation_files_conversation_updated
34
- ON conversation_files(conversation_id, updated_at DESC, id);
35
- `;
36
- export function assertNodeSchemaV7(database) {
37
- const templateColumns = database
38
- .prepare('PRAGMA table_info(conversation_template_versions)')
39
- .all();
40
- if (!templateColumns.some((column) => column.name === 'mcp_config_hash'))
41
- throw new Error('NODE_DATABASE_SCHEMA_INVALID:conversation_template_versions');
42
- const conversationColumns = database.prepare('PRAGMA table_info(hosted_conversations)').all();
43
- if (conversationColumns === undefined ||
44
- conversationColumns.some((column) => column.name === 'reasoning_effort'))
45
- throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversations');
46
- const conversationFiles = database
47
- .prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='conversation_files'")
48
- .get();
49
- if (typeof conversationFiles?.sql !== 'string' ||
50
- !conversationFiles.sql.includes("category IN ('UPLOAD','OUTPUT')"))
51
- throw new Error('NODE_DATABASE_SCHEMA_INVALID:conversation_files');
52
- }
@@ -1,28 +0,0 @@
1
- export const NODE_SCHEMA_VERSION_V8 = 8;
2
- /** Adds hosted conversation pin metadata and its authoritative list order. */
3
- export const NODE_SCHEMA_MIGRATION_V8 = String.raw `
4
- ALTER TABLE hosted_conversations
5
- ADD COLUMN pinned_at INTEGER CHECK (pinned_at IS NULL OR pinned_at >= 0);
6
- DROP INDEX hosted_conversations_user_activity;
7
- CREATE INDEX hosted_conversations_user_pin_activity
8
- ON hosted_conversations(
9
- user_storage_key,
10
- (pinned_at IS NOT NULL) DESC,
11
- last_activity_at DESC,
12
- id DESC
13
- );
14
- `;
15
- export function assertNodeSchemaV8(database) {
16
- const conversationColumns = database
17
- .prepare('PRAGMA table_info(hosted_conversations)')
18
- .all();
19
- if (!conversationColumns.some((column) => column.name === 'pinned_at'))
20
- throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversations');
21
- const index = database
22
- .prepare("SELECT sql FROM sqlite_master WHERE type='index' AND name='hosted_conversations_user_pin_activity'")
23
- .get();
24
- if (typeof index?.sql !== 'string' ||
25
- !index.sql.includes('(pinned_at IS NOT NULL) DESC') ||
26
- !index.sql.includes('last_activity_at DESC'))
27
- throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversations');
28
- }
@@ -1,163 +0,0 @@
1
- export const NODE_SCHEMA_VERSION_V9 = 9;
2
- /**
3
- * Persists title/message metadata, removes recovery states, and restores failed upgrades to the
4
- * active version. This unreleased migration is the single boundary from v8.
5
- */
6
- const NODE_SCHEMA_MIGRATION_V9_METADATA = String.raw `
7
- ALTER TABLE hosted_conversations
8
- ADD COLUMN title_source TEXT NOT NULL DEFAULT 'CUSTOM'
9
- CHECK (title_source IN ('AUTO','CUSTOM'));
10
-
11
- ALTER TABLE hosted_conversation_messages
12
- ADD COLUMN user_text_present INTEGER NOT NULL DEFAULT 1
13
- CHECK (user_text_present IN (0,1));
14
- `;
15
- export const NODE_SCHEMA_MIGRATION_V9_FINALIZE = String.raw `
16
- DELETE FROM conversation_files
17
- WHERE conversation_id IN (
18
- SELECT id
19
- FROM hosted_conversations
20
- WHERE status IN ('RECOVERABLE_DELETED','DELETING')
21
- );
22
-
23
- DELETE FROM hosted_conversation_messages
24
- WHERE conversation_id IN (
25
- SELECT id
26
- FROM hosted_conversations
27
- WHERE status IN ('RECOVERABLE_DELETED','DELETING')
28
- );
29
-
30
- DELETE FROM hosted_conversations
31
- WHERE status IN ('RECOVERABLE_DELETED','DELETING');
32
-
33
- UPDATE hosted_conversations
34
- SET pending_version_id = NULL,
35
- status = 'ACTIVE'
36
- WHERE status = 'UPGRADE_FAILED';
37
-
38
- UPDATE conversation_template_versions
39
- SET reference_count = (
40
- SELECT COUNT(*)
41
- FROM (
42
- SELECT id AS conversation_id, active_version_id AS version_id
43
- FROM hosted_conversations
44
- UNION
45
- SELECT id AS conversation_id, pending_version_id AS version_id
46
- FROM hosted_conversations
47
- WHERE pending_version_id IS NOT NULL
48
- AND pending_version_id <> active_version_id
49
- ) AS active_references
50
- WHERE active_references.version_id = conversation_template_versions.id
51
- );
52
-
53
- CREATE TABLE hosted_conversations_v9 (
54
- id TEXT PRIMARY KEY,
55
- user_storage_key TEXT NOT NULL,
56
- conversation_storage_key TEXT NOT NULL,
57
- client_request_id TEXT,
58
- node_id TEXT NOT NULL,
59
- session_id TEXT NOT NULL,
60
- template_id TEXT NOT NULL,
61
- template_name TEXT NOT NULL,
62
- active_version_id TEXT NOT NULL REFERENCES conversation_template_versions(id),
63
- pending_version_id TEXT REFERENCES conversation_template_versions(id),
64
- title TEXT NOT NULL,
65
- status TEXT NOT NULL CHECK (status IN ('ACTIVE','UPGRADE_PENDING')),
66
- model_id TEXT NOT NULL,
67
- template_deleted INTEGER NOT NULL DEFAULT 0 CHECK (template_deleted IN (0,1)),
68
- used_bytes INTEGER NOT NULL DEFAULT 0 CHECK (used_bytes >= 0),
69
- max_bytes INTEGER NOT NULL CHECK (max_bytes > 0),
70
- created_at INTEGER NOT NULL CHECK (created_at >= 0),
71
- updated_at INTEGER NOT NULL CHECK (updated_at >= 0),
72
- last_activity_at INTEGER NOT NULL CHECK (last_activity_at >= 0),
73
- pinned_at INTEGER CHECK (pinned_at IS NULL OR pinned_at >= 0),
74
- title_source TEXT NOT NULL DEFAULT 'CUSTOM' CHECK (title_source IN ('AUTO','CUSTOM')),
75
- UNIQUE (user_storage_key, conversation_storage_key),
76
- UNIQUE (user_storage_key, client_request_id)
77
- ) STRICT;
78
-
79
- INSERT INTO hosted_conversations_v9
80
- (id,user_storage_key,conversation_storage_key,client_request_id,node_id,session_id,
81
- template_id,template_name,active_version_id,pending_version_id,title,status,model_id,
82
- template_deleted,used_bytes,max_bytes,created_at,updated_at,last_activity_at,pinned_at,
83
- title_source)
84
- SELECT id,user_storage_key,conversation_storage_key,client_request_id,node_id,session_id,
85
- template_id,template_name,active_version_id,pending_version_id,title,status,model_id,
86
- template_deleted,used_bytes,max_bytes,created_at,updated_at,last_activity_at,pinned_at,
87
- title_source
88
- FROM hosted_conversations;
89
-
90
- DROP TABLE hosted_conversations;
91
- ALTER TABLE hosted_conversations_v9 RENAME TO hosted_conversations;
92
-
93
- CREATE INDEX hosted_conversations_user_pin_activity
94
- ON hosted_conversations(
95
- user_storage_key,
96
- (pinned_at IS NOT NULL) DESC,
97
- last_activity_at DESC,
98
- id DESC
99
- );
100
- CREATE INDEX hosted_conversations_template
101
- ON hosted_conversations(template_id, status, id);
102
- `;
103
- export const NODE_SCHEMA_MIGRATION_V9 = `${NODE_SCHEMA_MIGRATION_V9_METADATA}\n${NODE_SCHEMA_MIGRATION_V9_FINALIZE}`;
104
- export function isDraftNodeSchemaV9(database) {
105
- const conversationColumns = database
106
- .prepare('PRAGMA table_info(hosted_conversations)')
107
- .all();
108
- const titleSource = conversationColumns.find((column) => column.name === 'title_source');
109
- const conversationTable = database
110
- .prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='hosted_conversations'")
111
- .get();
112
- const messageColumns = database
113
- .prepare('PRAGMA table_info(hosted_conversation_messages)')
114
- .all();
115
- const userTextPresent = messageColumns.find((column) => column.name === 'user_text_present');
116
- return (titleSource?.notnull === 1 &&
117
- titleSource.dflt_value === "'CUSTOM'" &&
118
- conversationColumns.some((column) => column.name === 'recoverable_until') &&
119
- conversationColumns.some((column) => column.name === 'pinned_at') &&
120
- !conversationColumns.some((column) => column.name === 'reasoning_effort') &&
121
- typeof conversationTable?.sql === 'string' &&
122
- conversationTable.sql.includes("status IN ('ACTIVE','UPGRADE_PENDING','UPGRADE_FAILED','RECOVERABLE_DELETED','DELETING')") &&
123
- userTextPresent?.notnull === 1 &&
124
- userTextPresent.dflt_value === '1');
125
- }
126
- export function assertNodeSchemaV9(database) {
127
- const conversationColumns = database
128
- .prepare('PRAGMA table_info(hosted_conversations)')
129
- .all();
130
- const titleSource = conversationColumns.find((column) => column.name === 'title_source');
131
- if (titleSource?.notnull !== 1 ||
132
- titleSource.dflt_value !== "'CUSTOM'" ||
133
- conversationColumns.some((column) => column.name === 'recoverable_until'))
134
- throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversations');
135
- const conversationTable = database
136
- .prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='hosted_conversations'")
137
- .get();
138
- if (typeof conversationTable?.sql !== 'string' ||
139
- !conversationTable.sql.includes("status IN ('ACTIVE','UPGRADE_PENDING')") ||
140
- conversationTable.sql.includes('UPGRADE_FAILED') ||
141
- conversationTable.sql.includes('RECOVERABLE_DELETED') ||
142
- conversationTable.sql.includes('DELETING'))
143
- throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversations');
144
- const messageColumns = database
145
- .prepare('PRAGMA table_info(hosted_conversation_messages)')
146
- .all();
147
- const userTextPresent = messageColumns.find((column) => column.name === 'user_text_present');
148
- if (userTextPresent?.notnull !== 1 || userTextPresent.dflt_value !== '1')
149
- throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversation_messages');
150
- const foreignKeys = database.prepare('PRAGMA foreign_keys').get();
151
- if (foreignKeys?.foreign_keys !== 1)
152
- throw new Error('NODE_DATABASE_SCHEMA_INVALID:foreign_keys');
153
- if (database.prepare('PRAGMA foreign_key_check(hosted_conversations)').get() !== undefined)
154
- throw new Error('NODE_DATABASE_SCHEMA_INVALID:foreign_keys');
155
- for (const table of ['conversation_files', 'hosted_conversation_messages']) {
156
- const foreignKeys = database.prepare(`PRAGMA foreign_key_list(${table})`).all();
157
- if (!foreignKeys.some((foreignKey) => foreignKey.table === 'hosted_conversations' &&
158
- foreignKey.from === 'conversation_id' &&
159
- foreignKey.to === 'id' &&
160
- foreignKey.on_delete === 'CASCADE'))
161
- throw new Error(`NODE_DATABASE_SCHEMA_INVALID:${table}`);
162
- }
163
- }
@@ -1,96 +0,0 @@
1
- export const NODE_SCHEMA_VERSION_V10 = 10;
2
- /** Removes persistent hosted-conversation upgrade scheduling state. */
3
- export const NODE_SCHEMA_MIGRATION_V10 = String.raw `
4
- UPDATE conversation_template_versions
5
- SET reference_count = (
6
- SELECT COUNT(*)
7
- FROM hosted_conversations
8
- WHERE active_version_id = conversation_template_versions.id
9
- );
10
-
11
- CREATE TABLE hosted_conversations_v10 (
12
- id TEXT PRIMARY KEY,
13
- user_storage_key TEXT NOT NULL,
14
- conversation_storage_key TEXT NOT NULL,
15
- client_request_id TEXT,
16
- node_id TEXT NOT NULL,
17
- session_id TEXT NOT NULL,
18
- template_id TEXT NOT NULL,
19
- template_name TEXT NOT NULL,
20
- active_version_id TEXT NOT NULL REFERENCES conversation_template_versions(id),
21
- title TEXT NOT NULL,
22
- status TEXT NOT NULL CHECK (status IN ('ACTIVE')),
23
- model_id TEXT NOT NULL,
24
- template_deleted INTEGER NOT NULL DEFAULT 0 CHECK (template_deleted IN (0,1)),
25
- used_bytes INTEGER NOT NULL DEFAULT 0 CHECK (used_bytes >= 0),
26
- max_bytes INTEGER NOT NULL CHECK (max_bytes > 0),
27
- created_at INTEGER NOT NULL CHECK (created_at >= 0),
28
- updated_at INTEGER NOT NULL CHECK (updated_at >= 0),
29
- last_activity_at INTEGER NOT NULL CHECK (last_activity_at >= 0),
30
- pinned_at INTEGER CHECK (pinned_at IS NULL OR pinned_at >= 0),
31
- title_source TEXT NOT NULL DEFAULT 'CUSTOM' CHECK (title_source IN ('AUTO','CUSTOM')),
32
- UNIQUE (user_storage_key, conversation_storage_key),
33
- UNIQUE (user_storage_key, client_request_id)
34
- ) STRICT;
35
-
36
- INSERT INTO hosted_conversations_v10
37
- (id,user_storage_key,conversation_storage_key,client_request_id,node_id,session_id,
38
- template_id,template_name,active_version_id,title,status,model_id,template_deleted,
39
- used_bytes,max_bytes,created_at,updated_at,last_activity_at,pinned_at,title_source)
40
- SELECT id,user_storage_key,conversation_storage_key,client_request_id,node_id,session_id,
41
- template_id,template_name,active_version_id,title,'ACTIVE',model_id,template_deleted,
42
- used_bytes,max_bytes,created_at,updated_at,last_activity_at,pinned_at,title_source
43
- FROM hosted_conversations;
44
-
45
- DROP TABLE hosted_conversations;
46
- ALTER TABLE hosted_conversations_v10 RENAME TO hosted_conversations;
47
-
48
- CREATE INDEX hosted_conversations_user_pin_activity
49
- ON hosted_conversations(
50
- user_storage_key,
51
- (pinned_at IS NOT NULL) DESC,
52
- last_activity_at DESC,
53
- id DESC
54
- );
55
- CREATE INDEX hosted_conversations_template
56
- ON hosted_conversations(template_id, status, id);
57
- `;
58
- export function assertNodeSchemaV10(database) {
59
- const conversationColumns = database
60
- .prepare('PRAGMA table_info(hosted_conversations)')
61
- .all();
62
- const titleSource = conversationColumns.find((column) => column.name === 'title_source');
63
- if (titleSource?.notnull !== 1 ||
64
- titleSource.dflt_value !== "'CUSTOM'" ||
65
- conversationColumns.some((column) => column.name === 'pending_version_id' || column.name === 'recoverable_until'))
66
- throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversations');
67
- const conversationTable = database
68
- .prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='hosted_conversations'")
69
- .get();
70
- if (typeof conversationTable?.sql !== 'string' ||
71
- !conversationTable.sql.includes("status IN ('ACTIVE')") ||
72
- conversationTable.sql.includes('UPGRADE_PENDING') ||
73
- conversationTable.sql.includes('UPGRADE_FAILED') ||
74
- conversationTable.sql.includes('RECOVERABLE_DELETED') ||
75
- conversationTable.sql.includes('DELETING'))
76
- throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversations');
77
- const messageColumns = database
78
- .prepare('PRAGMA table_info(hosted_conversation_messages)')
79
- .all();
80
- const userTextPresent = messageColumns.find((column) => column.name === 'user_text_present');
81
- if (userTextPresent?.notnull !== 1 || userTextPresent.dflt_value !== '1')
82
- throw new Error('NODE_DATABASE_SCHEMA_INVALID:hosted_conversation_messages');
83
- const foreignKeys = database.prepare('PRAGMA foreign_keys').get();
84
- if (foreignKeys?.foreign_keys !== 1)
85
- throw new Error('NODE_DATABASE_SCHEMA_INVALID:foreign_keys');
86
- if (database.prepare('PRAGMA foreign_key_check(hosted_conversations)').get() !== undefined)
87
- throw new Error('NODE_DATABASE_SCHEMA_INVALID:foreign_keys');
88
- for (const table of ['conversation_files', 'hosted_conversation_messages']) {
89
- const foreignKeys = database.prepare(`PRAGMA foreign_key_list(${table})`).all();
90
- if (!foreignKeys.some((foreignKey) => foreignKey.table === 'hosted_conversations' &&
91
- foreignKey.from === 'conversation_id' &&
92
- foreignKey.to === 'id' &&
93
- foreignKey.on_delete === 'CASCADE'))
94
- throw new Error(`NODE_DATABASE_SCHEMA_INVALID:${table}`);
95
- }
96
- }