@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.
Files changed (74) hide show
  1. package/.github/extensions/web-relay/extension.mjs +9 -0
  2. package/.github/extensions/web-relay/server-lifecycle/managed-server.mjs +15 -1
  3. package/.github/extensions/web-relay/skills/question-bridge.mjs +4 -1
  4. package/CHANGELOG.md +396 -0
  5. package/README.md +12 -12
  6. package/bin/oar.js +677 -103
  7. package/package.json +7 -5
  8. package/server/claude-cloud-worker/claude-cloud-session-process.mjs +10 -4
  9. package/server/claude-worker/claude-session-process.mjs +39 -13
  10. package/server/claude-worker/claude-turn-publisher.mjs +20 -1
  11. package/server/claude-worker/subagent-timeline-recorder.mjs +75 -8
  12. package/server/copilot-worker/copilot-ask-user-tool.mjs +1 -1
  13. package/server/copilot-worker/copilot-prompt-context.mjs +3 -1
  14. package/server/copilot-worker/copilot-question-bridge.mjs +11 -6
  15. package/server/copilot-worker/copilot-sdk-adapter.mjs +11 -0
  16. package/server/copilot-worker/copilot-sdk-session-process.mjs +14 -1
  17. package/server/cursor-worker/cursor-ask-user-tool.mjs +1 -1
  18. package/server/cursor-worker/cursor-sdk-adapter.mjs +22 -7
  19. package/server/cursor-worker/cursor-session-worker.mjs +9 -2
  20. package/server/cursor-worker/cursor-turn-runner.mjs +18 -3
  21. package/server/grok-worker/grok-sdk-adapter.mjs +14 -0
  22. package/server/grok-worker/grok-turn-runner.mjs +13 -3
  23. package/server/public/app/api-client.js +3 -1
  24. package/server/public/app/ask-user-view.js +29 -4
  25. package/server/public/app/conversation-provider-indicator.mjs +18 -8
  26. package/server/public/app/question-answer-rule.mjs +15 -0
  27. package/server/public/app/question-multi-select.mjs +9 -2
  28. package/server/public/app/relay-event-view.mjs +5 -1
  29. package/server/public/app/settings-modal.js +17 -3
  30. package/server/public/index.html +9 -5
  31. package/server/relay-exit-codes.mjs +6 -0
  32. package/server/relay-self-restart.mjs +6 -1
  33. package/server/relay-tools.md +14 -11
  34. package/server/repositories/message-repository.mjs +29 -28
  35. package/server/repositories/subagent-timeline-statements.mjs +2 -0
  36. package/server/routes/ask-user-routes.mjs +41 -7
  37. package/server/routes/messages-routes.mjs +65 -10
  38. package/server/routes/preview-routes.mjs +73 -7
  39. package/server/routes/sessions-routes.mjs +49 -16
  40. package/server/server-runtime.mjs +156 -94
  41. package/server/services/cursor-session-root-service.mjs +70 -6
  42. package/server/services/data-dir-resolution.mjs +208 -19
  43. package/server/services/earlier-database-service.mjs +631 -0
  44. package/server/services/oar-cli-helpers.mjs +18 -5
  45. package/server/services/oar-state-layout.mjs +107 -0
  46. package/server/services/oar-state-migration-service.mjs +387 -96
  47. package/server/services/package-data-rescue-preinstall.mjs +22 -0
  48. package/server/services/package-data-rescue.mjs +137 -0
  49. package/server/services/preview-registry-service.mjs +3 -2
  50. package/server/services/push-dispatch-service.mjs +33 -6
  51. package/server/services/relay-event-service.mjs +183 -5
  52. package/server/services/relay-restart-queue.mjs +10 -3
  53. package/server/services/relay-singleton-guard.mjs +300 -36
  54. package/server/services/remote-relay-caller-context.mjs +7 -2
  55. package/server/services/remote-relay-dispatcher.mjs +30 -9
  56. package/server/services/session-activity-tracker.mjs +52 -15
  57. package/server/services/session-worker-launch-service.mjs +31 -1
  58. package/server/services/stale-turn-recovery.mjs +99 -0
  59. package/server/services/subagent-timeline-service.mjs +4 -1
  60. package/server/services/windows-autostart-service.mjs +415 -45
  61. package/server/services/windows-boot-autostart-service.mjs +962 -185
  62. package/shared/preview-instructions.mjs +17 -12
  63. package/shared/preview-tool-core.mjs +32 -14
  64. package/shared/question-answer-rule.mjs +63 -0
  65. package/shared/relay-events.mjs +54 -4
  66. package/shared/remote-relay-contract.mjs +20 -10
  67. package/shared/subagent-timeline.mjs +4 -0
  68. package/shared/windows-system-tools.mjs +25 -0
  69. package/shared/worker-runtime/config-loader.mjs +54 -8
  70. package/shared/worker-runtime/prompt-context.mjs +3 -1
  71. package/shared/worker-runtime/working-directory.mjs +65 -0
  72. package/.github/extensions/web-relay/README.md +0 -190
  73. package/server/README.md +0 -2187
  74. package/server/uploads/image_input.md +0 -540
