@zq-silk/yui 2.15.0 → 2.17.0

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 (104) hide show
  1. package/dist/cli/commandCatalog.js +17 -11
  2. package/dist/cli/interactionCandidates.js +20 -5
  3. package/dist/cli/interactionPolicy.js +5 -4
  4. package/dist/cli/roleWizard.js +7 -0
  5. package/dist/commands/globalRoleCommands.js +13 -2
  6. package/dist/commands/operatorCommands.js +2 -0
  7. package/dist/commands/profileCommands.js +19 -2
  8. package/dist/commands/roleConfiguration.js +3 -0
  9. package/dist/commands/taskCommands.js +16 -0
  10. package/dist/commands/taskRoleRuntimeStatus.js +3 -0
  11. package/dist/controller/agentJobControl.js +9 -1
  12. package/dist/controller/fileSchedulerStoreAdapter.js +35 -4
  13. package/dist/controller/globalInputDelivery.js +14 -8
  14. package/dist/controller/providerRetryAdmission.js +9 -0
  15. package/dist/controller/providerRetryDelivery.js +16 -0
  16. package/dist/controller/runtime.js +14 -0
  17. package/dist/controller/runtimeLaunchCoordinator.js +3 -1
  18. package/dist/executor/fileRoleLaunchPlanner.js +3 -0
  19. package/dist/message/messageContinuation.js +4 -0
  20. package/dist/output/rolePresentation.js +3 -0
  21. package/dist/profile/agentProfile.js +8 -0
  22. package/dist/profile/agentProfileRuntime.js +16 -1
  23. package/dist/review/reviewDecision.js +6 -0
  24. package/dist/role/availability.js +28 -0
  25. package/dist/role/role.js +6 -0
  26. package/dist/runtime/codexNativeAccess.js +21 -4
  27. package/dist/runtime/tmuxAdapters.js +5 -0
  28. package/dist/scheduler/activeRoleRunDelivery.js +9 -0
  29. package/dist/scheduler/leaderWakeupProcessor.js +8 -1
  30. package/dist/scheduler/roleRunLiveness.js +3 -0
  31. package/dist/storage/sqliteSchema.js +10 -0
  32. package/dist/storage/storageVersions.js +1 -1
  33. package/dist/web/assets/client/app/catalog.js +40 -14
  34. package/dist/web/assets/client/app/main.js +43 -26
  35. package/dist/web/assets/client/app/manage.js +18 -0
  36. package/dist/web/assets/client/app/selection.js +4 -1
  37. package/dist/web/assets/client/app/taskView.js +29 -16
  38. package/dist/web/assets/client/i18n/en.js +72 -21
  39. package/dist/web/assets/client/i18n/zh-CN.js +72 -21
  40. package/dist/web/assets/client/index.js +6 -0
  41. package/dist/web/assets/client/layout/manageShell.js +30 -8
  42. package/dist/web/assets/client/layout/shortcuts.js +9 -5
  43. package/dist/web/assets/client/layout/sidebarNav.js +147 -0
  44. package/dist/web/assets/client/layout/sizing.js +5 -2
  45. package/dist/web/assets/client/layout/workspace.js +193 -107
  46. package/dist/web/assets/client/lib/motion.js +59 -0
  47. package/dist/web/assets/client/lib/prefs.js +29 -2
  48. package/dist/web/assets/client/lib/theme.js +11 -4
  49. package/dist/web/assets/client/ui/primitives.js +40 -0
  50. package/dist/web/assets/client/views/dock/conversation.js +421 -123
  51. package/dist/web/assets/client/views/dock/session.js +229 -0
  52. package/dist/web/assets/client/views/dock/terminal.js +48 -39
  53. package/dist/web/assets/client/views/overview.js +8 -5
  54. package/dist/web/assets/client/views/task/page.js +7 -17
  55. package/dist/web/assets/shared/brand.js +22 -0
  56. package/dist/web/assets/shared/geometry.js +7 -1
  57. package/dist/web/assets/shared/icons.js +4 -0
  58. package/dist/web/assets/shared/motion.js +74 -0
  59. package/dist/web/assets/shell/appRail.js +14 -0
  60. package/dist/web/assets/shell/dialogs.js +1 -0
  61. package/dist/web/assets/shell/dock.js +19 -24
  62. package/dist/web/assets/shell/index.js +6 -2
  63. package/dist/web/assets/shell/login.js +9 -8
  64. package/dist/web/assets/shell/manage.js +32 -20
  65. package/dist/web/assets/shell/settingsContent.js +1 -1
  66. package/dist/web/assets/shell/sidebar.js +16 -23
  67. package/dist/web/assets/styles/base.js +1 -1
  68. package/dist/web/assets/styles/index.js +2 -0
  69. package/dist/web/assets/styles/layout/responsive.js +63 -19
  70. package/dist/web/assets/styles/layout/workspace.js +53 -16
  71. package/dist/web/assets/styles/motion.js +51 -0
  72. package/dist/web/assets/styles/tokens.js +5 -3
  73. package/dist/web/assets/styles/ui/controls.js +1 -1
  74. package/dist/web/assets/styles/ui/forms.js +1 -1
  75. package/dist/web/assets/styles/ui/surfaces.js +1 -2
  76. package/dist/web/assets/styles/views/conversation.js +97 -18
  77. package/dist/web/assets/styles/views/dock.js +34 -2
  78. package/dist/web/assets/styles/views/login.js +16 -13
  79. package/dist/web/assets/styles/views/manage.js +25 -42
  80. package/dist/web/assets/styles/views/page.js +2 -3
  81. package/dist/web/assets/styles/views/records.js +1 -1
  82. package/dist/web/assets/styles/views/settings.js +1 -1
  83. package/dist/web/assets/styles/views/sidebar.js +25 -20
  84. package/dist/web/assets/styles/views/task.js +8 -15
  85. package/dist/web/assets/styles/views/terminal.js +13 -9
  86. package/dist/web/webConversation.js +1 -0
  87. package/dist/web/webSettings.js +10 -2
  88. package/docs/managed-turn-and-session-runtime.md +10 -0
  89. package/docs/managed-turn-and-session-runtime.zh-CN.md +6 -0
  90. package/docs/release-workflow.md +46 -0
  91. package/docs/release-workflow.zh-CN.md +34 -0
  92. package/docs/roles-and-configuration.md +45 -1
  93. package/docs/roles-and-configuration.zh-CN.md +35 -0
  94. package/docs/storage-baseline.md +6 -1
  95. package/docs/storage-baseline.zh-CN.md +5 -1
  96. package/docs/testing/review-evaluation.md +35 -1
  97. package/docs/testing/review-evaluation.zh-CN.md +25 -1
  98. package/docs/testing/verification-levels.md +2 -2
  99. package/docs/testing/verification-levels.zh-CN.md +2 -2
  100. package/package.json +1 -1
  101. package/skills/yui-leader/VERSION +1 -1
  102. package/skills/yui-leader/references/execution.md +19 -8
  103. package/skills/yui-reviewer/SKILL.md +13 -2
  104. package/skills/yui-reviewer/VERSION +1 -1
