python-codex 0.3.1__py3-none-any.whl → 0.3.3__py3-none-any.whl
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.
- pycodex/__main__.py +4 -0
- pycodex/model.py +11 -2
- {python_codex-0.3.1.dist-info → python_codex-0.3.3.dist-info}/METADATA +77 -5
- {python_codex-0.3.1.dist-info → python_codex-0.3.3.dist-info}/RECORD +18 -11
- responses_server/stream_router.py +17 -13
- workspace_server/app.py +203 -10
- workspace_server/content_views.LICENSE.txt +470 -0
- workspace_server/content_views.css +1 -0
- workspace_server/content_views.mjs +25 -0
- workspace_server/editor.css +1 -0
- workspace_server/editor.mjs +1260 -0
- workspace_server/workspace.html +118 -62
- workspace_server/workspace_views.py +533 -0
- workspace_server/workspaces.html +2 -2
- workspace_server/workspaces.py +4 -0
- {python_codex-0.3.1.dist-info → python_codex-0.3.3.dist-info}/WHEEL +0 -0
- {python_codex-0.3.1.dist-info → python_codex-0.3.3.dist-info}/entry_points.txt +0 -0
- {python_codex-0.3.1.dist-info → python_codex-0.3.3.dist-info}/licenses/LICENSE +0 -0
workspace_server/workspace.html
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
6
|
<title>__WORKSPACE_TITLE__</title>
|
|
7
7
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.css">
|
|
8
|
+
<link rel="stylesheet" href="assets/content_views.css">
|
|
8
9
|
<style>
|
|
9
10
|
:root {
|
|
10
11
|
color-scheme: light;
|
|
@@ -78,61 +79,18 @@
|
|
|
78
79
|
min-width: 0;
|
|
79
80
|
border-bottom: 1px solid var(--line);
|
|
80
81
|
height: 44px;
|
|
81
|
-
padding: 0
|
|
82
|
+
padding: 0 8px;
|
|
82
83
|
color: var(--muted);
|
|
83
84
|
font-size: 12px;
|
|
84
85
|
display: flex;
|
|
85
86
|
align-items: center;
|
|
86
|
-
gap:
|
|
87
|
+
gap: 8px;
|
|
87
88
|
white-space: nowrap;
|
|
88
89
|
overflow: hidden;
|
|
89
90
|
}
|
|
90
|
-
.boardbar-paths {
|
|
91
|
-
min-width: 0;
|
|
92
|
-
display: flex;
|
|
93
|
-
align-items: baseline;
|
|
94
|
-
gap: 12px;
|
|
95
|
-
overflow: hidden;
|
|
96
|
-
line-height: 1.4;
|
|
97
|
-
}
|
|
98
|
-
.boardbar-title {
|
|
99
|
-
color: var(--ink);
|
|
100
|
-
font-size: 14px;
|
|
101
|
-
font-weight: 600;
|
|
102
|
-
}
|
|
103
|
-
.boardbar-paths code { border: 0; padding: 0; background: none; font-size: 11px; }
|
|
104
|
-
.board-location { margin-left: auto; font-size: 11px; overflow: hidden; text-overflow: ellipsis; }
|
|
105
|
-
.boardbar-paths span {
|
|
106
|
-
min-width: 0;
|
|
107
|
-
overflow: hidden;
|
|
108
|
-
text-overflow: ellipsis;
|
|
109
|
-
}
|
|
110
91
|
.workspace-back {
|
|
111
|
-
flex: 0 0 auto;
|
|
112
|
-
display: inline-flex;
|
|
113
|
-
align-items: center;
|
|
114
|
-
justify-content: center;
|
|
115
|
-
width: 32px;
|
|
116
|
-
height: 32px;
|
|
117
|
-
border: 0;
|
|
118
|
-
border-radius: var(--radius-sm);
|
|
119
|
-
background: transparent;
|
|
120
|
-
color: var(--ink);
|
|
121
|
-
padding: 0;
|
|
122
92
|
text-decoration: none;
|
|
123
93
|
}
|
|
124
|
-
.workspace-back:hover {
|
|
125
|
-
background: var(--accent-soft);
|
|
126
|
-
}
|
|
127
|
-
.workspace-back:focus {
|
|
128
|
-
outline: 2px solid var(--accent);
|
|
129
|
-
outline-offset: 1px;
|
|
130
|
-
}
|
|
131
|
-
.workspace-back svg {
|
|
132
|
-
display: block;
|
|
133
|
-
width: 18px;
|
|
134
|
-
height: 18px;
|
|
135
|
-
}
|
|
136
94
|
.board {
|
|
137
95
|
border: 0;
|
|
138
96
|
min-width: 0;
|
|
@@ -286,7 +244,10 @@
|
|
|
286
244
|
gap: 4px;
|
|
287
245
|
min-width: 0;
|
|
288
246
|
overflow-x: auto;
|
|
289
|
-
scrollbar-width:
|
|
247
|
+
scrollbar-width: none;
|
|
248
|
+
}
|
|
249
|
+
.tabs::-webkit-scrollbar {
|
|
250
|
+
display: none;
|
|
290
251
|
}
|
|
291
252
|
.tab {
|
|
292
253
|
position: relative;
|
|
@@ -309,7 +270,8 @@
|
|
|
309
270
|
background: var(--panel-hover);
|
|
310
271
|
color: var(--ink);
|
|
311
272
|
}
|
|
312
|
-
.tab-new:focus-visible
|
|
273
|
+
.tab-new:focus-visible,
|
|
274
|
+
.workspace-back:focus-visible {
|
|
313
275
|
outline: 2px solid var(--accent);
|
|
314
276
|
outline-offset: 1px;
|
|
315
277
|
}
|
|
@@ -375,7 +337,8 @@
|
|
|
375
337
|
user-select: text;
|
|
376
338
|
}
|
|
377
339
|
.tab-close,
|
|
378
|
-
.tab-new
|
|
340
|
+
.tab-new,
|
|
341
|
+
.workspace-back {
|
|
379
342
|
width: 31px;
|
|
380
343
|
height: 31px;
|
|
381
344
|
border: 0;
|
|
@@ -403,14 +366,16 @@
|
|
|
403
366
|
width: 12px;
|
|
404
367
|
height: 12px;
|
|
405
368
|
}
|
|
406
|
-
.tab-new
|
|
369
|
+
.tab-new,
|
|
370
|
+
.workspace-back {
|
|
407
371
|
display: grid;
|
|
408
372
|
place-items: center;
|
|
409
373
|
width: 30px;
|
|
410
374
|
height: 30px;
|
|
411
375
|
background: var(--panel-deep);
|
|
412
376
|
}
|
|
413
|
-
.tab-new svg
|
|
377
|
+
.tab-new svg,
|
|
378
|
+
.workspace-back svg {
|
|
414
379
|
display: block;
|
|
415
380
|
width: 18px;
|
|
416
381
|
height: 18px;
|
|
@@ -425,7 +390,8 @@
|
|
|
425
390
|
cursor: default;
|
|
426
391
|
}
|
|
427
392
|
.tab-close:hover,
|
|
428
|
-
.tab-new:hover
|
|
393
|
+
.tab-new:hover,
|
|
394
|
+
.workspace-back:hover {
|
|
429
395
|
color: var(--ink);
|
|
430
396
|
background: var(--panel-hover);
|
|
431
397
|
}
|
|
@@ -913,8 +879,6 @@
|
|
|
913
879
|
.workspace[data-mobile-pane="chat"] .board-pane,
|
|
914
880
|
.workspace[data-mobile-pane="board"] .chat { display: none; }
|
|
915
881
|
.topbar { height: 44px; padding: 6px 16px; }
|
|
916
|
-
.boardbar { padding: 0 16px; }
|
|
917
|
-
.board-location { display: none; }
|
|
918
882
|
.log { padding: 14px 16px; gap: 14px; }
|
|
919
883
|
.composer { padding: 8px 16px max(10px, env(safe-area-inset-bottom)); }
|
|
920
884
|
textarea { font-size: 16px; line-height: 24px; padding: 2px 0; }
|
|
@@ -933,11 +897,9 @@
|
|
|
933
897
|
<path d="M15 6l-6 6 6 6"/>
|
|
934
898
|
</svg>
|
|
935
899
|
</a>
|
|
936
|
-
<div class="
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
</div>
|
|
940
|
-
<span class="board-location" title="__BOARD_LABEL__">Board</span>
|
|
900
|
+
<div id="contentTabs" class="tabs content-tabs" role="tablist" aria-label="Board views"
|
|
901
|
+
data-board-title="Workspace: __WORKSPACE_TITLE__ Current dir: __CWD_LABEL__ Canvas file: __BOARD_LABEL__"></div>
|
|
902
|
+
<span id="viewStatus" class="content-status" role="status" hidden></span>
|
|
941
903
|
<button class="pane-toggle" type="button" data-pane="chat" title="Show chat" aria-label="Show chat">
|
|
942
904
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"
|
|
943
905
|
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
@@ -945,7 +907,10 @@
|
|
|
945
907
|
</svg>
|
|
946
908
|
</button>
|
|
947
909
|
</div>
|
|
948
|
-
<
|
|
910
|
+
<div class="content-area">
|
|
911
|
+
<iframe id="boardFrame" class="board" src="board" title="Canvas"></iframe>
|
|
912
|
+
<div id="contentView" class="content-view" role="tabpanel" hidden></div>
|
|
913
|
+
</div>
|
|
949
914
|
</section>
|
|
950
915
|
<button id="splitter" class="splitter" type="button" aria-label="Resize chat panel"></button>
|
|
951
916
|
<section class="chat" aria-label="pycodex chat">
|
|
@@ -1025,7 +990,9 @@
|
|
|
1025
990
|
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.2.6/dist/purify.min.js"></script>
|
|
1026
991
|
<script src="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.js"></script>
|
|
1027
992
|
<script src="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/contrib/auto-render.min.js"></script>
|
|
1028
|
-
<script>
|
|
993
|
+
<script type="module">
|
|
994
|
+
import {isWorkspaceLink, mountContentViews} from "./assets/content_views.mjs";
|
|
995
|
+
|
|
1029
996
|
const log = document.getElementById("log");
|
|
1030
997
|
const spinner = document.getElementById("spinner");
|
|
1031
998
|
const queueHint = document.getElementById("queueHint");
|
|
@@ -1060,6 +1027,18 @@
|
|
|
1060
1027
|
const markdownRenderer = window.markdownit
|
|
1061
1028
|
? window.markdownit({html: false, linkify: true, breaks: false})
|
|
1062
1029
|
: null;
|
|
1030
|
+
if (markdownRenderer) {
|
|
1031
|
+
markdownRenderer.renderer.rules.link_open = (tokens, index, options, env, renderer) => {
|
|
1032
|
+
const token = tokens[index];
|
|
1033
|
+
const href = token.attrGet("href");
|
|
1034
|
+
if (isWorkspaceLink(href)) {
|
|
1035
|
+
token.attrSet("data-workspace-link", href);
|
|
1036
|
+
// Preserve file/URI destinations without widening DOMPurify's protocol allowlist.
|
|
1037
|
+
token.attrSet("href", "#");
|
|
1038
|
+
}
|
|
1039
|
+
return renderer.renderToken(tokens, index, options);
|
|
1040
|
+
};
|
|
1041
|
+
}
|
|
1063
1042
|
const mathDelimiters = [
|
|
1064
1043
|
{left: "$$", right: "$$", display: true},
|
|
1065
1044
|
{left: "\\[", right: "\\]", display: true},
|
|
@@ -1146,8 +1125,13 @@
|
|
|
1146
1125
|
});
|
|
1147
1126
|
renderProtectedMath(root, protectedMath.expressions);
|
|
1148
1127
|
root.querySelectorAll("a").forEach((anchor) => {
|
|
1149
|
-
|
|
1150
|
-
|
|
1128
|
+
const link = anchor.getAttribute("data-workspace-link");
|
|
1129
|
+
if (isWorkspaceLink(link)) {
|
|
1130
|
+
anchor.setAttribute("href", link);
|
|
1131
|
+
} else if (!(anchor.getAttribute("href") || "").startsWith("#")) {
|
|
1132
|
+
anchor.target = "_blank";
|
|
1133
|
+
anchor.rel = "noopener noreferrer";
|
|
1134
|
+
}
|
|
1151
1135
|
});
|
|
1152
1136
|
renderMermaidInto(root);
|
|
1153
1137
|
}
|
|
@@ -2206,6 +2190,78 @@
|
|
|
2206
2190
|
resizePrompt();
|
|
2207
2191
|
startPolling();
|
|
2208
2192
|
startBoardPolling();
|
|
2193
|
+
document.querySelectorAll(".tabs").forEach(tabs => {
|
|
2194
|
+
tabs.addEventListener("wheel", event => {
|
|
2195
|
+
if (event.ctrlKey || event.shiftKey || event.deltaX !== 0 || event.deltaY === 0) return;
|
|
2196
|
+
const previous = tabs.scrollLeft;
|
|
2197
|
+
const unit = event.deltaMode === 1 ? tabs.clientHeight : event.deltaMode === 2 ? tabs.clientWidth : 1;
|
|
2198
|
+
tabs.scrollLeft += event.deltaY * unit;
|
|
2199
|
+
if (tabs.scrollLeft !== previous) event.preventDefault();
|
|
2200
|
+
}, {passive: false});
|
|
2201
|
+
});
|
|
2202
|
+
|
|
2203
|
+
const contentTabs = mountContentViews({
|
|
2204
|
+
tabs: document.getElementById("contentTabs"),
|
|
2205
|
+
frame: document.getElementById("boardFrame"),
|
|
2206
|
+
content: document.getElementById("contentView"),
|
|
2207
|
+
status: document.getElementById("viewStatus"),
|
|
2208
|
+
storage: window.localStorage,
|
|
2209
|
+
storageKey: "pycodex.workspace.contentTab:" + window.location.pathname,
|
|
2210
|
+
renderMarkdown: renderMarkdownInto,
|
|
2211
|
+
request: async (path, options = {}) => {
|
|
2212
|
+
const response = await fetch(new URL(path, window.location.href), options);
|
|
2213
|
+
const payload = await response.json();
|
|
2214
|
+
if (!response.ok) throw new Error(payload.detail || "HTTP " + response.status);
|
|
2215
|
+
return payload;
|
|
2216
|
+
},
|
|
2217
|
+
});
|
|
2218
|
+
let canvasDocument = null;
|
|
2219
|
+
|
|
2220
|
+
function followViewLink(event, href) {
|
|
2221
|
+
if (event.defaultPrevented || event.button !== 0) return;
|
|
2222
|
+
event.preventDefault();
|
|
2223
|
+
contentTabs.open(href).catch(error => showToast("Unable to open view: " + error.message));
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2226
|
+
function followMarkdownLink(event) {
|
|
2227
|
+
const anchor = event.target.closest("a[data-workspace-link]");
|
|
2228
|
+
if (anchor) followViewLink(event, anchor.getAttribute("data-workspace-link"));
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2231
|
+
function followCanvasLink(event) {
|
|
2232
|
+
const anchor = event.target.closest("a[href]");
|
|
2233
|
+
if (anchor && isWorkspaceLink(anchor.getAttribute("href"), false)) {
|
|
2234
|
+
followViewLink(event, anchor.getAttribute("href"));
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
|
|
2238
|
+
function bindCanvasLinks() {
|
|
2239
|
+
if (canvasDocument) canvasDocument.removeEventListener("click", followCanvasLink);
|
|
2240
|
+
canvasDocument = boardFrame.contentDocument;
|
|
2241
|
+
if (canvasDocument) canvasDocument.addEventListener("click", followCanvasLink);
|
|
2242
|
+
}
|
|
2243
|
+
|
|
2244
|
+
function startContentViews() {
|
|
2245
|
+
document.addEventListener("click", followMarkdownLink);
|
|
2246
|
+
boardFrame.addEventListener("load", bindCanvasLinks);
|
|
2247
|
+
bindCanvasLinks();
|
|
2248
|
+
contentTabs.start();
|
|
2249
|
+
}
|
|
2250
|
+
|
|
2251
|
+
function stopContentViews() {
|
|
2252
|
+
document.removeEventListener("click", followMarkdownLink);
|
|
2253
|
+
boardFrame.removeEventListener("load", bindCanvasLinks);
|
|
2254
|
+
if (canvasDocument) canvasDocument.removeEventListener("click", followCanvasLink);
|
|
2255
|
+
canvasDocument = null;
|
|
2256
|
+
contentTabs.stop();
|
|
2257
|
+
}
|
|
2258
|
+
|
|
2259
|
+
startContentViews();
|
|
2260
|
+
window.addEventListener("pagehide", stopContentViews);
|
|
2261
|
+
window.addEventListener("pageshow", startContentViews);
|
|
2262
|
+
document.addEventListener("visibilitychange", () => {
|
|
2263
|
+
if (document.visibilityState === "visible") contentTabs.poll();
|
|
2264
|
+
});
|
|
2209
2265
|
</script>
|
|
2210
2266
|
</body>
|
|
2211
2267
|
</html>
|