@oar-sh/oar 0.9.13 → 0.9.15
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/extension.mjs +9 -0
- package/.github/extensions/web-relay/server-lifecycle/managed-server.mjs +15 -1
- package/.github/extensions/web-relay/skills/question-bridge.mjs +4 -1
- package/CHANGELOG.md +396 -0
- package/README.md +12 -12
- package/bin/oar.js +677 -103
- package/package.json +7 -5
- package/server/claude-cloud-worker/claude-cloud-session-process.mjs +10 -4
- package/server/claude-worker/claude-session-process.mjs +39 -13
- package/server/claude-worker/claude-turn-publisher.mjs +20 -1
- package/server/claude-worker/subagent-timeline-recorder.mjs +75 -8
- package/server/copilot-worker/copilot-ask-user-tool.mjs +1 -1
- package/server/copilot-worker/copilot-prompt-context.mjs +3 -1
- package/server/copilot-worker/copilot-question-bridge.mjs +11 -6
- package/server/copilot-worker/copilot-sdk-adapter.mjs +11 -0
- package/server/copilot-worker/copilot-sdk-session-process.mjs +14 -1
- package/server/cursor-worker/cursor-ask-user-tool.mjs +1 -1
- package/server/cursor-worker/cursor-sdk-adapter.mjs +22 -7
- package/server/cursor-worker/cursor-session-worker.mjs +9 -2
- package/server/cursor-worker/cursor-turn-runner.mjs +18 -3
- package/server/grok-worker/grok-sdk-adapter.mjs +14 -0
- package/server/grok-worker/grok-turn-runner.mjs +13 -3
- package/server/public/app/api-client.js +3 -1
- package/server/public/app/ask-user-view.js +29 -4
- package/server/public/app/conversation-provider-indicator.mjs +18 -8
- package/server/public/app/question-answer-rule.mjs +15 -0
- package/server/public/app/question-multi-select.mjs +9 -2
- package/server/public/app/relay-event-view.mjs +5 -1
- package/server/public/app/settings-modal.js +17 -3
- package/server/public/index.html +9 -5
- package/server/relay-exit-codes.mjs +6 -0
- package/server/relay-self-restart.mjs +6 -1
- package/server/relay-tools.md +14 -11
- package/server/repositories/message-repository.mjs +29 -28
- package/server/repositories/subagent-timeline-statements.mjs +2 -0
- package/server/routes/ask-user-routes.mjs +41 -7
- package/server/routes/messages-routes.mjs +65 -10
- package/server/routes/preview-routes.mjs +73 -7
- package/server/routes/sessions-routes.mjs +49 -16
- package/server/server-runtime.mjs +156 -94
- package/server/services/cursor-session-root-service.mjs +70 -6
- package/server/services/data-dir-resolution.mjs +208 -19
- package/server/services/earlier-database-service.mjs +631 -0
- package/server/services/oar-cli-helpers.mjs +18 -5
- package/server/services/oar-state-layout.mjs +107 -0
- package/server/services/oar-state-migration-service.mjs +387 -96
- package/server/services/package-data-rescue-preinstall.mjs +22 -0
- package/server/services/package-data-rescue.mjs +137 -0
- package/server/services/preview-registry-service.mjs +3 -2
- package/server/services/push-dispatch-service.mjs +33 -6
- package/server/services/relay-event-service.mjs +183 -5
- package/server/services/relay-restart-queue.mjs +10 -3
- package/server/services/relay-singleton-guard.mjs +300 -36
- package/server/services/remote-relay-caller-context.mjs +7 -2
- package/server/services/remote-relay-dispatcher.mjs +30 -9
- package/server/services/session-activity-tracker.mjs +52 -15
- package/server/services/session-worker-launch-service.mjs +31 -1
- package/server/services/stale-turn-recovery.mjs +99 -0
- package/server/services/subagent-timeline-service.mjs +4 -1
- package/server/services/windows-autostart-service.mjs +415 -45
- package/server/services/windows-boot-autostart-service.mjs +962 -185
- package/shared/preview-instructions.mjs +17 -12
- package/shared/preview-tool-core.mjs +32 -14
- package/shared/question-answer-rule.mjs +63 -0
- package/shared/relay-events.mjs +54 -4
- package/shared/remote-relay-contract.mjs +20 -10
- package/shared/subagent-timeline.mjs +4 -0
- package/shared/windows-system-tools.mjs +25 -0
- package/shared/worker-runtime/config-loader.mjs +54 -8
- package/shared/worker-runtime/prompt-context.mjs +3 -1
- package/shared/worker-runtime/working-directory.mjs +65 -0
- package/.github/extensions/web-relay/README.md +0 -190
- package/server/README.md +0 -2187
- package/server/uploads/image_input.md +0 -540
|
@@ -66,7 +66,7 @@ export function describeRelayAddress({ config, lanAddress = null, wslNat = false
|
|
|
66
66
|
return { url, lines, qrUrl, tunnelUrl };
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
const VALUE_OPTIONS = ['--port', '--migrate-from', '--to'];
|
|
69
|
+
const VALUE_OPTIONS = ['--port', '--migrate-from', '--to', '--autostart'];
|
|
70
70
|
const LAUNCHER_FLAGS = ['--install-extension', '--no-install-extension', '--migrate-from'];
|
|
71
71
|
const COMMAND_OPTIONS = { '--setup': 'setup', '--start': 'start', '--stop': 'stop', '--status': 'status' };
|
|
72
72
|
const CLI_COMMANDS = {
|
|
@@ -79,8 +79,10 @@ const CLI_COMMANDS = {
|
|
|
79
79
|
doctor: {},
|
|
80
80
|
help: {},
|
|
81
81
|
version: {},
|
|
82
|
-
setup: { flags: ['--lan', '--local', '--new-token', '--defaults', '--start'], values: ['--port', '--migrate-from'] },
|
|
82
|
+
setup: { flags: ['--lan', '--local', '--new-token', '--defaults', '--start'], values: ['--port', '--migrate-from', '--autostart'] },
|
|
83
83
|
service: { words: ['install', 'remove', 'status'] },
|
|
84
|
+
autostart: { words: ['signin', 'boot', 'off', 'status'], flags: ['--replace'] },
|
|
85
|
+
uninstall: { flags: ['--purge'] },
|
|
84
86
|
update: { flags: ['--beta'], values: ['--to'] },
|
|
85
87
|
copilot: { flags: ['--install-extension', '--no-install-extension'], values: ['--port', '--migrate-from'], forwards: true },
|
|
86
88
|
};
|
|
@@ -95,10 +97,16 @@ export function usageText() {
|
|
|
95
97
|
' oar restart Restart the relay (waits for running turns)',
|
|
96
98
|
' oar status Is the relay running, on which port, as a service',
|
|
97
99
|
' oar url Relay URL, with a QR code when a phone can reach it',
|
|
98
|
-
' oar setup Auth token, access and
|
|
99
|
-
' [--port <port>] [--lan | --local] [--new-token] [--
|
|
100
|
+
' oar setup Auth token, access, port and autostart; asks, or takes',
|
|
101
|
+
' [--port <port>] [--lan | --local] [--new-token] [--autostart signin|boot|off]',
|
|
102
|
+
' [--defaults] [--start]',
|
|
103
|
+
' oar autostart signin | boot | off | status [--replace]',
|
|
104
|
+
' Start the relay at sign-in or at boot (Windows: boot asks for an admin once);',
|
|
105
|
+
' --replace replaces hand-made entries, keeping a copy',
|
|
100
106
|
' oar service install | remove | status',
|
|
101
107
|
' Start the relay at login',
|
|
108
|
+
' oar uninstall [--purge]',
|
|
109
|
+
' Remove autostart and the package; the data stays (--purge deletes it)',
|
|
102
110
|
' oar copilot [--port <port>] [--install-extension] [--no-install-extension] [-- gh copilot args...]',
|
|
103
111
|
' Relay plus a Copilot terminal session',
|
|
104
112
|
' oar doctor Check the install and the provider CLIs',
|
|
@@ -194,6 +202,9 @@ export function buildSystemdUnit({ nodeBin, packageRoot, configPath, dataDir, lo
|
|
|
194
202
|
// an install with a private Node, `node` and `npm` themselves.
|
|
195
203
|
...(pathEnv ? [`Environment="PATH=${escapeSystemdValue(pathEnv)}"`] : []),
|
|
196
204
|
'Restart=on-failure',
|
|
205
|
+
// 78 (RELAY_STOP_EXIT_CODE): the relay stopped on purpose, its database
|
|
206
|
+
// or data folder needs a decision; restarting it cannot help.
|
|
207
|
+
'RestartPreventExitStatus=78',
|
|
197
208
|
'RestartSec=5',
|
|
198
209
|
'',
|
|
199
210
|
'[Install]',
|
|
@@ -231,7 +242,9 @@ export function buildServicePath({ nodeBin, envPath = '', homeDir = '' } = {}) {
|
|
|
231
242
|
* accept the flag and run the scripts as before. `npm-install-scripts.test.mjs`
|
|
232
243
|
* holds this list to the lockfile.
|
|
233
244
|
*/
|
|
234
|
-
|
|
245
|
+
// @oar-sh/oar itself: its preinstall copies the data an earlier version
|
|
246
|
+
// kept inside the package before npm deletes it (package-data-rescue.mjs).
|
|
247
|
+
export const NPM_INSTALL_SCRIPT_PACKAGES = Object.freeze(['@oar-sh/oar', 'better-sqlite3', 'koffi']);
|
|
235
248
|
export const NPM_ALLOW_SCRIPTS_ARG = `--allow-scripts=${NPM_INSTALL_SCRIPT_PACKAGES.join(',')}`;
|
|
236
249
|
|
|
237
250
|
/**
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
import { resolveOarRoot } from './oar-state-migration-service.mjs';
|
|
6
|
+
|
|
7
|
+
// Pre-OAR managed config location — kept only as a migration source and as the
|
|
8
|
+
// config home for git checkouts, where nothing may change underfoot.
|
|
9
|
+
export function getLegacyManagedConfigDir(env = process.env, { platform = process.platform, pathImpl = path } = {}) {
|
|
10
|
+
if (platform === 'win32') {
|
|
11
|
+
return pathImpl.join(
|
|
12
|
+
env.LOCALAPPDATA || pathImpl.join(os.homedir(), 'AppData', 'Local'),
|
|
13
|
+
'copilot-remote',
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
return pathImpl.join(
|
|
17
|
+
env.XDG_CONFIG_HOME || pathImpl.join(os.homedir(), '.config'),
|
|
18
|
+
'copilot-remote',
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function isGitCheckout(packageRoot, { fsImpl = fs, pathImpl = path } = {}) {
|
|
23
|
+
try { return fsImpl.existsSync(pathImpl.join(packageRoot, '.git')); } catch { return false; }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Where launcher-managed state lives. A git checkout keeps every pre-OAR
|
|
28
|
+
* default (repo-local server/data, legacy managed config) so development and
|
|
29
|
+
* the two existing machines change nothing. A global install gets the OAR
|
|
30
|
+
* state root: config, data, logs all under ~/.oar (APPDATA\oar on Windows),
|
|
31
|
+
* which survives `npm i -g` updates.
|
|
32
|
+
*/
|
|
33
|
+
export function resolveStateLayout({
|
|
34
|
+
packageRoot,
|
|
35
|
+
env = process.env,
|
|
36
|
+
platform = process.platform,
|
|
37
|
+
fsImpl = fs,
|
|
38
|
+
pathImpl = path,
|
|
39
|
+
} = {}) {
|
|
40
|
+
if (isGitCheckout(packageRoot, { fsImpl, pathImpl })) {
|
|
41
|
+
return { checkout: true, root: null, configDir: getLegacyManagedConfigDir(env, { platform, pathImpl }), dataDir: null };
|
|
42
|
+
}
|
|
43
|
+
const root = resolveOarRoot(env, platform);
|
|
44
|
+
return { checkout: false, root, configDir: root, dataDir: pathImpl.join(root, 'data') };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The data and log folders a relay of this install is started with, '' where
|
|
49
|
+
* the relay is left to its own server-relative default. Every launcher pins
|
|
50
|
+
* these — `oar start`, `oar copilot` and both Windows autostart launchers —
|
|
51
|
+
* so the relay finds the same database however it was started. A folder the
|
|
52
|
+
* environment names wins; a global install otherwise uses the OAR state root;
|
|
53
|
+
* a checkout pins nothing of its own.
|
|
54
|
+
*/
|
|
55
|
+
export function resolveRelayStateDirs({
|
|
56
|
+
packageRoot,
|
|
57
|
+
env = process.env,
|
|
58
|
+
platform = process.platform,
|
|
59
|
+
fsImpl = fs,
|
|
60
|
+
pathImpl = path,
|
|
61
|
+
layout = resolveStateLayout({ packageRoot, env, platform, fsImpl, pathImpl }),
|
|
62
|
+
} = {}) {
|
|
63
|
+
const envDataDir = String(env?.COPILOT_WEB_RELAY_DATA_DIR || '').trim();
|
|
64
|
+
const envLogDir = String(env?.COPILOT_WEB_RELAY_LOG_DIR || '').trim();
|
|
65
|
+
return {
|
|
66
|
+
dataDir: envDataDir || layout?.dataDir || '',
|
|
67
|
+
logDir: envLogDir || (layout && !layout.checkout ? pathImpl.join(layout.root, 'logs') : ''),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The data and log folders an automatic launcher repair may pin: those of the
|
|
73
|
+
* install's layout alone, never ones only this relay's environment names (a
|
|
74
|
+
* short-lived relay started with a scratch data folder must not repoint the
|
|
75
|
+
* install's autostart). Null when the layout has none (a checkout), or when
|
|
76
|
+
* this relay runs on other folders than the layout's.
|
|
77
|
+
*/
|
|
78
|
+
export function resolveLayoutStateDirs({
|
|
79
|
+
packageRoot,
|
|
80
|
+
env = process.env,
|
|
81
|
+
platform = process.platform,
|
|
82
|
+
fsImpl = fs,
|
|
83
|
+
pathImpl = path,
|
|
84
|
+
} = {}) {
|
|
85
|
+
const layout = resolveStateLayout({ packageRoot, env, platform, fsImpl, pathImpl });
|
|
86
|
+
const dirs = resolveRelayStateDirs({ env: {}, layout, platform, pathImpl });
|
|
87
|
+
if (!dirs.dataDir || !dirs.logDir) return null;
|
|
88
|
+
const own = resolveRelayStateDirs({ env, layout, platform, pathImpl });
|
|
89
|
+
const same = (a, b) => {
|
|
90
|
+
const normalize = (value) => {
|
|
91
|
+
const resolved = pathImpl.resolve(String(value));
|
|
92
|
+
return platform === 'win32' ? resolved.toLowerCase() : resolved;
|
|
93
|
+
};
|
|
94
|
+
return normalize(a) === normalize(b);
|
|
95
|
+
};
|
|
96
|
+
return same(dirs.dataDir, own.dataDir) && same(dirs.logDir, own.logDir) ? dirs : null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* The log folder `oar copilot` and `oar start` give the relay (and write its
|
|
101
|
+
* output to): the relay's log folder, else, in a checkout, `logs` in the
|
|
102
|
+
* legacy managed config folder.
|
|
103
|
+
*/
|
|
104
|
+
export function getLauncherLogDir(env = process.env, layout = null, { platform = process.platform, pathImpl = path } = {}) {
|
|
105
|
+
return resolveRelayStateDirs({ env, layout, platform, pathImpl }).logDir
|
|
106
|
+
|| pathImpl.join(getLegacyManagedConfigDir(env, { platform, pathImpl }), 'logs');
|
|
107
|
+
}
|