@plmbr/notebook-intelligence 5.0.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 (137) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +412 -0
  3. package/lib/api.d.ts +288 -0
  4. package/lib/api.js +927 -0
  5. package/lib/cell-output-bundle.d.ts +25 -0
  6. package/lib/cell-output-bundle.js +129 -0
  7. package/lib/cell-output-toolbar.d.ts +26 -0
  8. package/lib/cell-output-toolbar.js +188 -0
  9. package/lib/chat-progress-feedback.d.ts +3 -0
  10. package/lib/chat-progress-feedback.js +27 -0
  11. package/lib/chat-sidebar.d.ts +92 -0
  12. package/lib/chat-sidebar.js +3452 -0
  13. package/lib/command-ids.d.ts +39 -0
  14. package/lib/command-ids.js +44 -0
  15. package/lib/components/ask-user-question.d.ts +2 -0
  16. package/lib/components/ask-user-question.js +85 -0
  17. package/lib/components/checkbox.d.ts +2 -0
  18. package/lib/components/checkbox.js +30 -0
  19. package/lib/components/claude-mcp-panel.d.ts +2 -0
  20. package/lib/components/claude-mcp-panel.js +275 -0
  21. package/lib/components/claude-mcp-paste.d.ts +7 -0
  22. package/lib/components/claude-mcp-paste.js +104 -0
  23. package/lib/components/claude-session-picker.d.ts +8 -0
  24. package/lib/components/claude-session-picker.js +127 -0
  25. package/lib/components/form-dialog.d.ts +25 -0
  26. package/lib/components/form-dialog.js +35 -0
  27. package/lib/components/launcher-picker.d.ts +6 -0
  28. package/lib/components/launcher-picker.js +135 -0
  29. package/lib/components/mcp-util.d.ts +2 -0
  30. package/lib/components/mcp-util.js +37 -0
  31. package/lib/components/notebook-generation-popover.d.ts +7 -0
  32. package/lib/components/notebook-generation-popover.js +60 -0
  33. package/lib/components/pill.d.ts +2 -0
  34. package/lib/components/pill.js +5 -0
  35. package/lib/components/plugins-panel.d.ts +3 -0
  36. package/lib/components/plugins-panel.js +466 -0
  37. package/lib/components/settings-panel.d.ts +11 -0
  38. package/lib/components/settings-panel.js +742 -0
  39. package/lib/components/skills-panel.d.ts +2 -0
  40. package/lib/components/skills-panel.js +1264 -0
  41. package/lib/handler.d.ts +8 -0
  42. package/lib/handler.js +36 -0
  43. package/lib/icons.d.ts +45 -0
  44. package/lib/icons.js +54 -0
  45. package/lib/index.d.ts +8 -0
  46. package/lib/index.js +2079 -0
  47. package/lib/markdown-renderer.d.ts +10 -0
  48. package/lib/markdown-renderer.js +64 -0
  49. package/lib/notebook-generation-toolbar.d.ts +16 -0
  50. package/lib/notebook-generation-toolbar.js +197 -0
  51. package/lib/notebook-generation.d.ts +8 -0
  52. package/lib/notebook-generation.js +12 -0
  53. package/lib/open-file-refresh-watcher-env.d.ts +4 -0
  54. package/lib/open-file-refresh-watcher-env.js +33 -0
  55. package/lib/open-file-refresh-watcher.d.ts +97 -0
  56. package/lib/open-file-refresh-watcher.js +190 -0
  57. package/lib/shell-utils.d.ts +6 -0
  58. package/lib/shell-utils.js +9 -0
  59. package/lib/task-target-notebook.d.ts +2 -0
  60. package/lib/task-target-notebook.js +28 -0
  61. package/lib/terminal-drag-format.d.ts +9 -0
  62. package/lib/terminal-drag-format.js +23 -0
  63. package/lib/terminal-drag.d.ts +12 -0
  64. package/lib/terminal-drag.js +268 -0
  65. package/lib/tokens.d.ts +149 -0
  66. package/lib/tokens.js +88 -0
  67. package/lib/tour/tour-anchors.d.ts +18 -0
  68. package/lib/tour/tour-anchors.js +18 -0
  69. package/lib/tour/tour-config.d.ts +66 -0
  70. package/lib/tour/tour-config.js +99 -0
  71. package/lib/tour/tour-defaults.json +58 -0
  72. package/lib/tour/tour-events.d.ts +19 -0
  73. package/lib/tour/tour-events.js +30 -0
  74. package/lib/tour/tour-overlay.d.ts +6 -0
  75. package/lib/tour/tour-overlay.js +350 -0
  76. package/lib/tour/tour-state.d.ts +20 -0
  77. package/lib/tour/tour-state.js +81 -0
  78. package/lib/tour/tour-steps.d.ts +33 -0
  79. package/lib/tour/tour-steps.js +216 -0
  80. package/lib/utils.d.ts +53 -0
  81. package/lib/utils.js +385 -0
  82. package/package.json +258 -0
  83. package/schema/plugin.json +42 -0
  84. package/src/api.ts +1424 -0
  85. package/src/cell-output-bundle.ts +176 -0
  86. package/src/cell-output-toolbar.ts +232 -0
  87. package/src/chat-progress-feedback.ts +35 -0
  88. package/src/chat-sidebar.tsx +5147 -0
  89. package/src/command-ids.ts +67 -0
  90. package/src/components/ask-user-question.tsx +151 -0
  91. package/src/components/checkbox.tsx +62 -0
  92. package/src/components/claude-mcp-panel.tsx +543 -0
  93. package/src/components/claude-mcp-paste.ts +132 -0
  94. package/src/components/claude-session-picker.tsx +214 -0
  95. package/src/components/form-dialog.tsx +75 -0
  96. package/src/components/launcher-picker.tsx +237 -0
  97. package/src/components/mcp-util.ts +53 -0
  98. package/src/components/notebook-generation-popover.tsx +127 -0
  99. package/src/components/pill.tsx +15 -0
  100. package/src/components/plugins-panel.tsx +774 -0
  101. package/src/components/settings-panel.tsx +1631 -0
  102. package/src/components/skills-panel.tsx +2084 -0
  103. package/src/handler.ts +51 -0
  104. package/src/icons.ts +71 -0
  105. package/src/index.ts +2583 -0
  106. package/src/markdown-renderer.tsx +153 -0
  107. package/src/notebook-generation-toolbar.tsx +281 -0
  108. package/src/notebook-generation.ts +23 -0
  109. package/src/open-file-refresh-watcher-env.ts +52 -0
  110. package/src/open-file-refresh-watcher.ts +260 -0
  111. package/src/shell-utils.ts +10 -0
  112. package/src/svg.d.ts +4 -0
  113. package/src/task-target-notebook.ts +37 -0
  114. package/src/terminal-drag-format.ts +29 -0
  115. package/src/terminal-drag.ts +382 -0
  116. package/src/tokens.ts +171 -0
  117. package/src/tour/tour-anchors.ts +21 -0
  118. package/src/tour/tour-config.ts +160 -0
  119. package/src/tour/tour-events.ts +34 -0
  120. package/src/tour/tour-overlay.tsx +474 -0
  121. package/src/tour/tour-state.ts +87 -0
  122. package/src/tour/tour-steps.ts +281 -0
  123. package/src/utils.ts +455 -0
  124. package/style/base.css +3238 -0
  125. package/style/icons/cell-toolbar-bug.svg +5 -0
  126. package/style/icons/cell-toolbar-chat.svg +5 -0
  127. package/style/icons/cell-toolbar-sparkle.svg +5 -0
  128. package/style/icons/claude.svg +1 -0
  129. package/style/icons/copilot-warning.svg +1 -0
  130. package/style/icons/copilot.svg +1 -0
  131. package/style/icons/copy.svg +1 -0
  132. package/style/icons/openai.svg +1 -0
  133. package/style/icons/opencode.svg +1 -0
  134. package/style/icons/sparkles-warning.svg +5 -0
  135. package/style/icons/sparkles.svg +1 -0
  136. package/style/index.css +1 -0
  137. package/style/index.js +1 -0