@@ -7,7 +7,8 @@ export const APP_SCRIPT = String.raw `
7
7
  // Everything kept in the browser is view state; Task facts always come from
8
8
  // the loopback API.
9
9
  //
10
- // layout/workspace sidebar | center | dock columns, dock modes, sizing
10
+ // layout/workspace sidebar | center | dock columns, dock views, sizing
11
+ // views/dock/session the dock's session page: one Role and Session, chat or terminal
11
12
  // app/taskView draws the selected Task, the dock discussion, the overview
12
13
  // app/selection selected Task, its detail reads, URL-driven navigation
13
14
  // app/catalog refresh loop, sidebar, catalog paging and filters
@@ -17,21 +18,22 @@ export const APP_SCRIPT = String.raw `
17
18
  // refresh catalog.refresh → sidebar, then the overview (nothing selected)
18
19
  // or selection.reload → taskView.render
19
20
  // select sidebar row / overview row / URL → selection.selectTask
20
- // leave back button or Escape → selection.clearSelection
21
+ // leave rail Workbench or Escape → selection.clearSelection
21
22
  // write Task page or discussion afterWrite → quiet catalog refresh
22
23
  // URL load and back/forward → catalog.applyFilters + selection.followUrl
23
24
  import { createI18n } from "/assets/js/lib/i18n.js";
24
25
  import { createThemeController } from "/assets/js/lib/theme.js";
25
26
  import { api } from "/assets/js/lib/api.js";
26
27
  import { createToast } from "/assets/js/ui/toast.js";
27
- import { createTerminalController } from "/assets/js/views/dock/terminal.js";
28
- import { createConversationController } from "/assets/js/views/dock/conversation.js";
28
+ import { createSessionPage } from "/assets/js/views/dock/session.js";
29
29
  import { createPreviewController } from "/assets/js/views/dock/preview.js";
30
30
  import { bindGlobalInput } from "/assets/js/views/globalInput.js";
31
31
  import { bindCreateTask } from "/assets/js/views/createTask.js";
32
32
  import { bindBodySearch } from "/assets/js/views/bodySearch.js";
33
33
  import { readQuery } from "/assets/js/layout/router.js";
34
+ import { rememberPlace, linkPlaces, readSessionAccessMode } from "/assets/js/lib/prefs.js";
34
35
  import { createWorkspace } from "/assets/js/layout/workspace.js";
36
+ import { createSidebarNav } from "/assets/js/layout/sidebarNav.js";
35
37
  import { bindShortcuts } from "/assets/js/layout/shortcuts.js";
36
38
  import { createTaskView } from "/assets/js/app/taskView.js";
37
39
  import { createSelection } from "/assets/js/app/selection.js";
