oysterun 1.5.1 → 1.5.2

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 (48) hide show
  1. package/README.md +1 -1
  2. package/dev/client/web/index.html +124 -43
  3. package/dev/client/web-chat/dist/assets/{ReactPrism-BjE2oD0Q.js → ReactPrism-BGRmaJf7.js} +1 -1
  4. package/dev/client/web-chat/dist/assets/{ReactPrism-BjE2oD0Q.js.map → ReactPrism-BGRmaJf7.js.map} +1 -1
  5. package/dev/client/web-chat/dist/assets/{index-DvF_JpCH.js → index-CRrbvWg7.js} +2 -2
  6. package/dev/client/web-chat/dist/assets/index-CRrbvWg7.js.map +1 -0
  7. package/dev/client/web-chat/dist/assets/{index-BhxLAseE.js → index-Cuy-f6-d.js} +81 -81
  8. package/dev/client/web-chat/dist/assets/index-Cuy-f6-d.js.map +1 -0
  9. package/dev/client/web-chat/dist/assets/{index-CiiYSq6l.js → index-W5ISbeWM.js} +1 -1
  10. package/dev/client/web-chat/dist/assets/{index-CiiYSq6l.js.map → index-W5ISbeWM.js.map} +1 -1
  11. package/dev/client/web-chat/dist/assets/{pdf-BZ28s_mu.js → pdf-BFZzIBtl.js} +3 -3
  12. package/dev/client/web-chat/dist/assets/pdf-BFZzIBtl.js.map +1 -0
  13. package/dev/client/web-chat/dist/assets/{web-CdnPyaZp.js → web-B2-C3qO8.js} +1 -1
  14. package/dev/client/web-chat/dist/assets/{web-CdnPyaZp.js.map → web-B2-C3qO8.js.map} +1 -1
  15. package/dev/client/web-chat/dist/assets/{web-CBS87LlI.js → web-DUrVmksC.js} +1 -1
  16. package/dev/client/web-chat/dist/assets/{web-CBS87LlI.js.map → web-DUrVmksC.js.map} +1 -1
  17. package/dev/client/web-chat/dist/index.html +1 -1
  18. package/docs/routec/config_hierachy.md +14 -2
  19. package/docs/routec/dev/scheduler_mail_skill.md +8 -3
  20. package/docs/routec/form_UI_fields.md +1 -1
  21. package/docs/routec/host_runtime_error_boundary.md +0 -1
  22. package/docs/routec/host_setup.md +6 -0
  23. package/docs/routec/oysterun_operation_interface_spec.md +4 -2
  24. package/host-service/README.md +1 -2
  25. package/host-service/adapters/codex-app-server-adapter.mjs +26 -7
  26. package/host-service/agent-config-migration.mjs +9 -39
  27. package/host-service/browser-root-project-index.mjs +488 -0
  28. package/host-service/folder-browser.mjs +27 -34
  29. package/host-service/mail-store.mjs +9 -4
  30. package/host-service/matrix-event-writer.mjs +2 -0
  31. package/host-service/matrix-facade.mjs +28 -0
  32. package/host-service/package.json +1 -1
  33. package/host-service/portable-scheduler-definitions.mjs +196 -254
  34. package/host-service/scheduler-service.mjs +46 -86
  35. package/host-service/scheduler-store.mjs +32 -47
  36. package/host-service/server.mjs +821 -644
  37. package/host-service/session-manager.mjs +0 -23
  38. package/host-service/templates/demo-agents/oysterun-github-tracker/.claude/commands/scheduler_task.md +7 -5
  39. package/host-service/templates/demo-agents/oysterun-github-tracker/.codex/prompts/scheduler_task.md +7 -5
  40. package/host-service/templates/demo-agents/oysterun-github-tracker/.oysterun/schedulers.json +4 -16
  41. package/host-service/templates/demo-agents/oysterun-github-tracker/README.md +6 -5
  42. package/host-service/templates/demo-agents/oysterun-github-tracker/tasks/repo_crawler_rich.py +63 -11
  43. package/host-service/transcript-store.mjs +15 -2
  44. package/package.json +1 -1
  45. package/dev/client/web-chat/dist/assets/index-BhxLAseE.js.map +0 -1
  46. package/dev/client/web-chat/dist/assets/index-DvF_JpCH.js.map +0 -1
  47. package/dev/client/web-chat/dist/assets/pdf-BZ28s_mu.js.map +0 -1
  48. package/host-service/agent-registry.mjs +0 -53