@@ -0,0 +1,67 @@
1
+ // Copyright (c) Mehmet Bektas <mbektasgh@outlook.com>
2
+
3
+ // Centralized command-id constants for the JupyterLab plugin. Hoisted out
4
+ // of `src/index.ts` so non-JL modules (and Jest tests) can import them
5
+ // without pulling the JupyterLab packages into their dependency graph.
6
+
7
+ export namespace CommandIDs {
8
+ export const chatuserInput = 'notebook-intelligence:chat-user-input';
9
+ export const insertAtCursor = 'notebook-intelligence:insert-at-cursor';
10
+ export const addCodeAsNewCell = 'notebook-intelligence:add-code-as-new-cell';
11
+ export const createNewFile = 'notebook-intelligence:create-new-file';
12
+ export const createNewNotebookFromPython =
13
+ 'notebook-intelligence:create-new-notebook-from-py';
14
+ export const renameNotebook = 'notebook-intelligence:rename-notebook';
15
+ export const addCodeCellToNotebook =
16
+ 'notebook-intelligence:add-code-cell-to-notebook';
17
+ export const addMarkdownCellToNotebook =
18
+ 'notebook-intelligence:add-markdown-cell-to-notebook';
19
+ export const editorGenerateCode =
20
+ 'notebook-intelligence:editor-generate-code';
21
+ export const editorExplainThisCode =
22
+ 'notebook-intelligence:editor-explain-this-code';
23
+ export const editorFixThisCode = 'notebook-intelligence:editor-fix-this-code';
24
+ export const editorExplainThisOutput =
25
+ 'notebook-intelligence:editor-explain-this-output';
26
+ export const editorTroubleshootThisOutput =
27
+ 'notebook-intelligence:editor-troubleshoot-this-output';
28
+ export const editorAskAboutThisOutput =
29
+ 'notebook-intelligence:editor-ask-about-this-output';
30
+ export const openGitHubCopilotLoginDialog =
31
+ 'notebook-intelligence:open-github-copilot-login-dialog';
32
+ export const openConfigurationDialog =
33
+ 'notebook-intelligence:open-configuration-dialog';
34
+ export const addMarkdownCellToActiveNotebook =
35
+ 'notebook-intelligence:add-markdown-cell-to-active-notebook';
36
+ export const addCodeCellToActiveNotebook =
37
+ 'notebook-intelligence:add-code-cell-to-active-notebook';
38
+ export const deleteCellAtIndex = 'notebook-intelligence:delete-cell-at-index';
39
+ export const insertCellAtIndex = 'notebook-intelligence:insert-cell-at-index';
40
+ export const getCellTypeAndSource =
41
+ 'notebook-intelligence:get-cell-type-and-source';
42
+ export const setCellTypeAndSource =
43
+ 'notebook-intelligence:set-cell-type-and-source';
44
+ export const getNumberOfCells = 'notebook-intelligence:get-number-of-cells';
45
+ export const getCellOutput = 'notebook-intelligence:get-cell-output';
46
+ export const runCellAtIndex = 'notebook-intelligence:run-cell-at-index';
47
+ export const getCurrentFileContent =
48
+ 'notebook-intelligence:get-current-file-content';
49
+ export const setCurrentFileContent =
50
+ 'notebook-intelligence:set-current-file-content';
51
+ export const openMCPConfigEditor =
52
+ 'notebook-intelligence:open-mcp-config-editor';
53
+ export const showFormInputDialog =
54
+ 'notebook-intelligence:show-form-input-dialog';
55
+ export const runCommandInTerminal =
56
+ 'notebook-intelligence:run-command-in-terminal';
57
+ export const openClaudeCodeLauncher =
58
+ 'notebook-intelligence:open-claude-code-launcher';
59
+ export const openOpenCodeLauncher =
60
+ 'notebook-intelligence:open-opencode-launcher';
61
+ export const openPiLauncher = 'notebook-intelligence:open-pi-launcher';
62
+ export const openGitHubCopilotCliLauncher =
63
+ 'notebook-intelligence:open-github-copilot-cli-launcher';
64
+ export const openCodexLauncher = 'notebook-intelligence:open-codex-launcher';
65
+ export const showTour = 'notebook-intelligence:show-tour';
66
+ export const focusChatInput = 'notebook-intelligence:focus-chat-input';
67
+ }
@@ -0,0 +1,151 @@
1
+ // Copyright (c) Mehmet Bektas <mbektasgh@outlook.com>
2
+
3
+ import React, { useId, useState } from 'react';
4
+
5
+ export function AskUserQuestion(props: any) {
6
+ const userQuestions = props.userQuestions.content;
7
+ const [selectedAnswers, setSelectedAnswers] = useState<{
8
+ [key: string]: string[];
9
+ }>({});
10
+
11
+ // Form-scoped id prefix so DOM ids stay unique even when two questions
12
+ // share label text (or several AskUserQuestion forms render in the
13
+ // same chat transcript). React.useId() is the purpose-built primitive
14
+ // here: stable for the component's lifetime, SSR-safe, and survives
15
+ // StrictMode double-render without producing mismatched id/htmlFor
16
+ // pairs (a Math.random fallback could mis-pair under cache eviction).
17
+ // The server-provided identifier is preferred when present so two
18
+ // remounts of the same form keep the same DOM ids.
19
+ const reactId = useId();
20
+ const serverId = userQuestions.identifier?.id;
21
+ const formIdPrefix =
22
+ typeof serverId === 'string' && serverId.length > 0
23
+ ? `nbi-auq-${serverId}`
24
+ : `nbi-auq${reactId}`;
25
+
26
+ const onOptionSelected = (question: any, option: any) => {
27
+ if (question.multiSelect) {
28
+ if (selectedAnswers[question.question]?.includes(option.label)) {
29
+ setSelectedAnswers({
30
+ ...selectedAnswers,
31
+ [question.question]: (
32
+ selectedAnswers[question.question] ?? []
33
+ ).filter((o: any) => o !== option.label)
34
+ });
35
+ } else {
36
+ setSelectedAnswers({
37
+ ...selectedAnswers,
38
+ [question.question]: [
39
+ ...(selectedAnswers[question.question] ?? []),
40
+ option.label
41
+ ]
42
+ });
43
+ }
44
+ } else {
45
+ setSelectedAnswers({
46
+ ...selectedAnswers,
47
+ [question.question]: [option.label]
48
+ });
49
+ }
50
+ };
51
+
52
+ return (
53
+ <>
54
+ {userQuestions.title ? (
55
+ <div>
56
+ <b>{userQuestions.title}</b>
57
+ </div>
58
+ ) : null}
59
+ {userQuestions.message ? <div>{userQuestions.message}</div> : null}
60
+ <form
61
+ className="ask-user-question-form"
62
+ onSubmit={event => {
63
+ event.preventDefault();
64
+ props.onSubmit(selectedAnswers);
65
+ }}
66
+ >
67
+ {userQuestions.questions.map((question: any, qIndex: number) => {
68
+ const questionDomId = `${formIdPrefix}-q${qIndex}`;
69
+ // A single-select group is a radio group with a shared name so
70
+ // screen readers announce "1 of N selected" rather than
71
+ // treating each option as an independent checkbox. The wrapper
72
+ // role mirrors the input type: radiogroup for radios, group
73
+ // (the ARIA-1.2 fallback when no dedicated checkbox-group role
74
+ // exists) for checkboxes.
75
+ const inputType = question.multiSelect ? 'checkbox' : 'radio';
76
+ const groupRole = question.multiSelect ? 'group' : 'radiogroup';
77
+ return (
78
+ <div
79
+ className="ask-user-question-container"
80
+ key={questionDomId}
81
+ role={groupRole}
82
+ aria-labelledby={`${questionDomId}-label`}
83
+ >
84
+ <div
85
+ className="ask-user-question-question"
86
+ id={`${questionDomId}-label`}
87
+ >
88
+ {question.question}
89
+ </div>
90
+ <div className="ask-user-question-header">{question.header}</div>
91
+ <div className="ask-user-question-options">
92
+ {question.options.map((option: any, oIndex: number) => {
93
+ const optionDomId = `${questionDomId}-o${oIndex}`;
94
+ return (
95
+ <div className="ask-user-question-option" key={optionDomId}>
96
+ <div className="ask-user-question-option-input-container">
97
+ <input
98
+ id={optionDomId}
99
+ name={questionDomId}
100
+ type={inputType}
101
+ checked={
102
+ selectedAnswers[question.question]?.includes(
103
+ option.label
104
+ ) ?? false
105
+ }
106
+ onChange={() => onOptionSelected(question, option)}
107
+ />
108
+ <label
109
+ htmlFor={optionDomId}
110
+ className="ask-user-question-option-label-container"
111
+ >
112
+ <div className="ask-user-question-option-label">
113
+ {option.label}
114
+ </div>
115
+ <div className="ask-user-question-option-description">
116
+ {option.description}
117
+ </div>
118
+ </label>
119
+ </div>
120
+ </div>
121
+ );
122
+ })}
123
+ </div>
124
+ </div>
125
+ );
126
+ })}
127
+ <div className="ask-user-question-footer">
128
+ <button
129
+ type="submit"
130
+ className="jp-Dialog-button jp-mod-accept jp-mod-styled"
131
+ >
132
+ <div className="jp-Dialog-buttonLabel">
133
+ {userQuestions.submitLabel}
134
+ </div>
135
+ </button>
136
+ <button
137
+ type="button"
138
+ className="jp-Dialog-button jp-mod-reject jp-mod-styled"
139
+ onClick={() => {
140
+ props.onCancel();
141
+ }}
142
+ >
143
+ <div className="jp-Dialog-buttonLabel">
144
+ {userQuestions.cancelLabel}
145
+ </div>
146
+ </button>
147
+ </div>
148
+ </form>
149
+ </>
150
+ );
151
+ }
@@ -0,0 +1,62 @@
1
+ // Copyright (c) Mehmet Bektas <mbektasgh@outlook.com>
2
+
3
+ import React from 'react';
4
+
5
+ import { MdOutlineCheckBoxOutlineBlank, MdCheckBox } from '../icons';
6
+
7
+ export function CheckBoxItem(props: any) {
8
+ const indent = props.indent || 0;
9
+ const disabled = props.disabled || false;
10
+ const checked = !!props.checked;
11
+
12
+ const activate = (event: React.SyntheticEvent) => {
13
+ if (!disabled) {
14
+ props.onClick(event);
15
+ }
16
+ };
17
+
18
+ // Custom checkbox widget. Tracks the WAI-ARIA pattern: role='checkbox'
19
+ // + aria-checked + tabIndex=0 + Space/Enter to toggle. Disabled state
20
+ // is exposed via aria-disabled so the element stays focusable; a
21
+ // screen reader user can still announce "checkbox, disabled" and hear
22
+ // what's off without being able to toggle it.
23
+ return (
24
+ <div
25
+ className={`checkbox-item checkbox-item-indent-${indent} ${props.header ? 'checkbox-item-header' : ''}`}
26
+ title={props.tooltip || props.title || ''}
27
+ role="checkbox"
28
+ aria-checked={checked}
29
+ aria-disabled={disabled || undefined}
30
+ tabIndex={disabled ? -1 : 0}
31
+ onClick={activate}
32
+ onKeyDown={event => {
33
+ if (event.key === ' ' || event.key === 'Enter') {
34
+ // Space scrolls the page by default, Enter is a no-op on a
35
+ // <div>; prevent both so the checkbox can own them.
36
+ event.preventDefault();
37
+ activate(event);
38
+ }
39
+ }}
40
+ >
41
+ <div className="checkbox-item-toggle">
42
+ {checked ? (
43
+ <MdCheckBox
44
+ className="checkbox-icon"
45
+ style={{ opacity: disabled ? 0.5 : 1 }}
46
+ aria-hidden="true"
47
+ />
48
+ ) : (
49
+ <MdOutlineCheckBoxOutlineBlank
50
+ className="checkbox-icon"
51
+ style={{ opacity: disabled ? 0.5 : 1 }}
52
+ aria-hidden="true"
53
+ />
54
+ )}
55
+ <span style={{ opacity: disabled ? 0.5 : 1 }}>{props.label}</span>
56
+ </div>
57
+ {props.title && (
58
+ <div className="checkbox-item-description">{props.title}</div>
59
+ )}
60
+ </div>
61
+ );
62
+ }