jupyterlab_ai_code_assistants_extension 0.6.15

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 (57) hide show
  1. package/LICENSE +29 -0
  2. package/README.md +44 -0
  3. package/lib/core/colour.d.ts +57 -0
  4. package/lib/core/colour.js +190 -0
  5. package/lib/core/icons.d.ts +12 -0
  6. package/lib/core/icons.js +99 -0
  7. package/lib/core/modes.d.ts +13 -0
  8. package/lib/core/modes.js +36 -0
  9. package/lib/core/panel.d.ts +233 -0
  10. package/lib/core/panel.js +1673 -0
  11. package/lib/core/popup.d.ts +40 -0
  12. package/lib/core/popup.js +404 -0
  13. package/lib/core/registry.d.ts +24 -0
  14. package/lib/core/registry.js +48 -0
  15. package/lib/core/request.d.ts +25 -0
  16. package/lib/core/request.js +64 -0
  17. package/lib/core/terminals.d.ts +129 -0
  18. package/lib/core/terminals.js +344 -0
  19. package/lib/core/types.d.ts +269 -0
  20. package/lib/core/types.js +6 -0
  21. package/lib/index.d.ts +3 -0
  22. package/lib/index.js +277 -0
  23. package/lib/providers/claude.d.ts +3 -0
  24. package/lib/providers/claude.js +88 -0
  25. package/lib/providers/codex.d.ts +3 -0
  26. package/lib/providers/codex.js +79 -0
  27. package/lib/providers/gemini.d.ts +2 -0
  28. package/lib/providers/gemini.js +73 -0
  29. package/lib/providers/index.d.ts +3 -0
  30. package/lib/providers/index.js +16 -0
  31. package/lib/providers/kimi.d.ts +23 -0
  32. package/lib/providers/kimi.js +139 -0
  33. package/package.json +169 -0
  34. package/schema/plugin.json +93 -0
  35. package/src/__tests__/colour.spec.ts +153 -0
  36. package/src/__tests__/core-neutrality.spec.ts +86 -0
  37. package/src/__tests__/labels.spec.ts +89 -0
  38. package/src/__tests__/launch-mode.spec.ts +53 -0
  39. package/src/__tests__/registry.spec.ts +178 -0
  40. package/src/core/colour.ts +224 -0
  41. package/src/core/icons.ts +121 -0
  42. package/src/core/modes.ts +45 -0
  43. package/src/core/panel.ts +2020 -0
  44. package/src/core/popup.ts +475 -0
  45. package/src/core/registry.ts +60 -0
  46. package/src/core/request.ts +96 -0
  47. package/src/core/terminals.ts +446 -0
  48. package/src/core/types.ts +305 -0
  49. package/src/index.ts +356 -0
  50. package/src/providers/claude.ts +102 -0
  51. package/src/providers/codex.ts +89 -0
  52. package/src/providers/gemini.ts +80 -0
  53. package/src/providers/index.ts +21 -0
  54. package/src/providers/kimi.ts +155 -0
  55. package/style/base.css +888 -0
  56. package/style/index.css +1 -0
  57. package/style/index.js +1 -0
