@oar-sh/oar 0.9.5 → 0.9.7

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 (119) hide show
  1. package/.github/extensions/web-relay/polling/polling-loop.mjs +12 -32
  2. package/.github/extensions/web-relay/skills/question-bridge.mjs +14 -39
  3. package/CHANGELOG.md +340 -0
  4. package/README.md +196 -26
  5. package/package.json +2 -1
  6. package/server/README.md +174 -7
  7. package/server/claude-cloud-worker/claude-cloud-event-normalizer.mjs +340 -0
  8. package/server/claude-cloud-worker/claude-cloud-session-process.mjs +1325 -0
  9. package/server/claude-cloud-worker/claude-cloud-session-worker.mjs +155 -0
  10. package/server/claude-worker/claude-remote-relay-tool.mjs +2 -0
  11. package/server/claude-worker/claude-sdk-adapter.mjs +18 -2
  12. package/server/claude-worker/claude-session-process.mjs +151 -1
  13. package/server/claude-worker/claude-session-worker.mjs +6 -0
  14. package/server/claude-worker/claude-turn-failure.mjs +92 -0
  15. package/server/claude-worker/claude-turn-publisher.mjs +52 -3
  16. package/server/claude-worker/sdk-message-normalizer.mjs +13 -1
  17. package/server/copilot-worker/copilot-model-switch.mjs +29 -3
  18. package/server/copilot-worker/copilot-question-bridge.mjs +2 -4
  19. package/server/copilot-worker/copilot-runtime-tree.mjs +91 -0
  20. package/server/copilot-worker/copilot-sdk-adapter.mjs +48 -8
  21. package/server/copilot-worker/copilot-sdk-session-process.mjs +897 -166
  22. package/server/cursor-worker/cursor-sdk-adapter.mjs +80 -13
  23. package/server/cursor-worker/cursor-turn-runner.mjs +5 -2
  24. package/server/db-schema.mjs +24 -0
  25. package/server/grok-worker/acp-client.mjs +68 -12
  26. package/server/grok-worker/grok-sdk-adapter.mjs +4 -0
  27. package/server/grok-worker/grok-turn-runner.mjs +6 -2
  28. package/server/migrations/0006-workspace-root-settings.mjs +67 -0
  29. package/server/migrations/0007-claude-cloud.mjs +82 -0
  30. package/server/public/app/agent-sessions-settings-ui.js +197 -0
  31. package/server/public/app/agent-sessions-settings.mjs +134 -0
  32. package/server/public/app/api-client.js +160 -6
  33. package/server/public/app/attachments-view.js +20 -1
  34. package/server/public/app/attribution-control.mjs +46 -0
  35. package/server/public/app/bootstrap.js +347 -31
  36. package/server/public/app/claude-cloud-conversation-ui.js +110 -0
  37. package/server/public/app/claude-cloud-settings-ui.js +374 -0
  38. package/server/public/app/claude-cloud-ui.mjs +611 -0
  39. package/server/public/app/composer-control-state.mjs +15 -3
  40. package/server/public/app/context-menu.mjs +140 -0
  41. package/server/public/app/context-tier-options.mjs +4 -0
  42. package/server/public/app/conversation-origin-ui.js +27 -0
  43. package/server/public/app/conversation-provider-indicator.mjs +22 -4
  44. package/server/public/app/conversation-view.js +178 -8
  45. package/server/public/app/cwd-picker.js +12 -0
  46. package/server/public/app/journal-view.js +704 -28
  47. package/server/public/app/markdown-strikethrough.mjs +31 -0
  48. package/server/public/app/math-dollars.mjs +89 -0
  49. package/server/public/app/model-selector-options.mjs +1 -1
  50. package/server/public/app/plan-usage-view.mjs +36 -8
  51. package/server/public/app/relay-board-inline.mjs +70 -0
  52. package/server/public/app/relay-board-view.js +157 -61
  53. package/server/public/app/relay-error-ctas.mjs +28 -5
  54. package/server/public/app/remote-relay-origin-view.mjs +120 -4
  55. package/server/public/app/router.js +49 -12
  56. package/server/public/app/settings-modal.js +33 -2
  57. package/server/public/app/settings-tabs.js +1 -1
  58. package/server/public/app/socket-handlers.js +60 -0
  59. package/server/public/app/store.js +4 -1
  60. package/server/public/app/subagent-fold.mjs +61 -0
  61. package/server/public/app/usage-limit-ui.js +225 -0
  62. package/server/public/index.html +471 -8
  63. package/server/relay-tools.md +13 -1
  64. package/server/repositories/message-repository.mjs +10 -1
  65. package/server/repositories/question-repository.mjs +1 -0
  66. package/server/repositories/remote-relay-repository.mjs +72 -1
  67. package/server/repositories/session-repository.mjs +47 -1
  68. package/server/routes/claude-cloud-routes.mjs +140 -0
  69. package/server/routes/git-routes.mjs +37 -0
  70. package/server/routes/messages-routes.mjs +202 -26
  71. package/server/routes/relay-board-routes.mjs +56 -2
  72. package/server/routes/remote-relay-routes.mjs +15 -1
  73. package/server/routes/sessions-routes.mjs +538 -72
  74. package/server/server-runtime.mjs +291 -27
  75. package/server/services/claude-account-usage-service.mjs +176 -0
  76. package/server/services/claude-cloud-repo-service.mjs +408 -0
  77. package/server/services/claude-cloud-session-service.mjs +326 -0
  78. package/server/services/claude-cloud-settings-service.mjs +269 -0
  79. package/server/services/git-remote-service.mjs +115 -0
  80. package/server/services/plan-usage-claude-cloud.mjs +211 -0
  81. package/server/services/plan-usage-claude.mjs +202 -40
  82. package/server/services/plan-usage-contract.mjs +39 -3
  83. package/server/services/plan-usage-service.mjs +82 -2
  84. package/server/services/preview-proxy-server.mjs +64 -36
  85. package/server/services/process-list-service.mjs +122 -0
  86. package/server/services/provider-reasoning-effort.mjs +3 -0
  87. package/server/services/relay-console-log.mjs +199 -0
  88. package/server/services/remote-relay-caller-context.mjs +78 -19
  89. package/server/services/remote-relay-client.mjs +9 -0
  90. package/server/services/remote-relay-dispatcher.mjs +451 -39
  91. package/server/services/remote-relay-inbound.mjs +83 -1
  92. package/server/services/remote-relay-loopback.mjs +245 -0
  93. package/server/services/remote-relay-registry-service.mjs +52 -0
  94. package/server/services/session-worker-launch-service.mjs +100 -15
  95. package/server/services/session-worker-process-service.mjs +410 -138
  96. package/server/services/session-worker-registry-service.mjs +1 -1
  97. package/server/services/session-worker-stop-service.mjs +24 -13
  98. package/server/services/session-worker-supervisor-service.mjs +89 -2
  99. package/server/services/usage-limit-pause-service.mjs +443 -0
  100. package/server/services/worker-launch-note-service.mjs +151 -0
  101. package/shared/ask-user-bridge.mjs +14 -39
  102. package/shared/claude-attribution.mjs +117 -0
  103. package/shared/claude-cloud/api-client.mjs +809 -0
  104. package/shared/claude-cloud/base-url.mjs +47 -0
  105. package/shared/claude-cloud/credentials.mjs +221 -0
  106. package/shared/claude-cloud/repo-url.mjs +111 -0
  107. package/shared/claude-usage-limit.mjs +257 -0
  108. package/shared/control-poller.mjs +69 -20
  109. package/shared/failure-note-text.mjs +38 -0
  110. package/shared/provider-routing.mjs +4 -2
  111. package/shared/question-wait.mjs +108 -0
  112. package/shared/remote-relay-contract.mjs +167 -22
  113. package/shared/remote-relay-tool-core.mjs +11 -8
  114. package/shared/steer-settle-failure.mjs +17 -0
  115. package/shared/steer-settle-markers.mjs +8 -0
  116. package/shared/worker-runtime/process-tree.mjs +483 -0
  117. package/shared/worker-runtime/relay-errors.mjs +31 -0
  118. package/shared/worker-runtime/send-and-wait-errors.mjs +4 -4
  119. package/shared/worker-runtime/turn-liveness.mjs +249 -0
