Commit graph

19733 commits

Author SHA1 Message Date
ethernet
6ecd335aa8
Merge pull request #75037 from NousResearch/sec-fixes
fix(sec): patch vulnerable deps + add publication-age floors and npm script allow-list

Co-authored-by: Kingsley Wong <7207924+datanerdie@users.noreply.github.com>
Co-authored-by: viky <vikyw89@gmail.com>
Co-authored-by: FT_IOxCS <237263164+ft-ioxcs@users.noreply.github.com>
Co-authored-by: 方明元 <fmy3@qq.com>
Co-authored-by: Yorkstone Supplies <58149681+sycamoregroupltd@users.noreply.github.com>
Co-authored-by: Steven Cuz Leath <Steven.Leath@gmail.com>
Co-authored-by: Kyle French <248366920+Dadmin88@users.noreply.github.com>
Co-authored-by: Eugeniusz Gilewski <egilewski@egilewski.com>
Co-authored-by: Christopher Gara <79837758+christopherrobin88@users.noreply.github.com>
Co-authored-by: LironTTG <147833337+LironTTG@users.noreply.github.com>
Co-authored-by: Austin Porada <bbasketballer75@gmail.com>
Co-authored-by: cresslank <9219265+cresslank@users.noreply.github.com>
Co-authored-by: Ion Mudreac <mudreac@gmail.com>
Co-authored-by: martinramos002 <262243228+martinramos002-bot@users.noreply.github.com>
Co-authored-by: Sensie-Agents <agents@joinsensie.com>
Co-authored-by: alexwill87 <173086651+alexwill87@users.noreply.github.com>
Co-authored-by: BullishMomentum56 <218643122+BullishMomentum56@users.noreply.github.com>
Co-authored-by: pintadoai <240097310+pintadoai@users.noreply.github.com>
Co-authored-by: Alfred Sahlberg <dinmail@gmail.com>
Co-authored-by: liuhao1024 <sunsky.lau@gmail.com>
Co-authored-by: Richard Ham <richard.ham@live.com>
Co-authored-by: jrcrittenden <jrcrittenden@gmail.com>
Co-authored-by: 峯岸 亮 <1920071390@campus.ouj.ac.jp>
Co-authored-by: Marcus Martini <6473852+napoleonmm83@users.noreply.github.com>
2026-07-31 14:07:32 -04:00
brooklyn!
0324849fe4
Merge pull request #61173 from NousResearch/bb/desktop-kanban
feat(desktop): Kanban — the founding plugin on the desktop SDK
2026-07-31 13:00:10 -05:00
ethernet
bc49e98143 docs(contributors): map salvaged supply-chain PR authors
scripts/contributor_audit.py resolves Co-authored-by trailers through
contributors/emails/, so a co-author with a plain (non-noreply) email and
no mapping file silently drops out of the generated release notes.