@@ -0,0 +1,79 @@
1
+ // The Codex provider: OpenAI's `codex` CLI.
2
+ //
3
+ // Ported from `jupyterlab_codex_extension` v0.6.12. Almost everything that
4
+ // extension did by hand is now shared panel behaviour, so what is left here is
5
+ // the descriptor plus the two tooltip lines Codex has and the others do not.
6
+ //
7
+ // The three divergences that matter are capability flags, not code:
8
+ //
9
+ // * `forkStrategy: 'native-command'` - `codex fork <parent>` mints the fork's
10
+ // id itself, so the panel snapshots the branch list, launches, and diffs to
11
+ // discover the id (the shared 2s x 90 discovery watcher)
12
+ // * `colourSource: 'none'` - Codex has no colour concept at all, so a tab tint
13
+ // only ever comes from the extension's own write-back store
14
+ // * `hasLiveProcess: true` - a project row shows a dot when a `codex` process
15
+ // is running in it, which is the only liveness signal Codex exposes
16
+ // The OpenAI "blossom" mark - Codex is OpenAI's CLI, so the panel wears its
17
+ // vendor's logo. Single path, `jp-icon3` so it picks up the theme's foreground
18
+ // in both light and dark. The box stays 16px like every other icon; the mark is
19
+ // scaled down INSIDE it by padding the viewBox (24 units of art in a 30-unit
20
+ // window, so ~80%), which keeps the sidebar tab and header alignment identical
21
+ // while the dense logo reads less heavy than the simpler glyphs around it.
22
+ const codexSvgStr = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="-3 -3 30 30" width="16" height="16">
23
+ <path class="jp-icon3" fill="#616161" d="M22.282 9.821a5.985 5.985 0 0 0-.516-4.91 6.046 6.046 0 0 0-6.51-2.9A6.065 6.065 0 0 0 4.981 4.18a5.985 5.985 0 0 0-3.998 2.9 6.046 6.046 0 0 0 .743 7.097 5.98 5.98 0 0 0 .51 4.911 6.051 6.051 0 0 0 6.515 2.9A5.985 5.985 0 0 0 13.26 24a6.056 6.056 0 0 0 5.772-4.206 5.99 5.99 0 0 0 3.997-2.9 6.056 6.056 0 0 0-.747-7.073ZM13.26 22.43a4.476 4.476 0 0 1-2.876-1.04l.141-.081 4.779-2.758a.795.795 0 0 0 .392-.681v-6.737l2.02 1.168a.071.071 0 0 1 .038.052v5.583a4.504 4.504 0 0 1-4.494 4.494ZM3.6 18.304a4.47 4.47 0 0 1-.535-3.014l.142.085 4.783 2.759a.771.771 0 0 0 .78 0l5.843-3.369v2.332a.08.08 0 0 1-.033.062L9.74 19.95a4.5 4.5 0 0 1-6.14-1.646ZM2.34 7.896a4.485 4.485 0 0 1 2.366-1.973V11.6a.766.766 0 0 0 .388.676l5.815 3.355-2.02 1.168a.076.076 0 0 1-.071 0l-4.83-2.786A4.504 4.504 0 0 1 2.34 7.872Zm16.597 3.858-5.833-3.387L15.119 7.2a.076.076 0 0 1 .071 0l4.83 2.791a4.494 4.494 0 0 1-.676 8.105v-5.678a.79.79 0 0 0-.407-.667Zm2.01-3.024-.141-.085-4.774-2.782a.776.776 0 0 0-.785 0L9.409 9.23V6.897a.066.066 0 0 1 .028-.061l4.83-2.787a4.5 4.5 0 0 1 6.68 4.66Zm-12.64 4.135-2.02-1.164a.08.08 0 0 1-.038-.057V6.075a4.5 4.5 0 0 1 7.375-3.453l-.142.08L8.704 5.46a.795.795 0 0 0-.393.681ZM9.409 12l2.602-1.504L14.618 12v3.008l-2.597 1.5-2.607-1.5Z"/>
24
+ </svg>`;
25
+ // Codex's own name for its unsafe switch. Kept in the assistant's terminology
26
+ // rather than normalised, because it is both the settings key under
27
+ // `providers.codex.` and the mode token the server maps to the CLI flag
28
+ // `--dangerously-bypass-approvals-and-sandbox`.
29
+ const BYPASS_MODE = 'dangerouslyBypassApprovalsAndSandbox';
30
+ export const descriptor = {
31
+ id: 'codex',
32
+ label: 'Codex',
33
+ panelTitle: 'Codex Sessions',
34
+ iconName: 'jupyterlab_ai_code_assistants_extension:codex',
35
+ iconSvg: codexSvgStr,
36
+ cliBinary: 'codex',
37
+ // `codex fork <parent>` owns both the verb and the new id.
38
+ forkStrategy: 'native-command',
39
+ // No `/color` equivalent, and nothing in the thread store records one.
40
+ colourSource: 'none',
41
+ // Forks are unnamed - Codex has no naming flag and no writable title field,
42
+ // so the panel never asks for a name it could not stamp anywhere.
43
+ namingStrategy: 'none',
44
+ // A bare `codex` mints its own thread id; there is no `--session-id`.
45
+ mintsNewSessionId: false,
46
+ launchModes: [
47
+ {
48
+ id: BYPASS_MODE,
49
+ title: 'Bypass Codex approvals and sandbox',
50
+ description: 'When enabled, newly spawned and resumed sessions are launched with `--dangerously-bypass-approvals-and-sandbox`. Bypasses every Codex approval prompt and sandbox - only enable in environments you trust.',
51
+ kind: 'boolean',
52
+ default: false,
53
+ menuLabel: 'Bypass Approvals'
54
+ }
55
+ ],
56
+ hasRemoteControl: false,
57
+ hasBgAgents: false,
58
+ // A `codex` process running in the project folder is the only liveness
59
+ // signal Codex exposes - it keeps no per-pid session record.
60
+ hasLiveProcess: true,
61
+ // Retired standalone extension this provider replaces.
62
+ legacyPluginId: 'jupyterlab_codex_extension'
63
+ };
64
+ export const hooks = {
65
+ // Codex's thread store records the model and the token spend of every
66
+ // conversation; no other assistant here does, so they are a provider line
67
+ // rather than a core one.
68
+ tooltipLines: ({ session }) => {
69
+ var _a;
70
+ const lines = [];
71
+ if (session.model) {
72
+ lines.push(`Model: ${session.model}`);
73
+ }
74
+ if (((_a = session.tokens_used) !== null && _a !== void 0 ? _a : 0) > 0) {
75
+ lines.push(`Tokens: ${session.tokens_used}`);
76
+ }
77
+ return lines;
78
+ }
79
+ };
@@ -0,0 +1,2 @@
1
+ import { IProviderDescriptor } from '../core/types';
2
+ export declare const descriptor: IProviderDescriptor;
@@ -0,0 +1,73 @@
1
+ // The Gemini provider - Google's `gemini` CLI.
2
+ //
3
+ // New here: no standalone extension preceded it, so there is nothing to port
4
+ // and nothing to migrate. Everything that makes this assistant different from
5
+ // the base one is descriptor data, so no core file knows it exists:
6
+ //
7
+ // * `forkStrategy: 'server-copy'` - gemini has no fork verb at all, so the
8
+ // server copies the chat file under a fresh id and answers with it
9
+ // * `colourSource: 'none'` - no colour command, and nothing in the chat store
10
+ // records one, so a tab tint only ever comes from the extension's own
11
+ // write-back store
12
+ // * `namingStrategy: 'server-side'` - a fork's name is stamped into the copied
13
+ // chat file's `summary`, which is the field the CLI itself displays a
14
+ // conversation under; there is no naming flag to pass it to
15
+ // * `mintsNewSessionId: true` - `--session-id <uuid>` starts a fresh
16
+ // conversation under an id we chose, so a new session is identifiable from
17
+ // its argv on the first poll instead of being an unknown terminal
18
+ // * two launch modes, gemini's `--yolo` switch and its four-step approval
19
+ // ladder
20
+ //
21
+ // No hooks: gemini rows carry no badge, no extra menu item and no derived
22
+ // colour, so the shared panel renders them unchanged.
23
+ // The four-pointed spark of the Gemini mark: four tips on the box edges, each
24
+ // pair joined by a quadratic whose control point is the centre, which is what
25
+ // pinches the sides inwards. Single path, `jp-icon3` so the theme drives the
26
+ // fill in both light and dark; the 16px box matches every other icon in the
27
+ // sidebar.
28
+ const geminiSvgStr = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">
29
+ <path class="jp-icon3" fill="#616161" d="M8 0Q8 8 16 8Q8 8 8 16Q8 8 0 8Q8 8 8 0Z"/>
30
+ </svg>`;
31
+ // Gemini's own names for its two launch surfaces. Kept in the assistant's
32
+ // terminology rather than normalised, because each is both the settings key
33
+ // under `providers.gemini.` and the mode token the server maps to a CLI flag.
34
+ const YOLO_MODE = 'yoloMode';
35
+ const APPROVAL_MODE = 'approvalMode';
36
+ export const descriptor = {
37
+ id: 'gemini',
38
+ label: 'Gemini',
39
+ panelTitle: 'Gemini Sessions',
40
+ iconName: 'jupyterlab_ai_code_assistants_extension:gemini',
41
+ iconSvg: geminiSvgStr,
42
+ cliBinary: 'gemini',
43
+ // No fork flag exists, so the server copies the chat file under a fresh id
44
+ // and the launch resumes that id like any other conversation.
45
+ forkStrategy: 'server-copy',
46
+ colourSource: 'none',
47
+ // The fork's name is written into the copy by the server; the CLI has no
48
+ // naming flag to take it.
49
+ namingStrategy: 'server-side',
50
+ // `--session-id <uuid>` starts a conversation under an id we mint.
51
+ mintsNewSessionId: true,
52
+ launchModes: [
53
+ {
54
+ id: YOLO_MODE,
55
+ title: 'YOLO mode',
56
+ description: 'When enabled, newly spawned and resumed sessions are launched with `--yolo`. Gemini auto-approves every tool call without asking - only enable in workspaces you trust.',
57
+ kind: 'boolean',
58
+ default: false,
59
+ menuLabel: 'YOLO'
60
+ },
61
+ {
62
+ id: APPROVAL_MODE,
63
+ title: 'Approval mode',
64
+ description: 'Approval ladder passed as `--approval-mode` when set to a value other than the default. A non-default value here takes precedence over the YOLO switch; only the forced YOLO menu action overrides it. `default` prompts for approval, `auto_edit` auto-approves edit tools, `yolo` auto-approves every tool, `plan` is read-only.',
65
+ kind: 'enum',
66
+ values: ['default', 'auto_edit', 'yolo', 'plan'],
67
+ default: 'default'
68
+ }
69
+ ],
70
+ hasRemoteControl: false,
71
+ hasBgAgents: false,
72
+ hasLiveProcess: false
73
+ };
@@ -0,0 +1,3 @@
1
+ import { IProviderModule } from '../core/types';
2
+ export declare const PROVIDERS: IProviderModule[];
3
+ export default PROVIDERS;
@@ -0,0 +1,16 @@
1
+ // The single registration point for assistants.
2
+ //
3
+ // One line per provider. Adding an assistant means adding its module and its
4
+ // line here; removing one means deleting both. No core file is edited either
5
+ // way, and nothing outside this directory names an assistant.
6
+ //
7
+ // A provider module exports a `descriptor` (pure data - the settings-schema
8
+ // generator reads it under plain Node) and optionally `hooks` (the DOM and
9
+ // JupyterLab-aware parts). Keep module-scope side effects out of both, so the
10
+ // generator can import this barrel without a browser.
11
+ import * as claude from './claude';
12
+ import * as codex from './codex';
13
+ import * as kimi from './kimi';
14
+ import * as gemini from './gemini';
15
+ export const PROVIDERS = [claude, codex, kimi, gemini];
16
+ export default PROVIDERS;
@@ -0,0 +1,23 @@
1
+ import { IProviderDescriptor, IProviderHooks } from '../core/types';
2
+ export declare const MENU_TITLE_COLUMNS = 60;
3
+ /** Trim `text` to `maxColumns` display columns, appending an ellipsis when
4
+ * anything was cut. Iterates by CODE POINT, so an astral character is never
5
+ * split into a lone surrogate (which chromium paints as the replacement
6
+ * glyph). Returns `text` unchanged when it already fits. */
7
+ export declare function truncateToColumns(text: string, maxColumns: number): string;
8
+ /** The distinguishing part of a kimi session id.
9
+ *
10
+ * Kimi ids are `session_<uuid>`, so the core's front-slice would render the
11
+ * constant `session_` for every conversation of a project - the exact thing
12
+ * the short id exists to tell apart. Slice past the prefix instead.
13
+ */
14
+ export declare function shortSessionId(sessionId: string): string;
15
+ /** Menu-item label for one branch: the conversation title trimmed to the
16
+ * column budget, followed by the short session id. Only the TITLE is trimmed -
17
+ * branches of one project share a path, so the id is what tells them apart and
18
+ * it must survive. The bracketed id is dropped when the title already IS the
19
+ * id (the server's last-resort fallback), which can never be truncated since a
20
+ * short id is at most 8 characters. */
21
+ export declare function branchMenuLabel(label: string, shortId: string): string;
22
+ export declare const descriptor: IProviderDescriptor;
23
+ export declare const hooks: IProviderHooks;
@@ -0,0 +1,139 @@
1
+ // The Kimi provider - Moonshot AI's `kimi` CLI.
2
+ //
3
+ // Ported from jupyterlab_kimi_code_extension v0.7.8. Everything that made that
4
+ // extension different from the base one is declared here as descriptor data,
5
+ // so no core file knows this assistant exists:
6
+ //
7
+ // * `forkStrategy: 'server-copy'` - kimi has no fork verb at all, so the
8
+ // server copies the session directory and answers with the new id
9
+ // * `colourSource: 'derived'` - kimi has no `/color`, so the default tint is a
10
+ // stable hash of the conversation id (a user-set colour still wins, per the
11
+ // Colour section of the acceptance criteria)
12
+ // * `namingStrategy: 'server-side'` - the name is stamped into the copied
13
+ // `state.json`, not passed to the CLI
14
+ // * one launch mode, `--yolo`, under kimi's own name
15
+ //
16
+ // The only hook is the branch label: kimi's conversation titles are
17
+ // auto-generated by a Chinese-first model, and both the session id shape and
18
+ // the glyph widths of those titles need handling the shared default cannot do.
19
+ // Crescent moon (Kimi is Moonshot AI's CLI) - an outer semicircle on the left,
20
+ // bitten from the right by a wider inner arc.
21
+ const kimiSvgStr = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">
22
+ <g class="jp-icon3" fill="#616161">
23
+ <path d="M8 1.5A6.5 6.5 0 1 0 8 14.5 8 8 0 0 1 8 1.5Z"/>
24
+ </g>
25
+ </svg>`;
26
+ // ------------------------------------------------------------------- labels
27
+ // Budget is in COLUMNS, not characters. Han, Kana, Hangul and emoji render at
28
+ // roughly one em against Latin's half, so counting characters bounds nothing:
29
+ // 60 Han glyphs measured 851-862px in a real Lumino submenu, at or above the
30
+ // 850px that filed the defect in the first place. Kimi is Moonshot AI's CLI,
31
+ // so a Chinese auto-generated title is the expected case, not an exotic one.
32
+ export const MENU_TITLE_COLUMNS = 60;
33
+ // East Asian Wide and Fullwidth ranges, plus emoji. Deliberately coarse: this
34
+ // bounds a menu width, so a handful of mis-classified glyphs cost pixels, not
35
+ // correctness. Anything outside these ranges counts as one column.
36
+ const WIDE_RANGES = [
37
+ [0x1100, 0x115f], // Hangul Jamo
38
+ [0x2e80, 0x303e], // CJK radicals, Kangxi, CJK symbols and punctuation
39
+ [0x3041, 0x33ff], // Hiragana, Katakana, Bopomofo, Hangul Compat, CJK Compat
40
+ [0x3400, 0x4dbf], // CJK Unified Extension A
41
+ [0x4e00, 0x9fff], // CJK Unified Ideographs
42
+ [0xa000, 0xa4cf], // Yi
43
+ [0xac00, 0xd7a3], // Hangul syllables
44
+ [0xf900, 0xfaff], // CJK Compatibility Ideographs
45
+ [0xfe30, 0xfe6f], // CJK Compatibility Forms
46
+ [0xff00, 0xff60], // Fullwidth forms
47
+ [0xffe0, 0xffe6], // Fullwidth signs
48
+ [0x1f300, 0x1faff], // Emoji and pictographs
49
+ [0x20000, 0x3fffd] // CJK Unified Extensions B and beyond
50
+ ];
51
+ function isWide(codePoint) {
52
+ return WIDE_RANGES.some(([lo, hi]) => codePoint >= lo && codePoint <= hi);
53
+ }
54
+ /** Trim `text` to `maxColumns` display columns, appending an ellipsis when
55
+ * anything was cut. Iterates by CODE POINT, so an astral character is never
56
+ * split into a lone surrogate (which chromium paints as the replacement
57
+ * glyph). Returns `text` unchanged when it already fits. */
58
+ export function truncateToColumns(text, maxColumns) {
59
+ let columns = 0;
60
+ let kept = '';
61
+ for (const ch of text) {
62
+ const width = isWide(ch.codePointAt(0)) ? 2 : 1;
63
+ if (columns + width > maxColumns) {
64
+ // The cut can land just after a space; drop it so the ellipsis hugs the
65
+ // last word. `trimEnd` is ES2019 and this project targets ES2018.
66
+ return `${kept.replace(/\s+$/, '')}…`;
67
+ }
68
+ columns += width;
69
+ kept += ch;
70
+ }
71
+ return text;
72
+ }
73
+ /** The distinguishing part of a kimi session id.
74
+ *
75
+ * Kimi ids are `session_<uuid>`, so the core's front-slice would render the
76
+ * constant `session_` for every conversation of a project - the exact thing
77
+ * the short id exists to tell apart. Slice past the prefix instead.
78
+ */
79
+ export function shortSessionId(sessionId) {
80
+ return sessionId.startsWith('session_')
81
+ ? sessionId.slice(8, 16)
82
+ : sessionId.slice(0, 8);
83
+ }
84
+ /** Menu-item label for one branch: the conversation title trimmed to the
85
+ * column budget, followed by the short session id. Only the TITLE is trimmed -
86
+ * branches of one project share a path, so the id is what tells them apart and
87
+ * it must survive. The bracketed id is dropped when the title already IS the
88
+ * id (the server's last-resort fallback), which can never be truncated since a
89
+ * short id is at most 8 characters. */
90
+ export function branchMenuLabel(label, shortId) {
91
+ const title = truncateToColumns(label, MENU_TITLE_COLUMNS);
92
+ return label === shortId ? title : `${title} (${shortId})`;
93
+ }
94
+ // -------------------------------------------------------------- descriptor
95
+ export const descriptor = {
96
+ id: 'kimi',
97
+ label: 'Kimi',
98
+ panelTitle: 'Kimi Code Sessions',
99
+ iconName: 'jupyterlab_ai_code_assistants_extension:kimi',
100
+ iconSvg: kimiSvgStr,
101
+ cliBinary: 'kimi',
102
+ // No fork flag exists, so the server copies the session directory under a
103
+ // fresh id and the launch resumes that id like any other conversation.
104
+ forkStrategy: 'server-copy',
105
+ // No `/color` command either: the tint is derived from the conversation id.
106
+ // The core's own FNV-1a is the same hash over the same six ids the retired
107
+ // extension used, so every conversation keeps the colour it already had.
108
+ colourSource: 'derived',
109
+ // The fork's name is written into the copy's `state.json` by the server; the
110
+ // CLI has no naming flag to take it.
111
+ namingStrategy: 'server-side',
112
+ // A bare `kimi` mints its own id and writes it on the first turn, and `-S`
113
+ // only ever resumes - so a new conversation cannot be launched under an id
114
+ // we chose, and is identified from the store on the next poll instead.
115
+ mintsNewSessionId: false,
116
+ launchModes: [
117
+ {
118
+ id: 'yoloMode',
119
+ title: 'YOLO mode',
120
+ description: 'When enabled, newly spawned and resumed sessions are launched with `--yolo`. Kimi auto-approves regular tool calls without asking - only enable in workspaces you trust.',
121
+ kind: 'boolean',
122
+ default: false,
123
+ menuLabel: 'YOLO'
124
+ }
125
+ ],
126
+ hasRemoteControl: false,
127
+ hasBgAgents: false,
128
+ hasLiveProcess: false,
129
+ // Retired standalone extension this provider replaces.
130
+ legacyPluginId: 'jupyterlab_kimi_code_extension'
131
+ };
132
+ // ------------------------------------------------------------------- hooks
133
+ export const hooks = {
134
+ /** Lumino sets no `max-width` on `.lm-Menu-itemLabel`, so an uncapped
135
+ * auto-generated title stretches the submenu across the window. The core's
136
+ * `shortId` argument is a front-slice, which is the constant `session_` for
137
+ * every kimi id, so the id is re-derived here. */
138
+ branchLabel: (branch, _shortId) => branchMenuLabel(branch.label, shortSessionId(branch.session_id))
139
+ };
package/package.json ADDED
@@ -0,0 +1,169 @@
1
+ {
2
+ "name": "jupyterlab_ai_code_assistants_extension",
3
+ "version": "0.6.15",
4
+ "description": "Jupyterlab extension to replace individual jupyterlab_*_code_extension and integrate into one, that offers joint capability, joint settings page and individual right toolbar panels per code assistant, with the ability in settings to decide which code assistant support is on (default - all are enabled)",
5
+ "keywords": [
6
+ "jupyter",
7
+ "jupyterlab",
8
+ "jupyterlab-extension"
9
+ ],
10
+ "homepage": "https://github.com/stellarshenson/jupyterlab_ai_code_assistants_extension",
11
+ "bugs": {
12
+ "url": "https://github.com/stellarshenson/jupyterlab_ai_code_assistants_extension/issues"
13
+ },
14
+ "license": "BSD-3-Clause",
15
+ "author": {
16
+ "name": "Stellars Henson",
17
+ "email": "konrad.jelen+github@gmail.com"
18
+ },
19
+ "files": [
20
+ "lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
21
+ "style/**/*.{css,js,eot,gif,html,jpg,json,png,svg,woff2,ttf}",
22
+ "src/**/*.{ts,tsx}",
23
+ "schema/*.json"
24
+ ],
25
+ "main": "lib/index.js",
26
+ "types": "lib/index.d.ts",
27
+ "style": "style/index.css",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/stellarshenson/jupyterlab_ai_code_assistants_extension.git"
31
+ },
32
+ "scripts": {
33
+ "build": "jlpm build:lib && jlpm generate:schema && jlpm build:labextension:dev",
34
+ "build:prod": "jlpm clean && jlpm build:lib:prod && jlpm generate:schema && jlpm build:labextension",
35
+ "build:labextension": "jupyter-builder build .",
36
+ "build:labextension:dev": "jupyter-builder build --development True .",
37
+ "build:lib": "tsc --sourceMap",
38
+ "build:lib:prod": "tsc",
39
+ "clean": "jlpm clean:lib",
40
+ "clean:lib": "rimraf lib tsconfig.tsbuildinfo",
41
+ "clean:lintcache": "rimraf .eslintcache .stylelintcache",
42
+ "clean:labextension": "rimraf jupyterlab_ai_code_assistants_extension/labextension jupyterlab_ai_code_assistants_extension/_version.py",
43
+ "clean:all": "jlpm clean:lib && jlpm clean:labextension && jlpm clean:lintcache",
44
+ "eslint": "jlpm eslint:check --fix",
45
+ "eslint:check": "eslint . --cache",
46
+ "generate:schema": "node scripts/generate-schema.mjs && prettier --write schema/plugin.json",
47
+ "install:extension": "jlpm build",
48
+ "lint": "jlpm stylelint && jlpm prettier && jlpm eslint",
49
+ "lint:check": "jlpm stylelint:check && jlpm prettier:check && jlpm eslint:check",
50
+ "prettier": "jlpm prettier:base --write --list-different",
51
+ "prettier:base": "prettier \"**/*{.ts,.tsx,.js,.jsx,.css,.json,.md}\"",
52
+ "prettier:check": "jlpm prettier:base --check",
53
+ "stylelint": "jlpm stylelint:check --fix",
54
+ "stylelint:check": "stylelint --cache \"style/**/*.css\"",
55
+ "test": "jest --coverage",
56
+ "watch": "run-p watch:src watch:labextension",
57
+ "watch:src": "tsc -w --sourceMap",
58
+ "watch:labextension": "jupyter-builder watch ."
59
+ },
60
+ "dependencies": {
61
+ "@jupyterlab/application": "^4.0.0",
62
+ "@jupyterlab/apputils": "^4.0.0",
63
+ "@jupyterlab/coreutils": "^6.0.0",
64
+ "@jupyterlab/filebrowser": "^4.0.0",
65
+ "@jupyterlab/services": "^7.0.0",
66
+ "@jupyterlab/settingregistry": "^4.0.0",
67
+ "@jupyterlab/terminal": "^4.0.0",
68
+ "@jupyterlab/ui-components": "^4.0.0",
69
+ "@lumino/commands": "^2.0.0",
70
+ "@lumino/coreutils": "^2.0.0",
71
+ "@lumino/disposable": "^2.0.0",
72
+ "@lumino/messaging": "^2.0.0",
73
+ "@lumino/widgets": "^2.0.0",
74
+ "jupyterlab_colourful_tab_extension": "^1.0.19"
75
+ },
76
+ "devDependencies": {
77
+ "@eslint/js": "^9.0.0",
78
+ "@jupyter/builder": "^1.2.0",
79
+ "@jupyter/eslint-plugin": "^0.0.5",
80
+ "@jupyterlab/testutils": "^4.0.0",
81
+ "@types/jest": "^29.2.0",
82
+ "@types/json-schema": "^7.0.11",
83
+ "eslint": "^9.0.0",
84
+ "eslint-config-prettier": "^9.0.0",
85
+ "eslint-plugin-prettier": "^5.0.0",
86
+ "globals": "^15.0.0",
87
+ "jest": "^29.2.0",
88
+ "mkdirp": "^1.0.3",
89
+ "npm-run-all2": "^7.0.1",
90
+ "prettier": "^3.0.0",
91
+ "rimraf": "^5.0.1",
92
+ "stylelint": "^15.10.1",
93
+ "stylelint-config-recommended": "^13.0.0",
94
+ "stylelint-config-standard": "^34.0.0",
95
+ "stylelint-csstree-validator": "^3.0.0",
96
+ "stylelint-prettier": "^4.0.0",
97
+ "typescript": "~5.5.4",
98
+ "typescript-eslint": "^8.0.0"
99
+ },
100
+ "resolutions": {
101
+ "lib0": "0.2.111",
102
+ "webpack": "5.106.0",
103
+ "chalk": "4.1.2"
104
+ },
105
+ "overrides": {
106
+ "webpack": "5.106.0",
107
+ "chalk": "4.1.2"
108
+ },
109
+ "sideEffects": [
110
+ "style/*.css",
111
+ "style/index.js"
112
+ ],
113
+ "styleModule": "style/index.js",
114
+ "publishConfig": {
115
+ "access": "public"
116
+ },
117
+ "jupyterlab": {
118
+ "discovery": {
119
+ "server": {
120
+ "managers": [
121
+ "pip"
122
+ ],
123
+ "base": {
124
+ "name": "jupyterlab_ai_code_assistants_extension"
125
+ }
126
+ }
127
+ },
128
+ "extension": true,
129
+ "outputDir": "jupyterlab_ai_code_assistants_extension/labextension",
130
+ "schemaDir": "schema",
131
+ "sharedPackages": {
132
+ "jupyterlab_colourful_tab_extension": {
133
+ "bundled": false,
134
+ "singleton": true
135
+ }
136
+ }
137
+ },
138
+ "prettier": {
139
+ "singleQuote": true,
140
+ "trailingComma": "none",
141
+ "arrowParens": "avoid",
142
+ "endOfLine": "auto",
143
+ "overrides": [
144
+ {
145
+ "files": "package.json",
146
+ "options": {
147
+ "tabWidth": 4
148
+ }
149
+ }
150
+ ]
151
+ },
152
+ "stylelint": {
153
+ "extends": [
154
+ "stylelint-config-recommended",
155
+ "stylelint-config-standard",
156
+ "stylelint-prettier/recommended"
157
+ ],
158
+ "plugins": [
159
+ "stylelint-csstree-validator"
160
+ ],
161
+ "rules": {
162
+ "csstree/validator": true,
163
+ "property-no-vendor-prefix": null,
164
+ "selector-class-pattern": "^([a-z][A-z\\d]*)(-[A-z\\d]+)*$",
165
+ "selector-no-vendor-prefix": null,
166
+ "value-no-vendor-prefix": null
167
+ }
168
+ }
169
+ }
@@ -0,0 +1,93 @@
1
+ {
2
+ "title": "AI Code Assistants",
3
+ "description": "One settings section for every AI code assistant panel. Generated from the provider registry by `jlpm generate:schema` - edit the provider descriptors, not this file.",
4
+ "type": "object",
5
+ "jupyter.lab.setting-icon": "jupyterlab_ai_code_assistants_extension:assistants",
6
+ "jupyter.lab.setting-icon-label": "AI Code Assistants",
7
+ "properties": {
8
+ "presentationMode": {
9
+ "type": "string",
10
+ "title": "Presentation mode",
11
+ "description": "How session rows are labelled, in every assistant's panel. `name` (default) shows the session name the assistant records for the project; the initial name is the project folder name, then the path is walked up to disambiguate when two projects share a folder name. `path` shows the project path relative to the JupyterLab notebook root (absolute if outside it).",
12
+ "enum": ["name", "path"],
13
+ "default": "name"
14
+ },
15
+ "recentLimit": {
16
+ "type": "integer",
17
+ "title": "Recent items count",
18
+ "description": "Number of sessions listed in the Recent section, sorted by last activity (descending). The section displays up to 10 rows and scrolls for the rest.",
19
+ "default": 10,
20
+ "minimum": 1,
21
+ "maximum": 100
22
+ },
23
+ "colouredTabs": {
24
+ "type": "boolean",
25
+ "title": "Coloured terminal tabs",
26
+ "description": "When enabled (default), a terminal running an assistant has its dock tab tinted with that conversation's colour. Turning it off clears the tint and stops it being applied. Requires `jupyterlab_colourful_tab_extension`; without it there is no tint either way.",
27
+ "default": true
28
+ },
29
+ "sidebar": {
30
+ "type": "string",
31
+ "title": "Sidebar position",
32
+ "description": "Which JupyterLab sidebar to dock the assistant panels to. `right` (default) keeps them clear of the file browser. `left` puts them next to it.",
33
+ "enum": ["left", "right"],
34
+ "default": "right"
35
+ },
36
+ "providers.claude.enabled": {
37
+ "type": "boolean",
38
+ "title": "Claude Code: enabled",
39
+ "description": "Show the Claude Code Sessions panel. A panel appears only when this is on AND the `claude` binary is on PATH.",
40
+ "default": true
41
+ },
42
+ "providers.claude.dangerouslySkipPermissions": {
43
+ "type": "boolean",
44
+ "title": "Claude Code: Dangerously skip permissions",
45
+ "description": "When enabled, newly spawned and resumed sessions are launched with `--dangerously-skip-permissions`. Bypasses every Claude Code permission prompt - only enable in sandboxes you trust.",
46
+ "default": false
47
+ },
48
+ "providers.codex.enabled": {
49
+ "type": "boolean",
50
+ "title": "Codex: enabled",
51
+ "description": "Show the Codex Sessions panel. A panel appears only when this is on AND the `codex` binary is on PATH.",
52
+ "default": true
53
+ },
54
+ "providers.codex.dangerouslyBypassApprovalsAndSandbox": {
55
+ "type": "boolean",
56
+ "title": "Codex: Bypass Codex approvals and sandbox",
57
+ "description": "When enabled, newly spawned and resumed sessions are launched with `--dangerously-bypass-approvals-and-sandbox`. Bypasses every Codex approval prompt and sandbox - only enable in environments you trust.",
58
+ "default": false
59
+ },
60
+ "providers.gemini.enabled": {
61
+ "type": "boolean",
62
+ "title": "Gemini: enabled",
63
+ "description": "Show the Gemini Sessions panel. A panel appears only when this is on AND the `gemini` binary is on PATH.",
64
+ "default": true
65
+ },
66
+ "providers.gemini.yoloMode": {
67
+ "type": "boolean",
68
+ "title": "Gemini: YOLO mode",
69
+ "description": "When enabled, newly spawned and resumed sessions are launched with `--yolo`. Gemini auto-approves every tool call without asking - only enable in workspaces you trust.",
70
+ "default": false
71
+ },
72
+ "providers.gemini.approvalMode": {
73
+ "type": "string",
74
+ "title": "Gemini: Approval mode",
75
+ "description": "Approval ladder passed as `--approval-mode` when set to a value other than the default. A non-default value here takes precedence over the YOLO switch; only the forced YOLO menu action overrides it. `default` prompts for approval, `auto_edit` auto-approves edit tools, `yolo` auto-approves every tool, `plan` is read-only.",
76
+ "default": "default",
77
+ "enum": ["default", "auto_edit", "yolo", "plan"]
78
+ },
79
+ "providers.kimi.enabled": {
80
+ "type": "boolean",
81
+ "title": "Kimi: enabled",
82
+ "description": "Show the Kimi Code Sessions panel. A panel appears only when this is on AND the `kimi` binary is on PATH.",
83
+ "default": true
84
+ },
85
+ "providers.kimi.yoloMode": {
86
+ "type": "boolean",
87
+ "title": "Kimi: YOLO mode",
88
+ "description": "When enabled, newly spawned and resumed sessions are launched with `--yolo`. Kimi auto-approves regular tool calls without asking - only enable in workspaces you trust.",
89
+ "default": false
90
+ }
91
+ },
92
+ "additionalProperties": true
93
+ }