@@ -39,20 +41,20 @@ import { createCatalog } from "/assets/js/app/catalog.js";
39
41
 
40
42
  const $ = function (selector) { return document.querySelector(selector); };
41
43
  const el = {
42
- sidebar: $(".sidebar"), sidebarDivider: $("#sidebar-divider"), center: $("#center"), detail: $("#detail"),
43
- search: $("#search"), filters: $("#status-filters"), attention: $("#attention-bar"), tasks: $("#task-list"),
44
+ sidebar: $(".sidebar"), rail: $(".app-rail"), railWorkbench: $("#rail-workbench"),
45
+ sidebarScrim: $("#sidebar-scrim"), sidebarCollapse: $("#sidebar-collapse"), sidebarDivider: $("#sidebar-divider"), center: $("#center"), detail: $("#detail"),
46
+ search: $("#search"), source: $("#catalog-source"), filters: $("#status-filters"), attention: $("#attention-bar"), tasks: $("#task-list"),
44
47
  catalogNext: $("#catalog-next"), catalogReset: $("#catalog-reset"), catalogCount: $("#catalog-count"),
45
48
  catalogAttentionReset: $("#catalog-attention-reset"),
46
49
  refresh: $("#refresh"), sync: $("#sync-state"), lastSync: $("#last-sync"), toast: $("#toast"),
47
- operator: $("#operator-terminal"), settingsOpen: $("#settings-open"), settings: $("#settings-dialog"),
50
+ dockTarget: $("#dock-target"), dockTargetLabel: $("#dock-target-label"), dockTargetIcon: $("#dock-target-icon"),
51
+ dockTargetOptions: $("#dock-target-options"), globalInputOpen: $("#global-input-open"), settings: $("#settings-dialog"),
48
52
  locale: $("#locale-select"), themeOptions: $("#theme-options"),
49
53
  dock: $("#dock"), divider: $("#dock-divider"), dockSwap: $("#dock-swap"), dockClose: $("#dock-close"),
50
- dockTabDiscussion: $("#dock-tab-discussion"), dockTabSession: $("#dock-tab-session"),
54
+ dockTabDiscussion: $("#dock-tab-discussion"),
51
55
  dockTabConversation: $("#dock-tab-conversation"), conversation: $("#dock-conversation"),
52
56
  dockTabPreview: $("#dock-tab-preview"), preview: $("#dock-preview"),
53
- discussion: $("#dock-discussion"), session: $("#dock-session"),
54
- terminalHost: $("#terminal-host"), terminalEmpty: $("#terminal-empty"), terminalState: $("#terminal-state"),
55
- sessionTargets: $("#session-targets"), terminalCli: $("#terminal-cli")
57
+ discussion: $("#dock-discussion"), settingsOpen: $("#settings-open")
56
58
  };
57
59
 
58
60
  // View state. Each group has exactly one writer.
@@ -73,26 +75,26 @@ const t = i18n.t;
73
75
  const locale = i18n.getLocale;
74
76
  const theme = createThemeController(el.themeOptions, t);
75
77
  const toast = createToast(el.toast);
76
- const conversation = createConversationController(el.conversation, t, locale);
77
78
  const preview = createPreviewController(el.preview, t);
78
- const terminal = createTerminalController({
79
- host: el.terminalHost, empty: el.terminalEmpty, state: el.terminalState, targets: el.sessionTargets, cli: el.terminalCli
80
- }, t, locale, toast);
81
- theme.subscribe(function () { terminal.retheme(); });
79
+ // The mode changed inside the session page: the dock header follows it.
80
+ const session = createSessionPage(el.conversation, t, locale, toast, function () { workspace.syncDockButtons(); });
81
+ theme.subscribe(function () { session.retheme(); });
82
82
 
83
83
  // Controllers are created in dependency order; the arrow callbacks below are
84
84
  // the only edges pointing at controllers created later.
85
85
  let taskView = null;
86
86
  let selection = null;
87
87
  let catalog = null;