@@ -1,190 +0,0 @@
1
- # Web Relay Extension
2
-
3
- The Copilot CLI extension that bridges local CLI sessions with the web relay server. This extension runs as a background agent in the CLI, polls the relay for pending turns, executes them, and streams activity back to the browser UI.
4
-
5
- > Scope: this extension serves the **GitHub Copilot** and **OpenAI (BYOK)** providers. Claude
6
- > conversations do not go through it — they run `server/claude-worker/claude-session-worker.mjs`,
7
- > a standalone Node worker that implements the same relay contracts. See `server/README.md`.
8
-
9
- ## Architecture Overview
10
-
11
- ```
12
- [Browser UI] <--WebSocket--> [server.js :3333] <--HTTP polling--> [CLI Extension]
13
- |
14
- [Session Workers]
15
- ```
16
-
17
- - **`extension.mjs`** — Entry point; registers tools, initializes polling loop, manages extension lifecycle.
18
- - **`polling/polling-loop.mjs`** — Main polling interval; fetches pending turns, executes via session workers, streams updates.
19
- - **`runtime/worker-websocket-link.mjs`** — WebSocket bridge; handles turn execution, tool calls, activity streaming.
20
- - **`skills/`** — Tool implementations: question routing, tool activity, tmux input bridge, reasoning streams.
21
- - **`utils/`** — Helpers: tmux input bridge, prompts, configuration.
22
- - **`server-lifecycle/`** — Manages relay server startup (extension-managed mode).
23
-
24
- ## Key Components
25
-
26
- ### Extension Entry Point (`extension.mjs`)
27
-
28
- - Registers extension tools and skill handlers
29
- - Starts the relay server if needed (extension-managed mode)
30
- - Initializes polling loop on first `gh copilot` invocation
31
- - Handles relay shutdown and restart requests
32
-
33
- ### Polling Loop (`polling/polling-loop.mjs`)
34
-
35
- - Runs continuously every `pollIntervalMs` (default 3000ms)
36
- - Fetches `/api/pending` to get next turn from the relay queue
37
- - Spawns or reuses session workers to execute turns
38
- - Streams tool/activity updates back to `/api/messages/{id}/events`
39
- - Handles worker failures and retries
40
- - Routes answers to `/api/ask-user` when agent needs user input
41
-
42
- ### Worker WebSocket Link (`runtime/worker-websocket-link.mjs`)
43
-
44
- - Opens WebSocket connection to `localhost:3333/ws/worker/{sdkSessionId}`
45
- - Bridges turn execution between the relay and the CLI session
46
- - Handles streaming of:
47
- - User messages sent to the agent
48
- - Tool invocation events
49
- - Streaming text output
50
- - Model/reasoning choices
51
- - Completion events
52
-
53
- ### Question Routing (`skills/question-routing-hooks.mjs`)
54
-
55
- - Intercepts `onElicitationRequest` and `onUserInputRequest` from the CLI session
56
- - Uses structured elicitation (`requestedSchema`) as the canonical ask-user flow
57
- - For structured answers:
58
- - Extracts `requestSchema` (JSON schema)
59
- - Registers question in relay database
60
- - Waits for browser to render form and user to submit
61
- - Retrieves `structuredAnswer` and returns `ElicitationResponse`
62
-
63
- ### Tool Activity (`skills/tool-activity.mjs`)
64
-
65
- - Hooks Copilot SDK tool invocations
66
- - Streams tool call details (name, arguments, status) to the relay
67
- - Relays tool results back to the browser UI for real-time activity display
68
- - Web Search and Web Fetch activity includes bounded query/URL details and output previews
69
- - `store_memory` activity includes the available `subject`, `fact`, `citations`, `reason`, and `scope` metadata with preserved field content and line breaks
70
- - `vote_memory` activity includes the available `fact`, `direction`, `reason`, and `scope` metadata with preserved field content and line breaks
71
- - Activity is persisted by the relay and is therefore available to authorized shared viewers and replayed history
72
-
73
- ### Subagent attribution
74
-
75
- The SDK `agentId` on a request is propagated as `subagentRunId` on question activity, tool-result
76
- activity, and `report_intent` thoughts. Without it, work done by a subagent would be rendered in the
77
- parent turn's bubble instead of the subagent's own. `skills/subagent-lifecycle.mjs` also preserves an
78
- already-known run's parent and display name when the run is re-discovered (for example on its next
79
- tool call), so a nested subagent is never demoted to a root or renamed mid-turn.
80
-
81
- ### Reasoning Stream (`skills/reasoning-stream.mjs`)
82
-
83
- - (Planned) Optional feature to stream extended reasoning/thinking from models
84
- - Can be toggled behind a feature flag
85
-
86
- ## Configuration
87
-
88
- The extension loads configuration from:
89
-
90
- 1. `server/config.json` (default settings)
91
- 2. Environment variables (e.g., `COPILOT_REMOTE_POLLING_INTERVAL`)
92
- 3. Relay API responses (feature flags, runtime config)
93
-
94
- Key config keys read by the extension:
95
-
96
- - `pollIntervalMs` — How often to fetch pending turns (ms)
97
- - `processingTimeoutMs` — Max turn execution time (ms)
98
- - `workerRestartIntervalMs` — Backoff between worker restarts on failure (ms)
99
- - Feature flags: `SESSION_WORKER_ROUTING_ENABLED`, `SESSION_WORKER_CONTINUATION_ROUTING_ENABLED`
100
-
101
- ## Session Worker Lifecycle
102
-
103
- 1. **Create** — New session worker spawned by polling loop on first turn for an `sdkSessionId`
104
- 2. **Connect** — Worker opens WebSocket link to relay and registers with `/api/workers`
105
- 3. **Execute** — Worker receives turns, executes via CLI session, streams activity
106
- 4. **Heartbeat** — Worker periodically sends keep-alive to indicate it's ready
107
- 5. **Degraded** — If heartbeat fails, relay marks worker as "degraded"; polling loop may restart it
108
- 6. **Restart** — If worker process exits unexpectedly or is in a bad state, polling loop spawns a replacement
109
-
110
- ## Startup Behavior
111
-
112
- ### Extension-Managed Mode (Default)
113
-
114
- - Extension detects if relay is running: `GET /api/status` health check
115
- - If relay is down, extension starts `server.js` via `npm start` from the relay repo root
116
- - Extension owns the relay lifecycle and keeps it running as long as CLI is active
117
- - Polling loop keeps running even between user turns
118
- - On exit, extension gracefully shuts down relay
119
-
120
- ### Standalone Mode
121
-
122
- - User manually runs `npm start` or `npm run copilot:relay` from relay repo
123
- - CLI extension still runs polling loop, but doesn't supervise the relay
124
- - Relay stays running after CLI exits (server continues listening on port 3333)
125
-
126
- **Single-Owner Rule:** Never run both modes simultaneously; it will cause port conflicts and undefined behavior.
127
-
128
- ## Browser-to-Extension Communication
129
-
130
- ### WebSocket Message Flow
131
-
132
- 1. Browser sends message: `POST /api/messages` (queues with relay)
133
- 2. Extension polls: `GET /api/pending` (fetches from queue)
134
- 3. Extension opens WebSocket: `ws://localhost:3333/ws/worker/{sdkSessionId}`
135
- 4. Browser listens: `GET /api/messages/{id}/events` (Server-Sent Events stream)
136
- 5. Worker streams: Tool invocations, text chunks, activity updates
137
- 6. Browser renders: Real-time chat, tool activity, streaming text
138
-
139
- ### Question Flow
140
-
141
- 1. Agent/tool calls `onElicitationRequest(schema)` or `onUserInputRequest()`
142
- 2. Question routing skill detects and registers in relay
143
- 3. Browser fetches: `GET /api/ask-user` (gets pending questions)
144
- 4. Browser renders: Form or text input based on schema type
145
- 5. User submits: `POST /api/ask-user` with answer
146
- 6. Extension retrieves: `GET /api/pending` (gets question + answer)
147
- 7. Extension returns: `ElicitationResponse` to agent
148
-
149
- ## Testing
150
-
151
- Test files located in:
152
- - `runtime/worker-websocket-link.test.mjs` — WebSocket bridge tests
153
- - `skills/*.test.mjs` — Skill handler tests
154
-
155
- Run them with the Node test runner (there is no `npm test` script). Match `*.test.mjs` explicitly —
156
- pointing the runner at a directory makes it try to execute the implementation modules too:
157
- ```bash
158
- node --test .github/extensions/web-relay/skills/*.test.mjs
159
- ```
160
-
161
- ## Troubleshooting
162
-
163
- ### Relay won't start
164
- - Check `npm install` has been run
165
- - Verify Node.js 24+ is in PATH
166
- - Check port 3333 is available (or use `"port"` in config)
167
- - See extension logs: `server/logs/ext-debug.log`
168
-
169
- ### Polling loop not running
170
- - Check extension is loaded: `gh extension list | grep web-relay`
171
- - Check relay is healthy: `curl http://localhost:3333/api/status`
172
- - Check CLI session is connected: Check browser sidebar for "Online" status
173
-
174
- ### Worker keeps restarting
175
- - Check worker process logs: `server/logs/` directory
176
- - Increase `processingTimeoutMs` if turns are timing out
177
- - Check Copilot SDK issues: `gh copilot` errors in terminal
178
-
179
- ### Structured answers not appearing
180
- - Check browser console for rendering errors
181
- - Verify `request_schema` is valid JSON: Relay logs may show schema parse errors
182
- - Check migration was applied: `server/data/copilot.db` should have `relay_questions.structured_answer` column
183
-
184
- ## Contributing
185
-
186
- When modifying the extension:
187
- - Keep polling loop responsive: avoid long synchronous operations
188
- - Don't block WebSocket handling: stream events instead of buffering large responses
189
- - Test with both macOS/Linux (tmux paths) and Windows (TTY-Console)
190
- - Update test files alongside feature changes