@@ -0,0 +1,117 @@
1
+ // Commit and pull-request attribution for Claude sessions.
2
+ //
3
+ // Claude Code appends its own trailer to every commit an agent makes
4
+ // ("Co-Authored-By: Claude … <noreply@anthropic.com>") and a line to every PR
5
+ // body. The CLI lets a settings object replace both (`Settings.attribution`,
6
+ // SDK 0.3.x), and OAR uses that so commits made through the relay carry one
7
+ // identity whatever model wrote them:
8
+ //
9
+ // Co-authored-by: Open Agent Relay (Claude Fable 5.1) <no-reply@oar.sh>
10
+ //
11
+ // Three modes: `oar` (the default), `vanilla` (the CLI's own attribution),
12
+ // `off` (none). The relay resolves the mode (provider setting, later a
13
+ // per-folder override) and the model label, and hands the finished settings
14
+ // object to the worker with each delivery; the worker applies it at spawn and
15
+ // when it changes. Shared by both sides so they build the same object.
16
+
17
+ export const CLAUDE_ATTRIBUTION_MODES = Object.freeze(['oar', 'vanilla', 'off']);
18
+ export const DEFAULT_CLAUDE_ATTRIBUTION_MODE = 'oar';
19
+
20
+ export const OAR_ATTRIBUTION_NAME = 'Open Agent Relay';
21
+ export const OAR_ATTRIBUTION_EMAIL = 'no-reply@oar.sh';
22
+ export const OAR_PR_ATTRIBUTION = '🤖 Generated with [Open Agent Relay](https://oar.sh)';
23
+
24
+ /** A mode string, or null for anything that is not one. */
25
+ export function normalizeClaudeAttributionMode(value) {
26
+ const mode = String(value ?? '').trim().toLowerCase();
27
+ return CLAUDE_ATTRIBUTION_MODES.includes(mode) ? mode : null;
28
+ }
29
+
30
+ /** The provider mode unless a folder override says otherwise; never null. */
31
+ export function resolveClaudeAttributionMode({ providerMode = null, folderMode = null } = {}) {
32
+ return normalizeClaudeAttributionMode(folderMode)
33
+ || normalizeClaudeAttributionMode(providerMode)
34
+ || DEFAULT_CLAUDE_ATTRIBUTION_MODE;
35
+ }
36
+
37
+ const FAMILY_LABELS = Object.freeze({
38
+ fable: 'Fable',
39
+ opus: 'Opus',
40
+ sonnet: 'Sonnet',
41
+ haiku: 'Haiku',
42
+ mythos: 'Mythos',
43
+ });
44
+
45
+ /**
46
+ * "claude-fable-5-1[1m]" → "Claude Fable 5.1"; "claude-haiku-4-5-20251001" →
47
+ * "Claude Haiku 4.5". The context-tier suffix and a date stamp are not part
48
+ * of the model's name. An id the pattern does not know is used as it is.
49
+ */
50
+ export function claudeAttributionModelLabel(modelId) {
51
+ const raw = String(modelId || '').trim();
52
+ if (!raw) return 'Claude';
53
+ const id = raw.replace(/\[[^\]]*\]\s*$/, '').trim();
54
+ const parts = id.toLowerCase().split('-').filter(Boolean);
55
+ if (parts[0] !== 'claude' || parts.length < 2) return id || raw;
56
+ const family = FAMILY_LABELS[parts[1]];
57
+ if (!family) return id;
58
+ const version = parts.slice(2)
59
+ .filter((part) => /^\d+$/.test(part) && part.length < 8)
60
+ .join('.');
61
+ return version ? `Claude ${family} ${version}` : `Claude ${family}`;
62
+ }
63
+
64
+ export function claudeAttributionTrailer(modelLabel) {
65
+ const label = String(modelLabel || '').trim() || 'Claude';
66
+ return `Co-authored-by: ${OAR_ATTRIBUTION_NAME} (${label}) <${OAR_ATTRIBUTION_EMAIL}>`;
67
+ }
68
+
69
+ /**
70
+ * The `Settings.attribution` object for a mode and model: the OAR identity,
71
+ * nothing at all (`off`), or null for `vanilla` (the key is left to the CLI).
72
+ * Always the object form: older CLIs reject `true`/`false` here.
73
+ */
74
+ export function buildClaudeAttributionSettings({ mode, modelId = '', modelLabel = '' } = {}) {
75
+ const resolved = normalizeClaudeAttributionMode(mode) || DEFAULT_CLAUDE_ATTRIBUTION_MODE;
76
+ if (resolved === 'vanilla') return null;
77
+ if (resolved === 'off') return { commit: '', pr: '', sessionUrl: false };
78
+ const label = String(modelLabel || '').trim() || claudeAttributionModelLabel(modelId);
79
+ return {
80
+ commit: claudeAttributionTrailer(label),
81
+ pr: OAR_PR_ATTRIBUTION,
82
+ // A relay session link in a public history: never.
83
+ sessionUrl: false,
84
+ };
85
+ }
86
+
87
+ function normalizeAttributionObject(value) {
88
+ if (value === null) return null;
89
+ if (!value || typeof value !== 'object') return undefined;
90
+ return {
91
+ commit: String(value.commit ?? ''),
92
+ pr: String(value.pr ?? ''),
93
+ sessionUrl: value.sessionUrl === true,
94
+ };
95
+ }
96
+
97
+ /**
98
+ * What a delivery's `settings` does to the worker's attribution — the twin
99
+ * of resolveDeliveredThinking: an absent key (an older relay) keeps the last
100
+ * known value; a present key replaces it, and null means vanilla.
101
+ */
102
+ export function resolveDeliveredAttribution(current, settings) {
103
+ const base = normalizeAttributionObject(current);
104
+ const kept = base === undefined ? null : base;
105
+ if (!settings || typeof settings !== 'object') return kept;
106
+ if (!Object.prototype.hasOwnProperty.call(settings, 'attribution')) return kept;
107
+ const next = normalizeAttributionObject(settings.attribution);
108
+ return next === undefined ? kept : next;
109
+ }
110
+
111
+ /** Two attribution values mean the same thing (both vanilla, or equal fields). */
112
+ export function sameClaudeAttribution(left, right) {
113
+ const a = normalizeAttributionObject(left) ?? null;
114
+ const b = normalizeAttributionObject(right) ?? null;
115
+ if (a === null || b === null) return a === b;
116
+ return a.commit === b.commit && a.pr === b.pr && a.sessionUrl === b.sessionUrl;
117
+ }