88
- const workspace = createWorkspace({
89
- el: el, state: state, terminal: terminal, conversation: conversation, preview: preview,
90
- sessionOpened: function () { taskView.updateSessionTargets(); }
88
+ const workspace = createWorkspace({ el: el, state: state, t: t, session: session, preview: preview });
89
+ const sidebarNav = createSidebarNav({
90
+ el: { sidebar: el.sidebar, rail: el.rail, scrim: el.sidebarScrim, collapse: el.sidebarCollapse },
91
+ relayout: function () { workspace.updateLayout(); }
91
92
  });
92
93
  taskView = createTaskView({
93
- el: el, state: state, t: t, locale: locale, api: api, toast: toast, terminal: terminal, workspace: workspace,
94
+ el: el, state: state, t: t, locale: locale, api: api, toast: toast, workspace: workspace,
94
95
  selectTask: function (taskId) { return selection.selectTask(taskId); },
95
96
  clearSelection: function () { selection.clearSelection(); },
97
+ revealSidebar: function () { sidebarNav.reveal(); },
96
98
  pickAttention: function (kind) { catalog.pickAttention(kind); },
97
99
  readPageSessions: function () { return catalog.readPageSessions(); },
98
100
  refreshCatalog: function () { return catalog.refresh({ quiet: true }); }
@@ -112,12 +114,26 @@ bindCreateTask({ t: t, api: api, selectTask: selection.selectTask,
112
114
  afterWrite: function () { catalog.refresh({ quiet: true }); } });
113
115
  bindBodySearch({ t: t, api: api, selectTask: selection.selectTask,
114
116
  currentTask: function () { return state.selected; },
115
- captureDraftTarget: conversation.captureDraftTarget, insertReference: conversation.insertReference });
117
+ captureDraftTarget: session.captureDraftTarget, insertReference: session.insertReference });
116
118
  bindShortcuts({
117
- el: el, state: state, globalInput: globalInput, workspace: workspace,
119
+ el: el, state: state, globalInput: globalInput, workspace: workspace, sidebarNav: sidebarNav,
118
120
  selection: selection, catalog: catalog, taskView: taskView
119
121
  });
120
- el.settingsOpen.addEventListener("click", function () { window.location.assign("/settings"); });
122
+ // Workbench <-> Models/Settings: each side remembers where the user was, so a
123
+ // round trip returns to the same filters, Task and management section.
124
+ function rememberWorkbench() { rememberPlace("workbench", window.location.pathname + window.location.search); }
125
+ el.rail.querySelectorAll("a[data-nav-area]").forEach(function (link) { link.addEventListener("click", rememberWorkbench); });
126
+ // The rail's Workbench entry on the workbench itself returns to the overview.
127
+ el.railWorkbench.addEventListener("click", function (event) {
128
+ if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
129
+ event.preventDefault();
130
+ sidebarNav.closeDrawer();
131
+ selection.clearSelection();
132
+ });
133
+ window.addEventListener("pagehide", rememberWorkbench);
134
+ function linkAll() { linkPlaces(el.rail); linkPlaces(el.sidebar); }
135
+ window.addEventListener("pageshow", linkAll);
136
+ linkAll();
121
137
 
122
138
  // The URL names the catalog filters and the selected Task (with its section).
123
139
  function applyStateFromUrl() {
@@ -132,7 +148,7 @@ window.addEventListener("popstate", function () {
132
148
 
133
149
  i18n.subscribe(function () {
134
150
  theme.render();
135
- terminal.relabel();
151
+ session.relabel();
136
152
  catalog.renderSidebar();
137
153
  taskView.relabel();
138
154
  workspace.updateLayout();
@@ -140,9 +156,10 @@ i18n.subscribe(function () {
140
156
 
141
157
  workspace.updateLayout();
142
158
  taskView.showOverview();
143
- conversation.open({ scope: "global", roleName: "operator" });
159
+ // The panel starts closed: name its owner without polling until it opens.
160
+ session.open({ scope: "global", roleName: "operator" }, { mode: readSessionAccessMode() === "native" ? "terminal" : "chat" });
161
+ session.close();
144
162
  applyStateFromUrl();
145
- workspace.restoreDefaultMode();
146
163
  catalog.refresh();
147
164
  window.setInterval(function () { catalog.refresh({ quiet: true }); }, 5000);
148
165
  `;
@@ -2,5 +2,23 @@ export const MANAGE_SCRIPT = String.raw `
2
2
  import "/assets/js/app/settings.js";
3
3
  import "/assets/js/app/models.js";
4
4
  import { startManagement } from "/assets/js/layout/manageShell.js";
5
+ import { createSidebarNav } from "/assets/js/layout/sidebarNav.js";
6
+ import { isEditing } from "/assets/js/lib/dom.js";
7
+
8
+ // The section list behaves like the workbench task list: collapsible beside
9
+ // the content, a drawer (with the global rail) on narrow screens.
10
+ const sidebarNav = createSidebarNav({
11
+ el: { sidebar: document.querySelector(".manage-rail"), rail: document.querySelector(".app-rail"), scrim: document.querySelector("#sidebar-scrim"),
12
+ collapse: document.querySelector("#sidebar-collapse") },
13
+ relayout: function () {}
14
+ });
15
+ document.querySelectorAll("[data-sidebar-toggle]").forEach(function (button) {
16
+ button.addEventListener("click", sidebarNav.reveal);
17
+ });
18
+ document.addEventListener("keydown", function (event) {
19
+ if (document.querySelector("dialog[open]") || event.metaKey || event.ctrlKey || event.altKey) return;
20
+ if (event.key === "Escape" && sidebarNav.drawerOpen()) { sidebarNav.closeDrawer(); return; }
21
+ if (event.key === "[" && !isEditing(document.activeElement)) sidebarNav.toggle();
22
+ });
5
23
  startManagement();
6
24
  `;
@@ -74,6 +74,7 @@ function clearSelection(deps) {
74
74
  syncUrl(deps.state, !urlTaskId());
75
75
  deps.workspace.updateLayout();
76
76
  deps.taskView.showOverview();
77
+ deps.taskView.revealPage();
77
78
  deps.renderTaskList();
78
79
  deps.taskView.updateSessionTargets();
79
80
  }
@@ -96,9 +97,11 @@ function followUrl(deps, params) {
96
97
  return;
97
98
  }
98
99
  if (state.selected && !canLeave(deps)) { syncUrl(state, true); return; }
100
+ const leaving = !!state.selected;
99
101
  dropSelection(deps);
100
102
  deps.workspace.updateLayout();
101
103
  deps.taskView.showOverview();
104
+ if (leaving) deps.taskView.revealPage();
102
105
  }
103
106
 
104
107
  async function load(deps, taskId, navigate) {
@@ -120,7 +123,7 @@ async function load(deps, taskId, navigate) {
120
123
  state.detail = detail;
121
124
  state.detailKey = fingerprint(core);
122
125
  deps.taskView.render(navigate);
123
- if (navigate) deps.taskView.applySection(readQuery().get("section"));
126
+ if (navigate) { deps.taskView.applySection(readQuery().get("section")); deps.taskView.revealPage(); }
124
127
  observe(deps, taskId, detail);
125
128
  }
126
129
 
@@ -12,8 +12,8 @@ import { renderOverview } from "/assets/js/views/overview.js";
12
12
  import { renderTaskDetail, selectTab, TABS, TAB_ALIASES } from "/assets/js/views/task/page.js";
13
13
  import { updateObservation } from "/assets/js/views/task/observation.js";
14
14
  import { renderDiscussion, discussionHasUnsent } from "/assets/js/views/dock/discussion.js";
15
- import { sameTarget } from "/assets/js/views/dock/terminal.js";
16
15
  import { setSectionParam } from "/assets/js/layout/router.js";
16
+ import { enter } from "/assets/js/lib/motion.js";
17
17
 
18
18
  // Only the observed identity participates: observation timestamps advance on
19
19
  // every poll and would otherwise re-render continuously.
@@ -28,16 +28,16 @@ function runtimeSignature(detail) {
28
28
  }).join(",");
29
29
  }
30
30
 
31
- // deps: { el, state, t, locale, api, toast, terminal, workspace,
32
- // selectTask, clearSelection, pickAttention, readPageSessions, refreshCatalog }
31
+ // deps: { el, state, t, locale, api, toast, workspace,
32
+ // selectTask, clearSelection, revealSidebar, pickAttention, readPageSessions, refreshCatalog }
33
33
  // el #detail, #center and the dock discussion
34
34
  // state reads selected, detail, detailKey and the catalog fields the
35
35
  // overview shows; writes activeTab
36
36
  // api Task reads for lazy blocks and the Task page's writes
37
- // terminal the dock's native Session (views/dock/terminal)
38
- // workspace layout/workspace: dock toggles and opening Sessions
37
+ // workspace layout/workspace: dock toggles, the session page and its Role list
39
38
  // selectTask(taskId) an overview row was chosen (app/selection)
40
- // clearSelection() the Task page's back button (app/selection)
39
+ // clearSelection() the Task page's "Tasks" crumb (app/selection)
40
+ // revealSidebar() the page header's task-list switch (layout/sidebarNav)
41
41
  // pickAttention(kind), readPageSessions() overview actions (app/catalog)
42
42
  // refreshCatalog() quiet catalog refresh after a write; resolves when done
43
43
  export function createTaskView(deps) {
@@ -59,7 +59,10 @@ export function createTaskView(deps) {
59
59
  showOverview: function () { showOverview(deps); },
60
60
  updateSessionTargets: function () { updateSessionTargets(deps); },
61
61
  switchTab: function (tab, options) { switchTab(deps, tab, options); },
62
- applySection: function (section) { applySection(deps, section); }
62
+ applySection: function (section) { applySection(deps, section); },
63
+ // The page content after an explicit navigation (a Task opened, back to
64
+ // the overview) rises in; polling redraws never call this.
65
+ revealPage: function () { reveal(deps.el.detail.querySelector(":scope > .page")); }
63
66
  };
64
67
  return view.controller;
65
68
  }
@@ -143,9 +146,15 @@ function detailContext(view) {
143
146
  const api = deps.api;
144
147
  return {
145
148
  activeTab: deps.state.activeTab,
146
- onTab: view.controller.switchTab,
149
+ onTab: function (tab, options) {
150
+ const changed = tab !== deps.state.activeTab;
151
+ switchTab(deps, tab, options);
152
+ if (changed) reveal(deps.el.detail.querySelector(".tab-panel:not([hidden])"));
153
+ },
147
154
  onBack: deps.clearSelection,
148
- showDock: deps.workspace.toggleDock,
155
+ revealSidebar: deps.revealSidebar,
156
+ togglePanel: function () { deps.workspace.toggleDock(); },
157
+ toggleOperator: deps.workspace.toggleOperator,
149
158
  openConversation: function (materials) {
150
159
  deps.workspace.openConversation({ scope: "task", taskId: deps.state.selected, roleName: "leader" }, materials);
151
160
  },
@@ -228,8 +237,8 @@ function drawDetail(deps, ctx) {
228
237
  el.center.scrollTop = scroll;
229
238
  }
230
239
 
231
- // The dock's Session chips: every role of the selected Task plus the global
232
- // operator, keeping the Session currently open even when it left the list.
240
+ // The Roles the dock's target menu offers: every Role of the selected Task,
241
+ // with whether it has a live native Session (Operator is always offered).
233
242
  function updateSessionTargets(deps) {
234
243
  const detail = deps.state.detail;
235
244
  const targets = [];
@@ -241,10 +250,7 @@ function updateSessionTargets(deps) {
241
250
  live: !!(runtimeRole && runtimeRole.runtimeSession && runtimeRole.runtimeSession.nativeSessionId) });
242
251
  });
243
252
  }
244
- targets.push({ scope: "global", roleName: "operator" });
245
- const current = deps.terminal.current();
246
- if (current && !targets.some(function (target) { return sameTarget(target, current); })) targets.unshift(current);
247
- deps.terminal.setTargets(targets);
253
+ deps.workspace.setTargets(targets);
248
254
  }
249
255
 
250
256
  function showOverview(deps) {
@@ -253,8 +259,15 @@ function showOverview(deps) {
253
259
  select: deps.selectTask,
254
260
  filterAttention: deps.pickAttention,
255
261
  readSessions: deps.readPageSessions,
256
- openOperator: deps.workspace.openOperator
262
+ togglePanel: function () { deps.workspace.toggleDock(); },
263
+ toggleOperator: deps.workspace.toggleOperator,
264
+ revealSidebar: deps.revealSidebar
257
265
  });
266
+ deps.workspace.syncDockButtons();
267
+ }
268
+
269
+ function reveal(element) {
270
+ if (element && typeof enter === "function") enter(element, "rise");
258
271
  }
259
272
 
260
273
  function switchTab(deps, tab, options) {
@@ -66,6 +66,9 @@ export const EN = {
66
66
  "jobs.category.ordinary": "Ordinary Tasks",
67
67
  "jobs.category.job": "Job execution Tasks",
68
68
  "jobs.category.all": "All Tasks",
69
+ "jobs.categoryShort.ordinary": "Ordinary",
70
+ "jobs.categoryShort.job": "Jobs",
71
+ "jobs.categoryShort.all": "All",
69
72
  "jobs.recentSuccess": "Most recent successful Run",
70
73
  "jobs.diagnostics": "Execution diagnostics",
71
74
  "jobs.artifacts": "Registered fixed artifacts",
@@ -146,6 +149,9 @@ export const EN = {
146
149
  "models.window.monthly": "Monthly",
147
150
  "manage.nav": "Main navigation",
148
151
  "manage.workbench": "Workbench",
152
+ "manage.sections": "Sections",
153
+ "manage.collapseSections": "Collapse sections",
154
+ "manage.showSections": "Show sections",
149
155
  "settings.section.preferences": "Preferences",
150
156
  "settings.section.skills": "Skills",
151
157
  "settings.section.server": "Agents & server",
@@ -444,6 +450,8 @@ export const EN = {
444
450
  "sidebar.workItems": "Work items",
445
451
  "sidebar.resize": "Resize task list",
446
452
  "sidebar.resizeHint": "Drag to resize · double-click to reset",
453
+ "sidebar.collapse": "Collapse task list",
454
+ "sidebar.show": "Show task list",
447
455
  "search.label": "Search tasks",
448
456
  "bodySearch.title": "Search task contents",
449
457
  "bodySearch.query": "Text to find",
@@ -505,7 +513,6 @@ export const EN = {
505
513
  "catalog.help.executionSignals": "Live runs, open work and recovery signals to inspect; not failures",
506
514
  "actions.refresh": "Refresh",
507
515
  "actions.operator": "Operator",
508
- "actions.back": "Back to tasks",
509
516
  "actions.close": "Close",
510
517
  "actions.answer": "Answer",
511
518
  "actions.save": "Save",
@@ -558,6 +565,7 @@ export const EN = {
558
565
  "shortcut.refresh": "Refresh",
559
566
  "shortcut.dock": "Show or hide the session panel",
560
567
  "shortcut.operator": "Operator session",
568
+ "shortcut.sidebar": "Show or hide the task list",
561
569
  "shortcut.tabs": "Switch task sections",
562
570
  "shortcut.escape": "Close panel / leave task",
563
571
  "loading.dashboard": "Reading local state…",
@@ -572,7 +580,6 @@ export const EN = {
572
580
  "common.notReported": "not reported",
573
581
  "detail.unobserved": "unknown",
574
582
  "detail.partial": "partial",
575
- "overview.kicker": "Workspace",
576
583
  "overview.title": "Overview",
577
584
  "overview.sub": "{total} tasks · {active} active",
578
585
  "overview.inbox": "Waiting on you",
@@ -604,7 +611,6 @@ export const EN = {
604
611
  "metrics.completed": "Completed",
605
612
  "metrics.total": "Total",
606
613
  "crumbs.label": "Breadcrumb",
607
- "crumbs.tasks": "Tasks",
608
614
  "task.updated": "Updated",
609
615
  "tabs.label": "Task sections",
610
616
  "tabs.overview": "Overview",
@@ -855,10 +861,7 @@ export const EN = {
855
861
  "store.job": "Operation",
856
862
  "dock.label": "Session panel",
857
863
  "dock.discussion": "Discussion",
858
- "dock.session": "Terminal",
859
864
  "conversation.title": "Conversation",
860
- "conversation.defaultMode": "Default view",
861
- "conversation.defaultSaved": "Saved for future openings in this browser. The current view and Session are unchanged.",
862
865
  "conversation.nativeRequest": "Codex native request",
863
866
  "conversation.nativeOmitted": "Additional or large native requests are available in Terminal.",
864
867
  "conversation.leaderQuestions": "Leader questions · Task input channel",
@@ -874,15 +877,22 @@ export const EN = {
874
877
  "conversation.input": "Message to the selected Session",
875
878
  "conversation.send": "Send",
876
879
  "conversation.model": "Session model",
877
- "conversation.modelsLoad": "Load available models",
878
- "conversation.modelApply": "Apply while idle",
879
- "conversation.launchModel": "Fixed launch request",
880
- "conversation.confirmedModel": "Last native confirmation",
880
+ "conversation.modelsLoad": "Reload",
881
+ "conversation.modelApply": "Apply selection",
882
+ "conversation.selectedModel": "Selected model",
883
+ "conversation.modelNotSelected": "Choose a model",
884
+ "conversation.modelsLoading": "Loading models…",
885
+ "conversation.modelsFailed": "Could not read models. Please reload.",
886
+ "conversation.modelsEmpty": "No models available",
887
+ "conversation.modelBusy": "A turn is running. Apply your selection when it finishes.",
888
+ "conversation.modelTerminalBusy": "Exit Codex in the native terminal before applying. Closing the terminal panel does not exit it.",
889
+ "conversation.launchModel": "Launch config",
890
+ "conversation.confirmedModel": "Execution model",
881
891
  "conversation.modelBoundary": "Same Codex Thread; idle only. Does not change Role defaults or the current Turn. A Host reconnect restores the fixed launch configuration; check the native confirmation again. No automatic retry.",
882
- "conversation.modelApplying": "Applying model; waiting for native confirmation…",
883
- "conversation.modelConfirmed": "Native model adoption confirmed for this live connection.",
884
- "conversation.modelFailed": "Not applied. Review the reason before trying again.",
885
- "conversation.modelUnknown": "Adoption unconfirmed. Do not retry; inspect confirmation or explicitly select a new Session through existing lifecycle controls.",
892
+ "conversation.modelApplying": "Switching model…",
893
+ "conversation.modelConfirmed": "Model switched",
894
+ "conversation.modelFailed": "Could not switch models. Check that the session is idle before retrying.",
895
+ "conversation.modelUnknown": "Switch not yet confirmed. Repeat submission is blocked.",
886
896
  "conversation.commands": "Supported commands",
887
897
  "conversation.literal": "Send as ordinary text",
888
898
  "conversation.command.help": "Show supported operations",
@@ -893,7 +903,6 @@ export const EN = {
893
903
  "conversation.command.latest": "Return to latest messages",
894
904
  "conversation.commandHelp": "/help · /status · /model · /stop · /latest. Tab completes an unambiguous command; Ctrl/⌘+Enter sends. These are Yui controls, not arbitrary native CLI commands.",
895
905
  "conversation.commandUnknown": "Unsupported command. Use /help, or explicitly send it as ordinary text.",
896
- "conversation.draftSaved": "Draft saved in this browser tab · Ctrl/⌘+Enter to send",
897
906
  "conversation.storageFailed": "Browser storage is unavailable. Keep a copy of this draft before leaving.",
898
907
  "conversation.receiptDetails": "Exact receipt",
899
908
  "conversation.receipt.sending": "Sending once…",
@@ -921,13 +930,48 @@ export const EN = {
921
930
  "conversation.empty": "No public items on this page. Older pages may contain messages.",
922
931
  "conversation.liveUnavailable": "Live reply observation unavailable; native history only",
923
932
  "conversation.truncated": "Long item excerpt; open native access for the full item.",
924
- "conversation.placeholder": "Message this Session…",
925
- "conversation.more": "More",
933
+ "conversation.placeholder": "Message this Session… (/ for commands)",
926
934
  "conversation.copy": "Copy",
927
935
  "conversation.copied": "Copied",
928
936
  "conversation.jump": "Jump to latest",
929
937
  "conversation.selectModel": "Select model",
930
938
  "conversation.worked": "Worked",
939
+ "conversation.modelConfirmedNote": "Confirmed {time} at start, resume or switch; not a live reading, and Desktop changes may not show",
940
+ "conversation.modelStateConfirmed": "Last confirmed",
941
+ "conversation.modelStatePending": "Applying",
942
+ "conversation.modelConfirmedShort": "last native confirmation {time}; not live",
943
+ "conversation.details": "Session details",
944
+ "conversation.copyIdentity": "Copy identity",
945
+ "conversation.copyFailed": "Copy unavailable in this browser",
946
+ "conversation.modelUnconfirmed": "Model unconfirmed",
947
+ "conversation.modelUnconfirmedHint": "No native confirmation for this Session; the launch config is not shown as current.",
948
+ "conversation.modelPendingLabel": "Applying",
949
+ "conversation.modelHistorical": "Previous Sessions are not observed live.",
950
+ "conversation.modelNoRead": "Not reported yet.",
951
+ "conversation.effortUnobserved": "effort not reported",
952
+ "conversation.launchNote": "Requested at launch; not current",
953
+ "conversation.agentDefault": "Agent default",
954
+ "conversation.sendHint": "Send (Ctrl/⌘+Enter)",
955
+ "conversation.backCurrent": "Back to current Session",
956
+ "conversation.backCurrentShort": "Current",
957
+ "conversation.readOnlyHistory": "Previous Session · read only",
958
+ "conversation.placeholderHistory": "Previous Sessions are read only",
959
+ "conversation.pendingInput": "Waiting for the last input's receipt",
960
+ "conversation.turnUnsettled": "Last input delivery is unsettled",
961
+ "conversation.inputUnavailable": "Input unavailable for this Session",
962
+ "conversation.sessionActive": "Running",
963
+ "conversation.sessionEnded": "Ended",
964
+ "conversation.sessionFailed": "Failed",
965
+ "conversation.previousSessions": "Previous",
966
+ "conversation.noSessionShort": "No Session",
967
+ "conversation.sessionLabel": "Session",
968
+ "conversation.sessionId": "Session ID",
969
+ "conversation.authority": "Authority",
970
+ "conversation.agent": "Agent",
971
+ "conversation.turn": "Turn",
972
+ "conversation.writer": "Input",
973
+ "conversation.stateUnknown": "Unknown",
974
+ "conversation.disconnectedShort": "Disconnected",
931
975
  "conversation.activity.commandExecution": "Ran",
932
976
  "conversation.activity.fileChange": "Edited files",
933
977
  "conversation.activity.mcpToolCall": "Used tool",
@@ -936,6 +980,7 @@ export const EN = {
936
980
  "conversation.activity.collabAgentToolCall": "Asked another agent",
937
981
  "dock.swap": "Swap with task details",
938
982
  "dock.hide": "Hide session panel",
983
+ "dock.show": "Show session panel",
939
984
  "dock.resize": "Resize session panel",
940
985
  "dock.target": "Session target",
941
986
  "discussion.title": "Task discussion",
@@ -993,13 +1038,19 @@ export const EN = {
993
1038
  "terminal.closed": "Detached",
994
1039
  "terminal.error": "Unavailable",
995
1040
  "terminal.errorDetail": "Unable to open this native Session. Check that the Controller is running and the Role has a Session.",
996
- "terminal.global": "Global",
997
- "terminal.noTargets": "No Roles",
998
- "terminal.emptyTitle": "Attach to a native Session",
999
- "terminal.emptyText": "Pick a Role above. The panel shows the Session's current screen; attaching never starts or restarts an Agent.",
1041
+ "session.mode": "Session view",
1042
+ "session.modeChat": "Chat",
1043
+ "session.modeTerminal": "Terminal",
1044
+ "terminal.unavailable": "Unavailable",
1045
+ "terminal.noSessionTitle": "No Session to attach",
1046
+ "terminal.noSessionText": "This Role has no attachable Session yet. Attaching never starts an Agent.",
1047
+ "terminal.notCurrentTitle": "Not the current Session",
1048
+ "terminal.notCurrentText": "The terminal can only attach to the current Session; the selected Session is no longer current.",
1049
+ "conversation.roleReadOnly": "This Role is read only here; its input goes through its dispatch controls.",
1000
1050
  "terminal.cliHint": "Full terminal",
1001
1051
  "terminal.historyLimited": "This Role has a {current}-line tmux history. Exit and re-enter it to use {target} lines.",
1002
1052
  "global.open": "Global input",
1053
+ "global.openRole": "Message another Role…",
1003
1054
  "global.title": "Global Role input",
1004
1055
  "global.help": "Queue is the default. A cancel request does not prove the Turn stopped.",
1005
1056
  "global.role": "Role",