package/README.md CHANGED
@@ -366,7 +366,7 @@ Core modules:
366
366
  - `host-service/adapters/claude-code-adapter.mjs`: Claude runtime bridge
367
367
  - `host-service/adapters/codex-app-server-adapter.mjs`: Codex runtime bridge
368
368
  - `host-service/agent-config.mjs`: `.oysterun` config layering and workspace policy
369
- - `host-service/agent-registry.mjs`: Host-local agent-folder mapping
369
+ - `host-service/browser-root-project-index.mjs`: in-memory Browser Root project discovery
370
370
  - `host-service/session-history.mjs`: recent session summaries
371
371
  - `host-service/upload-manager.mjs`: uploaded file persistence
372
372
  - `host-service/session-assets.mjs`: `~/.oysterun` asset paths
@@ -400,6 +400,11 @@
400
400
  color: var(--red);
401
401
  }
402
402
 
403
+ .project-registration-issues {
404
+ margin-bottom: 12px;
405
+ white-space: pre-line;
406
+ }
407
+
403
408
  .banner {
404
409
  background: var(--accent-soft);
405
410
  color: var(--accent);
@@ -2812,7 +2817,7 @@
2812
2817
  }
2813
2818
 
2814
2819
  .topbar-scheduler-new,
2815
- .topbar-scheduler-import,
2820
+ .topbar-scheduler-refresh,
2816
2821
  .topbar-session-loop-new,
2817
2822
  .topbar-session-loop-refresh,
2818
2823
  .topbar-explorer-add-folder {
@@ -2821,7 +2826,7 @@
2821
2826
  justify-content: center;
2822
2827
  }
2823
2828
 
