jupyterlab_ai_code_assistants_extension 1.2.38 → 1.2.41
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/core/terminals.js +2 -2
- package/lib/index.js +10 -22
- package/package.json +1 -1
- package/src/__tests__/index.spec.ts +34 -0
- package/src/core/terminals.ts +2 -2
- package/src/index.ts +8 -24
package/lib/core/terminals.js
CHANGED
|
@@ -41,8 +41,8 @@ function warnLegacyCompanion() {
|
|
|
41
41
|
// And said where the user is looking. The symptom is tabs that are simply
|
|
42
42
|
// plain, which reads as a feature that was never on rather than as something
|
|
43
43
|
// to fix, and a console line only reaches someone already suspecting the
|
|
44
|
-
// cause. The
|
|
45
|
-
//
|
|
44
|
+
// cause. The retired-extension notice in index.ts pairs its console line
|
|
45
|
+
// with a toast the same way. It does not
|
|
46
46
|
// close on its own, because the condition does not go away on its own.
|
|
47
47
|
Notification.warning(message, { autoClose: false });
|
|
48
48
|
}
|
package/lib/index.js
CHANGED
|
@@ -242,7 +242,7 @@ const plugin = {
|
|
|
242
242
|
/** Bring the docked panels in line with settings and CLI availability.
|
|
243
243
|
* Both must hold for a panel to be present. */
|
|
244
244
|
const reconcile = () => {
|
|
245
|
-
var _a, _b, _c
|
|
245
|
+
var _a, _b, _c;
|
|
246
246
|
for (const descriptor of registry.descriptors) {
|
|
247
247
|
const id = descriptor.id;
|
|
248
248
|
if (suppressed.has(id)) {
|
|
@@ -258,38 +258,26 @@ const plugin = {
|
|
|
258
258
|
// the server's word on each binary is final.
|
|
259
259
|
const roster = status;
|
|
260
260
|
const available = roster === null ? true : probe !== null && probe.available !== false;
|
|
261
|
-
// Enabled but binary absent
|
|
262
|
-
//
|
|
263
|
-
//
|
|
264
|
-
// Only when the probe SUCCEEDED and this provider is
|
|
265
|
-
//
|
|
266
|
-
//
|
|
267
|
-
// assistant installed would otherwise raise three toasts about assistants
|
|
268
|
-
// the user has never heard of. The console line stays for that case.
|
|
269
|
-
const chosen = (settings === null || settings === void 0 ? void 0 : settings.get(`providers.${id}.enabled`).user) !== undefined;
|
|
261
|
+
// Enabled but binary absent is logged to the console, never announced:
|
|
262
|
+
// enabled means the extension supports the assistant, not that it is
|
|
263
|
+
// installed, so a toast would name a tool the user never installed
|
|
264
|
+
// (DEF-PANE-277). Only when the probe SUCCEEDED and this provider is
|
|
265
|
+
// the one missing - blaming PATH for a server the frontend never
|
|
266
|
+
// reached names the wrong cause. Once per id, not per reconcile.
|
|
270
267
|
if (probe !== null &&
|
|
271
268
|
probe.available === false &&
|
|
272
269
|
enabled &&
|
|
273
|
-
chosen &&
|
|
274
270
|
!warnedUnavailable.has(id)) {
|
|
275
271
|
warnedUnavailable.add(id);
|
|
276
272
|
const binary = (_b = (_a = registry.get(id)) === null || _a === void 0 ? void 0 : _a.descriptor.cliBinary) !== null && _b !== void 0 ? _b : id;
|
|
277
|
-
const label = (_d = (_c = registry.get(id)) === null || _c === void 0 ? void 0 : _c.descriptor.label) !== null && _d !== void 0 ? _d : id;
|
|
278
273
|
console.info(`${LOG_PREFIX} "${id}" is enabled but its \`${binary}\` binary was not found on the server's PATH; panel not shown.`);
|
|
279
|
-
// And say it where the user is looking. A console line satisfies the
|
|
280
|
-
// comment above only for someone who already suspects the cause; the
|
|
281
|
-
// symptom is a panel that never appears, which reads as a broken
|
|
282
|
-
// install rather than a PATH difference between the Jupyter server
|
|
283
|
-
// and the user's shell. The retired-extension case next door already
|
|
284
|
-
// gets a notification, so the COMMON failure was the quiet one.
|
|
285
|
-
Notification.warning(`${label} is enabled but \`${binary}\` was not found on the Jupyter server's PATH, so its panel is not shown.`, { autoClose: 8000 });
|
|
286
274
|
}
|
|
287
275
|
// The latch is per ABSENCE, not per page load. Once the server reports
|
|
288
|
-
// the binary present again, a later disappearance gets its own
|
|
276
|
+
// the binary present again, a later disappearance gets its own line:
|
|
289
277
|
// without this, one transient absence - a CLI upgrade unlinking the
|
|
290
278
|
// binary for a moment, or an obsolete roster from an overlapping probe -
|
|
291
279
|
// permanently suppresses the real one (DEF-125). It cannot make the
|
|
292
|
-
//
|
|
280
|
+
// line repeat while the state is unchanged, which is what the
|
|
293
281
|
// once-per-id latch above exists to prevent: the two conditions are
|
|
294
282
|
// mutually exclusive.
|
|
295
283
|
if (probe !== null && probe.available !== false) {
|
|
@@ -302,7 +290,7 @@ const plugin = {
|
|
|
302
290
|
// A panel docked before the first roster was built without the
|
|
303
291
|
// server root, and cannot resolve paths until it has one.
|
|
304
292
|
if (roster !== null) {
|
|
305
|
-
panel.setRoot((
|
|
293
|
+
panel.setRoot((_c = roster.root_dir) !== null && _c !== void 0 ? _c : '', roster.delete_to_trash !== false);
|
|
306
294
|
}
|
|
307
295
|
}
|
|
308
296
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jupyterlab_ai_code_assistants_extension",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.41",
|
|
4
4
|
"description": "A full launcher and manager for every AI code assistant in JupyterLab - Claude Code, Codex, Kimi, Gemini and DeepSeek. Start, resume, fork, switch, and clean up CLI sessions from a side panel per assistant - one click lands you in the right terminal with the assistant already running, no duplicate tabs, no UUID hunting.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jupyter",
|
|
@@ -500,6 +500,40 @@ describe('ACC-PROV - the activation contract', () => {
|
|
|
500
500
|
live.docked.forEach(widget => widget.dispose());
|
|
501
501
|
});
|
|
502
502
|
|
|
503
|
+
it('DEF-PANE-277 - an enabled assistant whose binary is absent gets no panel and no toast', async () => {
|
|
504
|
+
const toasted = jest
|
|
505
|
+
.spyOn(Notification, 'warning')
|
|
506
|
+
.mockImplementation(() => '');
|
|
507
|
+
const logged = jest
|
|
508
|
+
.spyOn(console, 'info')
|
|
509
|
+
.mockImplementation(() => undefined);
|
|
510
|
+
const absent = PROVIDERS[1].descriptor.id;
|
|
511
|
+
|
|
512
|
+
// Saved explicitly, as the settings editor writes it. Enabled means the
|
|
513
|
+
// extension supports the assistant, not that it is installed.
|
|
514
|
+
const live = await activate({
|
|
515
|
+
composite: { [`providers.${absent}.enabled`]: true },
|
|
516
|
+
answers: [() => Promise.resolve(roster(absent))]
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
expect(
|
|
520
|
+
live.docked
|
|
521
|
+
.filter(widget => !widget.isDisposed)
|
|
522
|
+
.map(widget => widget.descriptor.id)
|
|
523
|
+
).not.toContain(absent);
|
|
524
|
+
expect(toasted).not.toHaveBeenCalled();
|
|
525
|
+
// The reason stays in the browser console, once.
|
|
526
|
+
expect(
|
|
527
|
+
logged.mock.calls
|
|
528
|
+
.map(args => String(args[0]))
|
|
529
|
+
.filter(line => line.includes(`"${absent}"`))
|
|
530
|
+
).toHaveLength(1);
|
|
531
|
+
|
|
532
|
+
toasted.mockRestore();
|
|
533
|
+
logged.mockRestore();
|
|
534
|
+
live.docked.forEach(widget => widget.dispose());
|
|
535
|
+
});
|
|
536
|
+
|
|
503
537
|
it('ACC-PROV-16 - a binary installed after start gains its panel on the next probe', async () => {
|
|
504
538
|
const late = PROVIDERS[2].descriptor.id;
|
|
505
539
|
let present = false;
|
package/src/core/terminals.ts
CHANGED
|
@@ -65,8 +65,8 @@ function warnLegacyCompanion(): void {
|
|
|
65
65
|
// And said where the user is looking. The symptom is tabs that are simply
|
|
66
66
|
// plain, which reads as a feature that was never on rather than as something
|
|
67
67
|
// to fix, and a console line only reaches someone already suspecting the
|
|
68
|
-
// cause. The
|
|
69
|
-
//
|
|
68
|
+
// cause. The retired-extension notice in index.ts pairs its console line
|
|
69
|
+
// with a toast the same way. It does not
|
|
70
70
|
// close on its own, because the condition does not go away on its own.
|
|
71
71
|
Notification.warning(message, { autoClose: false });
|
|
72
72
|
}
|
package/src/index.ts
CHANGED
|
@@ -333,46 +333,30 @@ const plugin: JupyterFrontEndPlugin<void> = {
|
|
|
333
333
|
const roster = status;
|
|
334
334
|
const available =
|
|
335
335
|
roster === null ? true : probe !== null && probe.available !== false;
|
|
336
|
-
// Enabled but binary absent
|
|
337
|
-
//
|
|
338
|
-
//
|
|
339
|
-
// Only when the probe SUCCEEDED and this provider is
|
|
340
|
-
//
|
|
341
|
-
//
|
|
342
|
-
// assistant installed would otherwise raise three toasts about assistants
|
|
343
|
-
// the user has never heard of. The console line stays for that case.
|
|
344
|
-
const chosen =
|
|
345
|
-
settings?.get(`providers.${id}.enabled`).user !== undefined;
|
|
336
|
+
// Enabled but binary absent is logged to the console, never announced:
|
|
337
|
+
// enabled means the extension supports the assistant, not that it is
|
|
338
|
+
// installed, so a toast would name a tool the user never installed
|
|
339
|
+
// (DEF-PANE-277). Only when the probe SUCCEEDED and this provider is
|
|
340
|
+
// the one missing - blaming PATH for a server the frontend never
|
|
341
|
+
// reached names the wrong cause. Once per id, not per reconcile.
|
|
346
342
|
if (
|
|
347
343
|
probe !== null &&
|
|
348
344
|
probe.available === false &&
|
|
349
345
|
enabled &&
|
|
350
|
-
chosen &&
|
|
351
346
|
!warnedUnavailable.has(id)
|
|
352
347
|
) {
|
|
353
348
|
warnedUnavailable.add(id);
|
|
354
349
|
const binary = registry.get(id)?.descriptor.cliBinary ?? id;
|
|
355
|
-
const label = registry.get(id)?.descriptor.label ?? id;
|
|
356
350
|
console.info(
|
|
357
351
|
`${LOG_PREFIX} "${id}" is enabled but its \`${binary}\` binary was not found on the server's PATH; panel not shown.`
|
|
358
352
|
);
|
|
359
|
-
// And say it where the user is looking. A console line satisfies the
|
|
360
|
-
// comment above only for someone who already suspects the cause; the
|
|
361
|
-
// symptom is a panel that never appears, which reads as a broken
|
|
362
|
-
// install rather than a PATH difference between the Jupyter server
|
|
363
|
-
// and the user's shell. The retired-extension case next door already
|
|
364
|
-
// gets a notification, so the COMMON failure was the quiet one.
|
|
365
|
-
Notification.warning(
|
|
366
|
-
`${label} is enabled but \`${binary}\` was not found on the Jupyter server's PATH, so its panel is not shown.`,
|
|
367
|
-
{ autoClose: 8000 }
|
|
368
|
-
);
|
|
369
353
|
}
|
|
370
354
|
// The latch is per ABSENCE, not per page load. Once the server reports
|
|
371
|
-
// the binary present again, a later disappearance gets its own
|
|
355
|
+
// the binary present again, a later disappearance gets its own line:
|
|
372
356
|
// without this, one transient absence - a CLI upgrade unlinking the
|
|
373
357
|
// binary for a moment, or an obsolete roster from an overlapping probe -
|
|
374
358
|
// permanently suppresses the real one (DEF-125). It cannot make the
|
|
375
|
-
//
|
|
359
|
+
// line repeat while the state is unchanged, which is what the
|
|
376
360
|
// once-per-id latch above exists to prevent: the two conditions are
|
|
377
361
|
// mutually exclusive.
|
|
378
362
|
if (probe !== null && probe.available !== false) {
|