@oar-sh/oar 0.9.18 → 0.9.20
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/.github/extensions/web-relay/polling/polling-loop.mjs +2 -26
- package/.github/extensions/web-relay/server-lifecycle/managed-server.mjs +13 -1
- package/.github/extensions/web-relay/skills/question-routing-hooks.mjs +2 -26
- package/CHANGELOG.md +359 -0
- package/README.md +10 -10
- package/bin/oar.js +391 -97
- package/package.json +4 -2
- package/server/claude-cloud-worker/claude-cloud-event-normalizer.mjs +60 -0
- package/server/claude-cloud-worker/claude-cloud-session-process.mjs +27 -0
- package/server/claude-worker/claude-remote-relay-tool.mjs +3 -2
- package/server/claude-worker/claude-session-process.mjs +3 -0
- package/server/claude-worker/claude-turn-publisher.mjs +163 -8
- package/server/claude-worker/claude-usage-totals.mjs +58 -0
- package/server/copilot-worker/copilot-plan-board.mjs +4 -7
- package/server/copilot-worker/copilot-sdk-event-normalizer.mjs +86 -3
- package/server/copilot-worker/copilot-sdk-session-process.mjs +57 -4
- package/server/cursor-worker/cursor-turn-runner.mjs +42 -6
- package/server/db-schema.mjs +18 -0
- package/server/deepseek-worker/deepseek-claude-backend.mjs +14 -0
- package/server/grok-worker/grok-turn-runner.mjs +44 -6
- package/server/migrations/0001-add-structured-answer.mjs +5 -7
- package/server/migrations/0002-recent-workspace-roots-path-key.mjs +5 -7
- package/server/migrations/0003-push-subscriptions.mjs +5 -7
- package/server/migrations/0004-steer-settle-markers.mjs +5 -7
- package/server/migrations/0005-remote-relays.mjs +5 -7
- package/server/migrations/0006-workspace-root-settings.mjs +5 -7
- package/server/migrations/0007-claude-cloud.mjs +5 -7
- package/server/migrations/0008-message-pins.mjs +5 -7
- package/server/migrations/0009-subagent-timeline.mjs +5 -7
- package/server/migrations/0010-subagent-timeline-pruning.mjs +5 -7
- package/server/migrations/0011-relay-event-subscriptions.mjs +5 -7
- package/server/migrations/0012-cross-relay-event-subscriptions.mjs +5 -7
- package/server/migrations/0013-previews.mjs +5 -7
- package/server/migrations/0014-conversation-groups.mjs +5 -7
- package/server/migrations/0015-conversation-group-position.mjs +5 -7
- package/server/migrations/0016-share-access-log.mjs +5 -7
- package/server/migrations/0017-conversation-history-indexes.mjs +5 -7
- package/server/migrations/0018-background-task-rows.mjs +5 -7
- package/server/migrations/0019-relay-event-subscription-options.mjs +5 -7
- package/server/migrations/0020-conversation-may-create-sessions.mjs +5 -7
- package/server/migrations/0021-conversation-group-agent-marks.mjs +5 -7
- package/server/migrations/0022-relay-schedules.mjs +5 -7
- package/server/migrations/0023-relay-asks.mjs +5 -7
- package/server/migrations/0024-deepseek-usage-totals.mjs +5 -7
- package/server/migrations/0025-deepseek-usage-requests-daily.mjs +5 -7
- package/server/migrations/0026-deepseek-usage-served-models.mjs +5 -7
- package/server/migrations/0027-deepseek-usage-checkpoint-runs.mjs +5 -7
- package/server/migrations/0028-deepseek-usage-checkpoint-request-runs.mjs +5 -7
- package/server/migrations/0029-deepseek-balance-rises.mjs +5 -7
- package/server/migrations/0030-deepseek-usage-actuals.mjs +5 -7
- package/server/migrations/0031-queue-provider.mjs +5 -7
- package/server/migrations/0032-runtime-session-billing-switch.mjs +5 -7
- package/server/migrations/0033-claude-api-usage-checkpoints.mjs +5 -7
- package/server/migrations/0034-claude-api-usage-totals.mjs +5 -7
- package/server/migrations/0035-conversation-plan-only.mjs +87 -0
- package/server/migrations/0036-token-usage.mjs +267 -0
- package/server/public/app/about-view.mjs +87 -3
- package/server/public/app/api-client.js +2 -1
- package/server/public/app/bootstrap.js +55 -2
- package/server/public/app/composer-control-state.mjs +12 -2
- package/server/public/app/context-usage-view.mjs +16 -0
- package/server/public/app/conversation-view.js +17 -2
- package/server/public/app/inbox-ui.js +32 -0
- package/server/public/app/inbox-view.mjs +141 -5
- package/server/public/app/plan-board-shared.mjs +49 -0
- package/server/public/app/plan-usage-view.mjs +1 -1
- package/server/public/app/relay-board-inline.mjs +4 -1
- package/server/public/app/relay-board-view.js +38 -10
- package/server/public/app/relay-event-view.mjs +4 -0
- package/server/public/app/socket-handlers.js +10 -2
- package/server/public/index.html +14 -0
- package/server/public/sw.js +8 -0
- package/server/relay-heap-guard.mjs +351 -0
- package/server/relay-self-restart.mjs +116 -9
- package/server/relay-tools.md +5 -4
- package/server/repositories/message-repository.mjs +31 -1
- package/server/repositories/remote-relay-repository.mjs +10 -0
- package/server/repositories/session-repository.mjs +6 -1
- package/server/routes/messages-routes.mjs +120 -4
- package/server/routes/relay-ask-routes.mjs +138 -8
- package/server/routes/relay-board-routes.mjs +55 -40
- package/server/routes/sessions-routes.mjs +141 -31
- package/server/server-runtime.mjs +142 -11
- package/server/services/about-service.mjs +59 -0
- package/server/services/cache-rebuild-service.mjs +7 -0
- package/server/services/conversation-preferences-service.mjs +31 -0
- package/server/services/database-file.mjs +413 -0
- package/server/services/db-backup-service.mjs +809 -0
- package/server/services/deepseek-usage-import.mjs +6 -9
- package/server/services/delete-archive-service.mjs +3 -0
- package/server/services/earlier-database-service.mjs +69 -126
- package/server/services/oar-cli-helpers.mjs +214 -12
- package/server/services/oar-cli-menu.mjs +1 -0
- package/server/services/oar-state-migration-service.mjs +33 -13
- package/server/services/package-data-rescue.mjs +4 -2
- package/server/services/plan-usage-claude-api.mjs +14 -15
- package/server/services/plan-usage-contract.mjs +6 -2
- package/server/services/plan-usage-deepseek.mjs +1 -1
- package/server/services/plan-usage-tokens.mjs +248 -0
- package/server/services/push-dispatch-service.mjs +134 -9
- package/server/services/relay-cli-launcher-service.mjs +3 -0
- package/server/services/relay-event-service.mjs +30 -0
- package/server/services/relay-question-context.mjs +11 -0
- package/server/services/relay-restart-picture.mjs +67 -22
- package/server/services/remote-inbox-watch-service.mjs +204 -0
- package/server/services/remote-relay-caller-context.mjs +80 -7
- package/server/services/remote-relay-dispatcher.mjs +68 -8
- package/server/services/restart-resume-service.mjs +5 -2
- package/server/services/session-worker-launch-service.mjs +12 -3
- package/server/services/session-worker-stop-service.mjs +27 -6
- package/server/services/token-usage-service.mjs +430 -0
- package/server/services/update-install-service.mjs +13 -0
- package/server/services/usage-limit-pause-service.mjs +8 -1
- package/server/services/worker-scope.mjs +77 -0
- package/shared/plan-board-actions.mjs +130 -0
- package/shared/plan-only.mjs +43 -0
- package/shared/relay-asks.mjs +3 -0
- package/shared/relay-events.mjs +38 -4
- package/shared/remote-relay-contract.mjs +98 -21
- package/shared/turn-token-usage.mjs +144 -0
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
*
|
|
29
29
|
* Additive and idempotent. Safe to run on every boot.
|
|
30
30
|
*
|
|
31
|
-
* Usage: node server/migrations/0025-deepseek-usage-requests-daily.mjs [path/to/
|
|
31
|
+
* Usage: node server/migrations/0025-deepseek-usage-requests-daily.mjs [path/to/oar.db]
|
|
32
32
|
*/
|
|
33
33
|
|
|
34
34
|
import { fileURLToPath } from 'url';
|
|
@@ -37,6 +37,7 @@ import process from 'process';
|
|
|
37
37
|
import Database from 'better-sqlite3';
|
|
38
38
|
|
|
39
39
|
import { DEEPSEEK_USAGE_TOTALS_TABLE, migrateDeepSeekUsageTotals } from './0024-deepseek-usage-totals.mjs';
|
|
40
|
+
import { cliDbPath } from '../services/database-file.mjs';
|
|
40
41
|
|
|
41
42
|
export const DEEPSEEK_USAGE_DAYS_TABLE = 'deepseek_usage_days';
|
|
42
43
|
export const DEEPSEEK_BALANCE_REFERENCE_TABLE = 'deepseek_balance_reference';
|
|
@@ -148,11 +149,6 @@ export function migrateDeepSeekUsageRequestsDaily(db) {
|
|
|
148
149
|
return { applied: columnsAdded + tablesAdded > 0, columnsAdded, tablesAdded };
|
|
149
150
|
}
|
|
150
151
|
|
|
151
|
-
function defaultDbPath() {
|
|
152
|
-
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
153
|
-
return path.resolve(here, '..', 'data', 'copilot.db');
|
|
154
|
-
}
|
|
155
|
-
|
|
156
152
|
export function migrate(dbPath, options = {}) {
|
|
157
153
|
const db = new Database(dbPath, options);
|
|
158
154
|
try {
|
|
@@ -164,8 +160,10 @@ export function migrate(dbPath, options = {}) {
|
|
|
164
160
|
|
|
165
161
|
const isMain = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
166
162
|
if (isMain) {
|
|
167
|
-
const dbPath = process.argv[2] ? path.resolve(process.argv[2]) : defaultDbPath();
|
|
168
163
|
try {
|
|
164
|
+
// The given path, else the database in server/data (oar.db, else the
|
|
165
|
+
// name before 0.9.20); never a new one.
|
|
166
|
+
const dbPath = cliDbPath(process.argv[2], new URL('..', import.meta.url));
|
|
169
167
|
const result = migrate(dbPath);
|
|
170
168
|
console.log(`Migration 0025 on ${dbPath}`);
|
|
171
169
|
console.log(result.applied
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* Idempotent: a database without such rows is left as it is. Safe to run on
|
|
30
30
|
* every boot.
|
|
31
31
|
*
|
|
32
|
-
* Usage: node server/migrations/0026-deepseek-usage-served-models.mjs [path/to/
|
|
32
|
+
* Usage: node server/migrations/0026-deepseek-usage-served-models.mjs [path/to/oar.db]
|
|
33
33
|
*/
|
|
34
34
|
|
|
35
35
|
import { fileURLToPath } from 'url';
|
|
@@ -40,6 +40,7 @@ import { DEEPSEEK_USAGE_CHECKPOINTS_TABLE, DEEPSEEK_USAGE_TOTALS_TABLE } from '.
|
|
|
40
40
|
import { DEEPSEEK_USAGE_DAYS_TABLE, migrateDeepSeekUsageRequestsDaily } from './0025-deepseek-usage-requests-daily.mjs';
|
|
41
41
|
import { deepseekServedModel } from '../../shared/deepseek-models.mjs';
|
|
42
42
|
import { estimateCost, estimateSearchCost } from '../../shared/deepseek-pricing.mjs';
|
|
43
|
+
import { cliDbPath } from '../services/database-file.mjs';
|
|
43
44
|
|
|
44
45
|
/** The DeepSeek model a stored model name is folded into, or '' when the row stays. */
|
|
45
46
|
export function deepseekFoldedModel(model) {
|
|
@@ -191,11 +192,6 @@ export function migrateDeepSeekUsageServedModels(db) {
|
|
|
191
192
|
return { applied: result.totalsFolded + result.daysFolded + result.checkpointsFolded > 0, ...result };
|
|
192
193
|
}
|
|
193
194
|
|
|
194
|
-
function defaultDbPath() {
|
|
195
|
-
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
196
|
-
return path.resolve(here, '..', 'data', 'copilot.db');
|
|
197
|
-
}
|
|
198
|
-
|
|
199
195
|
export function migrate(dbPath, options = {}) {
|
|
200
196
|
const db = new Database(dbPath, options);
|
|
201
197
|
try {
|
|
@@ -207,8 +203,10 @@ export function migrate(dbPath, options = {}) {
|
|
|
207
203
|
|
|
208
204
|
const isMain = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
209
205
|
if (isMain) {
|
|
210
|
-
const dbPath = process.argv[2] ? path.resolve(process.argv[2]) : defaultDbPath();
|
|
211
206
|
try {
|
|
207
|
+
// The given path, else the database in server/data (oar.db, else the
|
|
208
|
+
// name before 0.9.20); never a new one.
|
|
209
|
+
const dbPath = cliDbPath(process.argv[2], new URL('..', import.meta.url));
|
|
212
210
|
const result = migrate(dbPath);
|
|
213
211
|
console.log(`Migration 0026 on ${dbPath}`);
|
|
214
212
|
console.log(result.applied
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
*
|
|
22
22
|
* Additive and idempotent. Safe to run on every boot.
|
|
23
23
|
*
|
|
24
|
-
* Usage: node server/migrations/0027-deepseek-usage-checkpoint-runs.mjs [path/to/
|
|
24
|
+
* Usage: node server/migrations/0027-deepseek-usage-checkpoint-runs.mjs [path/to/oar.db]
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
27
|
import { fileURLToPath } from 'url';
|
|
@@ -30,6 +30,7 @@ import process from 'process';
|
|
|
30
30
|
import Database from 'better-sqlite3';
|
|
31
31
|
|
|
32
32
|
import { DEEPSEEK_USAGE_CHECKPOINTS_TABLE, migrateDeepSeekUsageTotals } from './0024-deepseek-usage-totals.mjs';
|
|
33
|
+
import { cliDbPath } from '../services/database-file.mjs';
|
|
33
34
|
|
|
34
35
|
// Added to deepseek_usage_checkpoints, with their DDL.
|
|
35
36
|
export const DEEPSEEK_USAGE_CHECKPOINT_RUN_COLUMNS = Object.freeze([
|
|
@@ -70,11 +71,6 @@ export function migrateDeepSeekUsageCheckpointRuns(db) {
|
|
|
70
71
|
return { applied: columnsAdded > 0, columnsAdded };
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
function defaultDbPath() {
|
|
74
|
-
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
75
|
-
return path.resolve(here, '..', 'data', 'copilot.db');
|
|
76
|
-
}
|
|
77
|
-
|
|
78
74
|
export function migrate(dbPath, options = {}) {
|
|
79
75
|
const db = new Database(dbPath, options);
|
|
80
76
|
try {
|
|
@@ -86,8 +82,10 @@ export function migrate(dbPath, options = {}) {
|
|
|
86
82
|
|
|
87
83
|
const isMain = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
88
84
|
if (isMain) {
|
|
89
|
-
const dbPath = process.argv[2] ? path.resolve(process.argv[2]) : defaultDbPath();
|
|
90
85
|
try {
|
|
86
|
+
// The given path, else the database in server/data (oar.db, else the
|
|
87
|
+
// name before 0.9.20); never a new one.
|
|
88
|
+
const dbPath = cliDbPath(process.argv[2], new URL('..', import.meta.url));
|
|
91
89
|
const result = migrate(dbPath);
|
|
92
90
|
console.log(`Migration 0027 on ${dbPath}`);
|
|
93
91
|
console.log(result.applied
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*
|
|
21
21
|
* Additive and idempotent. Safe to run on every boot.
|
|
22
22
|
*
|
|
23
|
-
* Usage: node server/migrations/0028-deepseek-usage-checkpoint-request-runs.mjs [path/to/
|
|
23
|
+
* Usage: node server/migrations/0028-deepseek-usage-checkpoint-request-runs.mjs [path/to/oar.db]
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
import { fileURLToPath } from 'url';
|
|
@@ -30,6 +30,7 @@ import Database from 'better-sqlite3';
|
|
|
30
30
|
|
|
31
31
|
import { DEEPSEEK_USAGE_CHECKPOINTS_TABLE } from './0024-deepseek-usage-totals.mjs';
|
|
32
32
|
import { migrateDeepSeekUsageCheckpointRuns } from './0027-deepseek-usage-checkpoint-runs.mjs';
|
|
33
|
+
import { cliDbPath } from '../services/database-file.mjs';
|
|
33
34
|
|
|
34
35
|
// Added to deepseek_usage_checkpoints, with their DDL.
|
|
35
36
|
export const DEEPSEEK_USAGE_CHECKPOINT_REQUEST_RUN_COLUMNS = Object.freeze([
|
|
@@ -68,11 +69,6 @@ export function migrateDeepSeekUsageCheckpointRequestRuns(db) {
|
|
|
68
69
|
return { applied: columnsAdded > 0, columnsAdded };
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
function defaultDbPath() {
|
|
72
|
-
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
73
|
-
return path.resolve(here, '..', 'data', 'copilot.db');
|
|
74
|
-
}
|
|
75
|
-
|
|
76
72
|
export function migrate(dbPath, options = {}) {
|
|
77
73
|
const db = new Database(dbPath, options);
|
|
78
74
|
try {
|
|
@@ -84,8 +80,10 @@ export function migrate(dbPath, options = {}) {
|
|
|
84
80
|
|
|
85
81
|
const isMain = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
86
82
|
if (isMain) {
|
|
87
|
-
const dbPath = process.argv[2] ? path.resolve(process.argv[2]) : defaultDbPath();
|
|
88
83
|
try {
|
|
84
|
+
// The given path, else the database in server/data (oar.db, else the
|
|
85
|
+
// name before 0.9.20); never a new one.
|
|
86
|
+
const dbPath = cliDbPath(process.argv[2], new URL('..', import.meta.url));
|
|
89
87
|
const result = migrate(dbPath);
|
|
90
88
|
console.log(`Migration 0028 on ${dbPath}`);
|
|
91
89
|
console.log(result.applied
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
*
|
|
20
20
|
* Additive and idempotent. Safe to run on every boot.
|
|
21
21
|
*
|
|
22
|
-
* Usage: node server/migrations/0029-deepseek-balance-rises.mjs [path/to/
|
|
22
|
+
* Usage: node server/migrations/0029-deepseek-balance-rises.mjs [path/to/oar.db]
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
import { fileURLToPath } from 'url';
|
|
@@ -28,6 +28,7 @@ import process from 'process';
|
|
|
28
28
|
import Database from 'better-sqlite3';
|
|
29
29
|
|
|
30
30
|
import { DEEPSEEK_BALANCE_REFERENCE_TABLE, migrateDeepSeekUsageRequestsDaily } from './0025-deepseek-usage-requests-daily.mjs';
|
|
31
|
+
import { cliDbPath } from '../services/database-file.mjs';
|
|
31
32
|
|
|
32
33
|
// Added to deepseek_balance_reference, with their DDL.
|
|
33
34
|
export const DEEPSEEK_BALANCE_RISE_COLUMNS = Object.freeze([
|
|
@@ -68,11 +69,6 @@ export function migrateDeepSeekBalanceRises(db) {
|
|
|
68
69
|
return { applied: columnsAdded > 0, columnsAdded };
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
function defaultDbPath() {
|
|
72
|
-
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
73
|
-
return path.resolve(here, '..', 'data', 'copilot.db');
|
|
74
|
-
}
|
|
75
|
-
|
|
76
72
|
export function migrate(dbPath, options = {}) {
|
|
77
73
|
const db = new Database(dbPath, options);
|
|
78
74
|
try {
|
|
@@ -84,8 +80,10 @@ export function migrate(dbPath, options = {}) {
|
|
|
84
80
|
|
|
85
81
|
const isMain = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
86
82
|
if (isMain) {
|
|
87
|
-
const dbPath = process.argv[2] ? path.resolve(process.argv[2]) : defaultDbPath();
|
|
88
83
|
try {
|
|
84
|
+
// The given path, else the database in server/data (oar.db, else the
|
|
85
|
+
// name before 0.9.20); never a new one.
|
|
86
|
+
const dbPath = cliDbPath(process.argv[2], new URL('..', import.meta.url));
|
|
89
87
|
const result = migrate(dbPath);
|
|
90
88
|
console.log(`Migration 0029 on ${dbPath}`);
|
|
91
89
|
console.log(result.applied
|
|
@@ -20,13 +20,14 @@
|
|
|
20
20
|
* The relay's own usage tables are not touched. Additive and idempotent.
|
|
21
21
|
* Safe to run on every boot.
|
|
22
22
|
*
|
|
23
|
-
* Usage: node server/migrations/0030-deepseek-usage-actuals.mjs [path/to/
|
|
23
|
+
* Usage: node server/migrations/0030-deepseek-usage-actuals.mjs [path/to/oar.db]
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
import { fileURLToPath } from 'url';
|
|
27
27
|
import path from 'path';
|
|
28
28
|
import process from 'process';
|
|
29
29
|
import Database from 'better-sqlite3';
|
|
30
|
+
import { cliDbPath } from '../services/database-file.mjs';
|
|
30
31
|
|
|
31
32
|
export const DEEPSEEK_USAGE_ACTUALS_TABLE = 'deepseek_usage_actuals';
|
|
32
33
|
|
|
@@ -92,11 +93,6 @@ export function migrateDeepSeekUsageActuals(db) {
|
|
|
92
93
|
return { applied: !existed, tableCreated: !existed };
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
function defaultDbPath() {
|
|
96
|
-
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
97
|
-
return path.resolve(here, '..', 'data', 'copilot.db');
|
|
98
|
-
}
|
|
99
|
-
|
|
100
96
|
export function migrate(dbPath, options = {}) {
|
|
101
97
|
const db = new Database(dbPath, options);
|
|
102
98
|
try {
|
|
@@ -108,8 +104,10 @@ export function migrate(dbPath, options = {}) {
|
|
|
108
104
|
|
|
109
105
|
const isMain = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
110
106
|
if (isMain) {
|
|
111
|
-
const dbPath = process.argv[2] ? path.resolve(process.argv[2]) : defaultDbPath();
|
|
112
107
|
try {
|
|
108
|
+
// The given path, else the database in server/data (oar.db, else the
|
|
109
|
+
// name before 0.9.20); never a new one.
|
|
110
|
+
const dbPath = cliDbPath(process.argv[2], new URL('..', import.meta.url));
|
|
113
111
|
const result = migrate(dbPath);
|
|
114
112
|
console.log(`Migration 0030 on ${dbPath}`);
|
|
115
113
|
console.log(result.applied
|
|
@@ -28,13 +28,14 @@
|
|
|
28
28
|
*
|
|
29
29
|
* Additive and idempotent. Safe to run on every boot.
|
|
30
30
|
*
|
|
31
|
-
* Usage: node server/migrations/0031-queue-provider.mjs [path/to/
|
|
31
|
+
* Usage: node server/migrations/0031-queue-provider.mjs [path/to/oar.db]
|
|
32
32
|
*/
|
|
33
33
|
|
|
34
34
|
import { fileURLToPath } from 'url';
|
|
35
35
|
import path from 'path';
|
|
36
36
|
import process from 'process';
|
|
37
37
|
import Database from 'better-sqlite3';
|
|
38
|
+
import { cliDbPath } from '../services/database-file.mjs';
|
|
38
39
|
|
|
39
40
|
export const QUEUE_PROVIDER_COLUMN = 'provider';
|
|
40
41
|
export const QUEUE_PROVIDER_TRIGGERS = Object.freeze(['queue_provider_after_insert', 'queue_provider_after_requeue']);
|
|
@@ -112,11 +113,6 @@ export function migrateQueueProvider(db) {
|
|
|
112
113
|
return { applied: columnsAdded > 0 || triggersAdded > 0 || rowsFilled > 0, columnsAdded, triggersAdded, rowsFilled };
|
|
113
114
|
}
|
|
114
115
|
|
|
115
|
-
function defaultDbPath() {
|
|
116
|
-
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
117
|
-
return path.resolve(here, '..', 'data', 'copilot.db');
|
|
118
|
-
}
|
|
119
|
-
|
|
120
116
|
export function migrate(dbPath, options = {}) {
|
|
121
117
|
const db = new Database(dbPath, options);
|
|
122
118
|
try {
|
|
@@ -128,8 +124,10 @@ export function migrate(dbPath, options = {}) {
|
|
|
128
124
|
|
|
129
125
|
const isMain = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
130
126
|
if (isMain) {
|
|
131
|
-
const dbPath = process.argv[2] ? path.resolve(process.argv[2]) : defaultDbPath();
|
|
132
127
|
try {
|
|
128
|
+
// The given path, else the database in server/data (oar.db, else the
|
|
129
|
+
// name before 0.9.20); never a new one.
|
|
130
|
+
const dbPath = cliDbPath(process.argv[2], new URL('..', import.meta.url));
|
|
133
131
|
const result = migrate(dbPath);
|
|
134
132
|
console.log(`Migration 0031 on ${dbPath}`);
|
|
135
133
|
console.log(result.applied
|
|
@@ -18,13 +18,14 @@
|
|
|
18
18
|
*
|
|
19
19
|
* Additive and idempotent. Safe to run on every boot.
|
|
20
20
|
*
|
|
21
|
-
* Usage: node server/migrations/0032-runtime-session-billing-switch.mjs [path/to/
|
|
21
|
+
* Usage: node server/migrations/0032-runtime-session-billing-switch.mjs [path/to/oar.db]
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import { fileURLToPath } from 'url';
|
|
25
25
|
import path from 'path';
|
|
26
26
|
import process from 'process';
|
|
27
27
|
import Database from 'better-sqlite3';
|
|
28
|
+
import { cliDbPath } from '../services/database-file.mjs';
|
|
28
29
|
|
|
29
30
|
// Added to runtime_sessions, with their DDL.
|
|
30
31
|
export const RUNTIME_SESSION_BILLING_SWITCH_COLUMNS = Object.freeze([
|
|
@@ -63,11 +64,6 @@ export function migrateRuntimeSessionBillingSwitch(db) {
|
|
|
63
64
|
return { applied: columnsAdded > 0, columnsAdded };
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
function defaultDbPath() {
|
|
67
|
-
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
68
|
-
return path.resolve(here, '..', 'data', 'copilot.db');
|
|
69
|
-
}
|
|
70
|
-
|
|
71
67
|
export function migrate(dbPath, options = {}) {
|
|
72
68
|
const db = new Database(dbPath, options);
|
|
73
69
|
try {
|
|
@@ -79,8 +75,10 @@ export function migrate(dbPath, options = {}) {
|
|
|
79
75
|
|
|
80
76
|
const isMain = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
81
77
|
if (isMain) {
|
|
82
|
-
const dbPath = process.argv[2] ? path.resolve(process.argv[2]) : defaultDbPath();
|
|
83
78
|
try {
|
|
79
|
+
// The given path, else the database in server/data (oar.db, else the
|
|
80
|
+
// name before 0.9.20); never a new one.
|
|
81
|
+
const dbPath = cliDbPath(process.argv[2], new URL('..', import.meta.url));
|
|
84
82
|
const result = migrate(dbPath);
|
|
85
83
|
console.log(`Migration 0032 on ${dbPath}`);
|
|
86
84
|
console.log(result.applied
|
|
@@ -33,13 +33,14 @@
|
|
|
33
33
|
*
|
|
34
34
|
* Additive and idempotent. Safe to run on every boot.
|
|
35
35
|
*
|
|
36
|
-
* Usage: node server/migrations/0033-claude-api-usage-checkpoints.mjs [path/to/
|
|
36
|
+
* Usage: node server/migrations/0033-claude-api-usage-checkpoints.mjs [path/to/oar.db]
|
|
37
37
|
*/
|
|
38
38
|
|
|
39
39
|
import { fileURLToPath } from 'url';
|
|
40
40
|
import path from 'path';
|
|
41
41
|
import process from 'process';
|
|
42
42
|
import Database from 'better-sqlite3';
|
|
43
|
+
import { cliDbPath } from '../services/database-file.mjs';
|
|
43
44
|
|
|
44
45
|
export const CLAUDE_API_USAGE_CHECKPOINTS_TABLE = 'claude_api_usage_checkpoints';
|
|
45
46
|
|
|
@@ -109,11 +110,6 @@ export function migrateClaudeApiUsageCheckpoints(db) {
|
|
|
109
110
|
return { applied: true, tablesAdded: 1 };
|
|
110
111
|
}
|
|
111
112
|
|
|
112
|
-
function defaultDbPath() {
|
|
113
|
-
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
114
|
-
return path.resolve(here, '..', 'data', 'copilot.db');
|
|
115
|
-
}
|
|
116
|
-
|
|
117
113
|
export function migrate(dbPath, options = {}) {
|
|
118
114
|
const db = new Database(dbPath, options);
|
|
119
115
|
try {
|
|
@@ -125,8 +121,10 @@ export function migrate(dbPath, options = {}) {
|
|
|
125
121
|
|
|
126
122
|
const isMain = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
127
123
|
if (isMain) {
|
|
128
|
-
const dbPath = process.argv[2] ? path.resolve(process.argv[2]) : defaultDbPath();
|
|
129
124
|
try {
|
|
125
|
+
// The given path, else the database in server/data (oar.db, else the
|
|
126
|
+
// name before 0.9.20); never a new one.
|
|
127
|
+
const dbPath = cliDbPath(process.argv[2], new URL('..', import.meta.url));
|
|
130
128
|
const result = migrate(dbPath);
|
|
131
129
|
console.log(`Migration 0033 on ${dbPath}`);
|
|
132
130
|
console.log(result.applied ? ` claude api usage checkpoints: tables added ${result.tablesAdded}` : ' skipped: nothing to change');
|
|
@@ -23,13 +23,14 @@
|
|
|
23
23
|
*
|
|
24
24
|
* Additive and idempotent. Safe to run on every boot.
|
|
25
25
|
*
|
|
26
|
-
* Usage: node server/migrations/0034-claude-api-usage-totals.mjs [path/to/
|
|
26
|
+
* Usage: node server/migrations/0034-claude-api-usage-totals.mjs [path/to/oar.db]
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
29
|
import { fileURLToPath } from 'url';
|
|
30
30
|
import path from 'path';
|
|
31
31
|
import process from 'process';
|
|
32
32
|
import Database from 'better-sqlite3';
|
|
33
|
+
import { cliDbPath } from '../services/database-file.mjs';
|
|
33
34
|
|
|
34
35
|
export const CLAUDE_API_USAGE_TOTALS_TABLE = 'claude_api_usage_totals';
|
|
35
36
|
|
|
@@ -83,11 +84,6 @@ export function migrateClaudeApiUsageTotals(db) {
|
|
|
83
84
|
return { applied: true, tablesAdded: 1 };
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
function defaultDbPath() {
|
|
87
|
-
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
88
|
-
return path.resolve(here, '..', 'data', 'copilot.db');
|
|
89
|
-
}
|
|
90
|
-
|
|
91
87
|
export function migrate(dbPath, options = {}) {
|
|
92
88
|
const db = new Database(dbPath, options);
|
|
93
89
|
try {
|
|
@@ -99,8 +95,10 @@ export function migrate(dbPath, options = {}) {
|
|
|
99
95
|
|
|
100
96
|
const isMain = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
101
97
|
if (isMain) {
|
|
102
|
-
const dbPath = process.argv[2] ? path.resolve(process.argv[2]) : defaultDbPath();
|
|
103
98
|
try {
|
|
99
|
+
// The given path, else the database in server/data (oar.db, else the
|
|
100
|
+
// name before 0.9.20); never a new one.
|
|
101
|
+
const dbPath = cliDbPath(process.argv[2], new URL('..', import.meta.url));
|
|
104
102
|
const result = migrate(dbPath);
|
|
105
103
|
console.log(`Migration 0034 on ${dbPath}`);
|
|
106
104
|
console.log(result.applied ? ` claude api usage totals: tables added ${result.tablesAdded}` : ' skipped: nothing to change');
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Migration: a conversation that is plan-only.
|
|
5
|
+
*
|
|
6
|
+
* `plan_only` is 1 when the session is locked in plan mode: agents cannot
|
|
7
|
+
* switch it to another mode (a relay_tool send or update_session naming one
|
|
8
|
+
* is refused), while the owner still can. NULL or 0 means not plan-only. It
|
|
9
|
+
* is set only when asked: relay_tool create_session or update_session with
|
|
10
|
+
* `planOnly`, or the owner's toggle. Plan mode alone never sets it.
|
|
11
|
+
*
|
|
12
|
+
* Also the index `idx_queue_conversation_status` on queue(conversation_id,
|
|
13
|
+
* status, timestamp), which the queue claim's plan-boundary hold reads.
|
|
14
|
+
*
|
|
15
|
+
* Additive and idempotent. Safe to run on every boot. Rolling back needs no
|
|
16
|
+
* data change: older code ignores the column and the lock with it.
|
|
17
|
+
*
|
|
18
|
+
* Usage: node server/migrations/0035-conversation-plan-only.mjs [path/to/oar.db]
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { fileURLToPath } from 'url';
|
|
22
|
+
import path from 'path';
|
|
23
|
+
import process from 'process';
|
|
24
|
+
import Database from 'better-sqlite3';
|
|
25
|
+
import { cliDbPath } from '../services/database-file.mjs';
|
|
26
|
+
|
|
27
|
+
export const QUEUE_CONVERSATION_STATUS_INDEX = 'idx_queue_conversation_status';
|
|
28
|
+
|
|
29
|
+
function indexExists(db, name) {
|
|
30
|
+
return !!db
|
|
31
|
+
.prepare(`SELECT name FROM sqlite_master WHERE type = 'index' AND name = ?`)
|
|
32
|
+
.get(name);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function tableExists(db, name) {
|
|
36
|
+
return !!db
|
|
37
|
+
.prepare(`SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?`)
|
|
38
|
+
.get(name);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function migrateConversationPlanOnly(db) {
|
|
42
|
+
if (!tableExists(db, 'conversations')) {
|
|
43
|
+
throw new Error('conversations is missing (the base schema has not run)');
|
|
44
|
+
}
|
|
45
|
+
const present = new Set(db.prepare(`PRAGMA table_info(conversations)`).all().map((column) => column.name));
|
|
46
|
+
let columnsAdded = 0;
|
|
47
|
+
if (!present.has('plan_only')) {
|
|
48
|
+
db.exec(`ALTER TABLE conversations ADD COLUMN plan_only INTEGER`);
|
|
49
|
+
columnsAdded = 1;
|
|
50
|
+
}
|
|
51
|
+
// The queue claim's plan-boundary hold looks up one conversation's pending
|
|
52
|
+
// and processing rows in send order (message-repository.mjs,
|
|
53
|
+
// planBoundaryHoldSql); without this index it walked every conversation's.
|
|
54
|
+
let indexesAdded = 0;
|
|
55
|
+
if (tableExists(db, 'queue') && !indexExists(db, QUEUE_CONVERSATION_STATUS_INDEX)) {
|
|
56
|
+
db.exec(`CREATE INDEX IF NOT EXISTS ${QUEUE_CONVERSATION_STATUS_INDEX} ON queue(conversation_id, status, timestamp)`);
|
|
57
|
+
indexesAdded = 1;
|
|
58
|
+
}
|
|
59
|
+
return { applied: columnsAdded + indexesAdded > 0, columnsAdded, indexesAdded };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function migrate(dbPath, options = {}) {
|
|
63
|
+
const db = new Database(dbPath, options);
|
|
64
|
+
try {
|
|
65
|
+
return migrateConversationPlanOnly(db);
|
|
66
|
+
} finally {
|
|
67
|
+
db.close();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const isMain = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
72
|
+
if (isMain) {
|
|
73
|
+
try {
|
|
74
|
+
// The given path, else the database in server/data (oar.db, else the
|
|
75
|
+
// name before 0.9.20); never a new one.
|
|
76
|
+
const dbPath = cliDbPath(process.argv[2], new URL('..', import.meta.url));
|
|
77
|
+
const result = migrate(dbPath);
|
|
78
|
+
console.log(`Migration 0035 on ${dbPath}`);
|
|
79
|
+
console.log(result.applied
|
|
80
|
+
? ` plan only: columns added ${result.columnsAdded}, indexes added ${result.indexesAdded}`
|
|
81
|
+
: ' skipped: nothing to change');
|
|
82
|
+
process.exit(0);
|
|
83
|
+
} catch (err) {
|
|
84
|
+
console.error(`Migration 0035 failed: ${err?.message || err}`);
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
}
|