2824
- .topbar-scheduler-import svg,
2829
+ .topbar-scheduler-refresh svg,
2825
2830
  .topbar-session-loop-refresh svg {
2826
2831
  display: block;
2827
2832
  width: 20px;
@@ -7875,18 +7880,14 @@
7875
7880
  +
7876
7881
  </button>
7877
7882
  <button
7878
- class="scheduler-new-icon-btn topbar-scheduler-import hidden"
7879
- id="topbar-scheduler-import-btn"
7883
+ class="scheduler-new-icon-btn topbar-scheduler-refresh hidden"
7884
+ id="topbar-scheduler-refresh-btn"
7880
7885
  type="button"
7881
- aria-label="Import schedules"
7882
- title="Import schedules"
7883
- data-scheduler-action="import-browser-root"
7886
+ aria-label="Refresh schedules"
7887
+ title="Refresh schedules"
7888
+ data-scheduler-action="refresh-browser-root"
7884
7889
  >
7885
- <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
7886
- <path d="M12 4v10"></path>
7887
- <path d="m8 10 4 4 4-4"></path>
7888
- <path d="M5 18h14"></path>
7889
- </svg>
7890
+
7890
7891
  </button>
7891
7892
  <button
7892
7893
  class="scheduler-new-icon-btn topbar-session-loop-new hidden"
@@ -8614,9 +8615,10 @@
8614
8615
  <option value="public">Public</option>
8615
8616
  </select>
8616
8617
  <div class="field-hint">
8617
- Controls shared <code>web.access</code>. When
8618
- Update .oysterun/config.json is unchecked, this is
8619
- used for the running session only.
8618
+ Saves the Browser Root project's shared
8619
+ <code>web.access</code>. Website settings are
8620
+ project-level and do not depend on the Update
8621
+ .oysterun/config.json toggle below.
8620
8622
  </div>
8621
8623
  </div>
8622
8624
  </div>
@@ -10296,6 +10298,10 @@ Terminal output will appear here.</pre
10296
10298
  class="panel agent-entry-panel web-site-panel"
10297
10299
  data-oysterun-host-web-list-layout="sessions_scheduler_row_list"
10298
10300
  >
10301
+ <div
10302
+ id="web-project-registration-issues"
10303
+ class="error-box project-registration-issues hidden"
10304
+ ></div>
10299
10305
  <div class="meta-text hidden" id="web-summary"></div>
10300
10306
  <div
10301
10307
  class="agent-entry-list web-site-list"
@@ -10421,6 +10427,10 @@ Terminal output will appear here.</pre
10421
10427
  <div class="page-screen scheduler-screen">
10422
10428
  <section class="panel page-form-panel scheduler-panel">
10423
10429
  <div id="scheduler-error" class="error-box hidden"></div>
10430
+ <div
10431
+ id="scheduler-project-registration-issues"
10432
+ class="error-box project-registration-issues hidden"
10433
+ ></div>
10424
10434
  <div id="scheduler-status" class="banner hidden"></div>
10425
10435
  <div
10426
10436
  id="scheduler-page-root"
@@ -11963,10 +11973,11 @@ Waiting for Claude login output…</pre
11963
11973
  function createHostSchedulerState() {
11964
11974
  return {
11965
11975
  rows: [],
11976
+ projectRegistrationIssues: [],
11966
11977
  loaded: false,
11967
11978
  loading: false,
11968
11979
  saving: false,
11969
- importing: false,
11980
+ refreshing: false,
11970
11981
  testingId: null,
11971
11982
  togglingId: null,
11972
11983
  deletingId: null,
@@ -12994,6 +13005,7 @@ Waiting for Claude login output…</pre
12994
13005
  let selectedSessionId = null;
12995
13006
  let catalog = [];
12996
13007
  let websiteCatalog = [];
13008
+ let projectRegistrationIssues = [];
12997
13009
  let liveSessions = [];
12998
13010
  let sessionHistory = [];
12999
13011
  let matrixTranscriptSessionIdsByAgent = {};
@@ -21375,6 +21387,7 @@ Waiting for Claude login output…</pre
21375
21387
  const isSchedulerSetupRequest = isSchedulerSetupRoute(normalized);
21376
21388
  await loadHostSchedulerSchedules({
21377
21389
  force: true,
21390
+ refreshBrowserRoot: true,
21378
21391
  scheduleId: isSchedulerSetupRequest ? normalized.scheduleId : "",
21379
21392
  newDraft: normalized.mode === "new",
21380
21393
  listRoute: !isSchedulerSetupRequest,
@@ -21390,6 +21403,12 @@ Waiting for Claude login output…</pre
21390
21403
  await loadHostSchedulerRuns(normalized.scheduleId, { force: true });
21391
21404
  }
21392
21405
  } else if (normalized.screen === "web") {
21406
+ await refreshCatalog({
21407
+ force: true,
21408
+ preserveView: true,
21409
+ skipProviders: true,
21410
+ refreshBrowserRoot: true,
21411
+ });
21393
21412
  renderWebCatalog();
21394
21413
  } else if (normalized.screen === "mail") {
21395
21414
  if (normalized.mailId) {
@@ -24543,7 +24562,11 @@ Waiting for Claude login output…</pre
24543
24562
  }
24544
24563
 
24545
24564
  function readDashboardAgentCatalog(opts = {}) {
24546
- return readDashboardDataRequest("catalog", "/agents/catalog", {
24565
+ const path =
24566
+ opts.refreshBrowserRoot === true
24567
+ ? "/agents/catalog?refresh_browser_root=1"
24568
+ : "/agents/catalog";
24569
+ return readDashboardDataRequest("catalog", path, {
24547
24570
  force: opts.force === true,
24548
24571
  });
24549
24572
  }
@@ -26199,11 +26222,11 @@ Waiting for Claude login output…</pre
26199
26222
  "Access",
26200
26223
  `<div
26201
26224
  class="value-stack"
26202
- data-oysterun-p56-session-profile-web-access="editable_current_session_or_config_save"
26225
+ data-oysterun-p56-session-profile-web-access="browser_root_shared_config"
26203
26226
  >
26204
26227
  <label
26205
26228
  class="toggle-row"
26206
- data-oysterun-p94-session-profile-web-enabled="editable_current_session_or_config_save"
26229
+ data-oysterun-p94-session-profile-web-enabled="browser_root_shared_config"
26207
26230
  >
26208
26231
  <span>
26209
26232
  <strong>Enabled</strong>
@@ -26342,9 +26365,6 @@ Waiting for Claude login output…</pre
26342
26365
  enabled: nextEnabled,
26343
26366
  available: nextEnabled ? previousWebsite?.available === true : false,
26344
26367
  access: nextAccess,
26345
- current_session_only: false,
26346
- live_session_access_override: false,
26347
- live_session_enabled_override: false,
26348
26368
  password:
26349
26369
  nextWebsitePassword ||
26350
26370
  getOwnerVisibleWebsitePassword(previousWebsite),
@@ -26377,12 +26397,22 @@ Waiting for Claude login output…</pre
26377
26397
  update_config: true,
26378
26398
  }
26379
26399
  );
26400
+ const persistedWebsite = response?.website || null;
26401
+ if (
26402
+ persistedWebsite?.enabled !== nextEnabled ||
26403
+ normalizeAgentWebAccess(persistedWebsite?.access) !== nextAccess
26404
+ ) {
26405
+ throw new Error(
26406
+ "Host did not confirm the saved Browser Root Website settings."
26407
+ );
26408
+ }
26380
26409
  syncLiveSessionFromStatusPayload(response);
26381
26410
  agentProfileWebsiteAccessState = {
26382
26411
  ...agentProfileWebsiteAccessState,
26383
26412
  saving: false,
26384
26413
  error: "",
26385
- status: "Saved and updated .oysterun/config.json.",
26414
+ status:
26415
+ "Saved Website settings to the Browser Root project .oysterun/config.json.",
26386
26416
  };
26387
26417
  invalidateDashboardDataCaches({ catalog: true, sessions: true });
26388
26418
  renderAgentProfileView();
@@ -29032,7 +29062,7 @@ Waiting for Claude login output…</pre
29032
29062
  setVisible("browser-site-exit-btn", isBrowser);
29033
29063
  setVisible("entry-start-session-btn", screen === "sessions");
29034
29064
  setVisible("topbar-scheduler-new-btn", isSchedulerList);
29035
- setVisible("topbar-scheduler-import-btn", isSchedulerList);
29065
+ setVisible("topbar-scheduler-refresh-btn", isSchedulerList);
29036
29066
  setVisible("topbar-session-loop-new-btn", isSessionLoop);
29037
29067
  setVisible("topbar-session-loop-refresh-btn", isSessionLoop);
29038
29068
  setVisible("topbar-explorer-add-folder-btn", showTopbarAddFolder);
@@ -29089,10 +29119,10 @@ Waiting for Claude login output…</pre
29089
29119
  topbarSessionLoopRefreshButton.disabled =
29090
29120
  !hasSelectedLiveSession || sessionLoopState.loading === true;
29091
29121
  }
29092
- const topbarSchedulerImportButton = $("topbar-scheduler-import-btn");
29093
- if (topbarSchedulerImportButton) {
29094
- topbarSchedulerImportButton.disabled =
29095
- hostSchedulerState.importing === true ||
29122
+ const topbarSchedulerRefreshButton = $("topbar-scheduler-refresh-btn");
29123
+ if (topbarSchedulerRefreshButton) {
29124
+ topbarSchedulerRefreshButton.disabled =
29125
+ hostSchedulerState.refreshing === true ||
29096
29126
  hostSchedulerState.loading === true;
29097
29127
  }
29098
29128
  setVisible("topbar-scheduler-save-btn", isSchedulerSetup);
@@ -30608,7 +30638,10 @@ Waiting for Claude login output…</pre
30608
30638
  });
30609
30639
  }
30610
30640
  const [catalogData, sessionsData, historyData] = await Promise.all([
30611
- readDashboardAgentCatalog({ force: forceRefresh }),
30641
+ readDashboardAgentCatalog({
30642
+ force: forceRefresh,
30643
+ refreshBrowserRoot: opts.refreshBrowserRoot === true,
30644
+ }),
30612
30645
  readDashboardLiveSessions({ force: forceRefresh }),
30613
30646
  readDashboardSessionHistory({ force: forceRefresh }),
30614
30647
  ]);
@@ -30621,6 +30654,11 @@ Waiting for Claude login output…</pre
30621
30654
  websiteCatalog = Array.isArray(catalogData.websites)
30622
30655
  ? catalogData.websites
30623
30656
  : [];
30657
+ projectRegistrationIssues = Array.isArray(
30658
+ catalogData.project_registration_issues
30659
+ )
30660
+ ? catalogData.project_registration_issues
30661
+ : [];
30624
30662
  liveSessions = (sessionsData.sessions || []).map((entry) => ({
30625
30663
  ...entry,
30626
30664
  runtimeCapabilities: normalizeRuntimeCapabilityState(
@@ -31436,6 +31474,25 @@ Waiting for Claude login output…</pre
31436
31474
  return "Unavailable";
31437
31475
  }
31438
31476
 
31477
+ function formatProjectRegistrationIssues(issues) {
31478
+ if (!Array.isArray(issues) || issues.length === 0) return "";
31479
+ return issues
31480
+ .filter((issue) => issue?.code === "project_id_collision")
31481
+ .map((issue) => {
31482
+ const projectId = sanitizeRouteText(issue.project_id) || "unknown";
31483
+ const folders = Array.isArray(issue.folders)
31484
+ ? issue.folders
31485
+ .map((folder) => sanitizeRouteText(folder))
31486
+ .filter(Boolean)
31487
+ : [];
31488
+ const folderText = folders.length
31489
+ ? `\n${folders.map((folder) => `- ${folder}`).join("\n")}`
31490
+ : "";
31491
+ return `Project registration conflict: multiple Browser Root folders resolve to ${projectId}.${folderText}\nRename one folder to create a unique project ID.`;
31492
+ })
31493
+ .join("\n\n");
31494
+ }
31495
+
31439
31496
  function normalizeWebsiteCatalogEntry(entry) {
31440
31497
  const website = entry?.website || {};
31441
31498
  const entryPath = sanitizeWebsiteEntryPath(
@@ -31574,6 +31631,10 @@ Waiting for Claude login output…</pre
31574
31631
  function renderWebCatalog() {
31575
31632
  const container = $("web-site-list");
31576
31633
  if (!container) return;
31634
+ showError(
31635
+ "web-project-registration-issues",
31636
+ formatProjectRegistrationIssues(projectRegistrationIssues)
31637
+ );
31577
31638
  const entries = Array.isArray(websiteCatalog)
31578
31639
  ? websiteCatalog.map(normalizeWebsiteCatalogEntry)
31579
31640
  : [];
@@ -40748,6 +40809,12 @@ Waiting for Claude login output…</pre
40748
40809
 
40749
40810
  function renderHostSchedulerView() {
40750
40811
  showError("scheduler-error", hostSchedulerState.error || "");
40812
+ showError(
40813
+ "scheduler-project-registration-issues",
40814
+ formatProjectRegistrationIssues(
40815
+ hostSchedulerState.projectRegistrationIssues
40816
+ )
40817
+ );
40751
40818
  setHostSchedulerStatus(hostSchedulerState.status || "");
40752
40819
  const route = normalizeClientRoute(getCurrentRoute());
40753
40820
  if (isSchedulerRunLogRoute(route)) {
@@ -40827,7 +40894,11 @@ Waiting for Claude login output…</pre
40827
40894
  };
40828
40895
  renderHostSchedulerView();
40829
40896
  try {
40830
- const data = await api("GET", "/scheduler/schedules");
40897
+ const schedulerPath =
40898
+ opts.refreshBrowserRoot === true
40899
+ ? "/scheduler/schedules?refresh_browser_root=1"
40900
+ : "/scheduler/schedules";
40901
+ const data = await api("GET", schedulerPath);
40831
40902
  const rows = Array.isArray(data.schedules) ? data.schedules : [];
40832
40903
  const requestedId = sanitizeRouteText(opts.scheduleId);
40833
40904
  const shouldOpenSetup =
@@ -40841,6 +40912,11 @@ Waiting for Claude login output…</pre
40841
40912
  hostSchedulerState = {
40842
40913
  ...hostSchedulerState,
40843
40914
  rows,
40915
+ projectRegistrationIssues: Array.isArray(
40916
+ data.project_registration_issues
40917
+ )
40918
+ ? data.project_registration_issues
40919
+ : [],
40844
40920
  loaded: true,
40845
40921
  loading: false,
40846
40922
  selectedId,
@@ -40868,39 +40944,44 @@ Waiting for Claude login output…</pre
40868
40944
  renderHostSchedulerView();
40869
40945
  }
40870
40946
 
40871
- async function importHostSchedulerBrowserRoot() {
40872
- if (hostSchedulerState.importing === true) return;
40947
+ async function refreshHostSchedulerBrowserRoot() {
40948
+ if (hostSchedulerState.refreshing === true) return;
40873
40949
  hostSchedulerState = {
40874
40950
  ...hostSchedulerState,
40875
- importing: true,
40951
+ refreshing: true,
40876
40952
  error: "",
40877
- status: "Importing schedules...",
40953
+ status: "Refreshing schedules...",
40878
40954
  };
40879
40955
  renderHostSchedulerView();
40880
40956
  try {
40881
40957
  const data = await api(
40882
40958
  "POST",
40883
- "/scheduler/schedules/import-browser-root",
40959
+ "/scheduler/schedules/refresh-browser-root",
40884
40960
  {}
40885
40961
  );
40886
40962
  const rows = Array.isArray(data.schedules) ? data.schedules : [];
40887
40963
  hostSchedulerState = {
40888
40964
  ...hostSchedulerState,
40889
40965
  rows,
40966
+ projectRegistrationIssues: Array.isArray(
40967
+ data.project_registration_issues
40968
+ )
40969
+ ? data.project_registration_issues
40970
+ : [],
40890
40971
  loaded: true,
40891
- importing: false,
40972
+ refreshing: false,
40892
40973
  loading: false,
40893
40974
  error: "",
40894
- status: `Imported ${Number(data.registered_count || 0)} schedule${
40895
- Number(data.registered_count || 0) === 1 ? "" : "s"
40896
- } from ${Number(data.imported_folder_count || 0)} folder${
40897
- Number(data.imported_folder_count || 0) === 1 ? "" : "s"
40975
+ status: `Refreshed ${Number(
40976
+ data.project_count || 0
40977
+ )} Browser Root project${
40978
+ Number(data.project_count || 0) === 1 ? "" : "s"
40898
40979
  }.`,
40899
40980
  };
40900
40981
  } catch (err) {
40901
40982
  hostSchedulerState = {
40902
40983
  ...hostSchedulerState,
40903
- importing: false,
40984
+ refreshing: false,
40904
40985
  error: err.message || String(err),
40905
40986
  status: "",
40906
40987
  };
@@ -41677,8 +41758,8 @@ Waiting for Claude login output…</pre
41677
41758
  openHostSchedulerNew();
41678
41759
  return true;
41679
41760
  }
41680
- if (action === "import-browser-root") {
41681
- void importHostSchedulerBrowserRoot();
41761
+ if (action === "refresh-browser-root") {
41762
+ void refreshHostSchedulerBrowserRoot();
41682
41763
  return true;
41683
41764
  }
41684
41765
  if (action === "set-rule-type") {
@@ -1,4 +1,4 @@
1
- import{g as ee,c as Y,r as K,j as Z}from"./index-BhxLAseE.js";var X={exports:{}};(function(e){var t=typeof window<"u"?window:typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?self:{};/**
1
+ import{g as ee,c as Y,r as K,j as Z}from"./index-Cuy-f6-d.js";var X={exports:{}};(function(e){var t=typeof window<"u"?window:typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?self:{};/**
2
2
  * Prism: Lightweight, robust, elegant syntax highlighting
3
3
  *
4
4
  * @license MIT <https://opensource.org/licenses/MIT>