@oar-sh/oar 0.9.1 → 0.9.3
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 +0 -3
- package/.github/extensions/web-relay/polling/heartbeat.mjs +2 -55
- package/.github/extensions/web-relay/polling/polling-loop.mjs +0 -1
- package/.github/extensions/web-relay/runtime/api-client.mjs +2 -34
- package/.github/extensions/web-relay/runtime/config-loader.mjs +2 -104
- package/.github/extensions/web-relay/runtime/send-and-wait-errors.mjs +2 -170
- package/.github/extensions/web-relay/runtime/session-io.mjs +1 -71
- package/.github/extensions/web-relay/runtime/worker-websocket-link.mjs +2 -325
- package/.github/extensions/web-relay/skills/prompt-context.mjs +2 -160
- package/CHANGELOG.md +269 -0
- package/README.md +407 -424
- package/bin/oar.js +142 -11
- package/package.json +8 -4
- package/server/README.md +59 -22
- package/server/claude-worker/claude-sdk-adapter.mjs +7 -2
- package/server/claude-worker/claude-session-process.mjs +1013 -45
- package/server/claude-worker/claude-session-worker.mjs +54 -9
- package/server/claude-worker/claude-turn-publisher.mjs +110 -19
- package/server/claude-worker/claude-worker-link-wiring.mjs +9 -0
- package/server/copilot-sdk-runtime.mjs +12 -3
- package/server/copilot-worker/copilot-ask-user-tool.mjs +89 -0
- package/server/copilot-worker/copilot-attachments.mjs +35 -2
- package/server/copilot-worker/copilot-continuation-signals.mjs +55 -0
- package/server/copilot-worker/copilot-model-switch.mjs +425 -0
- package/server/copilot-worker/copilot-prompt-context.mjs +20 -8
- package/server/copilot-worker/copilot-question-bridge.mjs +129 -16
- package/server/copilot-worker/copilot-sdk-adapter.mjs +59 -11
- package/server/copilot-worker/copilot-sdk-event-normalizer.mjs +136 -12
- package/server/copilot-worker/copilot-sdk-session-process.mjs +2753 -527
- package/server/copilot-worker/copilot-sdk-session-worker.mjs +94 -25
- package/server/cursor-worker/cursor-session-worker.mjs +5 -5
- package/server/cursor-worker/cursor-turn-runner.mjs +50 -4
- package/server/db-schema.mjs +61 -1
- package/server/features.mjs +155 -41
- package/server/grok-worker/grok-session-worker.mjs +5 -5
- package/server/grok-worker/grok-turn-runner.mjs +45 -4
- package/server/migrations/0004-steer-settle-markers.mjs +119 -0
- package/server/public/app/annotate-core.mjs +181 -0
- package/server/public/app/annotate-editor.js +617 -0
- package/server/public/app/api-client.js +86 -5
- package/server/public/app/ask-user-view.js +102 -13
- package/server/public/app/attachments-view.js +172 -3
- package/server/public/app/background-task-timeout-options.mjs +9 -0
- package/server/public/app/background-tasks-view.mjs +34 -19
- package/server/public/app/bootstrap.js +153 -69
- package/server/public/app/composer-control-state.mjs +52 -34
- package/server/public/app/context-tier-options.mjs +24 -4
- package/server/public/app/conversation-draft-sync.mjs +187 -0
- package/server/public/app/conversation-list-filter.mjs +86 -0
- package/server/public/app/conversation-preferences.mjs +47 -10
- package/server/public/app/conversation-provider-indicator.mjs +8 -0
- package/server/public/app/conversation-view.js +1032 -218
- package/server/public/app/emoji-view.js +2 -0
- package/server/public/app/font-scaling.js +4 -37
- package/server/public/app/journal-view.js +190 -24
- package/server/public/app/model-selector-options.mjs +185 -1
- package/server/public/app/new-conversation-model-choice.mjs +29 -9
- package/server/public/app/pwa-install.js +64 -136
- package/server/public/app/question-multi-select.mjs +52 -0
- package/server/public/app/reasoning-effort-labels.mjs +13 -3
- package/server/public/app/relay-prompt-sanitizer.mjs +26 -3
- package/server/public/app/router.js +120 -11
- package/server/public/app/settings-modal.js +225 -20
- package/server/public/app/settings-tabs.js +1 -1
- package/server/public/app/socket-handlers.js +47 -4
- package/server/public/app/steered-turn-merge.mjs +100 -0
- package/server/public/app/store.js +159 -16
- package/server/public/app/sync-outbox.mjs +16 -8
- package/server/public/app/tool-activity-emoji.mjs +36 -0
- package/server/public/app/transcript-viewport-anchor.mjs +210 -0
- package/server/public/app/update-ui.js +194 -0
- package/server/public/index.html +483 -24
- package/server/public/sw.js +7 -0
- package/server/relay-tools.md +2 -0
- package/server/relay.mjs +23 -21
- package/server/repositories/message-repository.mjs +78 -21
- package/server/repositories/question-repository.mjs +19 -1
- package/server/repositories/session-repository.mjs +7 -31
- package/server/routes/ask-user-routes.mjs +10 -0
- package/server/routes/messages-routes.mjs +689 -159
- package/server/routes/sessions-routes.mjs +574 -80
- package/server/server-runtime.mjs +393 -925
- package/server/services/claude-auth-service.mjs +7 -1
- package/server/services/cli-install-service.mjs +8 -27
- package/server/services/cli-process-runner.mjs +30 -0
- package/server/services/copilot-model-discovery-service.mjs +202 -0
- package/server/services/data-dir-resolution.mjs +47 -0
- package/server/services/grok-auth-service.mjs +9 -1
- package/server/services/live-turn-picker.mjs +47 -0
- package/server/services/model-variant-catalog-service.mjs +1183 -0
- package/server/services/oar-cli-helpers.mjs +6 -2
- package/server/services/relay-prompt-sanitizer.mjs +30 -3
- package/server/services/relay-question-context.mjs +46 -0
- package/server/services/sdk-session-import-service.mjs +144 -16
- package/server/services/sdk-session-sync-service.mjs +84 -27
- package/server/services/session-worker-registry-service.mjs +116 -3
- package/server/services/session-worker-supervisor-service.mjs +7 -1
- package/server/services/session-worker-websocket-service.mjs +119 -24
- package/server/services/status-event-service.mjs +8 -2
- package/server/services/steer-resend.mjs +45 -0
- package/server/services/update-check-service.mjs +220 -0
- package/server/services/update-install-service.mjs +279 -0
- package/server/services/windows-autostart-service.mjs +42 -6
- package/server/services/windows-boot-autostart-service.mjs +487 -0
- package/shared/ask-user-bridge.mjs +37 -5
- package/shared/background-task-timeout.mjs +12 -4
- package/shared/claude-model-catalog.mjs +49 -0
- package/shared/context-window-fallbacks.mjs +1 -0
- package/shared/control-poller.mjs +4 -1
- package/shared/copilot-model-order.mjs +182 -0
- package/shared/media-embed-instructions.mjs +35 -0
- package/shared/model-descriptors.mjs +181 -30
- package/shared/model-id.mjs +6 -0
- package/shared/pwa-app-name.mjs +44 -0
- package/shared/question-multi-select.mjs +16 -0
- package/shared/relay-stop-failure.mjs +15 -0
- package/shared/slash-command-guard.mjs +76 -0
- package/shared/steer-note.mjs +66 -0
- package/shared/steer-settle-failure.mjs +89 -0
- package/shared/steer-settle-markers.mjs +18 -0
- package/shared/update-semver.mjs +50 -0
- package/shared/worker-crash-guard.mjs +40 -14
- package/shared/worker-runtime/api-client.mjs +34 -0
- package/shared/worker-runtime/config-loader.mjs +104 -0
- package/shared/worker-runtime/heartbeat.mjs +109 -0
- package/shared/worker-runtime/prompt-context.mjs +160 -0
- package/shared/worker-runtime/runner-link-wiring.mjs +44 -0
- package/shared/worker-runtime/send-and-wait-errors.mjs +170 -0
- package/shared/worker-runtime/worker-websocket-link.mjs +436 -0
- package/server/claude-worker/claude-session-test-harness.mjs +0 -236
- package/server/claude-worker/fixtures/workflow-run-record.json +0 -1
- package/server/copilot-worker/copilot-sdk-test-harness.mjs +0 -329
- package/server/copilot-worker/fixtures/abort-turn.json +0 -588
- package/server/copilot-worker/fixtures/ask-user-turn.json +0 -1154
- package/server/copilot-worker/fixtures/background-timer-continuation.json +0 -445
- package/server/copilot-worker/fixtures/background-timer-turn.json +0 -497
- package/server/copilot-worker/fixtures/happy-turn.json +0 -566
- package/server/copilot-worker/fixtures/quota-turn.json +0 -647
- package/server/copilot-worker/fixtures/reasoning-turn.json +0 -625
- package/server/copilot-worker/fixtures/resume-turn.json +0 -700
- package/server/copilot-worker/fixtures/subagent-turn.json +0 -1378
- package/server/copilot-worker/fixtures/tool-permission-turn.json +0 -1293
- package/server/routes/messages-routes-test-harness.mjs +0 -111
- package/server/services/fixtures/claude-auth-stub.sh +0 -62
- package/server/services/fixtures/cli-install-stub.sh +0 -75
- package/server/services/fixtures/grok-stub.sh +0 -86
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { getUpdateState, setUpdateState, showTransientRelayNotice } from './store.js';
|
|
2
|
+
import {
|
|
3
|
+
applyUpdate,
|
|
4
|
+
cancelUpdate,
|
|
5
|
+
checkForUpdateNow,
|
|
6
|
+
dismissUpdate,
|
|
7
|
+
loadUpdateState,
|
|
8
|
+
setUpdateAutoCheck,
|
|
9
|
+
} from './api-client.js';
|
|
10
|
+
|
|
11
|
+
// The Updates section of Settings → General. Automatic checking is opt-in
|
|
12
|
+
// (zero telemetry by default), so the toggle drives real network behavior and
|
|
13
|
+
// the copy around it must stay honest. Everything server-provided (versions,
|
|
14
|
+
// notes URLs, npm logs) renders via textContent/setAttribute — never markup.
|
|
15
|
+
|
|
16
|
+
let renderedLogKey = '';
|
|
17
|
+
let actionInFlight = false;
|
|
18
|
+
|
|
19
|
+
function byId(id) {
|
|
20
|
+
return document.getElementById(id);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function setHidden(id, hidden) {
|
|
24
|
+
const element = byId(id);
|
|
25
|
+
if (element) element.hidden = !!hidden;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function renderUpdateSection() {
|
|
29
|
+
const state = getUpdateState();
|
|
30
|
+
const check = state?.check || null;
|
|
31
|
+
const install = state?.install || null;
|
|
32
|
+
const checkKilled = state?.checkKilled === true;
|
|
33
|
+
|
|
34
|
+
const toggle = byId('update-auto-check-toggle');
|
|
35
|
+
if (toggle) {
|
|
36
|
+
toggle.checked = check?.autoCheckEnabled === true;
|
|
37
|
+
toggle.disabled = checkKilled || actionInFlight;
|
|
38
|
+
}
|
|
39
|
+
const checkBtn = byId('update-check-now-btn');
|
|
40
|
+
if (checkBtn) checkBtn.disabled = checkKilled || actionInFlight;
|
|
41
|
+
setHidden('update-check-killed-help', !checkKilled);
|
|
42
|
+
|
|
43
|
+
const lastChecked = byId('update-last-checked');
|
|
44
|
+
if (lastChecked) {
|
|
45
|
+
let text = '';
|
|
46
|
+
if (!checkKilled) {
|
|
47
|
+
text = check?.lastCheckedAt
|
|
48
|
+
? `Last checked ${new Date(check.lastCheckedAt).toLocaleString()}`
|
|
49
|
+
: 'Never checked.';
|
|
50
|
+
if (check?.schemaUnsupported) {
|
|
51
|
+
text += ' The relay could not read the update feed — try updating manually.';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
lastChecked.textContent = text;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const showCard = check?.available === true && (!check.dismissed || check.critical === true);
|
|
58
|
+
setHidden('update-available-card', !showCard);
|
|
59
|
+
if (showCard) {
|
|
60
|
+
const text = byId('update-available-text');
|
|
61
|
+
if (text) {
|
|
62
|
+
text.textContent = `OAR ${check.version} available${check.critical ? ' — critical update' : ''}`;
|
|
63
|
+
}
|
|
64
|
+
const notesLink = byId('update-notes-link');
|
|
65
|
+
if (notesLink) {
|
|
66
|
+
const notesUrl = typeof check.notesUrl === 'string' ? check.notesUrl : '';
|
|
67
|
+
if (notesUrl.startsWith('https://')) {
|
|
68
|
+
notesLink.setAttribute('href', notesUrl);
|
|
69
|
+
notesLink.hidden = false;
|
|
70
|
+
} else {
|
|
71
|
+
notesLink.removeAttribute('href');
|
|
72
|
+
notesLink.hidden = true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const applyBtn = byId('update-apply-btn');
|
|
76
|
+
if (applyBtn) {
|
|
77
|
+
applyBtn.hidden = state?.installMethod !== 'npm-global' || install?.active === true;
|
|
78
|
+
applyBtn.disabled = actionInFlight;
|
|
79
|
+
}
|
|
80
|
+
setHidden('update-git-hint', state?.installMethod !== 'git-checkout');
|
|
81
|
+
const dismissBtn = byId('update-dismiss-btn');
|
|
82
|
+
if (dismissBtn) {
|
|
83
|
+
dismissBtn.hidden = check.critical === true;
|
|
84
|
+
dismissBtn.disabled = actionInFlight;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const installVisible = !!install && install.state !== 'idle';
|
|
89
|
+
setHidden('update-install-status', !installVisible);
|
|
90
|
+
setHidden('update-install-log', !installVisible || !install?.log);
|
|
91
|
+
const cancelBtn = byId('update-cancel-btn');
|
|
92
|
+
if (cancelBtn) {
|
|
93
|
+
cancelBtn.hidden = install?.state !== 'running';
|
|
94
|
+
cancelBtn.disabled = actionInFlight;
|
|
95
|
+
}
|
|
96
|
+
if (installVisible) {
|
|
97
|
+
const status = byId('update-install-status');
|
|
98
|
+
if (status) {
|
|
99
|
+
status.dataset.state = install.state;
|
|
100
|
+
status.textContent = install.state === 'running'
|
|
101
|
+
? `Updating to ${install.targetVersion}…`
|
|
102
|
+
: install.state === 'success'
|
|
103
|
+
? 'npm finished — the relay restarts when the queue is idle.'
|
|
104
|
+
: `Update failed: ${install.error || 'unknown error'}`;
|
|
105
|
+
}
|
|
106
|
+
const logPre = byId('update-install-log-pre');
|
|
107
|
+
const logKey = `${install.startedAt || ''}|${install.logSeq || 0}`;
|
|
108
|
+
if (logPre && logKey !== renderedLogKey) {
|
|
109
|
+
renderedLogKey = logKey;
|
|
110
|
+
logPre.textContent = install.log || '';
|
|
111
|
+
logPre.scrollTop = logPre.scrollHeight;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const outcome = install?.lastOutcome || null;
|
|
116
|
+
setHidden('update-outcome', !outcome);
|
|
117
|
+
if (outcome) {
|
|
118
|
+
const text = byId('update-outcome-text');
|
|
119
|
+
if (text) {
|
|
120
|
+
text.textContent = outcome.status === 'success'
|
|
121
|
+
? `Updated to ${outcome.version}.`
|
|
122
|
+
: `Update to ${outcome.attemptedVersion || outcome.version || 'a new version'} did not apply.`;
|
|
123
|
+
}
|
|
124
|
+
const outcomeLog = byId('update-outcome-log');
|
|
125
|
+
if (outcomeLog) {
|
|
126
|
+
const tail = outcome.status === 'failure' ? String(outcome.logTail || '') : '';
|
|
127
|
+
outcomeLog.textContent = tail;
|
|
128
|
+
outcomeLog.hidden = !tail;
|
|
129
|
+
}
|
|
130
|
+
const dismissBtn = byId('update-outcome-dismiss-btn');
|
|
131
|
+
if (dismissBtn) dismissBtn.disabled = actionInFlight;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export async function refreshUpdateSection() {
|
|
136
|
+
const payload = await loadUpdateState();
|
|
137
|
+
if (payload?.update) setUpdateState(payload.update);
|
|
138
|
+
renderUpdateSection();
|
|
139
|
+
return payload;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async function runUpdateAction(request, failureMessage) {
|
|
143
|
+
if (actionInFlight) return;
|
|
144
|
+
actionInFlight = true;
|
|
145
|
+
renderUpdateSection();
|
|
146
|
+
try {
|
|
147
|
+
const payload = await request();
|
|
148
|
+
if (!payload) {
|
|
149
|
+
showTransientRelayNotice(failureMessage);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (payload.update) setUpdateState(payload.update);
|
|
153
|
+
} finally {
|
|
154
|
+
actionInFlight = false;
|
|
155
|
+
renderUpdateSection();
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export async function updateAutoCheckSetting(enabled) {
|
|
160
|
+
// On failure the final render snaps the checkbox back to the stored state.
|
|
161
|
+
await runUpdateAction(() => setUpdateAutoCheck(enabled === true), 'Failed to save the update-check setting.');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export async function checkForUpdatesNow() {
|
|
165
|
+
// The service swallows network failures by design (the auto-poller must be
|
|
166
|
+
// silent), so an explicit click needs its own feedback: an unchanged
|
|
167
|
+
// check timestamp means the manifest was never reached.
|
|
168
|
+
const before = getUpdateState()?.check?.lastCheckedAt || null;
|
|
169
|
+
await runUpdateAction(() => checkForUpdateNow(), 'Update check failed.');
|
|
170
|
+
const after = getUpdateState()?.check?.lastCheckedAt || null;
|
|
171
|
+
if (after === before) {
|
|
172
|
+
showTransientRelayNotice('Update check failed — the update server could not be reached.');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export async function cancelRunningUpdate() {
|
|
177
|
+
await runUpdateAction(() => cancelUpdate(), 'Failed to cancel the update.');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export async function applyAvailableUpdate() {
|
|
181
|
+
const version = getUpdateState()?.check?.version;
|
|
182
|
+
if (!version) return;
|
|
183
|
+
await runUpdateAction(() => applyUpdate(version), 'Failed to start the update.');
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export async function dismissAvailableUpdate() {
|
|
187
|
+
const version = getUpdateState()?.check?.version;
|
|
188
|
+
if (!version) return;
|
|
189
|
+
await runUpdateAction(() => dismissUpdate({ version }), 'Failed to dismiss the update.');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export async function dismissUpdateOutcome() {
|
|
193
|
+
await runUpdateAction(() => dismissUpdate({ outcome: true }), 'Failed to dismiss.');
|
|
194
|
+
}
|