jupyterlab-codex-sidebar 0.1.4 → 0.1.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/.claude/settings.local.json +9 -0
- package/.github/workflows/unit-tests.yml +27 -0
- package/.jupyterlab-playwright.log +0 -0
- package/README.md +83 -9
- package/docs/images/codex-sidebar-screenshot.png +0 -0
- package/jupyterlab_codex/handlers.py +938 -297
- package/jupyterlab_codex/labextension/package.json +13 -3
- package/jupyterlab_codex/labextension/static/525.224526d045c727069de6.js +2 -0
- package/jupyterlab_codex/labextension/static/737.e7de3ad9dd6ded798340.js +1 -0
- package/jupyterlab_codex/labextension/static/remoteEntry.6ef5e7167763a316c000.js +1 -0
- package/jupyterlab_codex/protocol.py +297 -0
- package/jupyterlab_codex/runner.py +58 -15
- package/jupyterlab_codex/sessions.py +582 -97
- package/lib/codexChat.d.ts +13 -0
- package/lib/codexChat.js +2506 -0
- package/lib/codexChat.js.map +1 -0
- package/lib/codexChatAttachmentDedup.d.ts +10 -0
- package/lib/codexChatAttachmentDedup.js +35 -0
- package/lib/codexChatAttachmentDedup.js.map +1 -0
- package/lib/codexChatAttachmentLimit.d.ts +18 -0
- package/lib/codexChatAttachmentLimit.js +50 -0
- package/lib/codexChatAttachmentLimit.js.map +1 -0
- package/lib/codexChatAttachmentState.d.ts +15 -0
- package/lib/codexChatAttachmentState.js +16 -0
- package/lib/codexChatAttachmentState.js.map +1 -0
- package/lib/codexChatDocumentUtils.d.ts +70 -0
- package/lib/codexChatDocumentUtils.js +506 -0
- package/lib/codexChatDocumentUtils.js.map +1 -0
- package/lib/codexChatFormatting.d.ts +11 -0
- package/lib/codexChatFormatting.js +83 -0
- package/lib/codexChatFormatting.js.map +1 -0
- package/lib/codexChatNotice.d.ts +3 -0
- package/lib/codexChatNotice.js +74 -0
- package/lib/codexChatNotice.js.map +1 -0
- package/lib/codexChatPersistence.d.ts +35 -0
- package/lib/codexChatPersistence.js +158 -0
- package/lib/codexChatPersistence.js.map +1 -0
- package/lib/codexChatPrimitives.d.ts +44 -0
- package/lib/codexChatPrimitives.js +156 -0
- package/lib/codexChatPrimitives.js.map +1 -0
- package/lib/codexChatRender.d.ts +24 -0
- package/lib/codexChatRender.js +293 -0
- package/lib/codexChatRender.js.map +1 -0
- package/lib/codexChatSessionFactory.d.ts +15 -0
- package/lib/codexChatSessionFactory.js +45 -0
- package/lib/codexChatSessionFactory.js.map +1 -0
- package/lib/codexChatSessionKey.d.ts +3 -0
- package/lib/codexChatSessionKey.js +14 -0
- package/lib/codexChatSessionKey.js.map +1 -0
- package/lib/codexChatStorage.d.ts +4 -0
- package/lib/codexChatStorage.js +37 -0
- package/lib/codexChatStorage.js.map +1 -0
- package/lib/codexSessionResolver.d.ts +12 -0
- package/lib/codexSessionResolver.js +38 -0
- package/lib/codexSessionResolver.js.map +1 -0
- package/lib/handlers/activitySummarizer.d.ts +15 -0
- package/lib/handlers/activitySummarizer.js +327 -0
- package/lib/handlers/activitySummarizer.js.map +1 -0
- package/lib/handlers/codexMessageTypes.d.ts +30 -0
- package/lib/handlers/codexMessageTypes.js +2 -0
- package/lib/handlers/codexMessageTypes.js.map +1 -0
- package/lib/handlers/codexMessageUtils.d.ts +46 -0
- package/lib/handlers/codexMessageUtils.js +144 -0
- package/lib/handlers/codexMessageUtils.js.map +1 -0
- package/lib/handlers/handleCodexSocketMessage.d.ts +107 -0
- package/lib/handlers/handleCodexSocketMessage.js +78 -0
- package/lib/handlers/handleCodexSocketMessage.js.map +1 -0
- package/lib/handlers/sessionSyncHandler.d.ts +34 -0
- package/lib/handlers/sessionSyncHandler.js +181 -0
- package/lib/handlers/sessionSyncHandler.js.map +1 -0
- package/lib/hooks/useCodexSocket.d.ts +15 -0
- package/lib/hooks/useCodexSocket.js +84 -0
- package/lib/hooks/useCodexSocket.js.map +1 -0
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/panel.d.ts +1 -11
- package/lib/panel.js +1 -2815
- package/lib/panel.js.map +1 -1
- package/lib/protocol.d.ts +235 -0
- package/lib/protocol.js +278 -0
- package/lib/protocol.js.map +1 -0
- package/package.json +13 -3
- package/playwright.config.cjs +27 -0
- package/playwright.unit.config.cjs +19 -0
- package/pyproject.toml +1 -1
- package/release.sh +52 -14
- package/scripts/run_playwright_e2e.sh +96 -0
- package/scripts/run_playwright_freeze_repro.sh +58 -0
- package/scripts/run_playwright_queue_repro.sh +60 -0
- package/scripts/run_playwright_repro.sh +55 -0
- package/src/codexChat.tsx +3914 -0
- package/src/codexChatAttachmentDedup.ts +47 -0
- package/src/codexChatAttachmentLimit.ts +81 -0
- package/src/codexChatAttachmentState.ts +37 -0
- package/src/codexChatDocumentUtils.ts +644 -0
- package/src/codexChatFormatting.ts +94 -0
- package/src/codexChatNotice.ts +95 -0
- package/src/codexChatPersistence.ts +191 -0
- package/src/codexChatPrimitives.tsx +446 -0
- package/src/codexChatRender.tsx +376 -0
- package/src/codexChatSessionFactory.ts +79 -0
- package/src/codexChatSessionKey.ts +16 -0
- package/src/codexChatStorage.ts +36 -0
- package/src/codexSessionResolver.ts +56 -0
- package/src/handlers/activitySummarizer.ts +369 -0
- package/src/handlers/codexMessageTypes.ts +34 -0
- package/src/handlers/codexMessageUtils.ts +217 -0
- package/src/handlers/handleCodexSocketMessage.ts +204 -0
- package/src/handlers/sessionSyncHandler.ts +308 -0
- package/src/hooks/useCodexSocket.ts +109 -0
- package/src/index.ts +1 -1
- package/src/panel.tsx +1 -4184
- package/src/protocol.ts +582 -0
- package/style/index.css +480 -11
- package/test-results/.last-run.json +4 -0
- package/test.py +0 -0
- package/tests/e2e/cell-output-error-tail.spec.js +156 -0
- package/tests/e2e/codex-ui-test-helpers.js +138 -0
- package/tests/e2e/fixtures/notebooks/error-output-tail.ipynb +58 -0
- package/tests/e2e/fixtures/notebooks/error-output-tail.py +19 -0
- package/tests/e2e/fixtures/notebooks/tab1.ipynb +322 -0
- package/tests/e2e/fixtures/notebooks/tab1.py +272 -0
- package/tests/e2e/fixtures/notebooks/tab2.ipynb +252 -0
- package/tests/e2e/fixtures/notebooks/tab2.py +231 -0
- package/tests/e2e/fixtures/notebooks/tab3.ipynb +403 -0
- package/tests/e2e/fixtures/notebooks/tab3.py +331 -0
- package/tests/e2e/fixtures/notebooks/tab4.py +339 -0
- package/tests/e2e/freeze-notebook-tabs-repro.spec.js +295 -0
- package/tests/e2e/mock-codex-cli-flood.py +127 -0
- package/tests/e2e/mock-codex-cli-prompt-echo.py +88 -0
- package/tests/e2e/mock-codex-cli.py +95 -0
- package/tests/e2e/queue-multitab-repro.spec.js +189 -0
- package/tests/test_handlers.py +116 -0
- package/tests/test_protocol.py +169 -0
- package/tests/test_session_store_limits.py +50 -0
- package/tests/unit/codexChatAttachmentDedup.spec.ts +56 -0
- package/tests/unit/codexChatAttachmentLimit.spec.ts +57 -0
- package/tests/unit/codexChatAttachmentState.spec.ts +71 -0
- package/tests/unit/codexChatDocumentUtils.spec.ts +63 -0
- package/tests/unit/codexChatLimit.spec.ts +18 -0
- package/tests/unit/codexChatNotice.spec.ts +45 -0
- package/tests/unit/codexChatPersistence.spec.ts +199 -0
- package/tests/unit/codexChatSessionFactory.spec.ts +94 -0
- package/tests/unit/codexChatSessionKey.spec.ts +18 -0
- package/tests/unit/codexMessageUtils.spec.ts +89 -0
- package/tests/unit/codexSessionResolver.spec.ts +92 -0
- package/tests/unit/handleCodexSocketMessage.spec.ts +476 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/webpack.config.js +6 -0
- package/jupyterlab_codex/labextension/static/504.335f3447c84ba3d74517.js +0 -2
- package/jupyterlab_codex/labextension/static/972.8e856719e40acc1ef4cb.js +0 -1
- package/jupyterlab_codex/labextension/static/remoteEntry.a2982f776a1f0f515640.js +0 -1
- /package/jupyterlab_codex/labextension/static/{504.335f3447c84ba3d74517.js.LICENSE.txt → 525.224526d045c727069de6.js.LICENSE.txt} +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { normalizeSelectionPreviewText, type NotebookMode } from './codexChatDocumentUtils';
|
|
2
|
+
|
|
3
|
+
const ACTIVE_CELL_ATTACHMENT_SIGNATURE_SEPARATOR = '\u241f';
|
|
4
|
+
const ACTIVE_CELL_ATTACHMENT_KIND_SELECTION = 'selection';
|
|
5
|
+
const ACTIVE_CELL_ATTACHMENT_KIND_OUTPUT = 'output';
|
|
6
|
+
|
|
7
|
+
export type ActiveCellAttachmentSignatureInput = {
|
|
8
|
+
notebookMode: NotebookMode;
|
|
9
|
+
text: string;
|
|
10
|
+
locationLabel?: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export function makeActiveCellAttachmentDedupKey(sessionKey: string, threadId: string): string {
|
|
14
|
+
const normalizedThreadId = (threadId || '').trim();
|
|
15
|
+
if (normalizedThreadId) {
|
|
16
|
+
return `thread:${normalizedThreadId}`;
|
|
17
|
+
}
|
|
18
|
+
return `session:${(sessionKey || '').trim()}`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function buildActiveCellAttachmentSignature(kind: string, input: ActiveCellAttachmentSignatureInput): string {
|
|
22
|
+
const notebookMode = input.notebookMode;
|
|
23
|
+
const text = normalizeSelectionPreviewText(input.text || '');
|
|
24
|
+
const locationLabel = (input.locationLabel || '').trim();
|
|
25
|
+
|
|
26
|
+
return [
|
|
27
|
+
kind,
|
|
28
|
+
notebookMode,
|
|
29
|
+
locationLabel,
|
|
30
|
+
text
|
|
31
|
+
].join(ACTIVE_CELL_ATTACHMENT_SIGNATURE_SEPARATOR);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function buildActiveCellSelectionSignature(input: ActiveCellAttachmentSignatureInput): string {
|
|
35
|
+
return buildActiveCellAttachmentSignature(ACTIVE_CELL_ATTACHMENT_KIND_SELECTION, input);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function buildActiveCellOutputSignature(input: ActiveCellAttachmentSignatureInput): string {
|
|
39
|
+
return buildActiveCellAttachmentSignature(ACTIVE_CELL_ATTACHMENT_KIND_OUTPUT, input);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function isDuplicateActiveCellAttachmentSignature(previous: string | undefined, next: string): boolean {
|
|
43
|
+
if (!previous || !next) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
return previous === next;
|
|
47
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export type ActiveCellAttachmentLimitResult = {
|
|
2
|
+
selection: string;
|
|
3
|
+
cellOutput: string;
|
|
4
|
+
selectionTruncated: boolean;
|
|
5
|
+
cellOutputTruncated: boolean;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type SentAttachmentTruncationResult = {
|
|
9
|
+
selectionTruncated: boolean;
|
|
10
|
+
cellOutputTruncated: boolean;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
function clampNonNegativeInteger(value: number): number {
|
|
14
|
+
if (!Number.isFinite(value)) {
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
return Math.max(0, Math.floor(value));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function sliceByCharLimit(value: string, limit: number): string {
|
|
21
|
+
if (limit <= 0) {
|
|
22
|
+
return '';
|
|
23
|
+
}
|
|
24
|
+
if (value.length <= limit) {
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
return value.slice(0, limit);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function limitActiveCellAttachmentPayload(
|
|
31
|
+
selection: string,
|
|
32
|
+
cellOutput: string,
|
|
33
|
+
maxSelectionChars: number,
|
|
34
|
+
maxCellOutputChars: number
|
|
35
|
+
): ActiveCellAttachmentLimitResult {
|
|
36
|
+
const sourceSelection = typeof selection === 'string' ? selection : '';
|
|
37
|
+
const sourceCellOutput = typeof cellOutput === 'string' ? cellOutput : '';
|
|
38
|
+
const selectionLimit = clampNonNegativeInteger(maxSelectionChars);
|
|
39
|
+
const cellOutputLimit = clampNonNegativeInteger(maxCellOutputChars);
|
|
40
|
+
const nextSelection = sliceByCharLimit(sourceSelection, selectionLimit);
|
|
41
|
+
const nextCellOutput = sliceByCharLimit(sourceCellOutput, cellOutputLimit);
|
|
42
|
+
return {
|
|
43
|
+
selection: nextSelection,
|
|
44
|
+
cellOutput: nextCellOutput,
|
|
45
|
+
selectionTruncated: nextSelection.length < sourceSelection.length,
|
|
46
|
+
cellOutputTruncated: nextCellOutput.length < sourceCellOutput.length
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function buildAttachmentTruncationNotice(
|
|
51
|
+
selectionTruncated: boolean,
|
|
52
|
+
cellOutputTruncated: boolean,
|
|
53
|
+
maxSelectionChars: number,
|
|
54
|
+
maxCellOutputChars: number
|
|
55
|
+
): string | null {
|
|
56
|
+
if (!selectionTruncated && !cellOutputTruncated) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const selectionLimit = String(clampNonNegativeInteger(maxSelectionChars));
|
|
61
|
+
const cellOutputLimit = String(clampNonNegativeInteger(maxCellOutputChars));
|
|
62
|
+
if (selectionTruncated && cellOutputTruncated) {
|
|
63
|
+
return `Attached input and output were truncated before sending (input: ${selectionLimit} chars, output: ${cellOutputLimit} chars). The full input can be checked directly from the source file/cell.`;
|
|
64
|
+
}
|
|
65
|
+
if (selectionTruncated) {
|
|
66
|
+
return `Attached input was truncated before sending to stay within ${selectionLimit} characters. The full input can be checked directly from the source file/cell.`;
|
|
67
|
+
}
|
|
68
|
+
return `Attached output was truncated before sending to stay within ${cellOutputLimit} characters.`;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function resolveSentAttachmentTruncation(input: {
|
|
72
|
+
includeSelection: boolean;
|
|
73
|
+
includeCellOutput: boolean;
|
|
74
|
+
selectionTruncated: boolean;
|
|
75
|
+
cellOutputTruncated: boolean;
|
|
76
|
+
}): SentAttachmentTruncationResult {
|
|
77
|
+
return {
|
|
78
|
+
selectionTruncated: input.includeSelection && input.selectionTruncated,
|
|
79
|
+
cellOutputTruncated: input.includeCellOutput && input.cellOutputTruncated
|
|
80
|
+
};
|
|
81
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { NotebookMode } from './codexChatDocumentUtils';
|
|
2
|
+
|
|
3
|
+
export type CellAttachmentStateInput = {
|
|
4
|
+
includeActiveCell: boolean;
|
|
5
|
+
includeActiveCellOutput: boolean;
|
|
6
|
+
notebookMode: NotebookMode;
|
|
7
|
+
isNotebookEditor: boolean;
|
|
8
|
+
currentNotebookPath: string;
|
|
9
|
+
pairedOk: boolean | null | undefined;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type CellAttachmentState = {
|
|
13
|
+
showBadge: boolean;
|
|
14
|
+
contentEnabled: boolean;
|
|
15
|
+
outputEnabled: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export function resolveCellAttachmentState(input: CellAttachmentStateInput): CellAttachmentState {
|
|
19
|
+
const canShowCellAttachmentControl =
|
|
20
|
+
input.isNotebookEditor &&
|
|
21
|
+
(input.notebookMode === 'ipynb' || input.notebookMode === 'jupytext_py');
|
|
22
|
+
const canAttachCurrentCellContent =
|
|
23
|
+
input.includeActiveCell &&
|
|
24
|
+
canShowCellAttachmentControl;
|
|
25
|
+
const canAttachCurrentCellOutput =
|
|
26
|
+
canAttachCurrentCellContent && input.includeActiveCellOutput;
|
|
27
|
+
const showBadge =
|
|
28
|
+
canShowCellAttachmentControl &&
|
|
29
|
+
input.currentNotebookPath.length > 0 &&
|
|
30
|
+
input.pairedOk !== false;
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
showBadge,
|
|
34
|
+
contentEnabled: canAttachCurrentCellContent,
|
|
35
|
+
outputEnabled: canAttachCurrentCellOutput
|
|
36
|
+
};
|
|
37
|
+
}
|