This PR consolidates ~30 open dependency/supply-chain PRs and credits their
authors as co-authors on the merge commit. Nine of those emails had no
mapping. Added via scripts/add_contributor.py, one file per email:

  vikyw89@gmail.com          -> vikyw89              (#50902)
  fmy3@qq.com                -> superafun            (#60201)
  Steven.Leath@gmail.com     -> Leathal1             (#69711)
  bbasketballer75@gmail.com  -> bbasketballer75      (#69864, #73857)
  mudreac@gmail.com          -> mudrii               (#66871, #63099)
  agents@joinsensie.com      -> Sensie-agents        (#65150)
  dinmail@gmail.com          -> sahlbergalfred4-lgtm (#70003)
  richard.ham@live.com       -> zebadee2kk           (#50052)
  jrcrittenden@gmail.com     -> jrcrittenden         (#28749)

egilewski@egilewski.com, sunsky.lau@gmail.com and 1920071390@campus.ouj.ac.jp
were already mapped. Every other co-author uses a GitHub id+login noreply
address, which auto-resolves and needs no file.

tests/scripts/test_contributor_map.py passes.
2026-07-31 13:56:54 -04:00
ethernet
e803c5aeac fix(npm): self-upgrade a managed npm when engines.npm rejects it
The repo's .npmrc sets engine-strict=true and package.json pins
engines.npm, so an npm outside that range aborts every npm ci /
npm install we run inside the checkout:

    npm error code EBADENGINE
    npm error notsup Required: {"npm":"<11.10.0 || >=12.0.0"}
    npm error notsup Actual:   {"npm":"11.10.0"}

Our callers made that worse: _run_npm_install_deterministic sees
`npm ci` fail and falls through to `npm install`, which fails
identically, so the user got a buried EBADENGINE and no remedy.

React to the failure instead of predicting it. npm states the
required range in its own error, so there is no need for a version
probe on the happy path or a semver range matcher — the recovery
reads the constraint out of the output it just produced, upgrades,
and retries once.

Scope is deliberately narrow. Hermes only upgrades an npm inside its
own managed Node tree ($HERMES_HOME/node), installing with --prefix
so bin/npm keeps resolving to the upgraded lib/node_modules/npm; a
managed install writes prefix=~/.local into node/etc/npmrc, so
without the override the "upgrade" would land elsewhere while the
managed npm stayed stale. A system / nvm / brew / Nix npm belongs to
the user, so that case prints the exact command and lets the original
failure stand.

The upgrade runs from a temp cwd with npm_config_min_release_age=0,
otherwise the checkout's own min-release-age gate would refuse the
npm release we need.

_run_npm_install_deterministic's capture_output=False callers (the
desktop install) streamed npm output and returned stderr=None, which
would leave the recovery nothing to read — stderr is now teed, so
live output is unchanged and the text stays inspectable.

Verified end to end against real npm binaries on copies of a managed
tree: managed npm 11.10.0 -> EBADENGINE -> upgraded to 12.0.2 ->
retry exits 0; a foreign npm 11.10.0 hard-fails with the manual
command and is left untouched.
2026-07-31 13:42:04 -04:00
ethernet
3975e9d753 fix(npm): npm 11.10-12.0 support min-release-age but NOT min-release-age-exclude.
that would break stuff :)
2026-07-31 13:42:04 -04:00
ethernet
9c85d68bcc fix(js): update vite 2026-07-31 13:42:03 -04:00
ethernet
fabc2d7d33 fix(js): hoist eslint shared devDeps to workspace root 2026-07-31 13:42:03 -04:00
ethernet
f7082c5172 fix(sec): pin exact npm package versions in website/, lock. 2026-07-31 13:42:03 -04:00
ethernet
94c27cae60 fix(sec): add min-release-age = 2 wks in website/.npmrc 2026-07-31 13:42:03 -04:00
ethernet
a4ffe39f73 fix(sec): add allowScripts to website/ 2026-07-31 13:42:03 -04:00
ethernet
88aed1b797 feat(sec): add exclude-newer = 14 days to uv.lock
disabled for 2 packages that are too new
2026-07-31 13:42:03 -04:00
ethernet
43f18cca81 feat(sec): add min-release-age = 2 wks in .npmrc
has some exclusions for packages with recent security fixes, which are
to be removed in >= 2wks
2026-07-31 13:42:03 -04:00
ethernet
515e88a80f fix(sec): pin exact npm package versions everywhere 2026-07-31 13:42:03 -04:00
ethernet
2158f2a5ad fix(sec): add allowScripts 2026-07-31 13:42:03 -04:00
ethernet
f976284245 nix: update nixpkgs, update nodejs to 26
brings npm 12 :)
2026-07-31 13:42:03 -04:00
ethernet
390a1771b2 fix(sec): update npm deps to resolve npm audit warnings
pin brace-expansion to 5.0.8
update concurrently to 10.0.4
update electron-builder to 26.15.3
update eslint to 10.8.0
update eslint-plugin-perfectionist to 5.10.0
update @assistant-ui/react to 0.15.0
update @assistant-ui/react-streamdown to 0.3.8
update radix-ui to 1.6.7
update react-router-dom to react-router@8.3.0 - react-router-dom is no longer a standalone package, it just reexports react-router
remove @radix-ui/react-slot: we import this from `radix-ui`
remove eslint-plugin-react: we imported it, but never actually used it!
2026-07-31 13:42:03 -04:00
ethernet
1f70e7ee7e update tornado to 6.5.7
tornado 6.5.5 has 7 known vulnerabilities:
GHSA-pw6j-qg29-8w7f
PYSEC-2026-3387
PYSEC-2026-3388
PYSEC-2026-3389

they're fixed in >= 6.5.7
2026-07-31 13:42:03 -04:00
ethernet
ea266a6061 fix(sec): update pynacl to 1.6.2
pynacl 1.5.0 has 1 known vulnerability:
PYSEC-2026-3002
it's fixed in >=1.6.2
2026-07-31 13:42:03 -04:00
ethernet
09da075505 fix(sec): update pygments to 2.20.0
pygments 2.19.2 has 1 known vulnerability:
PYSEC-2026-2987
it's fixed in >= 2.20.0
2026-07-31 13:42:03 -04:00
ethernet
f8d032588c fix(sec): update pytest to 9.1.1
pytest 9.0.2 has 1 known vulnerability:
GHSA-6w46-j5rx-g56g
it's fixed in >= 9.0.3
2026-07-31 13:42:03 -04:00
ethernet
eeab0a251d fix(sec): update pydantic-settings to 2.14.2
pydantic-settings 2.13.1 has 1 known vulnerability:
GHSA-4xgf-cpjx-pc3j

it's fixed in >= 2.14.2
2026-07-31 13:42:03 -04:00
ethernet
bb2539ea16 fix(sec): update pyasn1 to 0.6.4
pyasn1 0.6.3 has 5 known vulnerabilities:

GHSA-8ppf-4f7h-5ppj
GHSA-hm4w-wwcw-mr6r
PYSEC-2026-3455
PYSEC-2026-3456
PYSEC-2026-3457

they're fixed in >= 0.6.4
2026-07-31 13:42:03 -04:00
ethernet
abcd213504 fix(sec): update pillow to 12.3.0
pillow 12.2.0 has 26 known vulnerabilities:

GHSA-45hq-cxwh-f6vc
GHSA-4x4j-2g7c-83w6
GHSA-5x94-69rx-g8h2
GHSA-62p4-gmf7-7g93
GHSA-6r8x-57c9-28j4
GHSA-8v84-f9pq-wr9x
GHSA-9hw9-ch79-4vh6
GHSA-fj7v-r99m-22gq
GHSA-jjj6-mw9f-p565
GHSA-pg7v-jwj7-p798
GHSA-phj9-mv4w-65pm
GHSA-vjc4-5qp5-m44j
GHSA-xj96-63gp-2gmr
PYSEC-2026-2253
PYSEC-2026-2254
PYSEC-2026-2255
PYSEC-2026-2256
PYSEC-2026-2257
PYSEC-2026-3451
PYSEC-2026-3452
PYSEC-2026-3453
PYSEC-2026-3454
PYSEC-2026-3493
PYSEC-2026-3494
PYSEC-2026-3495
PYSEC-2026-3496

they're fixed in >= 12.3.0
2026-07-31 13:42:03 -04:00
ethernet
0945cc5b52 fix(sec): update msgpack to 1.2.1
msgpack 1.1.2 has 1 known vulnerability: GHSA-6v7p-g79w-8964

it's fixed in >= 1.2.1
2026-07-31 13:42:03 -04:00
ethernet
a7efeb0829 fix(sec): update mcp to 1.28.1
mcp 1.26.0 has 3 known vulnerabilities: PYSEC-2026-3481,
PYSEC-2026-3482, PYSEC-2026-3483

they're fixed in >= 1.28.1
2026-07-31 13:42:03 -04:00
brooklyn!
8f8bee94f7
Merge pull request #75547 from NousResearch/bb/statusbar-off-default
Statusbar off by default
2026-07-31 12:18:33 -05:00
Brooklyn Nicholson
d399c1644b fix(desktop): statusbar off by default
The statusbar is now opt-in. Existing users with a stored preference
keep their choice; new users get a clean bottom edge. The way back is
the view.toggleStatusbar keybind or the ⌘K row, unchanged.
2026-07-31 12:11:23 -05:00
Teknium
afc54ca806 feat(models): add deepseek/deepseek-v4-flash-0731 to Nous portal and OpenRouter catalogs
Dated snapshot of deepseek-v4-flash, live on both provider endpoints
(verified via OpenRouter /api/v1/models and Nous portal /v1/models).
Context (1M via deepseek-v4-flash prefix match), reasoning stale-timeout
floor (600s), and pricing (official_models_api live billing on both
routes) all resolve without new entries. model-catalog.json regenerated
via scripts/build_model_catalog.py.
2026-07-31 09:43:03 -07:00
hermes-seaeye[bot]
daa1befaf6
fmt(js): npm run fix on merge (#75517)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-31 16:22:58 +00:00
Yi Lok Enoch Lam
5835201de1
fix: keep queued paste payloads atomic (#74797)
Co-authored-by: eloklam <22125285+eloklam@users.noreply.github.com>
Co-authored-by: Orca <help@stably.ai>
2026-07-31 12:04:59 -04:00
rob-maron
126ff7071b
Portal free user vision fix + flux3 polling improvements (#75448)
* flux3 polling improvments

* poll gap to 4s

* back to 5s

* vision model fix

* minor fix
2026-07-31 10:17:55 -04:00
Austin Pickett
44e5641dac chore(contributors): map james@terminaloutcomes.com -> yaleman 2026-07-31 10:17:30 -04:00
Austin Pickett
74fdc578cc fix(cron): set headers for chronos JWKS requests
The chronos cron-fire verifier constructed PyJWKClient without explicit
headers, so its JWKS fetch to the NAS portal hit the same WAF 403 the
dashboard-auth providers already guard against. It reaches the same
portal issuer, so it's the same bug class — mirror the fix here and add
a constructor-contract regression test.

Co-authored-by: James Hodgkinson <james@terminaloutcomes.com>
2026-07-31 10:17:30 -04:00
James Hodgkinson
eaa9582e38 fix(dashboard): set headers for Nous JWKS requests
The Nous PyJWKClient was constructed without explicit headers, while the
self_hosted provider already sends Accept + User-Agent. Without them the
Portal WAF can block the JWKS fetch, so the same failure mode remained for
the Nous dashboard-auth route. Mirror the self_hosted fix and add a
constructor-contract regression test.
2026-07-31 10:17:30 -04:00
James Hodgkinson
83cee29ff7 fix(dashboard): set headers for JWKS requests 2026-07-31 10:17:30 -04:00
Doud-FR
eb08467a7a fix(desktop): redact gateway credentials from token logs 2026-07-31 10:16:21 -04:00
Doud-FR
3553c1b313 fix(desktop): reject empty encrypted token payloads 2026-07-31 10:16:21 -04:00
Doud-FR
6cb459af9e fix(desktop): harden native token store handling 2026-07-31 10:16:21 -04:00
Doud-FR
61d8be5cb0 test(desktop): cover native OAuth persistence path 2026-07-31 10:16:21 -04:00
Doud-FR
f15c4db4c8 fix(desktop): log native token decryption failures 2026-07-31 10:16:21 -04:00
Doud-FR
a3618c2b22 fix(desktop): preserve non-Error OAuth load failures 2026-07-31 10:16:21 -04:00
Doud-FR
ca7659a86c test(desktop): guard native OAuth parser boundary 2026-07-31 10:16:21 -04:00
Doud-FR
df1f825ce7 fix(desktop): restore native OAuth tokens after restart 2026-07-31 10:16:21 -04:00
Austin Pickett
539e9b5c1b fix(dashboard): gate resume hydration on sanitized PTY payload
The resume wait notice cleared on the first nonempty raw PTY frame, but
the terminal is written sanitizer.next(text). The sanitizer collapses an
erase-only, all-newline, or partial-CSI resume frame to "", so a control-
only first frame hid the notice while xterm was still blank.

Gate hydration completion on the rendered payload actually written to the
terminal, and cover the control-only-first-frame case with a regression
test over the real sanitizer.

Co-authored-by: teknium1 <teknium@nousresearch.com>
2026-07-31 09:47:06 -04:00
xxxigm
bb189bf6fe feat(dashboard): show wait notice while resumed chat history loads
Cover the blank TUI + blinking-cursor window on session resume, then hide
the notice as soon as the first real PTY payload arrives so history can
stream in visibly.
2026-07-31 09:47:06 -04:00
xxxigm
490f7048dd feat(dashboard): add resume loading overlay helpers
Extract overlay visibility helpers so the chat resume wait notice can be
tested without mounting ChatPage.
2026-07-31 09:47:06 -04:00
Carbon
c31c27e03a fix(desktop): preserve voice stop across speech setup 2026-07-31 09:44:53 -04:00
kshitijk4poor
1789e06ed8 fix: trim identity prompt — remove jargon, tighten directive
Follow-up to PR #70238. Remove 'free-response channel' and
'authorization' jargon from the model-facing prompt. Collapse the
triple-negative 'do not ask / do not reject / do not stay silent'
into a single directive. ~70 tokens vs ~175 in the contributor's
version, same semantics.
2026-07-31 17:55:23 +05:30
KCAYAAI
b24c915168 fix(slack): trust adapter routing after stripping self mention 2026-07-31 17:55:23 +05:30
kshitijk4poor
53559aaf86 fix(agent): protect batch-compaction markers from micro supersede/defrag
Phase 2 review findings on the salvage branch:

C1 (critical): batch and micro summary markers share
COMPRESSED_SUMMARY_METADATA_KEY, and compress() never reset micro state.
After micro absorbed exchanges 1..k, a batch compaction summarizing
1..m (m>k) could fire; the next micro pass's supersede then dropped the
batch marker (whose content the stale rolling summary does NOT contain)
and archive_and_compact immediately made the loss durable. Defrag had
the same hazard: it rewrote "the newest marker" even if that was a
batch marker. Empirically confirmed with a probe (batch marker content
destroyed in one pass).

Fix, three parts:
- Micro-created markers now carry MICRO_COMPACT_MARKER_KEY; supersede
  and defrag only ever touch micro-tagged markers. Rehydration in
  _resolve_compact_cursor tags the marker it absorbs (containment
  proof), which safely covers adopting a batch marker as the new
  rolling base after a reset.
- compress() success path resets micro rolling summary/cursor state so
  a stale summary can never claim cumulativeness over a batch marker.
- Regression tests for both directions plus the reset.

W4: _splice_micro_compact_result no longer strips _db_persisted stamps
from surviving messages. Micro archives in place under the SAME session
id (unlike batch's child-session rotation, #57491), so surviving stamps
are accurate; stripping them meant an archive_and_compact failure left
every previously-persisted message unstamped and the next append-only
flush re-inserted them all as duplicate active rows.

W5: finalize_turn micro gate now checks agent._persist_disabled —
persistence-isolated fork agents (background review) must not burn an
aux call per review turn, and must never archive_and_compact the
canonical session rows if their compressor ever gains a DB binding.

W1: _serialize_one_exchange now delegates to _serialize_for_summary
(was a ~70-line near-verbatim copy; one serializer, one place to fix).

S4: _find_one_exchange boundary guard rejects only assistant/tool
boundaries (the actual alternation hazard) instead of requiring user —
a stray mid-list system/injected message can no longer wedge the
cursor forever.

5 new regression tests; 38 micro/prune tests, 400 compression-suite
tests, 61 finalize/persist tests pass; ruff clean.
2026-07-31 17:44:19 +05:30