@nevescloud/pip 3.1.0 → 3.2.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.
package/README.md CHANGED
@@ -26,7 +26,7 @@ Provider-named bundles re-export the three primitives most hosts compose, from a
26
26
 
27
27
  ```js
28
28
  // Anthropic — Claude on /v1/messages
29
- import { createPip, createRuntime, anthropic } from 'https://cdn.jsdelivr.net/npm/@nevescloud/pip@latest/bundle/anthropic';
29
+ import { createPip, createRuntime, anthropic } from 'https://cdn.jsdelivr.net/npm/@nevescloud/pip@latest/bundle/anthropic.esm.js';
30
30
 
31
31
  const rt = createRuntime({ provider: anthropic({ model: 'claude-opus-4-7', apiKey: '…' }) });
32
32
  const pip = createPip({ onSubmit: rt.onSubmit, onSlash: rt.onSlash, slashSource: rt.slashSource });
@@ -34,15 +34,15 @@ const pip = createPip({ onSubmit: rt.onSubmit, onSlash: rt.onSlash, slashSource:
34
34
 
35
35
  ```js
36
36
  // OpenAI-compatible — OpenAI, GitHub Models, Together, Groq, OpenRouter, LM Studio, llama.cpp
37
- import { createPip, createRuntime, openai } from 'https://cdn.jsdelivr.net/npm/@nevescloud/pip@latest/bundle/openai';
37
+ import { createPip, createRuntime, openai } from 'https://cdn.jsdelivr.net/npm/@nevescloud/pip@latest/bundle/openai.esm.js';
38
38
  ```
39
39
 
40
40
  ```js
41
41
  // Local — in-browser inference via transformers.js + WebGPU (different shape: no runtime, renderer is host-driven)
42
- import { createPip, createTransformersRenderer } from 'https://cdn.jsdelivr.net/npm/@nevescloud/pip@latest/bundle/local';
42
+ import { createPip, createTransformersRenderer } from 'https://cdn.jsdelivr.net/npm/@nevescloud/pip@latest/bundle/local.esm.js';
43
43
  ```
44
44
 
45
- `pip/bundle` (no provider segment) is an alias for `pip/bundle/anthropic` — the default when you haven't picked a brain. Bundles are sugar over the layered files; hosts with a different brain shape (UI only, custom provider, in-browser model) import the granular files directly. See [CONSUMERS.md](../../CONSUMERS.md) for the full entry-point list.
45
+ On jsdelivr the `.esm.js` suffix is required — jsdelivr serves files by raw path, not via `package.json` exports. npm-installed consumers can use the shorter `@nevescloud/pip/bundle/anthropic` (Node ESM resolver honors the exports map). `pip/bundle.esm.js` (or `pip/bundle` via npm) is an alias for `bundle/anthropic` — the default when you haven't picked a brain. Bundles are sugar over the layered files; hosts with a different brain shape (UI only, custom provider, in-browser model) import the granular files directly. See [CONSUMERS.md](../../CONSUMERS.md) for the full entry-point list.
46
46
 
47
47
  ## Options
48
48
 
@@ -86,7 +86,12 @@ pip.registerSlash({
86
86
  pip.unregisterSlash("model");
87
87
  ```
88
88
 
89
- Handler returns `{ reply?, clearedUI?, passThrough? } | null`. `null` falls through to `onSlash` (if provided) and then to the LLM. Built-ins ship `/help` (auto-lists registered + built-ins) and `/clear` (wipes pip's local history + DOM).
89
+ Handler returns `{ reply?, clearedUI?, openCompletions?, passThrough? } | null`. `null` falls through to `onSlash` (if provided) and then to the LLM. Built-ins ship `/help` (auto-lists registered + built-ins) and `/clear` (wipes pip's local history + DOM).
90
+
91
+ - `reply` — render as an assistant turn in chat history.
92
+ - `clearedUI` — the handler already painted its own UI (via `startTurn`, `askInChat`, etc.); pip-core skips creating a turn.
93
+ - `openCompletions` — re-open the autocomplete dropdown in arg-mode for this command. Use when the bare command (no arg) is meant to surface a sub-menu like a model picker — keeps the navigation inside the dropdown the user came from instead of logging a listing to history. Pip-core puts `"/<cmd> "` in the input, focuses it, and runs the registered `complete('')` to populate the dropdown.
94
+ - `passThrough` — treat as if the handler didn't match; falls through to `onSlash` then the LLM.
90
95
 
91
96
  ## Tool-using turns
92
97
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nevescloud/pip",
3
- "version": "3.1.0",
3
+ "version": "3.2.0",
4
4
  "description": "Floating assistant bubble + panel + chat runtime. ESM, no build.",
5
5
  "type": "module",
6
6
  "main": "pip-core.esm.js",
package/pip-core.esm.js CHANGED
@@ -1072,7 +1072,7 @@ export function createPip(opts = {}) {
1072
1072
  // null/0 disables. Manual opens are never auto-closed.
1073
1073
  panelAutoCloseMs = null,
1074
1074
  onSubmit = null, // optional host handler; receives (text, turnApi) — if present, bypasses `ask`
1075
- onSlash = null, // optional (text) -> { reply?, clearedUI? } | null — fallback after registered commands miss
1075
+ onSlash = null, // optional (text) -> { reply?, clearedUI?, openCompletions?, passThrough? } | null — fallback after registered commands miss
1076
1076
  slashSource = null, // optional () -> [{ name, description?, complete? }] — overrides built-in source from registerSlash()
1077
1077
  placeholder = "Ask Pip…",
1078
1078
  maxLength = 4000,
@@ -1960,6 +1960,21 @@ export function createPip(opts = {}) {
1960
1960
  if (!r && onSlash) r = onSlash(text);
1961
1961
  if (r && !r.passThrough) {
1962
1962
  if (r.clearedUI) { scrollToBottom(); return; }
1963
+ if (r.openCompletions) {
1964
+ // Sub-menu navigation: re-open arg-mode autocomplete for this
1965
+ // command without committing a turn. Lets hosts surface
1966
+ // sub-options (model list, scope picker, etc.) inside the same
1967
+ // dropdown the user used to reach the command, instead of
1968
+ // logging the listing to chat history.
1969
+ const slashName = text.match(/^\/(\S+)/)?.[1];
1970
+ if (slashName) {
1971
+ input.value = `/${slashName} `;
1972
+ input.setSelectionRange(input.value.length, input.value.length);
1973
+ input.focus();
1974
+ updateSlashSuggest();
1975
+ }
1976
+ return;
1977
+ }
1963
1978
  const t = startTurn({ echo: text });
1964
1979
  if (r.reply) setReplyText(t, r.reply, true);
1965
1980
  return;