clay-server 5.3.0-beta.4 → 5.3.0-beta.6
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/lib/ask-user-request-identity.js +18 -1
- package/lib/clay-product-control-tools.js +2 -2
- package/lib/clay-product-control.js +1 -1
- package/lib/clay-screen-controls.js +1 -0
- package/lib/clay-split-view-awareness.js +5 -2
- package/lib/clay-split-view-controls.js +14 -7
- package/lib/clay-split-view-input.js +5 -4
- package/lib/clay-split-view-render-proof.js +14 -4
- package/lib/clay-view-workspace-input.js +71 -0
- package/lib/project-delegated-follow-up.js +18 -9
- package/lib/project-file-history.js +11 -9
- package/lib/project-file-watch.js +26 -7
- package/lib/project-filesystem.js +5 -4
- package/lib/project-shared-browser.js +7 -3
- package/lib/project-split-view-document.js +16 -2
- package/lib/project-split-views.js +15 -294
- package/lib/project-user-message.js +4 -3
- package/lib/project-vendor-login.js +2 -2
- package/lib/project-view-input.js +11 -0
- package/lib/project-view-pair.js +26 -0
- package/lib/project-view-store.js +346 -0
- package/lib/project-view-terminal-binding.js +16 -0
- package/lib/project-view-workspace.js +126 -0
- package/lib/project.js +1 -0
- package/lib/public/app.js +2 -0
- package/lib/public/css/issues.css +3 -0
- package/lib/public/css/pane.css +5 -1
- package/lib/public/css/right-workbench.css +25 -3
- package/lib/public/css/scheduled-tasks.css +7 -0
- package/lib/public/css/shared-browser.css +21 -0
- package/lib/public/css/split-view-layout.css +37 -3
- package/lib/public/css/sticky-notes.css +3 -2
- package/lib/public/css/tool-pane.css +127 -0
- package/lib/public/index.html +3 -3
- package/lib/public/modules/app-header.js +24 -2
- package/lib/public/modules/app-messages.js +1 -1
- package/lib/public/modules/clay-file-links.js +2 -1
- package/lib/public/modules/clay-session-links.js +1 -1
- package/lib/public/modules/clay-split-view-screen.js +6 -3
- package/lib/public/modules/clay-tool-pane-screen.js +35 -0
- package/lib/public/modules/file-history-snapshot.js +12 -0
- package/lib/public/modules/file-pane-entrypoints.js +55 -0
- package/lib/public/modules/file-pane-history.js +78 -0
- package/lib/public/modules/file-pane-instances.js +140 -0
- package/lib/public/modules/file-pane-links.js +41 -0
- package/lib/public/modules/file-pane-render.js +48 -0
- package/lib/public/modules/file-pane-review.js +26 -0
- package/lib/public/modules/file-pane-toolbar.js +54 -0
- package/lib/public/modules/file-viewer-source.js +70 -0
- package/lib/public/modules/filebrowser.js +44 -83
- package/lib/public/modules/git-panel.js +5 -0
- package/lib/public/modules/issues.js +3 -4
- package/lib/public/modules/linear-panel.js +2 -2
- package/lib/public/modules/mate-knowledge-workbench.js +10 -6
- package/lib/public/modules/notifications.js +4 -1
- package/lib/public/modules/pane-activation.js +5 -0
- package/lib/public/modules/pane-binding.js +5 -1
- package/lib/public/modules/pane-browser-bridge.js +20 -6
- package/lib/public/modules/pane-browser-transport.js +110 -0
- package/lib/public/modules/pane-header-runtime.js +18 -0
- package/lib/public/modules/plantuml-preview.js +12 -12
- package/lib/public/modules/right-workbench.js +116 -67
- package/lib/public/modules/scheduled-tasks.js +7 -6
- package/lib/public/modules/shared-browser.js +75 -9
- package/lib/public/modules/split-pane-renderer.js +7 -8
- package/lib/public/modules/split-pane-runtime.js +23 -0
- package/lib/public/modules/split-view-drag-preview.js +90 -0
- package/lib/public/modules/split-view-layout-client.js +1 -1
- package/lib/public/modules/split-view-presentation-drag.js +36 -13
- package/lib/public/modules/split-view-presentation-drop.js +21 -18
- package/lib/public/modules/split-view-presentation-renderer.js +15 -10
- package/lib/public/modules/split-view-presentations.js +25 -33
- package/lib/public/modules/split-view.js +17 -16
- package/lib/public/modules/sticky-notes-browser.js +2 -2
- package/lib/public/modules/sticky-notes.js +8 -10
- package/lib/public/modules/terminal.js +45 -13
- package/lib/public/modules/theme.js +1 -1
- package/lib/public/modules/tool-pane-chrome.js +82 -0
- package/lib/public/modules/tool-pane-drag.js +134 -0
- package/lib/public/modules/tool-pane-layout.js +95 -0
- package/lib/public/modules/tool-pane-legacy.js +60 -0
- package/lib/public/modules/tool-pane-tree.js +51 -0
- package/lib/public/modules/view-legacy-coordinates.js +16 -0
- package/lib/public/modules/view-mutations.js +24 -0
- package/lib/public/modules/view-pair-presentation.js +74 -0
- package/lib/public/modules/view-pair-validation.js +12 -0
- package/lib/public/modules/view-presentation-state.js +37 -0
- package/lib/public/modules/view-workspace-controller.js +210 -0
- package/lib/public/modules/view-workspace-state.js +103 -0
- package/lib/public/modules/view-workspace-validation.js +47 -0
- package/lib/public/modules/wireframe-workbench.js +11 -0
- package/lib/public/modules/workbench-layout-preference.js +12 -5
- package/lib/public/modules/workbench-panels.js +21 -0
- package/lib/public/modules/workspace-assignment-card.js +9 -6
- package/lib/public/pane-assets/{app-ED2VCGNQ.js → app-7UZ727NA.js} +1 -1
- package/lib/public/pane-assets/chunk-2AIWCI6Y.js +1 -0
- package/lib/public/pane-assets/chunk-6MIHIQ2W.js +1 -0
- package/lib/public/pane-assets/chunk-6NYCNWVF.js +1 -0
- package/lib/public/pane-assets/chunk-6QFLYOVY.js +1 -0
- package/lib/public/pane-assets/chunk-6UJ2ALOB.js +1 -0
- package/lib/public/pane-assets/chunk-6XK2OATZ.js +1 -0
- package/lib/public/pane-assets/chunk-BKIDR2ME.js +1 -0
- package/lib/public/pane-assets/chunk-BMHTBRMO.js +1 -0
- package/lib/public/pane-assets/chunk-GEFCFZEN.js +1 -0
- package/lib/public/pane-assets/chunk-GN2NQEVC.js +2 -0
- package/lib/public/pane-assets/chunk-IMLMBPT4.js +166 -0
- package/lib/public/pane-assets/chunk-JIV7O5GN.js +1 -0
- package/lib/public/pane-assets/chunk-K5S6AILM.js +1 -0
- package/lib/public/pane-assets/chunk-LDIZLKB2.js +1 -0
- package/lib/public/pane-assets/chunk-OWNNLZ36.js +1 -0
- package/lib/public/pane-assets/chunk-P2C3LOWL.js +3 -0
- package/lib/public/pane-assets/chunk-PV4PCH2V.js +2 -0
- package/lib/public/pane-assets/chunk-R4LMPTKU.js +1 -0
- package/lib/public/pane-assets/chunk-R7QVVFUG.js +1 -0
- package/lib/public/pane-assets/chunk-TMGSDFJI.js +1 -0
- package/lib/public/pane-assets/chunk-VKYBAVWT.js +1 -0
- package/lib/public/pane-assets/chunk-VNAV23CM.js +1 -0
- package/lib/public/pane-assets/chunk-VWTHIQCE.js +1 -0
- package/lib/public/pane-assets/chunk-VZ2OKDAO.js +1 -0
- package/lib/public/pane-assets/chunk-WM3K5AFH.js +1 -0
- package/lib/public/pane-assets/chunk-XOB3O327.js +1 -0
- package/lib/public/pane-assets/chunk-XOOUCFYT.js +1 -0
- package/lib/public/pane-assets/manifest.json +383 -336
- package/lib/public/pane-assets/style-ZM7OOU3M.css +1 -0
- package/lib/public/style.css +1 -0
- package/lib/server-workbench-layout-settings.js +3 -3
- package/lib/server.js +1 -0
- package/lib/split-view-layout.js +11 -7
- package/lib/users-workbench-layout-preferences.js +14 -4
- package/lib/workbench-window-layout.js +30 -0
- package/lib/workspace-assignment-service.js +56 -11
- package/lib/workspace-follow-up-queue.js +92 -0
- package/lib/workspace-query-mcp-server.js +1 -1
- package/package.json +1 -1
- package/lib/public/pane-assets/chunk-6D4DPE5X.js +0 -1
- package/lib/public/pane-assets/chunk-6SM2WQJX.js +0 -1
- package/lib/public/pane-assets/chunk-7H36SUZA.js +0 -2
- package/lib/public/pane-assets/chunk-DGOFGEUK.js +0 -1
- package/lib/public/pane-assets/chunk-I57URYSL.js +0 -1
- package/lib/public/pane-assets/chunk-IYFILQHZ.js +0 -2
- package/lib/public/pane-assets/chunk-IZ2ZANEY.js +0 -167
- package/lib/public/pane-assets/chunk-JAEQCN5S.js +0 -1
- package/lib/public/pane-assets/chunk-ST2Q62ET.js +0 -1
- package/lib/public/pane-assets/style-JVCOCG3W.css +0 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { WORKBENCH_PANELS } from './workbench-panels.js';
|
|
2
|
+
import { validLinkedPair } from './view-pair-validation.js';
|
|
3
|
+
import { sessionTree } from './view-workspace-state.js';
|
|
4
|
+
function id(value) { return typeof value === 'string' && /^[A-Za-z0-9_-]{1,128}$/.test(value); }
|
|
5
|
+
function runtime(value) { return id(value) || typeof value === 'string' && /^runtime:[A-Za-z0-9_-]{1,128}$/.test(value); }
|
|
6
|
+
function fields(value, names) { return value && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).sort().join(',') === names.split(',').sort().join(','); }
|
|
7
|
+
function sameTree(a, b) { return !a || !b ? a === b : a.id || b.id ? a.id === b.id : a.axis === b.axis && a.ratio === b.ratio && sameTree(a.left,b.left) && sameTree(a.right,b.right); }
|
|
8
|
+
export function validWorkspaceView(view) {
|
|
9
|
+
var value = view && view.workspace;
|
|
10
|
+
if (!value || !fields(value, 'version,panes,tree,activePaneId' + (value.linkedPair === undefined ? '' : ',linkedPair') + (value.presentation === undefined ? '' : ',presentation')) || value.version !== 1 || !Array.isArray(value.panes) || value.panes.length > 24) return false;
|
|
11
|
+
var instances = [], origins = [], docked = [], open = [], resources = [], tools = 0, files = 0, overlays = 0;
|
|
12
|
+
for (var i = 0; i < value.panes.length; i++) {
|
|
13
|
+
var p = value.panes[i], r = p && p.resource;
|
|
14
|
+
if (!fields(p, 'instanceId,kind,open,placement,resource') || !id(p.instanceId) || instances.indexOf(p.instanceId) >= 0 || typeof p.open !== 'boolean' || ['docked', 'overlay'].indexOf(p.placement) < 0) return false;
|
|
15
|
+
instances.push(p.instanceId);
|
|
16
|
+
if (p.kind === 'session') {
|
|
17
|
+
if (!fields(r, 'originId') || !id(r.originId) || origins.indexOf(r.originId) >= 0 || !p.open || p.placement !== 'docked') return false;
|
|
18
|
+
origins.push(r.originId);
|
|
19
|
+
} else {
|
|
20
|
+
if (++tools > 16) return false;
|
|
21
|
+
if (p.kind === 'file') {
|
|
22
|
+
if (++files > 8) return false;
|
|
23
|
+
if (!fields(r, 'path,mode,rendered') || typeof r.path !== 'string' || !r.path || r.path.length > 4096 || /[\\\x00-\x1f\x7f:]/.test(r.path) || !r.path.split('/').every(function(part) { return part && part !== '.' && part !== '..'; }) || ['follow', 'pin'].indexOf(r.mode) < 0 || typeof r.rendered !== 'boolean') return false;
|
|
24
|
+
} else if (p.kind === 'terminal' || p.kind === 'browser') {
|
|
25
|
+
if (!runtime(r && r.runtimeId)) return false;
|
|
26
|
+
if (p.kind === 'terminal' ? !fields(r, 'id,identity,runtimeId') || !Number.isSafeInteger(r.id) || r.id < 1 || !id(r.identity) : !fields(r, 'id,runtimeId,sessionOriginId') || !id(r.id) || !id(r.sessionOriginId)) return false;
|
|
27
|
+
var key = p.kind + ':' + r.runtimeId + ':' + r.id;
|
|
28
|
+
if (resources.indexOf(key) >= 0) return false;
|
|
29
|
+
resources.push(key);
|
|
30
|
+
} else if (p.kind === 'workbench') {
|
|
31
|
+
if (!fields(r, 'name') || !Object.prototype.hasOwnProperty.call(WORKBENCH_PANELS, r.name) || resources.indexOf('workbench:' + r.name) >= 0) return false;
|
|
32
|
+
resources.push('workbench:' + r.name);
|
|
33
|
+
} else return false;
|
|
34
|
+
}
|
|
35
|
+
if (p.open) { open.push(p.instanceId); if (p.placement === 'docked') docked.push(p.instanceId); else overlays++; }
|
|
36
|
+
}
|
|
37
|
+
if (origins.length !== view.sessions.length || view.sessions.some(function(s) { return origins.indexOf(s.sessionOriginId) < 0; }) || overlays > 1 || (open.length ? open.indexOf(value.activePaneId) < 0 : value.activePaneId !== null)) return false;
|
|
38
|
+
var seen = [], nodes = 0;
|
|
39
|
+
function walk(node) {
|
|
40
|
+
if (++nodes > 47) return false;
|
|
41
|
+
if (fields(node, 'id')) { if (seen.indexOf(node.id) >= 0 || docked.indexOf(node.id) < 0) return false; seen.push(node.id); return true; }
|
|
42
|
+
return fields(node, 'axis,ratio,left,right') && ['horizontal', 'vertical'].indexOf(node.axis) >= 0 && Number.isFinite(node.ratio) && node.ratio >= .05 && node.ratio <= .95 && walk(node.left) && walk(node.right);
|
|
43
|
+
}
|
|
44
|
+
if (docked.length ? !walk(value.tree) || seen.length !== docked.length : value.tree !== null) return false;
|
|
45
|
+
if (value.presentation !== undefined && (!fields(value.presentation, 'focusedSessionOriginId,expandedPaneId') || value.presentation.focusedSessionOriginId !== null && origins.indexOf(value.presentation.focusedSessionOriginId) < 0 || value.presentation.expandedPaneId !== null && !value.panes.some(function (p) { return p.kind !== 'session' && p.open && p.instanceId === value.presentation.expandedPaneId; }))) return false;
|
|
46
|
+
return sameTree(sessionTree(value), view.tree) && (value.linkedPair === undefined || validLinkedPair(value.linkedPair, value, { sessionRefs: view.sessions.map(function (s) { return { originId: s.sessionOriginId }; }) }));
|
|
47
|
+
}
|
|
@@ -90,6 +90,7 @@ export function openWireframe(message) {
|
|
|
90
90
|
var draft = { source: wireframeSource(message.source, message.language), title: String(message.title || 'clay-sketch').slice(0, 100),
|
|
91
91
|
id: /^[a-zA-Z0-9_-]{1,80}$/.test(message.id || '') ? message.id : 'wireframe' };
|
|
92
92
|
store.set({ wireframeDraft: draft });
|
|
93
|
+
el.querySelector('[data-save]').disabled = false; el.querySelector('[data-download]').disabled = false;
|
|
93
94
|
el.querySelector('header strong').textContent = draft.title;
|
|
94
95
|
el.querySelector('.wireframe-save-status').textContent = '';
|
|
95
96
|
el.querySelector('form').hidden = true;
|
|
@@ -117,3 +118,13 @@ registerRightWorkbench('wireframe', closeWireframe);
|
|
|
117
118
|
store.subscribe(function (state, previous) {
|
|
118
119
|
if (state.currentSlug !== previous.currentSlug || state.activeSessionId !== previous.activeSessionId || state.myUserId !== previous.myUserId) closeWireframe();
|
|
119
120
|
});
|
|
121
|
+
|
|
122
|
+
export function restoreWireframeWorkbench() {
|
|
123
|
+
var draft = store.get('wireframeDraft');
|
|
124
|
+
if (draft) { openWireframe(draft); return; }
|
|
125
|
+
var el = panel() || createPanel();
|
|
126
|
+
if (!el) return;
|
|
127
|
+
claimRightWorkbench('wireframe'); el.classList.remove('hidden');
|
|
128
|
+
el.querySelector('[data-save]').disabled = true; el.querySelector('[data-download]').disabled = true;
|
|
129
|
+
el.querySelector('.wireframe-workbench-canvas').textContent = 'Open a sketch to view it here.';
|
|
130
|
+
}
|
|
@@ -8,7 +8,7 @@ function state() { return store.get('workbenchLayoutPreference'); }
|
|
|
8
8
|
function defaults(previous) {
|
|
9
9
|
var same = previous && previous.accountId === account();
|
|
10
10
|
return { mode: same ? previous.mode : 'overlay', accountId: account(), ready: false, loading: false, saving: false,
|
|
11
|
-
error: '', socket: getWs(), revision: same ? previous.revision : 0, generation: (previous && previous.generation || 0) + 1, checkedAt: 0 };
|
|
11
|
+
layouts: same ? previous.layouts || {} : {}, error: '', socket: getWs(), revision: same ? previous.revision : 0, generation: (previous && previous.generation || 0) + 1, checkedAt: 0 };
|
|
12
12
|
}
|
|
13
13
|
function initialize() {
|
|
14
14
|
if (!state() || state().accountId !== account() || state().socket !== getWs()) store.set({ workbenchLayoutPreference: defaults(state()) });
|
|
@@ -21,7 +21,7 @@ function current(receipt) {
|
|
|
21
21
|
store.get('connected') === receipt.connected && store.get('authIdentityLoaded') === receipt.identity &&
|
|
22
22
|
store.get('projectSplitViewSocketGeneration') === receipt.socketGeneration;
|
|
23
23
|
}
|
|
24
|
-
function request(mode) {
|
|
24
|
+
function request(mode, layout) {
|
|
25
25
|
var before = initialize(), saving = mode !== undefined;
|
|
26
26
|
var receipt = { generation: before.generation, project: store.get('currentSlug'), socket: getWs(),
|
|
27
27
|
connected: store.get('connected'), identity: store.get('authIdentityLoaded'), socketGeneration: store.get('projectSplitViewSocketGeneration') };
|
|
@@ -33,14 +33,15 @@ function request(mode) {
|
|
|
33
33
|
if (!current(receipt)) return false;
|
|
34
34
|
var response = await fetch(endpoint, { method: saving ? 'PUT' : 'GET', credentials: 'same-origin', cache: 'no-store', signal: controller.signal,
|
|
35
35
|
headers: { 'Content-Type': 'application/json', 'X-Clay-Settings': '1', 'X-Clay-Account-Id': before.accountId },
|
|
36
|
-
body: saving ? JSON.stringify({ mode: mode, revision: before.revision }) : undefined });
|
|
36
|
+
body: saving ? JSON.stringify(Object.assign({ mode: mode, revision: before.revision }, layout ? { layout: layout } : {})) : undefined });
|
|
37
37
|
var data = await response.json();
|
|
38
38
|
if (!current(receipt)) return false;
|
|
39
39
|
if (!response.ok) throw new Error(response.status === 409 ? 'Workbench layout changed elsewhere. Reload the preference and try again.' :
|
|
40
40
|
saving ? 'Workbench layout could not be saved. Reload the preference before trying again.' : 'Workbench layout could not be loaded. Try again.');
|
|
41
41
|
if (!data || data.accountId !== before.accountId || !validMode(data.mode) || !Number.isSafeInteger(data.revision) || data.revision < before.revision || data.revision === before.revision && data.mode !== before.mode ||
|
|
42
|
-
saving && (data.mode !== mode || data.revision !== before.revision + (mode === before.mode ? 0 : 1))) throw new Error('Workbench preference response is stale. Reload and try again.');
|
|
43
|
-
|
|
42
|
+
saving && (data.mode !== mode || data.revision !== before.revision + (mode === before.mode && (!layout || JSON.stringify((before.layouts || {})[layout.key]) === JSON.stringify({ base: layout.base, tree: layout.tree })) ? 0 : 1))) throw new Error('Workbench preference response is stale. Reload and try again.');
|
|
43
|
+
if (layout && (!data.layouts || JSON.stringify(data.layouts[layout.key]) !== JSON.stringify({ base: layout.base, tree: layout.tree }))) throw new Error('Window layout response is stale. Reload and try again.');
|
|
44
|
+
store.set({ workbenchLayoutPreference: Object.assign({}, state(), { mode: data.mode, revision: data.revision, layouts: data.layouts || {},
|
|
44
45
|
ready: true, loading: false, saving: false, error: '', checkedAt: Date.now(), receipt: null, promise: null }) });
|
|
45
46
|
return true;
|
|
46
47
|
} catch (error) {
|
|
@@ -74,3 +75,9 @@ store.subscribe(function (next, previous) {
|
|
|
74
75
|
store.set({ workbenchLayoutPreference: defaults(state()) });
|
|
75
76
|
}
|
|
76
77
|
});
|
|
78
|
+
|
|
79
|
+
export function saveWorkbenchWindowLayout(key, tree, base) {
|
|
80
|
+
var value = initialize();
|
|
81
|
+
if (!value.ready || value.loading || value.saving || !store.get('connected') || !store.get('authIdentityLoaded')) return Promise.resolve(false);
|
|
82
|
+
return request(value.mode, { key: key, tree: tree, base: base });
|
|
83
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// One registry for the non-resource workbenches and their existing entrypoints.
|
|
2
|
+
export var WORKBENCH_PANELS = {
|
|
3
|
+
'project-logs': { id: 'project-logs-panel', label: 'Logs', icon: 'notebook-text', open: 'openProjectLogs', load: function () { return import('./project-logs.js'); } },
|
|
4
|
+
you: { id: 'you-panel', label: 'Me', icon: 'user', open: 'openYou', load: function () { return import('./you.js'); } },
|
|
5
|
+
issues: { id: 'issues-panel', label: 'Issues', icon: 'circle-dot', open: 'openIssues', load: function () { return import('./issues.js'); } },
|
|
6
|
+
linear: { id: 'linear-panel', label: 'Linear', icon: 'list-todo', open: 'openLinear', load: function () { return import('./linear-panel.js'); } },
|
|
7
|
+
'notes-browser': { id: 'notes-browser', label: 'Sticky Notes', icon: 'sticky-note', open: 'openNotesBrowser', load: function () { return import('./sticky-notes-browser.js'); } },
|
|
8
|
+
'scheduled-tasks': { id: 'scheduled-tasks-panel', label: 'Scheduled Tasks', icon: 'calendar-clock', open: 'openScheduledTasks', load: function () { return import('./scheduled-tasks.js'); } },
|
|
9
|
+
debates: { id: 'debates-workbench', label: 'Debates', icon: 'messages-square', open: 'openDebatesWorkbench', load: function () { return import('./debates-workbench.js'); } },
|
|
10
|
+
'mcp-skills': { id: 'mcp-skills-workbench', label: 'MCP / Skills', icon: 'blocks', open: 'openMcpSkillsWorkbench', load: function () { return import('./mcp-skills-workbench.js'); } },
|
|
11
|
+
'mate-knowledge': { id: 'mate-knowledge-workbench', label: 'Knowledge', icon: 'book-open', open: 'openKnowledgeWorkbench', load: function () { return import('./mate-knowledge-workbench.js'); } },
|
|
12
|
+
wireframe: { id: 'wireframe-panel', label: 'Sketch', icon: 'panels-top-left', open: 'restoreWireframeWorkbench', load: function () { return import('./wireframe-workbench.js'); } }
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function setWorkbenchExpanded(name, expanded) {
|
|
16
|
+
var definition = WORKBENCH_PANELS[name], panel = definition && document.getElementById(definition.id);
|
|
17
|
+
if (!panel || panel.classList.contains('panel-fullscreen') === expanded) return;
|
|
18
|
+
var button = panel.querySelector('header button[aria-label*="fullscreen"], header button[title*="fullscreen"]');
|
|
19
|
+
if (button) button.click();
|
|
20
|
+
else panel.classList.toggle('panel-fullscreen', expanded);
|
|
21
|
+
}
|
|
@@ -11,6 +11,7 @@ function textElement(tag, className, text) {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
function statusLabel(status) {
|
|
14
|
+
if (status === "queued") return "Queued for Driver";
|
|
14
15
|
if (status === "starting") return "Starting";
|
|
15
16
|
if (status === "running") return "In progress";
|
|
16
17
|
if (status === "completed") return "Completed";
|
|
@@ -22,7 +23,7 @@ function statusLabel(status) {
|
|
|
22
23
|
|
|
23
24
|
function sendDecision(assignment, action, surface, context, card, opener) {
|
|
24
25
|
var ws = getWs();
|
|
25
|
-
if (!ws || ws.readyState !== 1 || !assignment || assignment.status !== "proposed") return false;
|
|
26
|
+
if (!ws || ws.readyState !== 1 || !assignment || (assignment.status !== "proposed" && !(assignment.status === "queued" && action === "cancel"))) return false;
|
|
26
27
|
pendingFocus[assignment.assignmentId] = opener || null;
|
|
27
28
|
card.setAttribute("aria-busy", "true");
|
|
28
29
|
var buttons = card.querySelectorAll("button");
|
|
@@ -79,10 +80,12 @@ export function createWorkspaceAssignmentCard(assignment, options) {
|
|
|
79
80
|
card.appendChild(header);
|
|
80
81
|
|
|
81
82
|
var targetText = followUp
|
|
82
|
-
? "
|
|
83
|
+
? "Send instructions to “" + (assignment.targetSessionTitle || "Existing session") + "” in " + (assignment.projectTitle || assignment.projectSlug || "project")
|
|
83
84
|
: "New private session in " + (assignment.projectTitle || assignment.projectSlug || "project");
|
|
84
85
|
var target = textElement("p", "workspace-assignment-target", targetText);
|
|
85
86
|
card.appendChild(target);
|
|
87
|
+
if (assignment.status === 'queued' && assignment.deliveryState === 'queued') card.appendChild(textElement('p', 'workspace-assignment-result', 'Approved. Waiting for the Driver to finish its current turn.'));
|
|
88
|
+
else if (assignment.deliveryState === 'accepted' && assignment.status === 'running') card.appendChild(textElement('p', 'workspace-assignment-result', 'Accepted by the Driver runtime. Completion is still pending.'));
|
|
86
89
|
card.appendChild(textElement("p", "workspace-assignment-task", assignment.task || ""));
|
|
87
90
|
|
|
88
91
|
if (assignment.error) {
|
|
@@ -94,17 +97,17 @@ export function createWorkspaceAssignmentCard(assignment, options) {
|
|
|
94
97
|
|
|
95
98
|
var actions = document.createElement("div");
|
|
96
99
|
actions.className = "workspace-assignment-actions";
|
|
97
|
-
if (assignment.status === "proposed") {
|
|
98
|
-
var cancel = textElement("button", "workspace-assignment-action secondary", "Cancel");
|
|
100
|
+
if (assignment.status === "proposed" || assignment.status === "queued") {
|
|
101
|
+
var cancel = textElement("button", "workspace-assignment-action secondary", assignment.status === "queued" ? "Cancel queued update" : "Cancel");
|
|
99
102
|
cancel.type = "button";
|
|
100
|
-
cancel.setAttribute("aria-label", "Cancel project assignment");
|
|
103
|
+
cancel.setAttribute("aria-label", assignment.status === "queued" ? "Cancel queued update" : "Cancel project assignment");
|
|
101
104
|
cancel.addEventListener("click", function () { sendDecision(assignment, "cancel", config.home ? "home" : "project", config.context, card, cancel); });
|
|
102
105
|
var approve = textElement("button", "workspace-assignment-action primary", "Approve");
|
|
103
106
|
approve.type = "button";
|
|
104
107
|
approve.setAttribute("aria-label", followUp ? "Approve follow-up in " + (assignment.targetSessionTitle || "the target session") : "Approve new session in " + (assignment.projectTitle || assignment.projectSlug || "the target project"));
|
|
105
108
|
approve.addEventListener("click", function () { sendDecision(assignment, "approve", config.home ? "home" : "project", config.context, card, approve); });
|
|
106
109
|
actions.appendChild(cancel);
|
|
107
|
-
actions.appendChild(approve);
|
|
110
|
+
if (assignment.status === "proposed") actions.appendChild(approve);
|
|
108
111
|
} else {
|
|
109
112
|
var resolved = textElement("span", "workspace-assignment-resolved", statusLabel(assignment.status));
|
|
110
113
|
resolved.setAttribute("role", "status");
|