@mmmbuto/nexuscrew 0.9.21 → 0.9.22
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/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to NexusCrew are tracked here.
|
|
4
4
|
|
|
5
|
+
## 0.9.22 — 2026-09-11
|
|
6
|
+
|
|
7
|
+
- **Fleet Ollama Cloud: `deepseek-v4.1-flash`** aggiunto ai modelli dell'engine
|
|
8
|
+
(contesto dichiarato 1M → 1048576; capacità text+image, reasoning; parallel
|
|
9
|
+
tool calls non dichiarato finché non misurato su device) e promosso a
|
|
10
|
+
**modello di default dei tre engine ollama-cloud** (`claude`, `codex-vl`,
|
|
11
|
+
`codex`), al posto di `glm-5.2` (che resta disponibile in lista).
|
|
12
|
+
- Il tarball npm non include più gli screenshot di `docs/img/` (restano nel
|
|
13
|
+
repository GitHub, referenziati dal README): il pacchetto 0.9.21 li
|
|
14
|
+
spediva per errore mostrando nomi di ambiente interno.
|
|
15
|
+
- **Fleet codex-vl app-server identity policy.** Managed `codex-vl.*` cells now
|
|
16
|
+
pass `CODEX_APP_SERVER_IDENTITY_REQUIRED=1` through the child environment so
|
|
17
|
+
the app-server daemon started by the TUI enforces the Fleet identity policy;
|
|
18
|
+
an explicit per-engine override remains authoritative.
|
|
19
|
+
|
|
5
20
|
## 0.9.21 — 2026-09-10
|
|
6
21
|
|
|
7
22
|
- **Identity channel generation gate is fail-closed.** The per-cell supervisor
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"0.9.
|
|
1
|
+
{"version":"0.9.22"}
|
package/lib/fleet/definitions.js
CHANGED
|
@@ -42,6 +42,7 @@ const MAX_TMUXSESSION_LEN = 64;
|
|
|
42
42
|
const ENGINE_ID_RE = /^[a-z0-9._-]{1,32}$/; // engine id: lowercase (design 4a/9f)
|
|
43
43
|
const CELL_ID_RE = /^[A-Za-z0-9._-]{1,32}$/; // cell id: ammette maiuscole (il punto e' un id umano valido)
|
|
44
44
|
const ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/; // identificatore env POSIX-like
|
|
45
|
+
const CODEX_APP_SERVER_IDENTITY_REQUIRED = 'CODEX_APP_SERVER_IDENTITY_REQUIRED';
|
|
45
46
|
const TMUX_NAME_RE = /^[\w.-]{1,64}$/; // parsing: ammette il punto (legacy puntato da migrare)
|
|
46
47
|
const TMUX_SAFE_NAME_RE = /^[\w-]{1,64}$/; // scrittura: nomi tmux-safe (NO punto: tmux lo normalizza in '_')
|
|
47
48
|
|
|
@@ -334,9 +335,22 @@ function parseEngine(e, { extraModels = null, onIssue = null } = {}) {
|
|
|
334
335
|
if (e.managed !== undefined) {
|
|
335
336
|
const managed = normalizeManagedSpec(e.managed, { extraModels, engineId: e.id, onIssue });
|
|
336
337
|
if (!managed) return null;
|
|
337
|
-
for (const key of ['command', 'args', '
|
|
338
|
+
for (const key of ['command', 'args', 'promptMode', 'promptFlag', 'model']) {
|
|
338
339
|
if (e[key] !== undefined) return null;
|
|
339
340
|
}
|
|
341
|
+
// Managed engines compose their environment from the profile. The sole
|
|
342
|
+
// user override permitted here is the daemon policy switch consumed by
|
|
343
|
+
// codex-vl app-server; arbitrary env values would bypass that boundary.
|
|
344
|
+
let managedEnv;
|
|
345
|
+
if (e.env !== undefined) {
|
|
346
|
+
if (managed.client !== 'codex-vl') return null;
|
|
347
|
+
if (!e.env || typeof e.env !== 'object' || Array.isArray(e.env)) return null;
|
|
348
|
+
const keys = Object.keys(e.env);
|
|
349
|
+
if (keys.length !== 1 || keys[0] !== CODEX_APP_SERVER_IDENTITY_REQUIRED) return null;
|
|
350
|
+
const value = e.env[CODEX_APP_SERVER_IDENTITY_REQUIRED];
|
|
351
|
+
if (typeof value !== 'string' || value.length > MAX_ENV_VAL_LEN) return null;
|
|
352
|
+
managedEnv = { [CODEX_APP_SERVER_IDENTITY_REQUIRED]: value };
|
|
353
|
+
}
|
|
340
354
|
// panelUrl (opzionale): STESSO validatore e STESSA conservazione del ramo
|
|
341
355
|
// custom, qui sotto. Un engine managed puo' legittimamente avere un
|
|
342
356
|
// pannello, e il fallback engine->cella di cellStatus vale per entrambi.
|
|
@@ -349,6 +363,7 @@ function parseEngine(e, { extraModels = null, onIssue = null } = {}) {
|
|
|
349
363
|
managedPanelUrl = e.panelUrl;
|
|
350
364
|
}
|
|
351
365
|
const managedOut = { id: e.id, label, rc, managed };
|
|
366
|
+
if (managedEnv) managedOut.env = managedEnv;
|
|
352
367
|
if (managedPanelUrl !== undefined) managedOut.panelUrl = managedPanelUrl;
|
|
353
368
|
return managedOut;
|
|
354
369
|
}
|
package/lib/fleet/managed.js
CHANGED
|
@@ -24,6 +24,11 @@ const OLLAMA_CLOUD_MODELS = Object.freeze([
|
|
|
24
24
|
// dichiara Context 1M tokens, Input Text, Image e le badge vision/tools/thinking/cloud.
|
|
25
25
|
// DICHIARATO 2026-09-06 https://ollama.com/library/kimi-k3
|
|
26
26
|
'kimi-k3',
|
|
27
|
+
// deepseek-v4.1-flash: disponibile su ollama.com/library (2026-09-11). La
|
|
28
|
+
// scheda dichiara Context 1M tokens, Input Text, Image e le badge
|
|
29
|
+
// tools/thinking/vision/cloud; 552B MoE (8B attivi).
|
|
30
|
+
// DICHIARATO 2026-09-11 https://ollama.com/library/deepseek-v4.1-flash
|
|
31
|
+
'deepseek-v4.1-flash',
|
|
27
32
|
]);
|
|
28
33
|
// Autorita' per OLLAMA_CONTEXT = IL CAMPO STRUTTURATO «Context» della scheda
|
|
29
34
|
// canale (ollama.com/library, fetch 2026-08-27) — NON la descrizione, che
|
|
@@ -55,6 +60,9 @@ const OLLAMA_CONTEXT = Object.freeze({
|
|
|
55
60
|
// kimi-k3: scheda «Context / 1M tokens», Input Text, Image (2026-09-06).
|
|
56
61
|
// DICHIARATO 2026-09-06 https://ollama.com/library/kimi-k3
|
|
57
62
|
'kimi-k3': 1000000,
|
|
63
|
+
// deepseek-v4.1-flash: scheda «Context / 1M tokens» (2026-09-11); come gli
|
|
64
|
+
// altri deepseek vale la convenzione binaria del repo (1M -> 1048576).
|
|
65
|
+
'deepseek-v4.1-flash': 1048576,
|
|
58
66
|
});
|
|
59
67
|
// Capacita' per modello OSSERVATE dalla scheda canale (ollama.com/library,
|
|
60
68
|
// 2026-08-27). Assenza = default conservativo (comportamento odierno, nessuna
|
|
@@ -73,6 +81,10 @@ const OLLAMA_MODEL_CAPABILITIES = Object.freeze({
|
|
|
73
81
|
// PARALLEL NON dichiarato: default conservativo false finche' non misurato su device.
|
|
74
82
|
// DICHIARATO 2026-09-06 https://ollama.com/library/kimi-k3
|
|
75
83
|
'kimi-k3': Object.freeze({ input: ['text', 'image'], reasoning: true, supportsParallelToolCalls: false }),
|
|
84
|
+
// deepseek-v4.1-flash: scheda tools/thinking/vision/cloud, Input Text, Image
|
|
85
|
+
// (2026-09-11). PARALLEL NON dichiarato: default conservativo false finche'
|
|
86
|
+
// non misurato su device.
|
|
87
|
+
'deepseek-v4.1-flash': Object.freeze({ input: ['text', 'image'], reasoning: true, supportsParallelToolCalls: false }),
|
|
76
88
|
});
|
|
77
89
|
// Descrittori dell'engine ollama-cloud per la generazione del catalogo client:
|
|
78
90
|
// stessa forma dei descrittori custom/PI (id, label, contextWindow, input,
|
|
@@ -346,6 +358,8 @@ const MANAGED_KEYS = new Set(['client', 'provider', 'credentialProfile', 'model'
|
|
|
346
358
|
// D3: massimo numero di nomi in `envPassthrough`. L'allowlist e' opt-in e per
|
|
347
359
|
// nome, mai un passthrough in blocco: un tetto basso ferma una lista incontrollata.
|
|
348
360
|
const MAX_ENV_PASSTHROUGH = 32;
|
|
361
|
+
const CODEX_APP_SERVER_IDENTITY_REQUIRED = 'CODEX_APP_SERVER_IDENTITY_REQUIRED';
|
|
362
|
+
const CODEX_APP_SERVER_IDENTITY_REQUIRED_DEFAULT = '1';
|
|
349
363
|
// Explicit credential source policy. Default 'auto' preserves the legacy
|
|
350
364
|
// resolution order (runtime -> store -> shell -> key files -> legacy) so a
|
|
351
365
|
// pre-WP1 fleet.json migrates no-op: no existing cell changes resolution.
|
|
@@ -400,7 +414,7 @@ const CATALOG = Object.freeze([
|
|
|
400
414
|
// launch valorizza ANTHROPIC_API_KEY, non ANTHROPIC_AUTH_TOKEN come Z.AI.
|
|
401
415
|
{ id: 'claude.opencode-go', client: 'claude', provider: 'opencode-go', label: 'OpenCode Go', auth: 'OPENCODE_API_KEY', endpoint: OPENCODE_GO_ANTHROPIC_ROOT, protocol: 'anthropic_messages', model: 'deepseek-v4-flash', models: OPENCODE_GO_MESSAGES_MODELS, strictModels: true, core: true },
|
|
402
416
|
{ id: 'claude.openrouter', client: 'claude', provider: 'openrouter', label: 'OpenRouter', auth: 'OPENROUTER_API_KEY', endpoint: 'https://openrouter.ai/api', protocol: 'anthropic_messages', requiresModel: true, core: true, notice: 'claude-openrouter' },
|
|
403
|
-
{ id: 'claude.ollama-cloud', client: 'claude', provider: 'ollama-cloud', label: 'Ollama Cloud', auth: 'OLLAMA_API_KEY', endpoint: 'https://ollama.com', protocol: 'anthropic_messages', model: '
|
|
417
|
+
{ id: 'claude.ollama-cloud', client: 'claude', provider: 'ollama-cloud', label: 'Ollama Cloud', auth: 'OLLAMA_API_KEY', endpoint: 'https://ollama.com', protocol: 'anthropic_messages', model: 'deepseek-v4.1-flash', models: OLLAMA_CLOUD_MODELS, legacySecrets: true, core: true },
|
|
404
418
|
{ id: 'claude.bedrock', client: 'claude', provider: 'bedrock', label: 'Amazon Bedrock', auth: 'login', endpoint: 'AWS Bedrock', protocol: 'anthropic_messages', core: true, providerEnv: { CLAUDE_CODE_USE_BEDROCK: '1' } },
|
|
405
419
|
{ id: 'claude.vertex', client: 'claude', provider: 'vertex', label: 'Google Vertex AI', auth: 'login', endpoint: 'Google Vertex AI', protocol: 'anthropic_messages', core: true, providerEnv: { CLAUDE_CODE_USE_VERTEX: '1' } },
|
|
406
420
|
{ id: 'claude.foundry', client: 'claude', provider: 'foundry', label: 'Microsoft Foundry', auth: 'login', endpoint: 'Microsoft Foundry', protocol: 'anthropic_messages', core: true, providerEnv: { CLAUDE_CODE_USE_FOUNDRY: '1' } },
|
|
@@ -414,7 +428,7 @@ const CATALOG = Object.freeze([
|
|
|
414
428
|
{ id: 'codex-vl.alibaba-token-plan', client: 'codex-vl', provider: 'alibaba-token-plan', label: 'Alibaba Token Plan Personal', auth: 'ALIBABA_CODE_API_KEY', endpoint: 'https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1', protocol: 'openai_responses', model: 'qwen3.8-max', models: ALIBABA_CODEX_MODELS, strictModels: true, core: true, notice: 'alibaba-token-plan' },
|
|
415
429
|
{ id: 'codex-vl.opencode-go', client: 'codex-vl', provider: 'opencode-go', label: 'OpenCode Go', auth: 'OPENCODE_API_KEY', endpoint: OPENCODE_GO_API_BASE, protocol: 'openai_responses', model: 'deepseek-v4-flash', models: OPENCODE_GO_RESPONSES_MODELS, strictModels: true, core: true },
|
|
416
430
|
{ id: 'codex-vl.openrouter', client: 'codex-vl', provider: 'openrouter', label: 'OpenRouter', auth: 'OPENROUTER_API_KEY', endpoint: 'https://openrouter.ai/api/v1', protocol: 'openai_responses', requiresModel: true, core: true, notice: 'codex-openrouter' },
|
|
417
|
-
{ id: 'codex-vl.ollama-cloud', client: 'codex-vl', provider: 'ollama-cloud', label: 'Ollama Cloud', auth: 'OLLAMA_API_KEY', endpoint: 'https://ollama.com/v1', protocol: 'openai_responses', model: '
|
|
431
|
+
{ id: 'codex-vl.ollama-cloud', client: 'codex-vl', provider: 'ollama-cloud', label: 'Ollama Cloud', auth: 'OLLAMA_API_KEY', endpoint: 'https://ollama.com/v1', protocol: 'openai_responses', model: 'deepseek-v4.1-flash', models: OLLAMA_CLOUD_MODELS, legacySecrets: true, core: true },
|
|
418
432
|
{ id: 'codex-vl.zai-a', client: 'codex-vl', provider: 'zai-a', label: 'Z.AI A (Responses nativo)', auth: 'ZAI_API_KEY_A', endpoint: 'https://api.z.ai/api/v1', protocol: 'openai_responses', model: 'glm-5.3', models: ZAI_RESPONSES_MODELS, strictModels: true, core: true },
|
|
419
433
|
{ id: 'codex-vl.zai-p', client: 'codex-vl', provider: 'zai-p', label: 'Z.AI P (Responses nativo)', auth: 'ZAI_API_KEY_P', endpoint: 'https://api.z.ai/api/v1', protocol: 'openai_responses', model: 'glm-5.3', models: ZAI_RESPONSES_MODELS, strictModels: true, core: true },
|
|
420
434
|
{ id: 'codex-vl.openai-api', client: 'codex-vl', provider: 'openai-api', label: 'OpenAI API', auth: 'OPENAI_API_KEY', endpoint: 'https://api.openai.com/v1', protocol: 'openai_responses', core: true },
|
|
@@ -425,7 +439,7 @@ const CATALOG = Object.freeze([
|
|
|
425
439
|
// Codex (upstream OpenAI, Responses).
|
|
426
440
|
{ id: 'codex.native', client: 'codex', provider: 'native', label: 'OpenAI / ChatGPT account', auth: 'login', endpoint: 'OpenAI account', protocol: 'openai_responses', default: true, core: true },
|
|
427
441
|
{ id: 'codex.openai-api', client: 'codex', provider: 'openai-api', label: 'OpenAI API', auth: 'OPENAI_API_KEY', endpoint: 'https://api.openai.com/v1', protocol: 'openai_responses', core: true },
|
|
428
|
-
{ id: 'codex.ollama-cloud', client: 'codex', provider: 'ollama-cloud', label: 'Ollama Cloud', auth: 'OLLAMA_API_KEY', endpoint: 'https://ollama.com/v1', protocol: 'openai_responses', model: '
|
|
442
|
+
{ id: 'codex.ollama-cloud', client: 'codex', provider: 'ollama-cloud', label: 'Ollama Cloud', auth: 'OLLAMA_API_KEY', endpoint: 'https://ollama.com/v1', protocol: 'openai_responses', model: 'deepseek-v4.1-flash', models: OLLAMA_CLOUD_MODELS, legacySecrets: true, core: true },
|
|
429
443
|
{ id: 'codex.ollama', client: 'codex', provider: 'ollama', label: 'Ollama local', auth: 'none', endpoint: 'local provider', protocol: 'openai_responses', localProvider: 'ollama', core: true },
|
|
430
444
|
{ id: 'codex.lmstudio', client: 'codex', provider: 'lmstudio', label: 'LM Studio', auth: 'none', endpoint: 'local provider', protocol: 'openai_responses', localProvider: 'lmstudio', core: true },
|
|
431
445
|
{ id: 'codex.custom', client: 'codex', provider: 'custom', label: 'Custom Responses endpoint', auth: 'dynamic', protocol: 'openai_responses', protocols: ['openai_responses'], custom: true, core: true },
|
|
@@ -2024,6 +2038,28 @@ function resolveManagedEngine(engine, cell, cfg = {}) {
|
|
|
2024
2038
|
// TUI interattivo nella cwd della cella.
|
|
2025
2039
|
if (model) args.push('--model', model);
|
|
2026
2040
|
}
|
|
2041
|
+
// The codex-vl TUI starts the app-server daemon itself, so this
|
|
2042
|
+
// launcher-owned switch must be in the child environment (not argv). A
|
|
2043
|
+
// definition-level value is an explicit user override; cfg.env is retained
|
|
2044
|
+
// as the runtime compatibility override for callers that do not carry a
|
|
2045
|
+
// parsed engine definition. Other managed clients never receive this key.
|
|
2046
|
+
if (spec.client === 'codex-vl') {
|
|
2047
|
+
const definitionEnv = engine && engine.env;
|
|
2048
|
+
const runtimeEnv = cfg && cfg.env;
|
|
2049
|
+
const hasDefinitionOverride = definitionEnv && Object.prototype.hasOwnProperty.call(
|
|
2050
|
+
definitionEnv, CODEX_APP_SERVER_IDENTITY_REQUIRED,
|
|
2051
|
+
);
|
|
2052
|
+
const hasRuntimeOverride = runtimeEnv && Object.prototype.hasOwnProperty.call(
|
|
2053
|
+
runtimeEnv, CODEX_APP_SERVER_IDENTITY_REQUIRED,
|
|
2054
|
+
);
|
|
2055
|
+
if (hasDefinitionOverride && typeof definitionEnv[CODEX_APP_SERVER_IDENTITY_REQUIRED] === 'string') {
|
|
2056
|
+
env[CODEX_APP_SERVER_IDENTITY_REQUIRED] = definitionEnv[CODEX_APP_SERVER_IDENTITY_REQUIRED];
|
|
2057
|
+
} else if (hasRuntimeOverride && typeof runtimeEnv[CODEX_APP_SERVER_IDENTITY_REQUIRED] === 'string') {
|
|
2058
|
+
env[CODEX_APP_SERVER_IDENTITY_REQUIRED] = runtimeEnv[CODEX_APP_SERVER_IDENTITY_REQUIRED];
|
|
2059
|
+
} else {
|
|
2060
|
+
env[CODEX_APP_SERVER_IDENTITY_REQUIRED] = CODEX_APP_SERVER_IDENTITY_REQUIRED_DEFAULT;
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2027
2063
|
// Prompt su argv (0.8.47): SOLO i client che non hanno un percorso classified
|
|
2028
2064
|
// delivery. kimi.native e claude.kimi-code usano promptMode 'send-keys' con
|
|
2029
2065
|
// deliverBootstrapPrompt (readiness classificata + at-most-once): il prompt
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mmmbuto/nexuscrew",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.22",
|
|
4
4
|
"description": "Faithful browser tmux client — attach to live sessions over a real PTY, localhost-only, mobile-easy",
|
|
5
5
|
"main": "lib/server.js",
|
|
6
6
|
"bin": {
|
|
@@ -22,8 +22,6 @@
|
|
|
22
22
|
"docs/live-prompt-templates/LIVE_PROMPT.en.md",
|
|
23
23
|
"docs/live-prompt-templates/LIVE_PROMPT.es.md",
|
|
24
24
|
"docs/live-prompt-templates/LIVE_PROMPT.it.md",
|
|
25
|
-
"docs/img/fleet-deck-desktop.png",
|
|
26
|
-
"docs/img/session-mobile.png",
|
|
27
25
|
"docs/MCP.md",
|
|
28
26
|
"docs/NODES.md",
|
|
29
27
|
"docs/NOTIFICATIONS.md",
|
|
Binary file
|
|
Binary file
|