mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
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>
This commit is contained in:
commit
6ecd335aa8
84 changed files with 6501 additions and 6909 deletions
47
.npmrc
Normal file
47
.npmrc
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# needed to prevent bad npm that has min-release-age but not exclude
|
||||
engine-strict=true
|
||||
|
||||
min-release-age=14
|
||||
# allow assistant-ui packages & a couple specific deps since they update a LOT.
|
||||
# remove this when we stabilize (or we haven't updated in 2 wks)
|
||||
min-release-age-exclude[]=@assistant-ui/*
|
||||
min-release-age-exclude[]=assistant-cloud
|
||||
min-release-age-exclude[]=assistant-stream
|
||||
min-release-age-exclude[]=@radix-ui/*
|
||||
min-release-age-exclude[]=radix-ui
|
||||
min-release-age-exclude[]=safe-content-frame
|
||||
|
||||
# react-router 8.3.0 includes fixes for vulns. remove this when 8.3.0 is > 2wks old.
|
||||
min-release-age-exclude[]=react-router
|
||||
|
||||
# eslint 10.8.0 includes fixes for vulns. remove this when 10.8.0 is > 2wks old.
|
||||
min-release-age-exclude[]=eslint
|
||||
min-release-age-exclude[]=@eslint/*
|
||||
|
||||
# tar 7.5.21 includes fixes for vulns. remove this when 7.5.21 is > 2wks old
|
||||
min-release-age-exclude[]=tar
|
||||
|
||||
# concurrently 10.0.4 includes fixes for vulns. remove this when 10.0.4 is > 2wks old
|
||||
min-release-age-exclude[]=concurrently
|
||||
|
||||
# fast-uri 3.1.4 includes fixes for vulns. remove this when 3.1.4 is > 2wks old
|
||||
min-release-age-exclude[]=fast-uri
|
||||
|
||||
# minimatch 10.2.6 includes fixes for vulns. remove this when 10.2.6 is > 2wks old
|
||||
min-release-age-exclude[]=minimatch
|
||||
|
||||
|
||||
# brace-expansion 5.0.8 includes fixes for vulns. remove this when 5.0.8 is > 2wks old
|
||||
min-release-age-exclude[]=brace-expansion
|
||||
|
||||
# vite 8.2.0 is the first release depending on rolldown >= 1.2.1, which fixes
|
||||
# a rolldown panic that breaks `npm run build` in apps/desktop
|
||||
# (rolldown/rolldown#10337 — a regression in 1.1.5, the version vite 8.1.5
|
||||
# pins as ~1.1.5). @oxc-project/types is here because rolldown 1.2.1 pins it
|
||||
# as `=0.142.0` — an exact pin, so no older release satisfies it and the age
|
||||
# gate would fail the whole install with ETARGET.
|
||||
# remove these once vite 8.2.0 is > 2wks old.
|
||||
min-release-age-exclude[]=vite
|
||||
min-release-age-exclude[]=rolldown
|
||||
min-release-age-exclude[]=@rolldown/*
|
||||
min-release-age-exclude[]=@oxc-project/types
|
||||
|
|
@ -20,40 +20,32 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@nous-research/ui": "0.16.0",
|
||||
"@tailwindcss/vite": "^4.2.4",
|
||||
"@tailwindcss/typography": "^0.5.19",
|
||||
"@tauri-apps/api": "^2.0.0",
|
||||
"@tauri-apps/plugin-dialog": "^2.0.0",
|
||||
"@tauri-apps/plugin-opener": "^2.0.0",
|
||||
"@tauri-apps/plugin-process": "^2.0.0",
|
||||
"@tauri-apps/plugin-shell": "^2.0.0",
|
||||
"@vscode/codicons": "^0.0.45",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"katex": "^0.16.45",
|
||||
"lucide-react": "^0.577.0",
|
||||
"nanostores": "^1.3.0",
|
||||
"radix-ui": "^1.4.3",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"tailwind-merge": "^3.5.0",
|
||||
"tailwindcss": "^4.2.1",
|
||||
"tw-shimmer": "^0.4.11"
|
||||
"@tailwindcss/typography": "0.5.20",
|
||||
"@tailwindcss/vite": "4.3.3",
|
||||
"@tauri-apps/api": "2.11.1",
|
||||
"@tauri-apps/plugin-dialog": "2.7.1",
|
||||
"@tauri-apps/plugin-opener": "2.5.4",
|
||||
"@tauri-apps/plugin-process": "2.3.1",
|
||||
"@tauri-apps/plugin-shell": "2.3.5",
|
||||
"@vscode/codicons": "0.0.45",
|
||||
"class-variance-authority": "0.7.1",
|
||||
"clsx": "2.1.1",
|
||||
"katex": "0.16.47",
|
||||
"lucide-react": "0.577.0",
|
||||
"nanostores": "1.4.0",
|
||||
"radix-ui": "1.6.7",
|
||||
"react": "19.2.7",
|
||||
"react-dom": "19.2.7",
|
||||
"tailwind-merge": "3.6.0",
|
||||
"tailwindcss": "4.3.3",
|
||||
"tw-shimmer": "0.4.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.39.4",
|
||||
"@tauri-apps/cli": "^2.0.0",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react": "^6.0.2",
|
||||
"eslint": "^9.39.4",
|
||||
"eslint-plugin-perfectionist": "^5.9.0",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks": "^7.1.1",
|
||||
"eslint-plugin-unused-imports": "^4.4.1",
|
||||
"globals": "^17.4.0",
|
||||
"typescript": "^6.0.3",
|
||||
"typescript-eslint": "^8.56.1",
|
||||
"vite": "^8.0.16"
|
||||
"@tauri-apps/cli": "2.11.4",
|
||||
"@types/react": "19.2.17",
|
||||
"@types/react-dom": "19.2.3",
|
||||
"@vitejs/plugin-react": "6.0.3",
|
||||
"typescript": "6.0.3",
|
||||
"vite": "8.2.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@
|
|||
},
|
||||
"scripts": {
|
||||
"clean": "npm run clean:e2e && npm run clean:renderer && npm run clean:electron",
|
||||
"clean:e2e":"tsc --build tsconfig.e2e.json --clean",
|
||||
"clean:renderer":"tsc --build tsconfig.json --clean ",
|
||||
"clean:electron":"tsc --build tsconfig.electron.json --clean",
|
||||
"clean:e2e": "tsc --build tsconfig.e2e.json --clean",
|
||||
"clean:renderer": "tsc --build tsconfig.json --clean ",
|
||||
"clean:electron": "tsc --build tsconfig.electron.json --clean",
|
||||
"dev": "concurrently -k \"npm:dev:renderer\" \"npm:dev:electron\"",
|
||||
"dev:fake-boot": "cross-env HERMES_DESKTOP_BOOT_FAKE=1 HERMES_DESKTOP_BOOT_FAKE_STEP_MS=650 npm run dev",
|
||||
"dev:mock": "node scripts/dev-mock.mjs",
|
||||
|
|
@ -64,110 +64,100 @@
|
|||
"test:e2e:update-snapshots": "npm run build && WLR_BACKENDS=headless WLR_NO_HARDWARE_CURSORS=1 cage -- npx playwright test e2e/ --reporter=list --update-snapshots"
|
||||
},
|
||||
"dependencies": {
|
||||
"@assistant-ui/react": "^0.14.23",
|
||||
"@assistant-ui/react-streamdown": "^0.3.4",
|
||||
"@audiowave/react": "^0.6.2",
|
||||
"@chenglou/pretext": "^0.0.6",
|
||||
"@codemirror/commands": "^6.10.4",
|
||||
"@codemirror/language": "^6.12.4",
|
||||
"@codemirror/language-data": "^6.5.2",
|
||||
"@codemirror/state": "^6.7.0",
|
||||
"@codemirror/view": "^6.43.3",
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
"@dnd-kit/sortable": "^10.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@assistant-ui/react": "0.15.1",
|
||||
"@assistant-ui/react-streamdown": "0.3.8",
|
||||
"@audiowave/react": "0.6.2",
|
||||
"@chenglou/pretext": "0.0.6",
|
||||
"@codemirror/commands": "6.10.4",
|
||||
"@codemirror/language": "6.12.4",
|
||||
"@codemirror/language-data": "6.5.2",
|
||||
"@codemirror/state": "6.7.1",
|
||||
"@codemirror/view": "6.43.6",
|
||||
"@dnd-kit/core": "6.3.1",
|
||||
"@dnd-kit/sortable": "10.0.0",
|
||||
"@dnd-kit/utilities": "3.2.2",
|
||||
"@hermes/shared": "file:../shared",
|
||||
"@icons-pack/react-simple-icons": "=13.11.1",
|
||||
"@lezer/highlight": "^1.2.3",
|
||||
"@nanostores/react": "^1.1.0",
|
||||
"@nous-research/ui": "^0.13.0",
|
||||
"@radix-ui/react-slot": "^1.2.4",
|
||||
"@streamdown/code": "^1.1.1",
|
||||
"@tabler/icons-react": "^3.41.1",
|
||||
"@tailwindcss/typography": "^0.5.19",
|
||||
"@tailwindcss/vite": "^4.2.4",
|
||||
"@tanstack/react-query": "^5.100.6",
|
||||
"@tanstack/react-virtual": "^3.13.24",
|
||||
"@vscode/codicons": "^0.0.45",
|
||||
"@xterm/addon-fit": "^0.11.0",
|
||||
"@xterm/addon-serialize": "^0.14.0",
|
||||
"@xterm/addon-unicode11": "^0.9.0",
|
||||
"@xterm/addon-web-links": "^0.12.0",
|
||||
"@xterm/addon-webgl": "^0.19.0",
|
||||
"@xterm/xterm": "^6.0.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"cmdk": "^1.1.1",
|
||||
"d3-force": "^3.0.0",
|
||||
"dnd-core": "^14.0.1",
|
||||
"dompurify": "^3.4.11",
|
||||
"emojibase-data": "^16.0.3",
|
||||
"fflate": "^0.8.3",
|
||||
"frimousse": "^0.3.0",
|
||||
"hast-util-from-html-isomorphic": "^2.0.0",
|
||||
"hast-util-to-text": "^4.0.2",
|
||||
"ignore": "^7.0.5",
|
||||
"katex": "^0.16.45",
|
||||
"mermaid": "^11.15.0",
|
||||
"motion": "^12.38.0",
|
||||
"nanostores": "^1.3.0",
|
||||
"@icons-pack/react-simple-icons": "13.11.1",
|
||||
"@lezer/highlight": "1.2.3",
|
||||
"@nanostores/react": "1.1.0",
|
||||
"@nous-research/ui": "0.16.0",
|
||||
"@streamdown/code": "1.1.1",
|
||||
"@tabler/icons-react": "3.44.0",
|
||||
"@tailwindcss/typography": "0.5.20",
|
||||
"@tailwindcss/vite": "4.3.3",
|
||||
"@tanstack/react-query": "5.101.2",
|
||||
"@tanstack/react-virtual": "3.14.6",
|
||||
"@vscode/codicons": "0.0.45",
|
||||
"@xterm/addon-fit": "0.11.0",
|
||||
"@xterm/addon-serialize": "0.14.0",
|
||||
"@xterm/addon-unicode11": "0.9.0",
|
||||
"@xterm/addon-web-links": "0.12.0",
|
||||
"@xterm/addon-webgl": "0.19.0",
|
||||
"@xterm/xterm": "6.0.0",
|
||||
"class-variance-authority": "0.7.1",
|
||||
"clsx": "2.1.1",
|
||||
"cmdk": "1.1.1",
|
||||
"d3-force": "3.0.0",
|
||||
"dnd-core": "14.0.1",
|
||||
"dompurify": "3.4.12",
|
||||
"emojibase-data": "16.0.3",
|
||||
"fflate": "0.8.3",
|
||||
"frimousse": "0.3.0",
|
||||
"hast-util-from-html-isomorphic": "2.0.0",
|
||||
"hast-util-to-text": "4.0.2",
|
||||
"ignore": "7.0.6",
|
||||
"katex": "0.16.47",
|
||||
"mermaid": "11.16.0",
|
||||
"motion": "12.42.2",
|
||||
"nanostores": "1.4.0",
|
||||
"node-pty": "1.1.0",
|
||||
"radix-ui": "^1.6.5",
|
||||
"react": "^19.2.5",
|
||||
"react-arborist": "^3.5.0",
|
||||
"react-dnd-html5-backend": "^14.0.3",
|
||||
"react-dom": "^19.2.5",
|
||||
"react-router-dom": "^7.17.0",
|
||||
"react-shiki": "^0.9.3",
|
||||
"remark-math": "^6.0.0",
|
||||
"remend": "^1.3.0",
|
||||
"shiki": "^4.0.2",
|
||||
"simple-git": "^3.36.0",
|
||||
"streamdown": "^2.5.0",
|
||||
"tailwind-merge": "^3.5.0",
|
||||
"tailwindcss": "^4.2.4",
|
||||
"tw-shimmer": "^0.4.11",
|
||||
"unicode-animations": "^1.0.3",
|
||||
"unified": "^11.0.5",
|
||||
"unist-util-visit-parents": "^6.0.2",
|
||||
"use-stick-to-bottom": "^1.1.6",
|
||||
"vfile": "^6.0.3",
|
||||
"web-haptics": "^0.0.6"
|
||||
"radix-ui": "1.6.7",
|
||||
"react": "19.2.7",
|
||||
"react-arborist": "3.13.2",
|
||||
"react-dnd-html5-backend": "14.1.0",
|
||||
"react-dom": "19.2.7",
|
||||
"react-router": "8.3.0",
|
||||
"react-shiki": "0.9.3",
|
||||
"remark-math": "6.0.0",
|
||||
"remend": "1.3.0",
|
||||
"shiki": "4.3.1",
|
||||
"simple-git": "3.36.0",
|
||||
"streamdown": "2.5.0",
|
||||
"tailwind-merge": "3.6.0",
|
||||
"tailwindcss": "4.3.3",
|
||||
"tw-shimmer": "0.4.12",
|
||||
"unicode-animations": "1.0.3",
|
||||
"unified": "11.0.5",
|
||||
"unist-util-visit-parents": "6.0.2",
|
||||
"use-stick-to-bottom": "1.1.6",
|
||||
"vfile": "6.0.3",
|
||||
"web-haptics": "0.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron/rebuild": "^4.0.6",
|
||||
"@eslint/js": "^9.39.4",
|
||||
"@playwright/test": "=1.58.2",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/react": "^16.3.2",
|
||||
"@types/d3-force": "^3.0.10",
|
||||
"@types/hast": "^3.0.4",
|
||||
"@types/node": "^22.20.0",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@typescript-eslint/eslint-plugin": "^8.59.1",
|
||||
"@typescript-eslint/parser": "^8.59.1",
|
||||
"@vitejs/plugin-react": "^6.0.1",
|
||||
"@electron/rebuild": "4.2.0",
|
||||
"@playwright/test": "1.58.2",
|
||||
"@testing-library/dom": "10.4.1",
|
||||
"@testing-library/react": "16.3.2",
|
||||
"@types/d3-force": "3.0.10",
|
||||
"@types/hast": "3.0.5",
|
||||
"@types/node": "22.20.1",
|
||||
"@types/react": "19.2.17",
|
||||
"@types/react-dom": "19.2.3",
|
||||
"@vitejs/plugin-react": "6.0.3",
|
||||
"bippy": "0.5.43",
|
||||
"concurrently": "^10.0.3",
|
||||
"cross-env": "^10.1.0",
|
||||
"concurrently": "10.0.4",
|
||||
"cross-env": "10.1.0",
|
||||
"electron": "40.10.2",
|
||||
"electron-builder": "^26.8.1",
|
||||
"esbuild": "^0.28.1",
|
||||
"eslint": "^9.39.4",
|
||||
"eslint-plugin-perfectionist": "^5.9.0",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks": "^7.1.1",
|
||||
"eslint-plugin-unused-imports": "^4.4.1",
|
||||
"globals": "^16.5.0",
|
||||
"jsdom": "^29.1.1",
|
||||
"prettier": "^3.8.3",
|
||||
"rcedit": "^5.0.2",
|
||||
"tsx": "^4.22.4",
|
||||
"typescript": "^6.0.3",
|
||||
"vite": "^8.0.10",
|
||||
"vitest": "^4.1.5",
|
||||
"wait-on": "^9.0.5"
|
||||
"electron-builder": "26.15.3",
|
||||
"esbuild": "0.28.1",
|
||||
"jsdom": "29.1.1",
|
||||
"prettier": "3.9.5",
|
||||
"rcedit": "5.0.2",
|
||||
"tsx": "4.23.1",
|
||||
"typescript": "6.0.3",
|
||||
"vite": "8.2.0",
|
||||
"vitest": "4.1.10",
|
||||
"wait-on": "9.0.10"
|
||||
},
|
||||
"build": {
|
||||
"electronVersion": "40.10.2",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type * as React from 'react'
|
||||
import { memo, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
import { ZoomableImage } from '@/components/chat/zoomable-image'
|
||||
import { PageLoader } from '@/components/page-loader'
|
||||
|
|
|
|||
|
|
@ -10,15 +10,11 @@ import { type ComposerScope, ComposerScopeProvider, MAIN_COMPOSER_SCOPE } from '
|
|||
|
||||
import { useComposerDraft } from './use-composer-draft'
|
||||
|
||||
const mockComposerApi = { setText: vi.fn() }
|
||||
const mockComposerApi = { setText: vi.fn(), getState: () => ({ text: '' }) }
|
||||
|
||||
vi.mock('@assistant-ui/react', () => ({
|
||||
useAui: () => ({ composer: () => mockComposerApi }),
|
||||
useAuiState: (selector: (state: { composer: { text: string } }) => unknown) => selector({ composer: { text: '' } }),
|
||||
useComposerRuntime: () => ({
|
||||
getState: () => ({ text: '' }),
|
||||
subscribe: () => () => undefined
|
||||
})
|
||||
useAui: () => ({ composer: () => mockComposerApi, subscribe: () => () => undefined }),
|
||||
useAuiState: (selector: (state: { composer: { text: string } }) => unknown) => selector({ composer: { text: '' } })
|
||||
}))
|
||||
|
||||
interface ProbeHarnessProps {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useAui, useAuiState, useComposerRuntime } from '@assistant-ui/react'
|
||||
import { useAui, useAuiState } from '@assistant-ui/react'
|
||||
import { type RefObject, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'
|
||||
|
||||
import { SLASH_COMMAND_RE } from '@/lib/chat-runtime'
|
||||
|
|
@ -58,7 +58,6 @@ export function useComposerDraft({
|
|||
sessionId
|
||||
}: UseComposerDraftArgs) {
|
||||
const aui = useAui()
|
||||
const composerRuntime = useComposerRuntime()
|
||||
// Which composer this is on the focus bus + which attachment set it owns.
|
||||
const { attachments: attachmentScope, target } = useComposerScope()
|
||||
|
||||
|
|
@ -79,7 +78,7 @@ export function useComposerDraft({
|
|||
const setComposerText = useCallback(
|
||||
(value: string) => {
|
||||
try {
|
||||
aui.composer().setText(value)
|
||||
aui.composer.setText(value)
|
||||
} catch {
|
||||
// Composer core not bound yet — DOM/draftRef carry the text.
|
||||
}
|
||||
|
|
@ -272,7 +271,7 @@ export function useComposerDraft({
|
|||
// eslint-disable-next-line no-restricted-syntax -- legitimate non-atom ref write (see eslint rule comment)
|
||||
useEffect(() => {
|
||||
const sync = () => {
|
||||
const text = composerRuntime.getState().text
|
||||
const text = aui.composer.getState().text
|
||||
draftRef.current = text
|
||||
|
||||
const editor = editorRef.current
|
||||
|
|
@ -304,13 +303,13 @@ export function useComposerDraft({
|
|||
}, DRAFT_PERSIST_DEBOUNCE_MS)
|
||||
}
|
||||
|
||||
const unsubscribe = composerRuntime.subscribe(sync)
|
||||
const unsubscribe = aui.subscribe(sync)
|
||||
|
||||
return () => {
|
||||
unsubscribe()
|
||||
window.clearTimeout(draftPersistTimerRef.current)
|
||||
}
|
||||
}, [composerRuntime, queueEditRef])
|
||||
}, [aui, queueEditRef])
|
||||
|
||||
const insertText = (text: string) => {
|
||||
const base = draftRef.current
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { cleanup, render, screen } from '@testing-library/react'
|
||||
import { MemoryRouter } from 'react-router-dom'
|
||||
import { MemoryRouter } from 'react-router'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { I18nProvider } from '@/i18n'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useStore } from '@nanostores/react'
|
||||
import { type ReactNode, useEffect, useMemo } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
import { blurComposerInput } from '@/app/chat/composer/focus'
|
||||
import { AGENTS_ROUTE } from '@/app/routes'
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { useQuery } from '@tanstack/react-query'
|
|||
import type { ReadableAtom } from 'nanostores'
|
||||
import type * as React from 'react'
|
||||
import { Suspense, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useLocation } from 'react-router'
|
||||
|
||||
import type { SubmitTextOptions } from '@/app/session/hooks/use-prompt-actions/utils'
|
||||
import { Thread } from '@/components/assistant-ui/thread'
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { sortableKeyboardCoordinates } from '@dnd-kit/sortable'
|
|||
import { useStore } from '@nanostores/react'
|
||||
import type * as React from 'react'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useLocation } from 'react-router'
|
||||
|
||||
import { PlatformAvatar } from '@/app/messaging/platform-icon'
|
||||
import { Button } from '@/components/ui/button'
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import {
|
|||
import { CSS } from '@dnd-kit/utilities'
|
||||
import { useStore } from '@nanostores/react'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
import { CodeEditor } from '@/components/chat/code-editor'
|
||||
import { Button } from '@/components/ui/button'
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { useStore } from '@nanostores/react'
|
|||
import { useQuery } from '@tanstack/react-query'
|
||||
import { Dialog as DialogPrimitive } from 'radix-ui'
|
||||
import { memo, useCallback, useDeferredValue, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
import {
|
||||
HUD_HEADING,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
import { useStore } from '@nanostores/react'
|
||||
import { type ComponentProps, lazy, memo, type ReactNode, Suspense, useMemo } from 'react'
|
||||
import { Navigate, Route, Routes, useParams } from 'react-router-dom'
|
||||
import { Navigate, Route, Routes, useParams } from 'react-router'
|
||||
|
||||
import { ContribBoundary } from '@/contrib/react/boundary'
|
||||
import { useContributions } from '@/contrib/react/use-contributions'
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
import { useStore } from '@nanostores/react'
|
||||
import { useQueryClient } from '@tanstack/react-query'
|
||||
import { type CSSProperties, lazy, type ReactNode, Suspense, useCallback, useEffect, useMemo, useRef } from 'react'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router'
|
||||
|
||||
import { formatRefValue } from '@/components/assistant-ui/directive-text'
|
||||
import { BootFailureOverlay } from '@/components/boot-failure-overlay'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useEffect, useRef } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
import { closeActiveTab } from '@/app/chat/close-tab'
|
||||
import { $terminalTakeover, setTerminalTakeover } from '@/app/right-sidebar/store'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useCallback, useMemo } from 'react'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router'
|
||||
|
||||
// Read/write an enum-shaped URL search param (e.g. ?tab=foo). Used to make
|
||||
// tabbed views survive a refresh. Always navigates with replace so tab clicks
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useLocation } from 'react-router-dom'
|
||||
import { useLocation } from 'react-router'
|
||||
|
||||
import { appViewForPath, isOverlayView } from '@/app/routes'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// @vitest-environment jsdom
|
||||
import { act, cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { MemoryRouter } from 'react-router-dom'
|
||||
import { MemoryRouter } from 'react-router'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import type { MessagingPlatformInfo } from '@/types/hermes'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useStore } from '@nanostores/react'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
import { useGatewayRequest } from '@/app/gateway/hooks/use-gateway-request'
|
||||
import { SETTINGS_ROUTE } from '@/app/routes'
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { useStore } from '@nanostores/react'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { createPortal } from 'react-dom'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
import { sessionTitle } from '@/lib/chat-runtime'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useStore } from '@nanostores/react'
|
||||
import { type MutableRefObject, useCallback, useEffect, useRef } from 'react'
|
||||
import type { NavigateFunction } from 'react-router-dom'
|
||||
import type { NavigateFunction } from 'react-router'
|
||||
|
||||
import { revealTreePane } from '@/components/pane-shell/tree/store'
|
||||
import { deleteSession, getSessionMessages, setSessionArchived } from '@/hermes'
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import type { ReactNode } from 'react'
|
||||
import { MemoryRouter } from 'react-router-dom'
|
||||
import { MemoryRouter } from 'react-router'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { useStore } from '@nanostores/react'
|
|||
import { useQuery } from '@tanstack/react-query'
|
||||
import type { ChangeEvent } from 'react'
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
import { useSearchParams } from 'react-router'
|
||||
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useCallback, useEffect, useMemo, useRef } from 'react'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router'
|
||||
|
||||
import { codiconIcon } from '@/components/ui/codicon'
|
||||
import { Tip } from '@/components/ui/tooltip'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { act, cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { MemoryRouter } from 'react-router-dom'
|
||||
import { MemoryRouter } from 'react-router'
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
// Radix Select calls scrollIntoView on its items when the content opens; jsdom
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { cleanup, fireEvent, render as rtlRender, screen, waitFor } from '@testing-library/react'
|
||||
import type { ReactElement } from 'react'
|
||||
import { MemoryRouter } from 'react-router-dom'
|
||||
import type * as ReactRouterDom from 'react-router-dom'
|
||||
import { MemoryRouter } from 'react-router'
|
||||
import type * as ReactRouterDom from 'react-router'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import type { ToolsetConfig } from '@/types/hermes'
|
||||
|
|
@ -11,7 +11,7 @@ import type { ToolsetConfig } from '@/types/hermes'
|
|||
// needs a router context. The navigate spy asserts the deep-link target.
|
||||
const navigateSpy = vi.fn()
|
||||
|
||||
vi.mock('react-router-dom', async importOriginal => ({
|
||||
vi.mock('react-router', async importOriginal => ({
|
||||
...(await importOriginal<typeof ReactRouterDom>()),
|
||||
useNavigate: () => navigateSpy
|
||||
}))
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
import { SETTINGS_ROUTE } from '@/app/routes'
|
||||
import { Button } from '@/components/ui/button'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useEffect } from 'react'
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
import { useSearchParams } from 'react-router'
|
||||
|
||||
interface DeepLinkHighlightOptions {
|
||||
param: string
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { cleanup, fireEvent, render, screen, waitFor, within } from '@testing-library/react'
|
||||
import { MemoryRouter } from 'react-router-dom'
|
||||
import { MemoryRouter } from 'react-router'
|
||||
import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { StatusbarControls } from '@/app/shell/statusbar-controls'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useCallback, useEffect, useMemo, useRef } from 'react'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router'
|
||||
|
||||
import { type CommandCenterSection } from '@/app/command-center'
|
||||
import {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useStore } from '@nanostores/react'
|
||||
import { type ComponentProps, memo, type ReactNode, useMemo, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
import {
|
||||
ContextMenu,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { cleanup, fireEvent, render, screen, within } from '@testing-library/react'
|
||||
import { MemoryRouter } from 'react-router-dom'
|
||||
import { MemoryRouter } from 'react-router'
|
||||
import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { StatusbarControls, type StatusbarItem } from '@/app/shell/statusbar-controls'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useStore } from '@nanostores/react'
|
||||
import { type ComponentProps, type MouseEvent, type ReactNode, useEffect, useState } from 'react'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router'
|
||||
|
||||
import { toggleLayoutEditMode } from '@/components/pane-shell/edit-mode'
|
||||
import { resetLayoutTree } from '@/components/pane-shell/tree/store'
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
// @vitest-environment jsdom
|
||||
import { QueryClientProvider } from '@tanstack/react-query'
|
||||
import { act, cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { MemoryRouter } from 'react-router-dom'
|
||||
import type * as ReactRouterDom from 'react-router-dom'
|
||||
import { MemoryRouter } from 'react-router'
|
||||
import type * as ReactRouterDom from 'react-router'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import type * as HermesApi from '@/hermes'
|
||||
|
|
@ -40,7 +40,7 @@ vi.mock('@/store/notifications', () => ({
|
|||
// so the deep-link target is assertable.
|
||||
const navigateSpy = vi.fn()
|
||||
|
||||
vi.mock('react-router-dom', async importOriginal => ({
|
||||
vi.mock('react-router', async importOriginal => ({
|
||||
...(await importOriginal<typeof ReactRouterDom>()),
|
||||
useNavigate: () => navigateSpy
|
||||
}))
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { useStore } from '@nanostores/react'
|
|||
import { useQuery } from '@tanstack/react-query'
|
||||
import type * as React from 'react'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
import { ArchiveSkillConfirmDialog } from '@/app/learning/archive-skill-confirm-dialog'
|
||||
import { CodeEditor } from '@/components/chat/code-editor'
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ import {
|
|||
BranchPickerPrimitive,
|
||||
ErrorPrimitive,
|
||||
MessagePrimitive,
|
||||
useAui,
|
||||
useAuiState,
|
||||
useMessageRuntime
|
||||
} from '@assistant-ui/react'
|
||||
import { useStore } from '@nanostores/react'
|
||||
import { type FC, useCallback, useMemo, useState } from 'react'
|
||||
|
|
@ -54,7 +54,7 @@ export const AssistantMessage: FC<{
|
|||
onDismissError?: (messageId: string) => void
|
||||
}> = ({ onBranchInNewChat, onDismissError }) => {
|
||||
const messageId = useAuiState(s => s.message.id)
|
||||
const messageRuntime = useMessageRuntime()
|
||||
const messageRuntime = useAui().message
|
||||
const { t } = useI18n()
|
||||
|
||||
// PERF: this component must NOT subscribe to the streaming text. Every
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useAuiState, useMessageRuntime } from '@assistant-ui/react'
|
||||
import { useAui, useAuiState } from '@assistant-ui/react'
|
||||
import { useStore } from '@nanostores/react'
|
||||
import { type MouseEvent, useCallback } from 'react'
|
||||
|
||||
|
|
@ -106,7 +106,7 @@ export function useTapbackDoubleClick(
|
|||
role: ChatMessage['role']
|
||||
): ((event: MouseEvent<HTMLElement>) => void) | undefined {
|
||||
const enabled = useStore($reactionsEnabled)
|
||||
const messageRuntime = useMessageRuntime()
|
||||
const messageRuntime = useAui().message
|
||||
|
||||
const onDoubleClick = useCallback(
|
||||
(event: MouseEvent<HTMLElement>) => {
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ export const UserEditComposer: FC<UserEditComposerProps> = ({ cwd, gateway, sess
|
|||
const next = `${base}${sep}${value}`
|
||||
|
||||
draftRef.current = next
|
||||
aui.composer().setText(next)
|
||||
aui.composer.setText(next)
|
||||
|
||||
const editor = editorRef.current
|
||||
|
||||
|
|
@ -230,7 +230,7 @@ export const UserEditComposer: FC<UserEditComposerProps> = ({ cwd, gateway, sess
|
|||
|
||||
if (nextDraft !== draftRef.current) {
|
||||
draftRef.current = nextDraft
|
||||
aui.composer().setText(nextDraft)
|
||||
aui.composer.setText(nextDraft)
|
||||
}
|
||||
|
||||
return nextDraft
|
||||
|
|
@ -338,7 +338,7 @@ export const UserEditComposer: FC<UserEditComposerProps> = ({ cwd, gateway, sess
|
|||
|
||||
const finish = () => {
|
||||
draftRef.current = composerPlainText(editor)
|
||||
aui.composer().setText(draftRef.current)
|
||||
aui.composer.setText(draftRef.current)
|
||||
requestEditFocus()
|
||||
starter ? window.setTimeout(refreshTrigger, 0) : closeTrigger()
|
||||
}
|
||||
|
|
@ -381,7 +381,7 @@ export const UserEditComposer: FC<UserEditComposerProps> = ({ cwd, gateway, sess
|
|||
rememberInitialDraft()
|
||||
const nextDraft = composerPlainText(editor)
|
||||
draftRef.current = nextDraft
|
||||
aui.composer().setText(nextDraft)
|
||||
aui.composer.setText(nextDraft)
|
||||
requestEditFocus()
|
||||
|
||||
return true
|
||||
|
|
@ -581,7 +581,7 @@ export const UserEditComposer: FC<UserEditComposerProps> = ({ cwd, gateway, sess
|
|||
// and leave revert as the only way out (#49903 is the same unguarded-core
|
||||
// hazard on the main composer).
|
||||
try {
|
||||
aui.composer().send()
|
||||
aui.composer.send()
|
||||
} catch {
|
||||
setSubmitting(false)
|
||||
}
|
||||
|
|
@ -624,7 +624,7 @@ export const UserEditComposer: FC<UserEditComposerProps> = ({ cwd, gateway, sess
|
|||
// down (a send/cancel raced this timer), cancel() throws "Composer is
|
||||
// not available" as an uncaught renderer error. Nothing to cancel then.
|
||||
try {
|
||||
aui.composer().cancel()
|
||||
aui.composer.cancel()
|
||||
} catch {
|
||||
// Composer core already gone — the edit is closing anyway.
|
||||
}
|
||||
|
|
@ -690,7 +690,7 @@ export const UserEditComposer: FC<UserEditComposerProps> = ({ cwd, gateway, sess
|
|||
|
||||
if (event.key === 'Escape') {
|
||||
event.preventDefault()
|
||||
aui.composer().cancel()
|
||||
aui.composer.cancel()
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { act, cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { MemoryRouter, useNavigate } from 'react-router-dom'
|
||||
import { MemoryRouter, useNavigate } from 'react-router'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { FindBar } from '@/components/find-bar'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useStore } from '@nanostores/react'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useLocation } from 'react-router'
|
||||
|
||||
import { Tip } from '@/components/ui/tooltip'
|
||||
import { useI18n } from '@/i18n'
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import '@/debug/dev-only'
|
|||
import { QueryClientProvider } from '@tanstack/react-query'
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import { HashRouter } from 'react-router-dom'
|
||||
import { HashRouter } from 'react-router'
|
||||
|
||||
import App from './app'
|
||||
import { ErrorBoundary } from './components/error-boundary'
|
||||
|
|
|
|||
|
|
@ -19,10 +19,6 @@
|
|||
"check": "npm run typecheck && npm run lint"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.39.4",
|
||||
"eslint": "^9.39.4",
|
||||
"globals": "^17.4.0",
|
||||
"typescript": "^6.0.3",
|
||||
"typescript-eslint": "^8.56.1"
|
||||
"typescript": "6.0.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
contributors/emails/Steven.Leath@gmail.com
Normal file
2
contributors/emails/Steven.Leath@gmail.com
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Leathal1
|
||||
# PR #69711 salvage (deps: pyasn1 0.6.4)
|
||||
2
contributors/emails/agents@joinsensie.com
Normal file
2
contributors/emails/agents@joinsensie.com
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Sensie-agents
|
||||
# PR #65150 salvage (deps: lazy dependency floors)
|
||||
2
contributors/emails/bbasketballer75@gmail.com
Normal file
2
contributors/emails/bbasketballer75@gmail.com
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
bbasketballer75
|
||||
# PR #69864, #73857 salvage (deps: npm advisories)
|
||||
2
contributors/emails/dinmail@gmail.com
Normal file
2
contributors/emails/dinmail@gmail.com
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
sahlbergalfred4-lgtm
|
||||
# PR #70003 salvage (deps: security-sensitive packages)
|
||||
2
contributors/emails/fmy3@qq.com
Normal file
2
contributors/emails/fmy3@qq.com
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
superafun
|
||||
# PR #60201 salvage (sec: npm allowScripts allowlist)
|
||||
2
contributors/emails/jrcrittenden@gmail.com
Normal file
2
contributors/emails/jrcrittenden@gmail.com
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
jrcrittenden
|
||||
# PR #28749 salvage (sec: release-age gate on hermes update)
|
||||
2
contributors/emails/mudreac@gmail.com
Normal file
2
contributors/emails/mudreac@gmail.com
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
mudrii
|
||||
# PR #66871, #63099 salvage (deps: vulnerable floors)
|
||||
2
contributors/emails/richard.ham@live.com
Normal file
2
contributors/emails/richard.ham@live.com
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
zebadee2kk
|
||||
# PR #50052 salvage (sec: bump deps for 25 CVEs)
|
||||
2
contributors/emails/vikyw89@gmail.com
Normal file
2
contributors/emails/vikyw89@gmail.com
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
vikyw89
|
||||
# PR #50902 salvage (sec: npm/uv dependency cooldown)
|
||||
|
|
@ -12,10 +12,8 @@
|
|||
*/
|
||||
|
||||
import js from '@eslint/js'
|
||||
import typescriptEslint from '@typescript-eslint/eslint-plugin'
|
||||
import typescriptParser from '@typescript-eslint/parser'
|
||||
import tseslint from 'typescript-eslint';
|
||||
import perfectionist from 'eslint-plugin-perfectionist'
|
||||
import reactPlugin from 'eslint-plugin-react'
|
||||
import hooksPlugin from 'eslint-plugin-react-hooks'
|
||||
import unusedImports from 'eslint-plugin-unused-imports'
|
||||
import globals from 'globals'
|
||||
|
|
@ -31,7 +29,7 @@ export default [
|
|||
globals: {
|
||||
...globals.node
|
||||
},
|
||||
parser: typescriptParser,
|
||||
parser: tseslint.parser,
|
||||
parserOptions: {
|
||||
ecmaFeatures: { jsx: true },
|
||||
ecmaVersion: 'latest',
|
||||
|
|
@ -39,9 +37,8 @@ export default [
|
|||
}
|
||||
},
|
||||
plugins: {
|
||||
'@typescript-eslint': typescriptEslint,
|
||||
'@typescript-eslint': tseslint.plugin,
|
||||
perfectionist,
|
||||
react: reactPlugin,
|
||||
'react-hooks': hooksPlugin,
|
||||
'unused-imports': unusedImports
|
||||
},
|
||||
|
|
@ -95,9 +92,6 @@ export default [
|
|||
'react-hooks/exhaustive-deps': 'warn',
|
||||
'react-hooks/rules-of-hooks': 'error',
|
||||
'unused-imports/no-unused-imports': 'error'
|
||||
},
|
||||
settings: {
|
||||
react: { version: 'detect' }
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
|||
38
flake.lock
generated
38
flake.lock
generated
|
|
@ -7,11 +7,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772408722,
|
||||
"narHash": "sha256-rHuJtdcOjK7rAHpHphUb1iCvgkU3GpfvicLMwwnfMT0=",
|
||||
"lastModified": 1782949081,
|
||||
"narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "f20dc5d9b8027381c474144ecabc9034d6a839a3",
|
||||
"rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -22,11 +22,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1775036866,
|
||||
"narHash": "sha256-ZojAnPuCdy657PbTq5V0Y+AHKhZAIwSIT2cb8UgAz/U=",
|
||||
"lastModified": 1785318670,
|
||||
"narHash": "sha256-dN6Ou5x/+23FZLEpYP3IffO+NyJFzUlGumt1uu3MMaY=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "6201e203d09599479a3b3450ed24fa81537ebc4e",
|
||||
"rev": "0954f7ee2f6bb3dc7d4e3d0d8bcb8fd4bde4cfc5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -69,11 +69,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772555609,
|
||||
"narHash": "sha256-3BA3HnUvJSbHJAlJj6XSy0Jmu7RyP2gyB/0fL7XuEDo=",
|
||||
"lastModified": 1785115949,
|
||||
"narHash": "sha256-8AM37BfyGaL2v/SZyg4PupRxJ01Y4htvM+WrTjWrPpo=",
|
||||
"owner": "pyproject-nix",
|
||||
"repo": "build-system-pkgs",
|
||||
"rev": "c37f66a953535c394244888598947679af231863",
|
||||
"rev": "62c0d86027edb1c4f39a5facc09876348144f7c9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -82,18 +82,18 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"pyproject-nix_2": {
|
||||
"pyproject-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772865871,
|
||||
"narHash": "sha256-/ZTSg97aouL0SlPHaokA4r3iuH9QzHVuWPACD2CUCFY=",
|
||||
"lastModified": 1784591072,
|
||||
"narHash": "sha256-zP/WaDxrRu8GANZM61+V2LT/7ycEEdoyLWn7M6WzU7M=",
|
||||
"owner": "pyproject-nix",
|
||||
"repo": "pyproject.nix",
|
||||
"rev": "e537db02e72d553cea470976b9733581bcf5b3ed",
|
||||
"rev": "e3b599ca2e7fcf93d4edf65d7f19bbf6491724f3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -108,11 +108,11 @@
|
|||
"nixpkgs": "nixpkgs",
|
||||
"npm-lockfile-fix": "npm-lockfile-fix",
|
||||
"pyproject-build-systems": "pyproject-build-systems",
|
||||
"pyproject-nix": "pyproject-nix_2",
|
||||
"uv2nix": "uv2nix_2"
|
||||
"pyproject-nix": "pyproject-nix",
|
||||
"uv2nix": "uv2nix"
|
||||
}
|
||||
},
|
||||
"uv2nix_2": {
|
||||
"uv2nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
|
|
@ -122,11 +122,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1773039484,
|
||||
"narHash": "sha256-+boo33KYkJDw9KItpeEXXv8+65f7hHv/earxpcyzQ0I=",
|
||||
"lastModified": 1785277507,
|
||||
"narHash": "sha256-9Tq3UDX2hD/aveW/HvkBlAmEwJTOlY5HQXJM+L5BGmE=",
|
||||
"owner": "pyproject-nix",
|
||||
"repo": "uv2nix",
|
||||
"rev": "b68be7cfeacbed9a3fa38a2b5adc0cfb81d9bb1f",
|
||||
"rev": "5a836d395cbf5fc22670eb98dd4aa4fc4d406977",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
|
|
@ -2023,30 +2023,44 @@ def _make_tui_argv(tui_dir: Path, tui_dev: bool) -> tuple[list[str], Path]:
|
|||
tui_dir,
|
||||
include_child_workspaces=True,
|
||||
)
|
||||
result = subprocess.run(
|
||||
[
|
||||
npm,
|
||||
"install",
|
||||
*npm_workspace_args,
|
||||
# --include=dev: ui-tui's build toolchain (esbuild, typescript)
|
||||
# lives in devDependencies. An inherited NODE_ENV=production
|
||||
# (e.g. from a container shell or a parent TUI launch) or an
|
||||
# npm `omit=dev` config would silently skip them and the TUI
|
||||
# build would fail. See _run_npm_install_deterministic.
|
||||
"--include=dev",
|
||||
"--silent",
|
||||
"--no-fund",
|
||||
"--no-audit",
|
||||
"--progress=false",
|
||||
],
|
||||
cwd=str(npm_cwd),
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
env={**os.environ, "CI": "1"},
|
||||
)
|
||||
npm_install_cmd = [
|
||||
npm,
|
||||
"install",
|
||||
*npm_workspace_args,
|
||||
# --include=dev: ui-tui's build toolchain (esbuild, typescript)
|
||||
# lives in devDependencies. An inherited NODE_ENV=production
|
||||
# (e.g. from a container shell or a parent TUI launch) or an
|
||||
# npm `omit=dev` config would silently skip them and the TUI
|
||||
# build would fail. See _run_npm_install_deterministic.
|
||||
"--include=dev",
|
||||
"--silent",
|
||||
"--no-fund",
|
||||
"--no-audit",
|
||||
"--progress=false",
|
||||
]
|
||||
|
||||
def _run_tui_install() -> subprocess.CompletedProcess:
|
||||
return subprocess.run(
|
||||
npm_install_cmd,
|
||||
cwd=str(npm_cwd),
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
env={**os.environ, "CI": "1"},
|
||||
)
|
||||
|
||||
result = _run_tui_install()
|
||||
if result.returncode != 0:
|
||||
# An npm outside the root package.json's `engines.npm` range fails
|
||||
# here before doing any work; upgrade a Hermes-managed npm once and
|
||||
# retry rather than dumping EBADENGINE at the user.
|
||||
from hermes_cli.npm_engine import maybe_repair_npm_engine
|
||||
|
||||
combined_output = f"{result.stdout or ''}\n{result.stderr or ''}"
|
||||
if maybe_repair_npm_engine(npm, combined_output):
|
||||
result = _run_tui_install()
|
||||
if result.returncode != 0:
|
||||
combined = f"{result.stdout or ''}\n{result.stderr or ''}".strip()
|
||||
preview = "\n".join(combined.splitlines()[-30:])
|
||||
|
|
@ -5454,34 +5468,84 @@ def _run_npm_install_deterministic(
|
|||
# install path and nix/lib.nix npm ci hooks.
|
||||
run_env = {**os.environ, **(env or {}), "CI": "1"}
|
||||
|
||||
lockfile = cwd / "package-lock.json"
|
||||
if lockfile.exists():
|
||||
ci_cmd = [npm, "ci", "--include=dev", *extra_args]
|
||||
ci_result = subprocess.run(
|
||||
ci_cmd,
|
||||
def _run(cmd: list[str]) -> subprocess.CompletedProcess:
|
||||
return _run_npm_watching_for_engine_failure(
|
||||
cmd,
|
||||
cwd=cwd,
|
||||
env=run_env,
|
||||
capture_output=capture_output,
|
||||
)
|
||||
|
||||
def _attempt() -> subprocess.CompletedProcess:
|
||||
lockfile = cwd / "package-lock.json"
|
||||
if lockfile.exists():
|
||||
ci_result = _run([npm, "ci", "--include=dev", *extra_args])
|
||||
if ci_result.returncode == 0:
|
||||
return ci_result
|
||||
# Fall through to `npm install` — lockfile may be out of sync on a
|
||||
# WIP fork/branch, or `npm ci` may not be available on very old npm.
|
||||
return _run([npm, "install", "--no-save", "--include=dev", *extra_args])
|
||||
|
||||
result = _attempt()
|
||||
if result.returncode == 0:
|
||||
return result
|
||||
|
||||
# An npm outside the root package.json's `engines.npm` range fails every
|
||||
# command here identically (the `npm install` fallback included), so the
|
||||
# failure is worth exactly one upgrade attempt. `maybe_repair_npm_engine`
|
||||
# returns True only when it actually upgraded a Hermes-managed npm.
|
||||
from hermes_cli.npm_engine import maybe_repair_npm_engine
|
||||
|
||||
combined = f"{result.stdout or ''}\n{result.stderr or ''}"
|
||||
if not maybe_repair_npm_engine(npm, combined):
|
||||
return result
|
||||
return _attempt()
|
||||
|
||||
|
||||
def _run_npm_watching_for_engine_failure(
|
||||
cmd: list[str],
|
||||
*,
|
||||
cwd: Path,
|
||||
env: dict[str, str],
|
||||
capture_output: bool,
|
||||
) -> subprocess.CompletedProcess:
|
||||
"""Run *cmd*, always retaining stderr so ``EBADENGINE`` stays detectable.
|
||||
|
||||
``capture_output=False`` callers stream npm's progress live and would
|
||||
otherwise hand back a ``CompletedProcess`` with ``stderr=None``, leaving the
|
||||
engine-failure recovery nothing to read. Tee stderr instead: each line is
|
||||
forwarded to this process's stderr as it arrives (so live output is
|
||||
unchanged) and accumulated for the caller.
|
||||
"""
|
||||
if capture_output:
|
||||
return subprocess.run(
|
||||
cmd,
|
||||
cwd=cwd,
|
||||
env=env,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
check=False,
|
||||
)
|
||||
if ci_result.returncode == 0:
|
||||
return ci_result
|
||||
# Fall through to `npm install` — lockfile may be out of sync on a
|
||||
# WIP fork/branch, or `npm ci` may not be available on very old npm.
|
||||
install_cmd = [npm, "install", "--no-save", "--include=dev", *extra_args]
|
||||
return subprocess.run(
|
||||
install_cmd,
|
||||
|
||||
captured: list[str] = []
|
||||
with subprocess.Popen(
|
||||
cmd,
|
||||
cwd=cwd,
|
||||
env=run_env,
|
||||
capture_output=capture_output,
|
||||
env=env,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
check=False,
|
||||
)
|
||||
) as proc:
|
||||
if proc.stderr is not None:
|
||||
for line in proc.stderr:
|
||||
captured.append(line)
|
||||
sys.stderr.write(line)
|
||||
sys.stderr.flush()
|
||||
returncode = proc.wait()
|
||||
return subprocess.CompletedProcess(cmd, returncode, None, "".join(captured))
|
||||
|
||||
|
||||
def _missing_web_build_tool(output: str) -> str | None:
|
||||
|
|
|
|||
276
hermes_cli/npm_engine.py
Normal file
276
hermes_cli/npm_engine.py
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
"""Recover from npm ``EBADENGINE`` failures by upgrading a managed npm.
|
||||
|
||||
The repo's ``.npmrc`` sets ``engine-strict=true`` and the root ``package.json``
|
||||
pins an ``engines.npm`` range, 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: {"node":">=20.0.0","npm":"<11.10.0 || >=12.0.0"}
|
||||
npm error notsup Actual: {"npm":"10.9.8","node":"v22.23.1"}
|
||||
|
||||
Rather than predicting the failure (which would mean a semver range matcher and
|
||||
an ``npm --version`` probe before work that usually succeeds), we react to it:
|
||||
npm states the required range in the error, so the recovery reads the
|
||||
constraint straight out of the output it just produced.
|
||||
|
||||
Scope of the repair is deliberately narrow. Hermes only upgrades an npm that
|
||||
lives inside its **own** managed Node tree (``$HERMES_HOME/node``), installing
|
||||
in place with ``--prefix`` so ``bin/npm`` keeps resolving to the upgraded
|
||||
``lib/node_modules/npm``. A system / nvm / brew / Nix npm belongs to the user
|
||||
and their other projects; for those we print the exact command and let the
|
||||
original failure stand.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
from hermes_constants import get_hermes_home, with_hermes_node_path
|
||||
|
||||
__all__ = [
|
||||
"is_ebadengine",
|
||||
"required_npm_range",
|
||||
"managed_npm_prefix",
|
||||
"upgrade_managed_npm",
|
||||
"maybe_repair_npm_engine",
|
||||
]
|
||||
|
||||
# npm prints `npm error notsup Required: {...}` on npm >= 10 and
|
||||
# `npm ERR! notsup Required: {...}` on older releases.
|
||||
_REQUIRED_RE = re.compile(r"Required:\s*(\{.*?\})")
|
||||
_ACTUAL_RE = re.compile(r"Actual:\s*(\{.*?\})")
|
||||
|
||||
# Wall-clock cap for the self-upgrade. The measured in-place upgrade of a
|
||||
# managed tree takes ~1s; this only has to cover a slow registry.
|
||||
_UPGRADE_TIMEOUT = 300
|
||||
|
||||
|
||||
def is_ebadengine(output: str) -> bool:
|
||||
"""Return True when *output* is an npm engine-compatibility failure."""
|
||||
if not output:
|
||||
return False
|
||||
return "EBADENGINE" in output or "Unsupported engine" in output
|
||||
|
||||
|
||||
def _iter_required_blocks(output: str) -> list[dict]:
|
||||
blocks: list[dict] = []
|
||||
for match in _REQUIRED_RE.finditer(output or ""):
|
||||
try:
|
||||
parsed = json.loads(match.group(1))
|
||||
except ValueError:
|
||||
continue
|
||||
if isinstance(parsed, dict):
|
||||
blocks.append(parsed)
|
||||
return blocks
|
||||
|
||||
|
||||
def required_npm_range(output: str) -> str | None:
|
||||
"""Return the ``engines.npm`` range npm demanded in *output*.
|
||||
|
||||
Returns ``None`` when the output has no engine failure, or when the
|
||||
failure is about Node rather than npm — upgrading npm cannot fix a Node
|
||||
version mismatch, so the caller must not try.
|
||||
|
||||
When several packages report conflicting npm ranges the repo's own root
|
||||
constraint is preferred (it is the one we control); otherwise the first
|
||||
range wins, since any of them is a strict improvement over an npm that
|
||||
satisfies none.
|
||||
"""
|
||||
if not is_ebadengine(output):
|
||||
return None
|
||||
ranges = [
|
||||
str(block["npm"]).strip()
|
||||
for block in _iter_required_blocks(output)
|
||||
if block.get("npm")
|
||||
]
|
||||
if not ranges:
|
||||
return None
|
||||
distinct = list(dict.fromkeys(ranges))
|
||||
if len(distinct) > 1:
|
||||
repo_range = _repo_npm_range()
|
||||
if repo_range in distinct:
|
||||
return repo_range
|
||||
return distinct[0]
|
||||
|
||||
|
||||
def actual_npm_version(output: str) -> str | None:
|
||||
"""Return the npm version npm reported as ``Actual`` in *output*."""
|
||||
for match in _ACTUAL_RE.finditer(output or ""):
|
||||
try:
|
||||
parsed = json.loads(match.group(1))
|
||||
except ValueError:
|
||||
continue
|
||||
if isinstance(parsed, dict) and parsed.get("npm"):
|
||||
return str(parsed["npm"]).strip()
|
||||
return None
|
||||
|
||||
|
||||
def _repo_npm_range() -> str | None:
|
||||
"""Return ``engines.npm`` from the checkout's root ``package.json``."""
|
||||
package_json = Path(__file__).resolve().parent.parent / "package.json"
|
||||
try:
|
||||
data = json.loads(package_json.read_text(encoding="utf-8"))
|
||||
except (OSError, ValueError):
|
||||
return None
|
||||
engines = data.get("engines")
|
||||
if not isinstance(engines, dict):
|
||||
return None
|
||||
value = engines.get("npm")
|
||||
return str(value).strip() if value else None
|
||||
|
||||
|
||||
def managed_npm_prefix(npm: str | os.PathLike[str] | None) -> Path | None:
|
||||
"""Return the Hermes-managed Node root *npm* lives in, else ``None``.
|
||||
|
||||
Symlinks are resolved first: an install links ``~/.local/bin/npm`` at
|
||||
``$HERMES_HOME/node/bin/npm``, which itself links into
|
||||
``lib/node_modules/npm/bin/npm-cli.js``. Every one of those spellings is
|
||||
the managed npm and must be recognised as such, or the repair silently
|
||||
declines to fix the very install it owns.
|
||||
"""
|
||||
if not npm:
|
||||
return None
|
||||
prefix = get_hermes_home() / "node"
|
||||
try:
|
||||
resolved = Path(npm).resolve()
|
||||
prefix_resolved = prefix.resolve()
|
||||
except OSError:
|
||||
return None
|
||||
if resolved == prefix_resolved or prefix_resolved in resolved.parents:
|
||||
return prefix
|
||||
return None
|
||||
|
||||
|
||||
def _upgrade_env() -> dict[str, str]:
|
||||
env = with_hermes_node_path()
|
||||
# The checkout's .npmrc sets `min-release-age`, which would gate the npm
|
||||
# release we are trying to install. The upgrade runs from a temp cwd so
|
||||
# that file is out of scope; this neutralises a user-level ~/.npmrc too.
|
||||
env["npm_config_min_release_age"] = "0"
|
||||
# `unicode-animations`-style postinstall animations no-op under CI=1.
|
||||
env["CI"] = "1"
|
||||
return env
|
||||
|
||||
|
||||
def upgrade_managed_npm(
|
||||
npm: str,
|
||||
npm_range: str,
|
||||
*,
|
||||
prefix: Path,
|
||||
quiet: bool = False,
|
||||
) -> bool:
|
||||
"""Upgrade the managed npm at *npm* in place to satisfy *npm_range*.
|
||||
|
||||
``--prefix`` targets the managed tree explicitly: a managed install writes
|
||||
``prefix=~/.local`` into ``$HERMES_HOME/node/etc/npmrc`` so that global
|
||||
installs land on PATH, and without the override the "upgrade" would install
|
||||
a second npm somewhere else while the managed one stayed stale.
|
||||
"""
|
||||
if not quiet:
|
||||
print(
|
||||
f"→ Upgrading Hermes-managed npm to satisfy {npm_range}…",
|
||||
flush=True,
|
||||
)
|
||||
try:
|
||||
# A temp cwd keeps the checkout's .npmrc (engine-strict, min-release-age)
|
||||
# from applying to the upgrade itself.
|
||||
with tempfile.TemporaryDirectory(prefix="hermes-npm-upgrade-") as tmp:
|
||||
result = subprocess.run(
|
||||
[
|
||||
npm,
|
||||
"install",
|
||||
"--global",
|
||||
"--prefix",
|
||||
str(prefix),
|
||||
f"npm@{npm_range}",
|
||||
"--no-fund",
|
||||
"--no-audit",
|
||||
"--progress=false",
|
||||
],
|
||||
cwd=tmp,
|
||||
env=_upgrade_env(),
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
timeout=_UPGRADE_TIMEOUT,
|
||||
check=False,
|
||||
)
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
if not quiet:
|
||||
print(" ✗ npm upgrade could not be started", file=sys.stderr)
|
||||
return False
|
||||
|
||||
if result.returncode != 0:
|
||||
if not quiet:
|
||||
detail = (result.stderr or result.stdout or "").strip().splitlines()
|
||||
print(" ✗ npm upgrade failed", file=sys.stderr)
|
||||
for line in detail[-10:]:
|
||||
print(f" {line}", file=sys.stderr)
|
||||
return False
|
||||
|
||||
if not quiet:
|
||||
print(f" ✓ npm upgraded to {_probe_version(npm) or npm_range}", flush=True)
|
||||
return True
|
||||
|
||||
|
||||
def _probe_version(npm: str) -> str | None:
|
||||
try:
|
||||
result = subprocess.run(
|
||||
[npm, "--version"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
timeout=30,
|
||||
env=with_hermes_node_path(),
|
||||
check=False,
|
||||
)
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
return None
|
||||
return (result.stdout or "").strip() or None
|
||||
|
||||
|
||||
def _print_manual_fix(npm: str, npm_range: str, actual: str | None) -> None:
|
||||
have = f"npm {actual} " if actual else "This npm "
|
||||
print(
|
||||
f"\n✗ {have}does not satisfy the range this project requires: {npm_range}\n"
|
||||
f" Resolved npm: {npm}\n"
|
||||
" Hermes only upgrades npm inside its own managed Node install, so this\n"
|
||||
" one is left alone. Upgrade it yourself with:\n"
|
||||
f' npm install -g npm@"{npm_range}"',
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
|
||||
def maybe_repair_npm_engine(
|
||||
npm: str | None,
|
||||
output: str,
|
||||
*,
|
||||
quiet: bool = False,
|
||||
) -> bool:
|
||||
"""Repair an ``EBADENGINE`` failure when Hermes owns the npm involved.
|
||||
|
||||
*output* is the combined stdout/stderr of the npm command that just failed.
|
||||
Returns ``True`` only when npm was actually upgraded, meaning the caller
|
||||
should retry its command once. Returns ``False`` for every other case —
|
||||
not an engine failure, a Node (not npm) mismatch, an npm Hermes does not
|
||||
own, or a failed upgrade — leaving the original failure to stand.
|
||||
"""
|
||||
npm_range = required_npm_range(output)
|
||||
if not npm_range or not npm:
|
||||
return False
|
||||
|
||||
prefix = managed_npm_prefix(npm)
|
||||
if prefix is None:
|
||||
if not quiet:
|
||||
_print_manual_fix(npm, npm_range, actual_npm_version(output))
|
||||
return False
|
||||
|
||||
return upgrade_managed_npm(npm, npm_range, prefix=prefix, quiet=quiet)
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
makeWrapper,
|
||||
callPackage,
|
||||
python312,
|
||||
nodejs_22,
|
||||
nodejs_26,
|
||||
electron,
|
||||
ripgrep,
|
||||
git,
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
extraDependencyGroups ? [ ],
|
||||
}:
|
||||
let
|
||||
nodejs = nodejs_22;
|
||||
nodejs = nodejs_26;
|
||||
mkHermesVenv =
|
||||
extraDependencyGroups:
|
||||
callPackage ./python.nix {
|
||||
|
|
|
|||
8149
package-lock.json
generated
8149
package-lock.json
generated
File diff suppressed because it is too large
Load diff
28
package.json
28
package.json
|
|
@ -35,15 +35,35 @@
|
|||
},
|
||||
"homepage": "https://github.com/NousResearch/Hermes-Agent#readme",
|
||||
"dependencies": {
|
||||
"@streamdown/math": "^1.0.2",
|
||||
"agent-browser": "^0.26.0"
|
||||
"@streamdown/math": "1.0.2",
|
||||
"agent-browser": "0.26.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "9.39.5",
|
||||
"typescript-eslint": "8.64.0",
|
||||
"eslint-plugin-perfectionist": "5.10.0",
|
||||
"eslint-plugin-react-hooks": "7.1.1",
|
||||
"eslint-plugin-unused-imports": "4.4.1",
|
||||
"globals": "17.7.0"
|
||||
},
|
||||
"overrides": {
|
||||
"lodash": "4.18.1",
|
||||
"yauzl": "^3.3.1",
|
||||
"protobufjs": "^8.7.1"
|
||||
"protobufjs": "^8.7.1",
|
||||
"brace-expansion": "5.0.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
"node": ">=20.0.0",
|
||||
"npm": "<11.10.0 || >=12.0.0"
|
||||
},
|
||||
"allowScripts": {
|
||||
"unicode-animations": false,
|
||||
"esbuild@0.28.1": true,
|
||||
"node-pty@1.1.0": true,
|
||||
"electron-winstaller@5.4.0": true,
|
||||
"agent-browser@0.26.0": true,
|
||||
"electron@40.10.2": true,
|
||||
"fsevents@2.3.2": true,
|
||||
"fsevents@2.3.3": true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ dependencies = [
|
|||
# libs required for the codecs we use, so it's safe to ship in the base
|
||||
# install rather than gating it behind an extra + a mid-session lazy install
|
||||
# (which deadlocked the CLI under prompt_toolkit — see #40490).
|
||||
"Pillow==12.2.0",
|
||||
"Pillow==12.3.0",
|
||||
# Windows log rotation. Stdlib ``RotatingFileHandler.doRollover()`` uses
|
||||
# ``os.rename()`` which fails with ``PermissionError [WinError 32]`` on
|
||||
# Windows whenever any other process holds an append-mode handle on
|
||||
|
|
@ -162,7 +162,7 @@ modal = ["modal==1.3.4"]
|
|||
daytona = ["daytona==0.155.0"]
|
||||
vercel = ["vercel==0.7.2"]
|
||||
hindsight = ["hindsight-client==0.6.1"]
|
||||
dev = ["debugpy==1.8.20", "pytest==9.0.2", "pytest-asyncio==1.3.0", "mcp==1.26.0", "starlette==1.3.1", "ty==0.0.21", "ruff==0.15.10", "setuptools==81.0.0"] # starlette: CVE-2026-48710; setuptools: latest <82 (torch >=2.11 caps setuptools<82)
|
||||
dev = ["debugpy==1.8.20", "pytest==9.1.1", "pytest-asyncio==1.3.0", "mcp==1.28.1", "starlette==1.3.1", "ty==0.0.21", "ruff==0.15.10", "setuptools==83.0.0"] # starlette: CVE-2026-48710; setuptools: 83 (torch >=2.13 requires setuptools 83)
|
||||
messaging = ["python-telegram-bot[webhooks]==22.6", "discord.py[voice]==2.7.1", "aiohttp==3.14.1", "brotlicffi==1.2.0.1", "slack-bolt==1.29.0", "slack-sdk==3.43.0", "qrcode==7.4.2"] # aiohttp 3.14.1: CVE-2026-34513/34518/34519/34520/34525 + 34993(RCE)/47265
|
||||
cron = [] # croniter is now a core dependency; this extra kept for back-compat
|
||||
slack = ["slack-bolt==1.29.0", "slack-sdk==3.43.0", "aiohttp==3.14.1"]
|
||||
|
|
@ -227,7 +227,7 @@ pty = []
|
|||
# `request.url` can be bypassed. We pin a patched Starlette directly in every
|
||||
# extra that exposes a Starlette-backed server surface so pip/uv can't resolve
|
||||
# a vulnerable pre-1.0.1 transitive. Bump in lockstep with uv.lock.
|
||||
mcp = ["mcp==1.26.0", "starlette==1.3.1"] # starlette: CVE-2026-48710
|
||||
mcp = ["mcp==1.28.1", "starlette==1.3.1"] # starlette: CVE-2026-48710
|
||||
# Backwards-compatible no-op alias. Relay is a core dependency on supported
|
||||
# wheel targets and intentionally unavailable on other platforms.
|
||||
nemo-relay = []
|
||||
|
|
@ -238,7 +238,7 @@ teams = ["microsoft-teams-apps==2.0.13.4", "aiohttp==3.14.1"] # aiohttp 3.14.1:
|
|||
# The cua-driver binary itself is installed via `hermes tools` post-setup
|
||||
# (curl install script); this extra just pins the MCP client used to talk
|
||||
# to it, which is already provided by the `mcp` extra.
|
||||
computer-use = ["mcp==1.26.0", "starlette==1.3.1"] # starlette: CVE-2026-48710
|
||||
computer-use = ["mcp==1.28.1", "starlette==1.3.1"] # starlette: CVE-2026-48710
|
||||
acp = ["agent-client-protocol==0.9.0"]
|
||||
# mistral: Voxtral STT + TTS. Pinned to an exact verified-clean version.
|
||||
# The `mistralai` PyPI project was quarantined 2026-05-12 after the malicious
|
||||
|
|
@ -335,7 +335,7 @@ all = [
|
|||
]
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools>=77.0,<83"]
|
||||
requires = ["setuptools==83.0.0"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project.scripts]
|
||||
|
|
@ -343,6 +343,17 @@ hermes = "hermes_cli.main:main"
|
|||
hermes-agent = "run_agent:main"
|
||||
hermes-acp = "acp_adapter.entry:main"
|
||||
|
||||
[tool.uv]
|
||||
override-dependencies = [
|
||||
# discord.py's latest published version, 2.7.1, pins pynacl at <1.6. however, pynacl 1.5.0 has known vulnerabilities.
|
||||
# discord.py has updated pynacl to 1.6 on `main`, but has not yet published a patch release.
|
||||
# so, we force-override this to pynacl 1.6. here.
|
||||
# remove this when we update discord.py
|
||||
"pynacl>=1.6,<1.7",
|
||||
]
|
||||
exclude-newer = "14 days"
|
||||
exclude-newer-package = { vercel = false, nemo-relay = false, huggingface_hub = false }
|
||||
|
||||
[tool.setuptools]
|
||||
# Top-level single-file modules (not packages). Without this, uv2nix's
|
||||
# sealed venv is missing hermes_constants, run_agent, etc.
|
||||
|
|
|
|||
|
|
@ -11,10 +11,9 @@
|
|||
"fix": "npm run lint:fix"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^9.39.4",
|
||||
"@types/plist": "^3.0.5",
|
||||
"plist": "^3.1.0",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.9"
|
||||
"@types/plist": "3.0.5",
|
||||
"plist": "3.1.1",
|
||||
"typescript": "6.0.3",
|
||||
"vitest": "4.1.10"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
229
tests/hermes_cli/test_npm_engine.py
Normal file
229
tests/hermes_cli/test_npm_engine.py
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
"""Tests for npm ``EBADENGINE`` recovery (``hermes_cli/npm_engine.py``).
|
||||
|
||||
The behaviour under test is a contract about *reacting* to npm's own engine
|
||||
check: npm states the range it wants in the failure, Hermes upgrades only an
|
||||
npm it owns, and every other case leaves the original failure alone.
|
||||
"""
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from hermes_cli.npm_engine import (
|
||||
actual_npm_version,
|
||||
is_ebadengine,
|
||||
managed_npm_prefix,
|
||||
maybe_repair_npm_engine,
|
||||
required_npm_range,
|
||||
)
|
||||
|
||||
|
||||
# Verbatim npm 10 output shape (`npm error`), and the npm 9 shape (`npm ERR!`).
|
||||
EBADENGINE_OUTPUT = """
|
||||
npm error code EBADENGINE
|
||||
npm error engine Unsupported engine
|
||||
npm error engine Not compatible with your version of node/npm: hermes-agent@1.0.0
|
||||
npm error notsup Not compatible with your version of node/npm: hermes-agent@1.0.0
|
||||
npm error notsup Required: {"node":">=20.0.0","npm":"<11.10.0 || >=12.0.0"}
|
||||
npm error notsup Actual: {"npm":"11.10.0","node":"v22.23.1"}
|
||||
"""
|
||||
|
||||
LEGACY_EBADENGINE_OUTPUT = """
|
||||
npm ERR! code EBADENGINE
|
||||
npm ERR! engine Unsupported engine
|
||||
npm ERR! notsup Required: {"node":">=20.0.0","npm":">=12.0.0"}
|
||||
npm ERR! notsup Actual: {"npm":"9.6.7","node":"v20.1.0"}
|
||||
"""
|
||||
|
||||
# A lockfile mismatch — the other common `npm ci` failure. Must NOT be treated
|
||||
# as an engine problem, or every out-of-sync lockfile would trigger an upgrade.
|
||||
ELOCK_OUTPUT = """
|
||||
npm error code EUSAGE
|
||||
npm error `npm ci` can only install packages when your package.json and
|
||||
npm error package-lock.json are in sync.
|
||||
"""
|
||||
|
||||
|
||||
class TestDetection:
|
||||
def test_recognises_modern_and_legacy_engine_failures(self):
|
||||
assert is_ebadengine(EBADENGINE_OUTPUT)
|
||||
assert is_ebadengine(LEGACY_EBADENGINE_OUTPUT)
|
||||
|
||||
def test_unrelated_failures_are_not_engine_failures(self):
|
||||
assert not is_ebadengine(ELOCK_OUTPUT)
|
||||
assert not is_ebadengine("")
|
||||
assert not is_ebadengine("npm error code E404")
|
||||
|
||||
def test_range_comes_from_the_error_not_a_hardcoded_list(self):
|
||||
assert required_npm_range(EBADENGINE_OUTPUT) == "<11.10.0 || >=12.0.0"
|
||||
assert required_npm_range(LEGACY_EBADENGINE_OUTPUT) == ">=12.0.0"
|
||||
|
||||
def test_actual_version_is_reported_back(self):
|
||||
assert actual_npm_version(EBADENGINE_OUTPUT) == "11.10.0"
|
||||
|
||||
def test_no_range_for_non_engine_output(self):
|
||||
assert required_npm_range(ELOCK_OUTPUT) is None
|
||||
assert required_npm_range("") is None
|
||||
|
||||
def test_node_only_mismatch_yields_no_npm_range(self):
|
||||
"""Upgrading npm cannot fix a Node version mismatch, so don't try."""
|
||||
node_only = (
|
||||
'npm error code EBADENGINE\n'
|
||||
'npm error notsup Required: {"node":">=20.0.0"}\n'
|
||||
'npm error notsup Actual: {"npm":"10.9.8","node":"v18.0.0"}\n'
|
||||
)
|
||||
assert required_npm_range(node_only) is None
|
||||
|
||||
def test_malformed_required_block_is_ignored(self):
|
||||
broken = (
|
||||
"npm error code EBADENGINE\n"
|
||||
"npm error notsup Required: {not json}\n"
|
||||
)
|
||||
assert required_npm_range(broken) is None
|
||||
|
||||
|
||||
class TestManagedDetection:
|
||||
"""The upgrade must fire for every spelling of the managed npm, and for
|
||||
no other npm — this is the boundary between "Hermes fixes it" and "the
|
||||
user's own toolchain is left alone"."""
|
||||
|
||||
@pytest.fixture
|
||||
def managed_tree(self, tmp_path, monkeypatch):
|
||||
home = tmp_path / ".hermes"
|
||||
node = home / "node"
|
||||
(node / "bin").mkdir(parents=True)
|
||||
(node / "lib" / "node_modules" / "npm" / "bin").mkdir(parents=True)
|
||||
cli = node / "lib" / "node_modules" / "npm" / "bin" / "npm-cli.js"
|
||||
cli.write_text("#!/usr/bin/env node\n", encoding="utf-8")
|
||||
(node / "bin" / "npm").symlink_to(cli)
|
||||
monkeypatch.setenv("HERMES_HOME", str(home))
|
||||
return home
|
||||
|
||||
def test_direct_managed_bin_is_managed(self, managed_tree):
|
||||
npm = managed_tree / "node" / "bin" / "npm"
|
||||
assert managed_npm_prefix(npm) == managed_tree / "node"
|
||||
|
||||
def test_symlink_from_local_bin_resolves_to_managed(self, managed_tree, tmp_path):
|
||||
"""An install links ~/.local/bin/npm at the managed tree; that link is
|
||||
the npm a user's PATH actually resolves, so it must count as managed."""
|
||||
local_bin = tmp_path / "local-bin"
|
||||
local_bin.mkdir()
|
||||
link = local_bin / "npm"
|
||||
link.symlink_to(managed_tree / "node" / "bin" / "npm")
|
||||
assert managed_npm_prefix(link) == managed_tree / "node"
|
||||
|
||||
def test_system_npm_is_not_managed(self, managed_tree, tmp_path):
|
||||
system_npm = tmp_path / "usr" / "bin" / "npm"
|
||||
system_npm.parent.mkdir(parents=True)
|
||||
system_npm.write_text("#!/bin/sh\n", encoding="utf-8")
|
||||
assert managed_npm_prefix(system_npm) is None
|
||||
|
||||
def test_no_npm_is_not_managed(self, managed_tree):
|
||||
assert managed_npm_prefix(None) is None
|
||||
assert managed_npm_prefix("") is None
|
||||
|
||||
|
||||
class TestRepairDecision:
|
||||
"""`maybe_repair_npm_engine` returns True only when it actually upgraded,
|
||||
because its return value is what gates the caller's single retry."""
|
||||
|
||||
@pytest.fixture
|
||||
def managed_npm(self, tmp_path, monkeypatch):
|
||||
home = tmp_path / ".hermes"
|
||||
bin_dir = home / "node" / "bin"
|
||||
bin_dir.mkdir(parents=True)
|
||||
npm = bin_dir / "npm"
|
||||
npm.write_text("#!/bin/sh\n", encoding="utf-8")
|
||||
npm.chmod(0o755)
|
||||
monkeypatch.setenv("HERMES_HOME", str(home))
|
||||
return npm
|
||||
|
||||
def test_upgrades_managed_npm_with_the_range_npm_asked_for(
|
||||
self, managed_npm, monkeypatch
|
||||
):
|
||||
calls = []
|
||||
|
||||
def fake_run(cmd, **kwargs):
|
||||
calls.append((cmd, kwargs))
|
||||
return subprocess.CompletedProcess(cmd, 0, "", "")
|
||||
|
||||
monkeypatch.setattr(subprocess, "run", fake_run)
|
||||
assert maybe_repair_npm_engine(str(managed_npm), EBADENGINE_OUTPUT, quiet=True)
|
||||
|
||||
upgrade_cmd = calls[0][0]
|
||||
assert upgrade_cmd[1:3] == ["install", "--global"]
|
||||
# The range must come from npm's error, and target the managed prefix
|
||||
# explicitly (the managed etc/npmrc points `prefix` elsewhere).
|
||||
assert "npm@<11.10.0 || >=12.0.0" in upgrade_cmd
|
||||
prefix_index = upgrade_cmd.index("--prefix")
|
||||
assert Path(upgrade_cmd[prefix_index + 1]) == managed_npm.parent.parent
|
||||
|
||||
def test_upgrade_runs_outside_the_checkout(self, managed_npm, monkeypatch):
|
||||
"""The repo .npmrc sets min-release-age, which would gate the very npm
|
||||
release we need; the upgrade must not run under it."""
|
||||
seen = {}
|
||||
|
||||
def fake_run(cmd, **kwargs):
|
||||
seen.update(kwargs)
|
||||
return subprocess.CompletedProcess(cmd, 0, "", "")
|
||||
|
||||
monkeypatch.setattr(subprocess, "run", fake_run)
|
||||
maybe_repair_npm_engine(str(managed_npm), EBADENGINE_OUTPUT, quiet=True)
|
||||
|
||||
cwd = Path(seen["cwd"])
|
||||
assert not (cwd / ".npmrc").exists()
|
||||
assert seen["env"]["npm_config_min_release_age"] == "0"
|
||||
|
||||
def test_failed_upgrade_reports_no_retry(self, managed_npm, monkeypatch):
|
||||
monkeypatch.setattr(
|
||||
subprocess,
|
||||
"run",
|
||||
lambda cmd, **kw: subprocess.CompletedProcess(cmd, 1, "", "boom"),
|
||||
)
|
||||
assert not maybe_repair_npm_engine(
|
||||
str(managed_npm), EBADENGINE_OUTPUT, quiet=True
|
||||
)
|
||||
|
||||
def test_unmanaged_npm_is_never_touched(self, managed_npm, tmp_path, monkeypatch, capsys):
|
||||
system_npm = tmp_path / "usr-bin-npm"
|
||||
system_npm.write_text("#!/bin/sh\n", encoding="utf-8")
|
||||
|
||||
def explode(cmd, **kwargs): # pragma: no cover - must not be reached
|
||||
raise AssertionError(f"must not run a subprocess for a foreign npm: {cmd}")
|
||||
|
||||
monkeypatch.setattr(subprocess, "run", explode)
|
||||
assert not maybe_repair_npm_engine(str(system_npm), EBADENGINE_OUTPUT)
|
||||
|
||||
# The user gets the exact command to run, since we refuse to run it.
|
||||
err = capsys.readouterr().err
|
||||
assert 'npm install -g npm@"<11.10.0 || >=12.0.0"' in err
|
||||
|
||||
def test_non_engine_failure_never_upgrades(self, managed_npm, monkeypatch):
|
||||
def explode(cmd, **kwargs): # pragma: no cover - must not be reached
|
||||
raise AssertionError("a lockfile mismatch must not trigger an upgrade")
|
||||
|
||||
monkeypatch.setattr(subprocess, "run", explode)
|
||||
assert not maybe_repair_npm_engine(str(managed_npm), ELOCK_OUTPUT, quiet=True)
|
||||
|
||||
|
||||
class TestRepoRangeIsSatisfiable:
|
||||
"""Invariant: whatever the root package.json demands, the recovery can
|
||||
parse and act on it — a malformed range would make the repair a no-op."""
|
||||
|
||||
def test_root_engines_npm_range_is_a_usable_constraint(self):
|
||||
repo_root = Path(__file__).resolve().parents[2]
|
||||
package_json = repo_root / "package.json"
|
||||
engines = json.loads(package_json.read_text(encoding="utf-8")).get("engines", {})
|
||||
npm_range = engines.get("npm")
|
||||
if not npm_range:
|
||||
pytest.skip("root package.json does not pin engines.npm")
|
||||
|
||||
synthetic = (
|
||||
"npm error code EBADENGINE\n"
|
||||
'npm error notsup Required: '
|
||||
+ json.dumps({"node": ">=20.0.0", "npm": npm_range})
|
||||
+ "\n"
|
||||
)
|
||||
assert required_npm_range(synthetic) == npm_range
|
||||
|
|
@ -782,7 +782,7 @@ class TestLazyMcpInstall:
|
|||
from tools.computer_use import cua_backend
|
||||
from tools.lazy_deps import FeatureUnavailable
|
||||
unavailable = FeatureUnavailable(
|
||||
"tool.computer_use", ("mcp==1.26.0",), "lazy installs disabled"
|
||||
"tool.computer_use", ("mcp==1.28.1",), "lazy installs disabled"
|
||||
)
|
||||
with patch.object(cua_backend, "_maybe_nudge_update"), \
|
||||
patch("tools.lazy_deps.ensure", side_effect=unavailable), \
|
||||
|
|
|
|||
|
|
@ -277,14 +277,14 @@ LAZY_DEPS: dict[str, tuple[str, ...]] = {
|
|||
# for stripped/source-build installs that somehow dropped it. The vision
|
||||
# call site uses prompt=False so it can never raise a blocking input()
|
||||
# prompt mid-session (#40490).
|
||||
"tool.vision": ("Pillow==12.2.0",),
|
||||
"tool.vision": ("Pillow==12.3.0",),
|
||||
# Computer Use (cua-driver) — the MCP client SDK used to spawn and talk
|
||||
# to the cua-driver process over stdio. Matches the `mcp` / `computer-use`
|
||||
# extras in pyproject.toml. The one-liner installer pulls this in via
|
||||
# `[all]`; lazy-installing here covers lean / partial / broken-extra
|
||||
# installs so computer_use never dead-ends on `No module named 'mcp'`.
|
||||
"tool.computer_use": (
|
||||
"mcp==1.26.0",
|
||||
"mcp==1.28.1",
|
||||
"starlette==1.3.1", # CVE-2026-48710 — keep in sync with pyproject [computer-use]
|
||||
),
|
||||
# HF Agent Trace Viewer upload (hermes trace upload / /upload-trace).
|
||||
|
|
|
|||
|
|
@ -21,30 +21,21 @@
|
|||
"dependencies": {
|
||||
"@hermes/ink": "file:./packages/hermes-ink",
|
||||
"@hermes/shared": "file:../apps/shared",
|
||||
"@nanostores/react": "^1.1.0",
|
||||
"ink": "^6.8.0",
|
||||
"ink-text-input": "^6.0.0",
|
||||
"nanostores": "^1.2.0",
|
||||
"react": "^19.2.4",
|
||||
"undici": "^6.25.0",
|
||||
"unicode-animations": "^1.0.3"
|
||||
"@nanostores/react": "1.1.0",
|
||||
"ink": "6.8.0",
|
||||
"ink-text-input": "6.0.0",
|
||||
"nanostores": "1.4.0",
|
||||
"react": "19.2.7",
|
||||
"undici": "6.27.0",
|
||||
"unicode-animations": "1.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9",
|
||||
"@types/node": "^22.20.0",
|
||||
"@types/react": "^19.2.14",
|
||||
"@typescript-eslint/eslint-plugin": "^8",
|
||||
"@typescript-eslint/parser": "^8",
|
||||
"esbuild": "^0.28.1",
|
||||
"eslint": "^9",
|
||||
"eslint-plugin-perfectionist": "^5",
|
||||
"eslint-plugin-react": "^7",
|
||||
"eslint-plugin-react-hooks": "^7",
|
||||
"eslint-plugin-unused-imports": "^4",
|
||||
"globals": "^16",
|
||||
"prettier": "^3",
|
||||
"tsx": "^4.22.4",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.3"
|
||||
"@types/node": "22.20.1",
|
||||
"@types/react": "19.2.17",
|
||||
"esbuild": "0.28.1",
|
||||
"prettier": "3.9.5",
|
||||
"tsx": "4.23.1",
|
||||
"typescript": "6.0.3",
|
||||
"vitest": "4.1.10"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,33 +27,33 @@
|
|||
"./package.json": "./package.json"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"ink-text-input": ">=6.0.0",
|
||||
"react": ">=19.0.0"
|
||||
"ink-text-input": "6.0.0",
|
||||
"react": "19.2.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"@alcalzone/ansi-tokenize": "^0.1.0",
|
||||
"auto-bind": "^5.0.0",
|
||||
"bidi-js": "^1.0.0",
|
||||
"chalk": "^5.4.0",
|
||||
"cli-boxes": "^3.0.0",
|
||||
"code-excerpt": "^4.0.0",
|
||||
"emoji-regex": "^10.4.0",
|
||||
"get-east-asian-width": "^1.3.0",
|
||||
"indent-string": "^5.0.0",
|
||||
"lodash-es": "^4.17.0",
|
||||
"react": ">=19.0.0",
|
||||
"@alcalzone/ansi-tokenize": "0.1.3",
|
||||
"auto-bind": "5.0.1",
|
||||
"bidi-js": "1.0.3",
|
||||
"chalk": "5.6.2",
|
||||
"cli-boxes": "3.0.0",
|
||||
"code-excerpt": "4.0.0",
|
||||
"emoji-regex": "10.6.0",
|
||||
"get-east-asian-width": "1.6.0",
|
||||
"indent-string": "5.0.0",
|
||||
"lodash-es": "4.18.1",
|
||||
"react": "19.2.7",
|
||||
"react-reconciler": "0.33.0",
|
||||
"semver": "^7.6.0",
|
||||
"signal-exit": "^4.1.0",
|
||||
"stack-utils": "^2.0.0",
|
||||
"strip-ansi": "^7.1.0",
|
||||
"supports-hyperlinks": "^3.1.0",
|
||||
"type-fest": "^4.30.0",
|
||||
"usehooks-ts": "^3.1.0",
|
||||
"wrap-ansi": "^9.0.0"
|
||||
"semver": "7.8.5",
|
||||
"signal-exit": "4.1.0",
|
||||
"stack-utils": "2.0.6",
|
||||
"strip-ansi": "7.2.0",
|
||||
"supports-hyperlinks": "3.2.0",
|
||||
"type-fest": "4.41.0",
|
||||
"usehooks-ts": "3.1.1",
|
||||
"wrap-ansi": "9.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.28.1",
|
||||
"typescript": "^6.0.3"
|
||||
"esbuild": "0.28.1",
|
||||
"typescript": "6.0.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
286
uv.lock
generated
286
uv.lock
generated
|
|
@ -7,6 +7,18 @@ resolution-markers = [
|
|||
"python_full_version < '3.12'",
|
||||
]
|
||||
|
||||
[options]
|
||||
exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values.
|
||||
exclude-newer-span = "P14D"
|
||||
|
||||
[options.exclude-newer-package]
|
||||
nemo-relay = false
|
||||
vercel = false
|
||||
huggingface-hub = false
|
||||
|
||||
[manifest]
|
||||
overrides = [{ name = "pynacl", specifier = ">=1.6,<1.7" }]
|
||||
|
||||
[[package]]
|
||||
name = "agent-client-protocol"
|
||||
version = "0.9.0"
|
||||
|
|
@ -1845,9 +1857,9 @@ requires-dist = [
|
|||
{ name = "lark-oapi", marker = "extra == 'feishu'", specifier = "==1.6.8" },
|
||||
{ name = "markdown", specifier = "==3.10.2" },
|
||||
{ name = "mautrix", extras = ["encryption"], marker = "extra == 'matrix'", specifier = "==0.21.0" },
|
||||
{ name = "mcp", marker = "extra == 'computer-use'", specifier = "==1.26.0" },
|
||||
{ name = "mcp", marker = "extra == 'dev'", specifier = "==1.26.0" },
|
||||
{ name = "mcp", marker = "extra == 'mcp'", specifier = "==1.26.0" },
|
||||
{ name = "mcp", marker = "extra == 'computer-use'", specifier = "==1.28.1" },
|
||||
{ name = "mcp", marker = "extra == 'dev'", specifier = "==1.28.1" },
|
||||
{ name = "mcp", marker = "extra == 'mcp'", specifier = "==1.28.1" },
|
||||
{ name = "mem0ai", marker = "extra == 'mem0'", specifier = "==2.0.10" },
|
||||
{ name = "microsoft-teams-apps", marker = "extra == 'teams'", specifier = "==2.0.13.4" },
|
||||
{ name = "mistralai", marker = "extra == 'mistral'", specifier = "==2.4.8" },
|
||||
|
|
@ -1863,14 +1875,14 @@ requires-dist = [
|
|||
{ name = "packaging", specifier = "==26.0" },
|
||||
{ name = "parallel-web", marker = "extra == 'parallel-web'", specifier = "==0.4.2" },
|
||||
{ name = "pathspec", specifier = "==1.1.1" },
|
||||
{ name = "pillow", specifier = "==12.2.0" },
|
||||
{ name = "pillow", specifier = "==12.3.0" },
|
||||
{ name = "prompt-toolkit", specifier = "==3.0.52" },
|
||||
{ name = "psutil", specifier = "==7.2.2" },
|
||||
{ name = "ptyprocess", marker = "sys_platform != 'win32'", specifier = ">=0.7.0,<1" },
|
||||
{ name = "pvporcupine", marker = "extra == 'wake'", specifier = "==4.0.3" },
|
||||
{ name = "pydantic", specifier = "==2.13.4" },
|
||||
{ name = "pyjwt", extras = ["crypto"], specifier = "==2.13.0" },
|
||||
{ name = "pytest", marker = "extra == 'dev'", specifier = "==9.0.2" },
|
||||
{ name = "pytest", marker = "extra == 'dev'", specifier = "==9.1.1" },
|
||||
{ name = "pytest-asyncio", marker = "extra == 'dev'", specifier = "==1.3.0" },
|
||||
{ name = "python-dotenv", specifier = "==1.2.2" },
|
||||
{ name = "python-multipart", specifier = ">=0.0.9,<1" },
|
||||
|
|
@ -1888,7 +1900,7 @@ requires-dist = [
|
|||
{ name = "ruamel-yaml", specifier = "==0.18.17" },
|
||||
{ name = "ruff", marker = "extra == 'dev'", specifier = "==0.15.10" },
|
||||
{ name = "sentencepiece", marker = "extra == 'wake'", specifier = "==0.2.2" },
|
||||
{ name = "setuptools", marker = "extra == 'dev'", specifier = "==81.0.0" },
|
||||
{ name = "setuptools", marker = "extra == 'dev'", specifier = "==83.0.0" },
|
||||
{ name = "sherpa-onnx", marker = "extra == 'wake'", specifier = "==1.13.4" },
|
||||
{ name = "simple-term-menu", marker = "extra == 'cli'", specifier = "==1.6.6" },
|
||||
{ name = "slack-bolt", marker = "extra == 'messaging'", specifier = "==1.29.0" },
|
||||
|
|
@ -1985,14 +1997,14 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "httplib2"
|
||||
version = "0.31.2"
|
||||
version = "0.32.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pyparsing" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c1/1f/e86365613582c027dda5ddb64e1010e57a3d53e99ab8a72093fa13d565ec/httplib2-0.31.2.tar.gz", hash = "sha256:385e0869d7397484f4eab426197a4c020b606edd43372492337c0b4010ae5d24", size = 250800, upload-time = "2026-01-23T11:04:44.165Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/84/f5/ccf58de92d61e3ad921119668f54ed36ca1d0cf5dcc5c1657dfb164fd78b/httplib2-0.32.0.tar.gz", hash = "sha256:48a0ef30a42db65d8f3399045e1d09ab0ba66e3b9efc360d07f80ea55d286025", size = 254283, upload-time = "2026-06-26T10:13:56.265Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2f/90/fd509079dfcab01102c0fdd87f3a9506894bc70afcf9e9785ef6b2b3aff6/httplib2-0.31.2-py3-none-any.whl", hash = "sha256:dbf0c2fa3862acf3c55c078ea9c0bc4481d7dc5117cae71be9514912cf9f8349", size = 91099, upload-time = "2026-01-23T11:04:42.78Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/a0/550eec327e5f5c7b732531c489f5307efec41f047b0d703bd4ca1e5ad2db/httplib2-0.32.0-py3-none-any.whl", hash = "sha256:dc6705cacdf3fb0a2aba7629fa33c90fd93e30035db0c157325826be177e4816", size = 93148, upload-time = "2026-06-26T10:13:54.985Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2362,7 +2374,7 @@ encryption = [
|
|||
|
||||
[[package]]
|
||||
name = "mcp"
|
||||
version = "1.26.0"
|
||||
version = "1.28.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
|
|
@ -2380,9 +2392,9 @@ dependencies = [
|
|||
{ name = "typing-inspection" },
|
||||
{ name = "uvicorn", marker = "sys_platform != 'emscripten'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/fc/6d/62e76bbb8144d6ed86e202b5edd8a4cb631e7c8130f3f4893c3f90262b10/mcp-1.26.0.tar.gz", hash = "sha256:db6e2ef491eecc1a0d93711a76f28dec2e05999f93afd48795da1c1137142c66", size = 608005, upload-time = "2026-01-24T19:40:32.468Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6e/77/9450b8f251a13affb6281997d0523c4615f8a8b35d0b21ff30db3a5aac9d/mcp-1.28.1.tar.gz", hash = "sha256:d51e36a5f5644faea4f85ea649bfffa6bc6c26770d42798ad6a3de3d2ba69683", size = 638501, upload-time = "2026-06-26T12:57:29.093Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/d9/eaa1f80170d2b7c5ba23f3b59f766f3a0bb41155fbc32a69adfa1adaaef9/mcp-1.26.0-py3-none-any.whl", hash = "sha256:904a21c33c25aa98ddbeb47273033c435e595bbacfdb177f4bd87f6dceebe1ca", size = 233615, upload-time = "2026-01-24T19:40:30.652Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/5e/d118fce19f87a2e7d8101c35c8ae0ec289098a4df0ff244cec23e415aca0/mcp-1.28.1-py3-none-any.whl", hash = "sha256:2726bca5e7193f61c5dde8b12500a6de2d9acf6d1a1c0be9e8c2e706437991df", size = 222620, upload-time = "2026-06-26T12:57:27.218Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2542,37 +2554,43 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "msgpack"
|
||||
version = "1.1.2"
|
||||
version = "1.2.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/4d/f2/bfb55a6236ed8725a96b0aa3acbd0ec17588e6a2c3b62a93eb513ed8783f/msgpack-1.1.2.tar.gz", hash = "sha256:3b60763c1373dd60f398488069bcdc703cd08a711477b5d480eecc9f9626f47e", size = 173581, upload-time = "2025-10-08T09:15:56.596Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/31/f9/c0a1c127f9049db9155afc316952ea571720dd01833ff5e4d7e8e6352dbb/msgpack-1.2.1.tar.gz", hash = "sha256:04c721c2c7448767e9e3f2520a475663d8ee0f09c31890f6d2bd70fd636a9647", size = 183960, upload-time = "2026-06-18T16:13:52.594Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/97/560d11202bcd537abca693fd85d81cebe2107ba17301de42b01ac1677b69/msgpack-1.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2e86a607e558d22985d856948c12a3fa7b42efad264dca8a3ebbcfa2735d786c", size = 82271, upload-time = "2025-10-08T09:14:49.967Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/04/28a41024ccbd67467380b6fb440ae916c1e4f25e2cd4c63abe6835ac566e/msgpack-1.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:283ae72fc89da59aa004ba147e8fc2f766647b1251500182fac0350d8af299c0", size = 84914, upload-time = "2025-10-08T09:14:50.958Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/46/b817349db6886d79e57a966346cf0902a426375aadc1e8e7a86a75e22f19/msgpack-1.1.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:61c8aa3bd513d87c72ed0b37b53dd5c5a0f58f2ff9f26e1555d3bd7948fb7296", size = 416962, upload-time = "2025-10-08T09:14:51.997Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/da/e0/6cc2e852837cd6086fe7d8406af4294e66827a60a4cf60b86575a4a65ca8/msgpack-1.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:454e29e186285d2ebe65be34629fa0e8605202c60fbc7c4c650ccd41870896ef", size = 426183, upload-time = "2025-10-08T09:14:53.477Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/25/98/6a19f030b3d2ea906696cedd1eb251708e50a5891d0978b012cb6107234c/msgpack-1.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7bc8813f88417599564fafa59fd6f95be417179f76b40325b500b3c98409757c", size = 411454, upload-time = "2025-10-08T09:14:54.648Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/cd/9098fcb6adb32187a70b7ecaabf6339da50553351558f37600e53a4a2a23/msgpack-1.1.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bafca952dc13907bdfdedfc6a5f579bf4f292bdd506fadb38389afa3ac5b208e", size = 422341, upload-time = "2025-10-08T09:14:56.328Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e6/ae/270cecbcf36c1dc85ec086b33a51a4d7d08fc4f404bdbc15b582255d05ff/msgpack-1.1.2-cp311-cp311-win32.whl", hash = "sha256:602b6740e95ffc55bfb078172d279de3773d7b7db1f703b2f1323566b878b90e", size = 64747, upload-time = "2025-10-08T09:14:57.882Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/79/309d0e637f6f37e83c711f547308b91af02b72d2326ddd860b966080ef29/msgpack-1.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:d198d275222dc54244bf3327eb8cbe00307d220241d9cec4d306d49a44e85f68", size = 71633, upload-time = "2025-10-08T09:14:59.177Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/4d/7c4e2b3d9b1106cd0aa6cb56cc57c6267f59fa8bfab7d91df5adc802c847/msgpack-1.1.2-cp311-cp311-win_arm64.whl", hash = "sha256:86f8136dfa5c116365a8a651a7d7484b65b13339731dd6faebb9a0242151c406", size = 64755, upload-time = "2025-10-08T09:15:00.48Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/bd/8b0d01c756203fbab65d265859749860682ccd2a59594609aeec3a144efa/msgpack-1.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:70a0dff9d1f8da25179ffcf880e10cf1aad55fdb63cd59c9a49a1b82290062aa", size = 81939, upload-time = "2025-10-08T09:15:01.472Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/34/68/ba4f155f793a74c1483d4bdef136e1023f7bcba557f0db4ef3db3c665cf1/msgpack-1.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:446abdd8b94b55c800ac34b102dffd2f6aa0ce643c55dfc017ad89347db3dbdb", size = 85064, upload-time = "2025-10-08T09:15:03.764Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/60/a064b0345fc36c4c3d2c743c82d9100c40388d77f0b48b2f04d6041dbec1/msgpack-1.1.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c63eea553c69ab05b6747901b97d620bb2a690633c77f23feb0c6a947a8a7b8f", size = 417131, upload-time = "2025-10-08T09:15:05.136Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/65/92/a5100f7185a800a5d29f8d14041f61475b9de465ffcc0f3b9fba606e4505/msgpack-1.1.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:372839311ccf6bdaf39b00b61288e0557916c3729529b301c52c2d88842add42", size = 427556, upload-time = "2025-10-08T09:15:06.837Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/87/ffe21d1bf7d9991354ad93949286f643b2bb6ddbeab66373922b44c3b8cc/msgpack-1.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2929af52106ca73fcb28576218476ffbb531a036c2adbcf54a3664de124303e9", size = 404920, upload-time = "2025-10-08T09:15:08.179Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/41/8543ed2b8604f7c0d89ce066f42007faac1eaa7d79a81555f206a5cdb889/msgpack-1.1.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be52a8fc79e45b0364210eef5234a7cf8d330836d0a64dfbb878efa903d84620", size = 415013, upload-time = "2025-10-08T09:15:09.83Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/41/0d/2ddfaa8b7e1cee6c490d46cb0a39742b19e2481600a7a0e96537e9c22f43/msgpack-1.1.2-cp312-cp312-win32.whl", hash = "sha256:1fff3d825d7859ac888b0fbda39a42d59193543920eda9d9bea44d958a878029", size = 65096, upload-time = "2025-10-08T09:15:11.11Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/ec/d431eb7941fb55a31dd6ca3404d41fbb52d99172df2e7707754488390910/msgpack-1.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:1de460f0403172cff81169a30b9a92b260cb809c4cb7e2fc79ae8d0510c78b6b", size = 72708, upload-time = "2025-10-08T09:15:12.554Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/31/5b1a1f70eb0e87d1678e9624908f86317787b536060641d6798e3cf70ace/msgpack-1.1.2-cp312-cp312-win_arm64.whl", hash = "sha256:be5980f3ee0e6bd44f3a9e9dea01054f175b50c3e6cdb692bc9424c0bbb8bf69", size = 64119, upload-time = "2025-10-08T09:15:13.589Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/31/b46518ecc604d7edf3a4f94cb3bf021fc62aa301f0cb849936968164ef23/msgpack-1.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4efd7b5979ccb539c221a4c4e16aac1a533efc97f3b759bb5a5ac9f6d10383bf", size = 81212, upload-time = "2025-10-08T09:15:14.552Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:42eefe2c3e2af97ed470eec850facbe1b5ad1d6eacdbadc42ec98e7dcf68b4b7", size = 84315, upload-time = "2025-10-08T09:15:15.543Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/68/93180dce57f684a61a88a45ed13047558ded2be46f03acb8dec6d7c513af/msgpack-1.1.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1fdf7d83102bf09e7ce3357de96c59b627395352a4024f6e2458501f158bf999", size = 412721, upload-time = "2025-10-08T09:15:16.567Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fac4be746328f90caa3cd4bc67e6fe36ca2bf61d5c6eb6d895b6527e3f05071e", size = 424657, upload-time = "2025-10-08T09:15:17.825Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/38/f8/4398c46863b093252fe67368b44edc6c13b17f4e6b0e4929dbf0bdb13f23/msgpack-1.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fffee09044073e69f2bad787071aeec727183e7580443dfeb8556cbf1978d162", size = 402668, upload-time = "2025-10-08T09:15:19.003Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/ce/698c1eff75626e4124b4d78e21cca0b4cc90043afb80a507626ea354ab52/msgpack-1.1.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5928604de9b032bc17f5099496417f113c45bc6bc21b5c6920caf34b3c428794", size = 419040, upload-time = "2025-10-08T09:15:20.183Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/32/f3cd1667028424fa7001d82e10ee35386eea1408b93d399b09fb0aa7875f/msgpack-1.1.2-cp313-cp313-win32.whl", hash = "sha256:a7787d353595c7c7e145e2331abf8b7ff1e6673a6b974ded96e6d4ec09f00c8c", size = 65037, upload-time = "2025-10-08T09:15:21.416Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:a465f0dceb8e13a487e54c07d04ae3ba131c7c5b95e2612596eafde1dccf64a9", size = 72631, upload-time = "2025-10-08T09:15:22.431Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e5/db/0314e4e2db56ebcf450f277904ffd84a7988b9e5da8d0d61ab2d057df2b6/msgpack-1.1.2-cp313-cp313-win_arm64.whl", hash = "sha256:e69b39f8c0aa5ec24b57737ebee40be647035158f14ed4b40e6f150077e21a84", size = 64118, upload-time = "2025-10-08T09:15:23.402Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/6b/e9b1cdc042c4458801d2545ed782a95f3d6ba8e270cce8745b8603c7f748/msgpack-1.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:29a3f6e9667868429d8240dfd063ea5ffdc1321c13d783aa23827a38de0dcb22", size = 82812, upload-time = "2026-06-18T16:12:45.022Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/3a/dd518a1bf78ed1e9ad8afe57307c079a00eafe4b3068932a27ca1ea56b4f/msgpack-1.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aded5bdf32609dc7987a49bbbd15a8ef096193f96dd8bbeb791de729e650acf5", size = 82739, upload-time = "2026-06-18T16:12:46.025Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/e0/7ba9e1542bf0771a27b8b37c1316e3f95ae9d748fd765284655c476ad4ef/msgpack-1.2.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:146ee4e9ce80b365c6d4c47073da9da7bcec473e58194ceee5dd7620ace77e06", size = 414233, upload-time = "2026-06-18T16:12:47.029Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/8d/671d81534ea0e2b0e8a121be100020da09eb78861fe3aa8f3ef7dcd3bed1/msgpack-1.2.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a28d076ca7c82b9c8728ad90b7147489449557038bed50e4241eb832395169b4", size = 423843, upload-time = "2026-06-18T16:12:48.19Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d2/b6/e5c737515ed1f166664b87601b532f58cbb73d8aa6a90b99f7c2c5037e8e/msgpack-1.2.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7d31c0ac0c640f877804c67cb2bc9f4e23dc2db97e96c2e67fa27d38283b41f8", size = 390772, upload-time = "2026-06-18T16:12:49.624Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/46/62ed8c2e87d7021eab19921594d961ef3aa3794eec76c716dc30f3bfd433/msgpack-1.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8ff92d7feeaf5bc26c51495b69e2f99ed97ab79346fb6555f44be7dd2ac6503b", size = 409559, upload-time = "2026-06-18T16:12:50.936Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/ff/59aa3887b860bbf43532835e192b1c388a17590d6068ae4f8b2bc74c906e/msgpack-1.2.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:779197a6513bab3c3632265e3d0f7cb3227e62510841a6f34f1eaa37efbb345e", size = 387838, upload-time = "2026-06-18T16:12:52.161Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/09/11/f8563e471093420cf6478cb3271a0175d8402b82d879783d4035d2d03360/msgpack-1.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:67f6dd22fa72a93752643f07889796d62739a13415ee630169a8ce764f86cf9f", size = 421732, upload-time = "2026-06-18T16:12:53.556Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/cf/e673683c4c6c90c1022b24c65af4b03eda72b182a1176ef6449069d66acc/msgpack-1.2.1-cp311-cp311-win32.whl", hash = "sha256:91054a783328e0ea7954b8771095705c8d2243b814743fbaadf14552c9c52c5d", size = 64091, upload-time = "2026-06-18T16:12:54.821Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/07/ca212739d179f9083bff2c7c08c24101c3555a334fadc2b876b18768a3ae/msgpack-1.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2eda0b7ebb1283a98d3e4492ac933c8af6aff59fd3df1c3ed024f536af4b1dc8", size = 70462, upload-time = "2026-06-18T16:12:55.898Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/be/6798347b425e26f35db82e69dd83c09716c856a3714e7bffc4c0860fd830/msgpack-1.2.1-cp311-cp311-win_arm64.whl", hash = "sha256:6ee967f7c7e1df2890c671ff2ee51a28ded0efc95da3e507176dee881ce36c66", size = 65059, upload-time = "2026-06-18T16:12:57.053Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/dd/9e8cbd8f5582ca4b590336f2b91ee5662f6a6ca562b565abaf696a0f81ff/msgpack-1.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2ef59c659f289eddf8aa6623823f19fa2f40a4029266889eac7a2505dd210c35", size = 83531, upload-time = "2026-06-18T16:12:58.249Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/2e/ebdb85a8da151397a2790363676b7ed7c125924fe618e4c6d8befb0cc62c/msgpack-1.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d3567748a5107cb40cdf66a275430c2f87c07777698f4bfd25c35f44d533258c", size = 82657, upload-time = "2026-06-18T16:12:59.396Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/aa/753ad8b007b464e1d8aa0c8e650b9c5f4f725e658fc5ac8a7635c55b7f6e/msgpack-1.2.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:60926b75d00c8e816ef98f3034f484a8bc64242d66839cef4cf7e503142316a0", size = 410634, upload-time = "2026-06-18T16:13:00.383Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/fd/6adabd4f6d5e686f97dd02ce7fce3fe4cf672cbac36b8f67ff4040e8ad8b/msgpack-1.2.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:020e881a764b20d8d7ca1a54fc01b8175519d108e3c3f194fddc200bda95951a", size = 419989, upload-time = "2026-06-18T16:13:01.776Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/cc/85039b7b0eb168aaad7383a23c97e291a11f08351cb45a606ce865e4e3f1/msgpack-1.2.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4202c74688ca06591f78cb18988228bd4cca2cc75d57b60008372892d2f1e6e6", size = 377544, upload-time = "2026-06-18T16:13:03.637Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/bf/35963899493b32030c85fc513b723ae66144ac70c11ebc52e889e16e3d99/msgpack-1.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8b267ce94efb76fbd1b3373511420074ee3187f0f7811bf394531de13294735a", size = 400842, upload-time = "2026-06-18T16:13:05.012Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/df/8e2ac970c8f99264cd9997d1c73df5466bc19da3301d7dc5500862a9b089/msgpack-1.2.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e4f1d0f8f98ade9634e01fb704a408f9336c0a8f1117b369f5db83dc7551d8b1", size = 374108, upload-time = "2026-06-18T16:13:06.232Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/17/dd/fa8bd265110dfa51c20cb529f9e6d240a16fafe7e645004c6af2d01353ba/msgpack-1.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f02cf17a6ca1abe29b5f980644f7551f94d71f2011509b26d8625ce038f0df64", size = 414939, upload-time = "2026-06-18T16:13:07.478Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/b9/8377a5ad8953fc0437c70cc98d9ae29f27fe5ac5109fbec0812085865735/msgpack-1.2.1-cp312-cp312-win32.whl", hash = "sha256:0c0d9802354507bcba62af19c17918e3eb437cc25e6f50657d511b5856a77aac", size = 64504, upload-time = "2026-06-18T16:13:08.822Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/7f/ce1e377df7e62461fefd9eb23bfb93a4a523f40a517b377b8f844d836828/msgpack-1.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:5c24aa15d5963051e1a5c62b12c50cd705992502b5ec1f3bece6046f33c9fc24", size = 71421, upload-time = "2026-06-18T16:13:09.828Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/32/ebfe84c9929f08f188d56c7a2fd913406a9ddad76a634697c1c43b8112e6/msgpack-1.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:4227224aaec8f7fbcbfbd4272319347b2bb4030366502600f8c45588c5187b07", size = 64775, upload-time = "2026-06-18T16:13:11.056Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/ac/dcddcab6f6c20ecb387ca5e980371cdb3f87ff69aeca388be97eebc4c074/msgpack-1.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0a70e3cf2804a300d921bb0940426e35f4e489a23adfb77a808892241db0a064", size = 83151, upload-time = "2026-06-18T16:13:12.173Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/71/fbcfa83a1d6a9c6091942d1cfd070962244664b87427a9a49a6897b1b219/msgpack-1.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:491cc39455ca765fad51fb451bf2915eb2cf41192ab5801ce8d67c1d614fe056", size = 82351, upload-time = "2026-06-18T16:13:13.194Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/10/ddf7b06db879e8792d13934ddda09ff20bd2a583fd84c9b59aae9b0e650b/msgpack-1.2.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f310233ef7fb9c14e201c93639fe5f5260b005f56f0b29048e999c30935596cc", size = 407518, upload-time = "2026-06-18T16:13:14.233Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/d3/36a46a8ed992b781acbc05928bd5bee3c810cb0c3563bf81a7b0c04a1a76/msgpack-1.2.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:787c9bebb5833e8f6fc8abca3c0597683d8d87f56a8842b6b89c75a5f3176e2d", size = 416405, upload-time = "2026-06-18T16:13:15.435Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/84/e8e9598b557c0ba6ddae901a73780a4c75ac667dddf59414b1e56a42fb34/msgpack-1.2.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dc871b997a9370d855b7394465f2f350e847a5b806dd38dcc9c989e7d87da155", size = 376257, upload-time = "2026-06-18T16:13:17.022Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/16/738fe6d875ad7e2a9429c165322a4ec088f4f273cdfae63d96a89c467961/msgpack-1.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:85f57e960d877f2977f6430896191b04a21f8901b3b4baf2e4604329f4db5402", size = 397469, upload-time = "2026-06-18T16:13:18.287Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ca/be/6d5952df75a7f24f35833af764c3a6860780364cb3a0030beb8099e1b2b4/msgpack-1.2.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:1233ee2dd0cefba127583de50ea654677277047d238303521db35def3d7b2e7c", size = 372802, upload-time = "2026-06-18T16:13:19.685Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/39/e2ef7dbf0473bcb8dc7c50bf782a892d67414877b63e47fc88eb189ef5e6/msgpack-1.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e3dc2feb0876209d9c38aa56cb1de169bd6c4348f1aa48271f241226590993e6", size = 411273, upload-time = "2026-06-18T16:13:21.028Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/c5/133f4512a56e983a93445c836c9d94d88f3bc2e0980ff4b9e577bd8416ce/msgpack-1.2.1-cp313-cp313-win32.whl", hash = "sha256:6d09badf350af2be9d189184e04e64cf54ad93569ab3d96fca58bd3e84aad707", size = 64471, upload-time = "2026-06-18T16:13:22.293Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/98/577e10b055096a7dd40732358cabaf7180a20c79ed1dcdbb618e4b9deac7/msgpack-1.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:33f14fba63278b714efe6ad07e50ea5f03d91537aa6a1c5f1ceca4cf44013ca9", size = 71274, upload-time = "2026-06-18T16:13:23.455Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/ee/0c0048e7cfbef23c6a94791b8959ab28155232e7956de8a305b5ff588f05/msgpack-1.2.1-cp313-cp313-win_arm64.whl", hash = "sha256:afc5febcd4c99effbc02b528e49d6fd0760b2b7d48c05239e345a5fa6e743d9a", size = 64795, upload-time = "2026-06-18T16:13:24.687Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3031,64 +3049,45 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "pillow"
|
||||
version = "12.2.0"
|
||||
version = "12.3.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/8c/21/c2bcdd5906101a30244eaffc1b6e6ce71a31bd0742a01eb89e660ebfac2d/pillow-12.2.0.tar.gz", hash = "sha256:a830b1a40919539d07806aa58e1b114df53ddd43213d9c8b75847eee6c0182b5", size = 46987819, upload-time = "2026-04-01T14:46:17.687Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1c/3d/bb7fca845737cf9d7dbde16ed1843984665ff2e0a518f5db43e77ec540b9/pillow-12.3.0.tar.gz", hash = "sha256:3b8182a766685eaa002637e28b4ec8d6b18819a0c71f579bf0dbaa5830297cce", size = 47025035, upload-time = "2026-07-01T11:56:38.965Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/68/e1/748f5663efe6edcfc4e74b2b93edfb9b8b99b67f21a854c3ae416500a2d9/pillow-12.2.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:8be29e59487a79f173507c30ddf57e733a357f67881430449bb32614075a40ab", size = 5354347, upload-time = "2026-04-01T14:42:44.255Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/a1/d5ff69e747374c33a3b53b9f98cca7889fce1fd03d79cdc4e1bccc6c5a87/pillow-12.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:71cde9a1e1551df7d34a25462fc60325e8a11a82cc2e2f54578e5e9a1e153d65", size = 4695873, upload-time = "2026-04-01T14:42:46.452Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/21/e3fbdf54408a973c7f7f89a23b2cb97a7ef30c61ab4142af31eee6aebc88/pillow-12.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f490f9368b6fc026f021db16d7ec2fbf7d89e2edb42e8ec09d2c60505f5729c7", size = 6280168, upload-time = "2026-04-01T14:42:49.228Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/f1/00b7278c7dd52b17ad4329153748f87b6756ec195ff786c2bdf12518337d/pillow-12.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8bd7903a5f2a4545f6fd5935c90058b89d30045568985a71c79f5fd6edf9b91e", size = 8088188, upload-time = "2026-04-01T14:42:51.735Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/cf/220a5994ef1b10e70e85748b75649d77d506499352be135a4989c957b701/pillow-12.2.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3997232e10d2920a68d25191392e3a4487d8183039e1c74c2297f00ed1c50705", size = 6394401, upload-time = "2026-04-01T14:42:54.343Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/bd/e51a61b1054f09437acfbc2ff9106c30d1eb76bc1453d428399946781253/pillow-12.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e74473c875d78b8e9d5da2a70f7099549f9eb37ded4e2f6a463e60125bccd176", size = 7079655, upload-time = "2026-04-01T14:42:56.954Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/3d/45132c57d5fb4b5744567c3817026480ac7fc3ce5d4c47902bc0e7f6f853/pillow-12.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:56a3f9c60a13133a98ecff6197af34d7824de9b7b38c3654861a725c970c197b", size = 6503105, upload-time = "2026-04-01T14:42:59.847Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/2e/9df2fc1e82097b1df3dce58dc43286aa01068e918c07574711fcc53e6fb4/pillow-12.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:90e6f81de50ad6b534cab6e5aef77ff6e37722b2f5d908686f4a5c9eba17a909", size = 7203402, upload-time = "2026-04-01T14:43:02.664Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/2e/2941e42858ebb67e50ae741473de81c2984e6eff7b397017623c676e2e8d/pillow-12.2.0-cp311-cp311-win32.whl", hash = "sha256:8c984051042858021a54926eb597d6ee3012393ce9c181814115df4c60b9a808", size = 6378149, upload-time = "2026-04-01T14:43:05.274Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/42/836b6f3cd7f3e5fa10a1f1a5420447c17966044c8fbf589cc0452d5502db/pillow-12.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e6b2a0c538fc200b38ff9eb6628228b77908c319a005815f2dde585a0664b60", size = 7082626, upload-time = "2026-04-01T14:43:08.557Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/88/549194b5d6f1f494b485e493edc6693c0a16f4ada488e5bd974ed1f42fad/pillow-12.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:9a8a34cc89c67a65ea7437ce257cea81a9dad65b29805f3ecee8c8fe8ff25ffe", size = 2463531, upload-time = "2026-04-01T14:43:10.743Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/58/be/7482c8a5ebebbc6470b3eb791812fff7d5e0216c2be3827b30b8bb6603ed/pillow-12.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d192a155bbcec180f8564f693e6fd9bccff5a7af9b32e2e4bf8c9c69dbad6b5", size = 5308279, upload-time = "2026-04-01T14:43:13.246Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/95/0a351b9289c2b5cbde0bacd4a83ebc44023e835490a727b2a3bd60ddc0f4/pillow-12.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f3f40b3c5a968281fd507d519e444c35f0ff171237f4fdde090dd60699458421", size = 4695490, upload-time = "2026-04-01T14:43:15.584Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/de/af/4e8e6869cbed569d43c416fad3dc4ecb944cb5d9492defaed89ddd6fe871/pillow-12.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:03e7e372d5240cc23e9f07deca4d775c0817bffc641b01e9c3af208dbd300987", size = 6284462, upload-time = "2026-04-01T14:43:18.268Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/9e/c05e19657fd57841e476be1ab46c4d501bffbadbafdc31a6d665f8b737b6/pillow-12.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b86024e52a1b269467a802258c25521e6d742349d760728092e1bc2d135b4d76", size = 8094744, upload-time = "2026-04-01T14:43:20.716Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/54/1789c455ed10176066b6e7e6da1b01e50e36f94ba584dc68d9eebfe9156d/pillow-12.2.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7371b48c4fa448d20d2714c9a1f775a81155050d383333e0a6c15b1123dda005", size = 6398371, upload-time = "2026-04-01T14:43:23.443Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/e3/fdc657359e919462369869f1c9f0e973f353f9a9ee295a39b1fea8ee1a77/pillow-12.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62f5409336adb0663b7caa0da5c7d9e7bdbaae9ce761d34669420c2a801b2780", size = 7087215, upload-time = "2026-04-01T14:43:26.758Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/f8/2f6825e441d5b1959d2ca5adec984210f1ec086435b0ed5f52c19b3b8a6e/pillow-12.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:01afa7cf67f74f09523699b4e88c73fb55c13346d212a59a2db1f86b0a63e8c5", size = 6509783, upload-time = "2026-04-01T14:43:29.56Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/f9/029a27095ad20f854f9dba026b3ea6428548316e057e6fc3545409e86651/pillow-12.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc3d34d4a8fbec3e88a79b92e5465e0f9b842b628675850d860b8bd300b159f5", size = 7212112, upload-time = "2026-04-01T14:43:32.091Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/42/025cfe05d1be22dbfdb4f264fe9de1ccda83f66e4fc3aac94748e784af04/pillow-12.2.0-cp312-cp312-win32.whl", hash = "sha256:58f62cc0f00fd29e64b29f4fd923ffdb3859c9f9e6105bfc37ba1d08994e8940", size = 6378489, upload-time = "2026-04-01T14:43:34.601Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/7b/25a221d2c761c6a8ae21bfa3874988ff2583e19cf8a27bf2fee358df7942/pillow-12.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:7f84204dee22a783350679a0333981df803dac21a0190d706a50475e361c93f5", size = 7084129, upload-time = "2026-04-01T14:43:37.213Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/e1/542a474affab20fd4a0f1836cb234e8493519da6b76899e30bcc5d990b8b/pillow-12.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:af73337013e0b3b46f175e79492d96845b16126ddf79c438d7ea7ff27783a414", size = 2463612, upload-time = "2026-04-01T14:43:39.421Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4a/01/53d10cf0dbad820a8db274d259a37ba50b88b24768ddccec07355382d5ad/pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:8297651f5b5679c19968abefd6bb84d95fe30ef712eb1b2d9b2d31ca61267f4c", size = 4100837, upload-time = "2026-04-01T14:43:41.506Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/98/f3a6657ecb698c937f6c76ee564882945f29b79bad496abcba0e84659ec5/pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:50d8520da2a6ce0af445fa6d648c4273c3eeefbc32d7ce049f22e8b5c3daecc2", size = 4176528, upload-time = "2026-04-01T14:43:43.773Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/bc/8986948f05e3ea490b8442ea1c1d4d990b24a7e43d8a51b2c7d8b1dced36/pillow-12.2.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:766cef22385fa1091258ad7e6216792b156dc16d8d3fa607e7545b2b72061f1c", size = 3640401, upload-time = "2026-04-01T14:43:45.87Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/34/46/6c717baadcd62bc8ed51d238d521ab651eaa74838291bda1f86fe1f864c9/pillow-12.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5d2fd0fa6b5d9d1de415060363433f28da8b1526c1c129020435e186794b3795", size = 5308094, upload-time = "2026-04-01T14:43:48.438Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56b25336f502b6ed02e889f4ece894a72612fe885889a6e8c4c80239ff6e5f5f", size = 4695402, upload-time = "2026-04-01T14:43:51.292Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/dd/42107efcb777b16fa0393317eac58f5b5cf30e8392e266e76e51cff28c3d/pillow-12.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f1c943e96e85df3d3478f7b691f229887e143f81fedab9b20205349ab04d73ed", size = 6280005, upload-time = "2026-04-01T14:43:54.242Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/68/b93e09e5e8549019e61acf49f65b1a8530765a7f812c77a7461bca7e4494/pillow-12.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:03f6fab9219220f041c74aeaa2939ff0062bd5c364ba9ce037197f4c6d498cd9", size = 8090669, upload-time = "2026-04-01T14:43:57.335Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/6e/3ccb54ce8ec4ddd1accd2d89004308b7b0b21c4ac3d20fa70af4760a4330/pillow-12.2.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5cdfebd752ec52bf5bb4e35d9c64b40826bc5b40a13df7c3cda20a2c03a0f5ed", size = 6395194, upload-time = "2026-04-01T14:43:59.864Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3", size = 7082423, upload-time = "2026-04-01T14:44:02.74Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/78/5f/e9f86ab0146464e8c133fe85df987ed9e77e08b29d8d35f9f9f4d6f917ba/pillow-12.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:00a2865911330191c0b818c59103b58a5e697cae67042366970a6b6f1b20b7f9", size = 6505667, upload-time = "2026-04-01T14:44:05.381Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/1e/409007f56a2fdce61584fd3acbc2bbc259857d555196cedcadc68c015c82/pillow-12.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e1757442ed87f4912397c6d35a0db6a7b52592156014706f17658ff58bbf795", size = 7208580, upload-time = "2026-04-01T14:44:08.39Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/c4/7349421080b12fb35414607b8871e9534546c128a11965fd4a7002ccfbee/pillow-12.2.0-cp313-cp313-win32.whl", hash = "sha256:144748b3af2d1b358d41286056d0003f47cb339b8c43a9ea42f5fea4d8c66b6e", size = 6375896, upload-time = "2026-04-01T14:44:11.197Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:390ede346628ccc626e5730107cde16c42d3836b89662a115a921f28440e6a3b", size = 7081266, upload-time = "2026-04-01T14:44:13.947Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/25/f968f618a062574294592f668218f8af564830ccebdd1fa6200f598e65c5/pillow-12.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:8023abc91fba39036dbce14a7d6535632f99c0b857807cbbbf21ecc9f4717f06", size = 2463508, upload-time = "2026-04-01T14:44:16.312Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4d/a4/b342930964e3cb4dce5038ae34b0eab4653334995336cd486c5a8c25a00c/pillow-12.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:042db20a421b9bafecc4b84a8b6e444686bd9d836c7fd24542db3e7df7baad9b", size = 5309927, upload-time = "2026-04-01T14:44:18.89Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/de/23198e0a65a9cf06123f5435a5d95cea62a635697f8f03d134d3f3a96151/pillow-12.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:dd025009355c926a84a612fecf58bb315a3f6814b17ead51a8e48d3823d9087f", size = 4698624, upload-time = "2026-04-01T14:44:21.115Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/01/a6/1265e977f17d93ea37aa28aa81bad4fa597933879fac2520d24e021c8da3/pillow-12.2.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:88ddbc66737e277852913bd1e07c150cc7bb124539f94c4e2df5344494e0a612", size = 6321252, upload-time = "2026-04-01T14:44:23.663Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/83/5982eb4a285967baa70340320be9f88e57665a387e3a53a7f0db8231a0cd/pillow-12.2.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d362d1878f00c142b7e1a16e6e5e780f02be8195123f164edf7eddd911eefe7c", size = 8126550, upload-time = "2026-04-01T14:44:26.772Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/48/6ffc514adce69f6050d0753b1a18fd920fce8cac87620d5a31231b04bfc5/pillow-12.2.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c727a6d53cb0018aadd8018c2b938376af27914a68a492f59dfcaca650d5eea", size = 6433114, upload-time = "2026-04-01T14:44:29.615Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/36/a3/f9a77144231fb8d40ee27107b4463e205fa4677e2ca2548e14da5cf18dce/pillow-12.2.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:efd8c21c98c5cc60653bcb311bef2ce0401642b7ce9d09e03a7da87c878289d4", size = 7115667, upload-time = "2026-04-01T14:44:32.773Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/fc/ac4ee3041e7d5a565e1c4fd72a113f03b6394cc72ab7089d27608f8aaccb/pillow-12.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9f08483a632889536b8139663db60f6724bfcb443c96f1b18855860d7d5c0fd4", size = 6538966, upload-time = "2026-04-01T14:44:35.252Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c0/a8/27fb307055087f3668f6d0a8ccb636e7431d56ed0750e07a60547b1e083e/pillow-12.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dac8d77255a37e81a2efcbd1fc05f1c15ee82200e6c240d7e127e25e365c39ea", size = 7238241, upload-time = "2026-04-01T14:44:37.875Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/4b/926ab182c07fccae9fcb120043464e1ff1564775ec8864f21a0ebce6ac25/pillow-12.2.0-cp313-cp313t-win32.whl", hash = "sha256:ee3120ae9dff32f121610bb08e4313be87e03efeadfc6c0d18f89127e24d0c24", size = 6379592, upload-time = "2026-04-01T14:44:40.336Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/c4/f9e476451a098181b30050cc4c9a3556b64c02cf6497ea421ac047e89e4b/pillow-12.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:325ca0528c6788d2a6c3d40e3568639398137346c3d6e66bb61db96b96511c98", size = 7085542, upload-time = "2026-04-01T14:44:43.251Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/a4/285f12aeacbe2d6dc36c407dfbbe9e96d4a80b0fb710a337f6d2ad978c75/pillow-12.2.0-cp313-cp313t-win_arm64.whl", hash = "sha256:2e5a76d03a6c6dcef67edabda7a52494afa4035021a79c8558e14af25313d453", size = 2465765, upload-time = "2026-04-01T14:44:45.996Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/b7/2437044fb910f499610356d1352e3423753c98e34f915252aafecc64889f/pillow-12.2.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0538bd5e05efec03ae613fd89c4ce0368ecd2ba239cc25b9f9be7ed426b0af1f", size = 5273969, upload-time = "2026-04-01T14:45:55.538Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/f4/8316e31de11b780f4ac08ef3654a75555e624a98db1056ecb2122d008d5a/pillow-12.2.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:394167b21da716608eac917c60aa9b969421b5dcbbe02ae7f013e7b85811c69d", size = 4659674, upload-time = "2026-04-01T14:45:58.093Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/37/664fca7201f8bb2aa1d20e2c3d5564a62e6ae5111741966c8319ca802361/pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5d04bfa02cc2d23b497d1e90a0f927070043f6cbf303e738300532379a4b4e0f", size = 5288479, upload-time = "2026-04-01T14:46:01.141Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/62/5b0ed78fce87346be7a5cfcfaaad91f6a1f98c26f86bdbafa2066c647ef6/pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0c838a5125cee37e68edec915651521191cef1e6aa336b855f495766e77a366e", size = 7032230, upload-time = "2026-04-01T14:46:03.874Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/28/ec0fc38107fc32536908034e990c47914c57cd7c5a3ece4d8d8f7ffd7e27/pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a6c9fa44005fa37a91ebfc95d081e8079757d2e904b27103f4f5fa6f0bf78c0", size = 5355404, upload-time = "2026-04-01T14:46:06.33Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/8b/51b0eddcfa2180d60e41f06bd6d0a62202b20b59c68f5a132e615b75aecf/pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:25373b66e0dd5905ed63fa3cae13c82fbddf3079f2c8bf15c6fb6a35586324c1", size = 6002215, upload-time = "2026-04-01T14:46:08.83Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/60/5382c03e1970de634027cee8e1b7d39776b778b81812aaf45b694dfe9e28/pillow-12.2.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:bfa9c230d2fe991bed5318a5f119bd6780cda2915cca595393649fc118ab895e", size = 7080946, upload-time = "2026-04-01T14:46:11.734Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/c8/0a78b0e02d7ac54bc03e5321c9220da52f0c2ea83b21f7c40e7f3169c502/pillow-12.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:00808c5e14ef63ac5161091d242999076604ff74b883423a11e5d7bbb38bf756", size = 5392415, upload-time = "2026-07-01T11:53:47.162Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/5b/a02d30018abd97ced9f5a6c63d28597694a00d066516b9c1c6de45859fc9/pillow-12.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37d6d0a00072fd2948eb22bce7e1475f34569d90c87c59f7a2ec59541b77f7a6", size = 4785266, upload-time = "2026-07-01T11:53:49.079Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/98/766667a4be768150a202836acd9fad19c06824ca86c4286d3cf6b274964e/pillow-12.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bcb46e2f9feff8d06323983bd83ed00c201fdcab3d74973e7072a889b3979fcd", size = 6263814, upload-time = "2026-07-01T11:53:51.32Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/2d/ede717bc1144f63886c21fd349bb95860b0d1a21149ff16f2bb362b612b6/pillow-12.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23d27a3e0307ec2244cc51e7287b919aa68d097504ebe19df4e76a98a3eea5bd", size = 6934408, upload-time = "2026-07-01T11:53:53.487Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/48/9c58b685e69d49c31af6c8eb9012055fab7e665785165c84796e2c73ce72/pillow-12.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4f883547d4b7f0495ebe7056b0cc2aea76094e7a4abc8e933540f3271df27d9c", size = 6337160, upload-time = "2026-07-01T11:53:55.457Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/fa/dc2a5c0ba6df93f67c31d34b808b7ce440b40cdbf96f0b81cde1d1e6fa93/pillow-12.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:236ff70b9312fb68943c703aa842ca6a758abfa45ac187a5e7c1452e96ef72b5", size = 7045172, upload-time = "2026-07-01T11:53:57.736Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/a5/444817a4d4c4c2417df00513086ca196f388d8f9ef40c2e4ccd1ad1af54b/pillow-12.3.0-cp311-cp311-win32.whl", hash = "sha256:10e41f0fbf1eec8cfd234b8fe17a4caac7c9d0db4c204d3c173a8f9f6ef3232b", size = 6472232, upload-time = "2026-07-01T11:53:59.767Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/c6/4bad1b18d132a50b27e1365e1ab163616f7a5bb56d330f66f9d1d9d4f9d4/pillow-12.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8e95e1385e4998ae9694eeaa4730ba5457ff61185b3a55e2e7bea0880aef452a", size = 7233653, upload-time = "2026-07-01T11:54:02.066Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/16/00f91ab7760dc842f5aad55217e80fc4a7067a0604535249bc8a2d6d9870/pillow-12.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:ebaea975e03d3141d9d3a507df75c9b3ec90fa9d2ffd07567b3a978d9d790b26", size = 2568195, upload-time = "2026-07-01T11:54:04.622Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/37/bf/fb3ebff8ddcb76aac5a01389251bbbb9519922a9b520d8247c1ca864a25d/pillow-12.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ba09209fbe443b4acccebe845d8a138b89a8f4fbaeedd44953490b5315d5e965", size = 5345969, upload-time = "2026-07-01T11:54:06.397Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/66/9a386a92561f402389a4fc70c18838bf6d35eb5eb5c6850b4b2dc64f5048/pillow-12.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffd0c5368496f41b0944be820fcb7a838aa6e623d250b01acf2643939c3f99d7", size = 4780323, upload-time = "2026-07-01T11:54:09.351Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/25/27/ac8f99618ffd3dde21db0f4d4b1d2ab00c0880595bfd17df103f7f39fd0c/pillow-12.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9c7f76c0673154f044e9d78c8655fb4213f6ca31a836df48b40fe5d187717b9", size = 6266838, upload-time = "2026-07-01T11:54:11.71Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/21/a35af28dcc61f37ed850a2d64c65c701321dfbf25085e469d5559360cbbf/pillow-12.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:78cb2c6865a35ab8ff8b75fd122f6033b92a62c82801110e48ddd6c936a45d91", size = 6940830, upload-time = "2026-07-01T11:54:13.732Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/51/8b08617af3ad95e33ce6d7dd2c99ed6c8298f7fb131636303956be022e25/pillow-12.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e491916b378fba47242221bb9ead245211b70d504f495d105d17b14a24b4907c", size = 6344383, upload-time = "2026-07-01T11:54:15.756Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1d/72/cf78ac9780bb93c28328f408973845a309d4d145041665f734572ced1b52/pillow-12.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0dd2064cbc55aaec028ef5fbb60fa47bb6c3e7918e07ff17935284b227a9d2df", size = 7052934, upload-time = "2026-07-01T11:54:17.721Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/20/20/25e0f4dc178a6bc0696793720055519a0de89e7661dae886992decbd2f81/pillow-12.3.0-cp312-cp312-win32.whl", hash = "sha256:dbce0b29841537a2fa4a214c2bbf14de3587c9680caa9b4e217568472490b28f", size = 6472684, upload-time = "2026-07-01T11:54:19.839Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/89/da2f7971a317f83d807fdd4065c0af40208e59e692cc43d315a71a0e96d1/pillow-12.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a2b55dd6b2a4c4b7d87ffa56bdb33fdc5fdb9a462173861a7bc097f17d91cb09", size = 7227137, upload-time = "2026-07-01T11:54:22.025Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/de/47/4845a0a6c0dbf1db8456bd9fc791f13c5ced7ced20606d08a0aacfd25b49/pillow-12.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:331b624368d4f1d069149002f25f44bc61c8919ce8ddb3c45bdad8f6e2d89510", size = 2568267, upload-time = "2026-07-01T11:54:24.051Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/ac/31fb64e1e7efb5a4b50cd3d92049ba89ac6e4d8d3bb6a74e15048ca3353e/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:21900ce7ba264168cd50defae43cd75d25c833ad4ad6e73ffc5596d12e25ac89", size = 4161684, upload-time = "2026-07-01T11:54:25.934Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/b4/9805e23d2b4d77842b468513841fda254ee42f0289d25088340e4ff46e2d/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:4e8c2a84d977f50b9daed6eeaf3baef67d00d5d74d932288f02cb94518ee3ace", size = 4255487, upload-time = "2026-07-01T11:54:27.935Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/39/ecf519435a200c693fe053a6ee4d835b41cf963a4dfc2551c4e637cb2a71/pillow-12.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:ae26d61dfa7a47befdc7572b521024e8745f3d809bd95ca9505a7bba9ef849ec", size = 3696433, upload-time = "2026-07-01T11:54:29.813Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/42/92/2fc3ffad878ae8dd5469ec1bc8eb83b71f48e13efdf68f02709003982a32/pillow-12.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7a743ff716f746fc19a9557f60dab1600d4613255f8a7aeb3cdde4db7eb15a66", size = 5345889, upload-time = "2026-07-01T11:54:31.97Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/76/8803c13605b763d33d156c4678fc77f8443389c0c51c8aef707bb02015f4/pillow-12.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d69141514cc30b774ceea5e3ed3a6635c8d8a96edf664689b890f4089111fb35", size = 4780109, upload-time = "2026-07-01T11:54:34.026Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/01/e18aff37cb0b4aac47ac90f016d347a49aca667ef97f190b06ac2aabc928/pillow-12.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f7401aebd7f581d7f83a439d87d474999317ee099218e5ad25d125290990ba65", size = 6263736, upload-time = "2026-07-01T11:54:36.131Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/62/de5bdd77d935331f4f802edc11e4d82950f642caad6cb2f949837b8560e2/pillow-12.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0847a763afefb695bc912d7c131e7e0632d4edc1d8698f58ddabec8e46b8b6d3", size = 6937129, upload-time = "2026-07-01T11:54:38.216Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/4d/105627a13300c5e0df1d174230b32fd1273062c96f7745fd552b945d1e1d/pillow-12.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:571b9fcb07b97ef3a492028fb3d2dc0993ca23a06138b0315286566d29ef718a", size = 6339562, upload-time = "2026-07-01T11:54:40.354Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/1d/f13de01a553988ab895ba1c722e06cf3144d4f57656fd5b81b6d881f1179/pillow-12.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:756c768d0c9c2955feb7a56c37ea24aea2e369f8d36a88da270b6a9f19e62b5e", size = 7049439, upload-time = "2026-07-01T11:54:42.489Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/f9/066794cca041b969964f779ee5fa66a9498bbf34248ac39c5d7954e4198f/pillow-12.3.0-cp313-cp313-win32.whl", hash = "sha256:a876864214e136f0eb367788dbd7df045f4806801518e2cfe9e13229cfe06d8f", size = 6473287, upload-time = "2026-07-01T11:54:44.9Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/9b/7a58e61d62be561da3a356fe2384d4059a6345fc130e23ef1c36a5b81d24/pillow-12.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:1cca606cd25738df4ed873d5ad46bbdb3d83b5cbca291f6b4ff13a4df6b0bbe8", size = 7239691, upload-time = "2026-07-01T11:54:47.141Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/b0/c4ed4f0ef8f8fa5ee8351537db6650bb8189f7e118842978dd6589065692/pillow-12.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:b629de27fda84b42cde7edef0d85f13b958b47f6e9bbcbba9b673c562a89bd8b", size = 2568185, upload-time = "2026-07-01T11:54:49.137Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/18/2e8b40223153ccbc60df07f9e8928dc0c76202aa4e55ae9f53962b6510d6/pillow-12.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b3c777e849237620b022f7f297dd67705f9f5cf1685f09f02e46f93e92725468", size = 5302510, upload-time = "2026-07-01T11:56:25.736Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/3e/51fabf59d5ab801ceab709453d3ab6b180083496579549de4c45ced6528a/pillow-12.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:b343699e8308bdc51978310e1c959c584e7869cc8c40780058c87da7781a1e94", size = 4736058, upload-time = "2026-07-01T11:56:28.041Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/20/22fe9384b7949e25fb1293bcfc84fb82590ff4ea6b37c95b24d26d793d86/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbd139c8447d25dd750ab79ee274cc5e1fe80fc56340ab10b18a195e1b6eca3e", size = 5237776, upload-time = "2026-07-01T11:56:30.263Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/08/14/f6ba68107680ffa74b39985f3f30884e41318fbc4250caa423c79b4788bb/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e7e480451b9fa137494bccd3a7d69adbe8ac65a87d97be61e11f1b1050a5bac3", size = 5860358, upload-time = "2026-07-01T11:56:32.68Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/36/54/0169bc772ec491108b62f644f8ecf1fe5d8ae5ebafde2ee2142210166903/pillow-12.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:04f01d28a6aaff387bf842a13be313df23ba0597a44f1a976c9feb3c6ff4711a", size = 7231786, upload-time = "2026-07-01T11:56:35.046Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3280,11 +3279,11 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "pyasn1"
|
||||
version = "0.6.3"
|
||||
version = "0.6.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5c/5f/6583902b6f79b399c9c40674ac384fd9cd77805f9e6205075f828ef11fb2/pyasn1-0.6.3.tar.gz", hash = "sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf", size = 148685, upload-time = "2026-03-17T01:06:53.382Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a4/9a/23310166d960def5897e91fe20e5b724601b02a22e84ba1f94232c0b7f67/pyasn1-0.6.4.tar.gz", hash = "sha256:9c447d8431c947fe4c8febc4ed9e760bc29011a5b01e5c74b67025bd9fb8ce81", size = 151262, upload-time = "2026-07-09T01:12:33.988Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/a0/7d793dce3fa811fe047d6ae2431c672364b462850c6235ae306c0efd025f/pyasn1-0.6.3-py3-none-any.whl", hash = "sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde", size = 83997, upload-time = "2026-03-17T01:06:52.036Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/3b/6163796d69c3977d1e4287bea4a6979161cbbdd170ebb430511e8e1999ce/pyasn1-0.6.4-py3-none-any.whl", hash = "sha256:deda9277cfd454080ec40b207fb6df82206a3a2688735233cdcd8d3d565f088b", size = 84410, upload-time = "2026-07-09T01:12:32.92Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3427,25 +3426,25 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "pydantic-settings"
|
||||
version = "2.13.1"
|
||||
version = "2.14.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pydantic" },
|
||||
{ name = "python-dotenv" },
|
||||
{ name = "typing-inspection" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/52/6d/fffca34caecc4a3f97bda81b2098da5e8ab7efc9a66e819074a11955d87e/pydantic_settings-2.13.1.tar.gz", hash = "sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025", size = 223826, upload-time = "2026-02-19T13:45:08.055Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5c/b5/8f48e906c3e0205276e8bd8cb7512217a87b2685304d64be27cad5b3019f/pydantic_settings-2.14.2.tar.gz", hash = "sha256:c19dd64b19097f1de80184f0cc7b0272a13ae6e170cbf240a3e27e381ed14a5f", size = 237700, upload-time = "2026-06-19T13:44:56.324Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/00/4b/ccc026168948fec4f7555b9164c724cf4125eac006e176541483d2c959be/pydantic_settings-2.13.1-py3-none-any.whl", hash = "sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237", size = 58929, upload-time = "2026-02-19T13:45:06.034Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/c1/6e422f34e569cf8e18df68d1939c81c099d2b61e4f7d9621c8a77560799c/pydantic_settings-2.14.2-py3-none-any.whl", hash = "sha256:a20c97b37910b6550d5ea50fbcc2d4187defe58cd57070b73863d069419c9440", size = 61715, upload-time = "2026-06-19T13:44:55.02Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pygments"
|
||||
version = "2.19.2"
|
||||
version = "2.20.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3464,22 +3463,25 @@ crypto = [
|
|||
|
||||
[[package]]
|
||||
name = "pynacl"
|
||||
version = "1.5.0"
|
||||
version = "1.6.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "cffi" },
|
||||
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a7/22/27582568be639dfe22ddb3902225f91f2f17ceff88ce80e4db396c8986da/PyNaCl-1.5.0.tar.gz", hash = "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba", size = 3392854, upload-time = "2022-01-07T22:05:41.134Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d9/9a/4019b524b03a13438637b11538c82781a5eda427394380381af8f04f467a/pynacl-1.6.2.tar.gz", hash = "sha256:018494d6d696ae03c7e656e5e74cdfd8ea1326962cc401bcf018f1ed8436811c", size = 3511692, upload-time = "2026-01-01T17:48:10.851Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/75/0b8ede18506041c0bf23ac4d8e2971b4161cd6ce630b177d0a08eb0d8857/PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1", size = 349920, upload-time = "2022-01-07T22:05:49.156Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/59/bb/fddf10acd09637327a97ef89d2a9d621328850a72f1fdc8c08bdf72e385f/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92", size = 601722, upload-time = "2022-01-07T22:05:50.989Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/70/87a065c37cca41a75f2ce113a5a2c2aa7533be648b184ade58971b5f7ccc/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394", size = 680087, upload-time = "2022-01-07T22:05:52.539Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ee/87/f1bb6a595f14a327e8285b9eb54d41fef76c585a0edef0a45f6fc95de125/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d", size = 856678, upload-time = "2022-01-07T22:05:54.251Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/28/ca86676b69bf9f90e710571b67450508484388bfce09acf8a46f0b8c785f/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858", size = 1133660, upload-time = "2022-01-07T22:05:56.056Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/85/c262db650e86812585e2bc59e497a8f59948a005325a11bbbc9ecd3fe26b/PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b", size = 663824, upload-time = "2022-01-07T22:05:57.434Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/1a/cc308a884bd299b651f1633acb978e8596c71c33ca85e9dc9fa33a5399b9/PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff", size = 1117912, upload-time = "2022-01-07T22:05:58.665Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/25/2d/b7df6ddb0c2a33afdb358f8af6ea3b8c4d1196ca45497dd37a56f0c122be/PyNaCl-1.5.0-cp36-abi3-win32.whl", hash = "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543", size = 204624, upload-time = "2022-01-07T22:06:00.085Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/22/d3db169895faaf3e2eda892f005f433a62db2decbcfbc2f61e6517adfa87/PyNaCl-1.5.0-cp36-abi3-win_amd64.whl", hash = "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93", size = 212141, upload-time = "2022-01-07T22:06:01.861Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/7b/4845bbf88e94586ec47a432da4e9107e3fc3ce37eb412b1398630a37f7dd/pynacl-1.6.2-cp38-abi3-macosx_10_10_universal2.whl", hash = "sha256:c949ea47e4206af7c8f604b8278093b674f7c79ed0d4719cc836902bf4517465", size = 388458, upload-time = "2026-01-01T17:32:16.829Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/b4/e927e0653ba63b02a4ca5b4d852a8d1d678afbf69b3dbf9c4d0785ac905c/pynacl-1.6.2-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8845c0631c0be43abdd865511c41eab235e0be69c81dc66a50911594198679b0", size = 800020, upload-time = "2026-01-01T17:32:18.34Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/81/d60984052df5c97b1d24365bc1e30024379b42c4edcd79d2436b1b9806f2/pynacl-1.6.2-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:22de65bb9010a725b0dac248f353bb072969c94fa8d6b1f34b87d7953cf7bbe4", size = 1399174, upload-time = "2026-01-01T17:32:20.239Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/f7/322f2f9915c4ef27d140101dd0ed26b479f7e6f5f183590fd32dfc48c4d3/pynacl-1.6.2-cp38-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:46065496ab748469cdd999246d17e301b2c24ae2fdf739132e580a0e94c94a87", size = 835085, upload-time = "2026-01-01T17:32:22.24Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3e/d0/f301f83ac8dbe53442c5a43f6a39016f94f754d7a9815a875b65e218a307/pynacl-1.6.2-cp38-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8a66d6fb6ae7661c58995f9c6435bda2b1e68b54b598a6a10247bfcdadac996c", size = 1437614, upload-time = "2026-01-01T17:32:23.766Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/58/fc6e649762b029315325ace1a8c6be66125e42f67416d3dbd47b69563d61/pynacl-1.6.2-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:26bfcd00dcf2cf160f122186af731ae30ab120c18e8375684ec2670dccd28130", size = 818251, upload-time = "2026-01-01T17:32:25.69Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/a8/b917096b1accc9acd878819a49d3d84875731a41eb665f6ebc826b1af99e/pynacl-1.6.2-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c8a231e36ec2cab018c4ad4358c386e36eede0319a0c41fed24f840b1dac59f6", size = 1402859, upload-time = "2026-01-01T17:32:27.215Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/42/fe60b5f4473e12c72f977548e4028156f4d340b884c635ec6b063fe7e9a5/pynacl-1.6.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:68be3a09455743ff9505491220b64440ced8973fe930f270c8e07ccfa25b1f9e", size = 791926, upload-time = "2026-01-01T17:32:29.314Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/f9/e40e318c604259301cc091a2a63f237d9e7b424c4851cafaea4ea7c4834e/pynacl-1.6.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8b097553b380236d51ed11356c953bf8ce36a29a3e596e934ecabe76c985a577", size = 1363101, upload-time = "2026-01-01T17:32:31.263Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/48/47/e761c254f410c023a469284a9bc210933e18588ca87706ae93002c05114c/pynacl-1.6.2-cp38-abi3-win32.whl", hash = "sha256:5811c72b473b2f38f7e2a3dc4f8642e3a3e9b5e7317266e4ced1fba85cae41aa", size = 227421, upload-time = "2026-01-01T17:32:33.076Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/41/ad/334600e8cacc7d86587fe5f565480fde569dfb487389c8e1be56ac21d8ac/pynacl-1.6.2-cp38-abi3-win_amd64.whl", hash = "sha256:62985f233210dee6548c223301b6c25440852e13d59a8b81490203c3227c5ba0", size = 239754, upload-time = "2026-01-01T17:32:34.557Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/29/7d/5945b5af29534641820d3bd7b00962abbbdfee84ec7e19f0d5b3175f9a31/pynacl-1.6.2-cp38-abi3-win_arm64.whl", hash = "sha256:834a43af110f743a754448463e8fd61259cd4ab5bbedcf70f9dabad1d28a394c", size = 184801, upload-time = "2026-01-01T17:32:36.309Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3502,7 +3504,7 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "9.0.2"
|
||||
version = "9.1.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
|
|
@ -3511,9 +3513,9 @@ dependencies = [
|
|||
{ name = "pluggy" },
|
||||
{ name = "pygments" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3983,7 +3985,7 @@ resolution-markers = [
|
|||
"python_full_version < '3.12'",
|
||||
]
|
||||
dependencies = [
|
||||
{ name = "numpy", marker = "python_full_version < '3.12'" },
|
||||
{ name = "numpy" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/7a/97/5a3609c4f8d58b039179648e62dd220f89864f56f7357f5d4f45c29eb2cc/scipy-1.17.1.tar.gz", hash = "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", size = 30573822, upload-time = "2026-02-23T00:26:24.851Z" }
|
||||
wheels = [
|
||||
|
|
@ -4038,7 +4040,7 @@ resolution-markers = [
|
|||
"python_full_version == '3.12.*'",
|
||||
]
|
||||
dependencies = [
|
||||
{ name = "numpy", marker = "python_full_version >= '3.12'" },
|
||||
{ name = "numpy" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a7/25/c2700dfaf6442b4effaa91af24ebce5dc9d31bb4a69706313aae70d72cd0/scipy-1.18.0.tar.gz", hash = "sha256:67b2ad2ad54c72ca6d04975a9b2df8c3638c34ddd5b28738e94fc2b57929d378", size = 30774447, upload-time = "2026-06-19T15:01:43.456Z" }
|
||||
wheels = [
|
||||
|
|
@ -4102,11 +4104,11 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "setuptools"
|
||||
version = "81.0.0"
|
||||
version = "83.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0d/1c/73e719955c59b8e424d015ab450f51c0af856ae46ea2da83eba51cc88de1/setuptools-81.0.0.tar.gz", hash = "sha256:487b53915f52501f0a79ccfd0c02c165ffe06631443a886740b91af4b7a5845a", size = 1198299, upload-time = "2026-02-06T21:10:39.601Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/34/26/f5d29e25ffdb535afef2d35cdb55b325298f96debd670da4c325e08d70f4/setuptools-83.0.0.tar.gz", hash = "sha256:025bccbbf0fa05b6192bc64ae1e7b16e001fd6d6d4d5de03c97b1c1ade523bef", size = 1154254, upload-time = "2026-07-04T15:31:22.699Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/e3/c164c88b2e5ce7b24d667b9bd83589cf4f3520d97cad01534cd3c4f55fdb/setuptools-81.0.0-py3-none-any.whl", hash = "sha256:fdd925d5c5d9f62e4b74b30d6dd7828ce236fd6ed998a08d81de62ce5a6310d6", size = 1062021, upload-time = "2026-02-06T21:10:37.175Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/40/e1e72872c6354b306daef1703549e8e83b4d43cfea356311bf722a043752/setuptools-83.0.0-py3-none-any.whl", hash = "sha256:29b23c360f22f414dc7336bb39178cc7bcbf6021ed2733cde173f09dba19abb3", size = 1008090, upload-time = "2026-07-04T15:31:20.885Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -4398,19 +4400,19 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "tornado"
|
||||
version = "6.5.5"
|
||||
version = "6.5.7"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f8/f1/3173dfa4a18db4a9b03e5d55325559dab51ee653763bb8745a75af491286/tornado-6.5.5.tar.gz", hash = "sha256:192b8f3ea91bd7f1f50c06955416ed76c6b72f96779b962f07f911b91e8d30e9", size = 516006, upload-time = "2026-03-10T21:31:02.067Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/64/24/95ec527ad67b76d59299e5465b3935d05e4294b7e0290a3924b7487df30b/tornado-6.5.7.tar.gz", hash = "sha256:66c513a76cda70d53907bc27cf1447557699c2e95aa48ba27a442ff61c3ddfc2", size = 519252, upload-time = "2026-06-08T17:34:51.232Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/59/8c/77f5097695f4dd8255ecbd08b2a1ed8ba8b953d337804dd7080f199e12bf/tornado-6.5.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:487dc9cc380e29f58c7ab88f9e27cdeef04b2140862e5076a66fb6bb68bb1bfa", size = 445983, upload-time = "2026-03-10T21:30:44.28Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/5e/7625b76cd10f98f1516c36ce0346de62061156352353ef2da44e5c21523c/tornado-6.5.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:65a7f1d46d4bb41df1ac99f5fcb685fb25c7e61613742d5108b010975a9a6521", size = 444246, upload-time = "2026-03-10T21:30:46.571Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/04/7b5705d5b3c0fab088f434f9c83edac1573830ca49ccf29fb83bf7178eec/tornado-6.5.5-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e74c92e8e65086b338fd56333fb9a68b9f6f2fe7ad532645a290a464bcf46be5", size = 447229, upload-time = "2026-03-10T21:30:48.273Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/34/01/74e034a30ef59afb4097ef8659515e96a39d910b712a89af76f5e4e1f93c/tornado-6.5.5-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:435319e9e340276428bbdb4e7fa732c2d399386d1de5686cb331ec8eee754f07", size = 448192, upload-time = "2026-03-10T21:30:51.22Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/00/fe9e02c5a96429fce1a1d15a517f5d8444f9c412e0bb9eadfbe3b0fc55bf/tornado-6.5.5-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3f54aa540bdbfee7b9eb268ead60e7d199de5021facd276819c193c0fb28ea4e", size = 448039, upload-time = "2026-03-10T21:30:53.52Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/9e/656ee4cec0398b1d18d0f1eb6372c41c6b889722641d84948351ae19556d/tornado-6.5.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:36abed1754faeb80fbd6e64db2758091e1320f6bba74a4cf8c09cd18ccce8aca", size = 447445, upload-time = "2026-03-10T21:30:55.541Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/76/4921c00511f88af86a33de770d64141170f1cfd9c00311aea689949e274e/tornado-6.5.5-cp39-abi3-win32.whl", hash = "sha256:dd3eafaaeec1c7f2f8fdcd5f964e8907ad788fe8a5a32c4426fbbdda621223b7", size = 448582, upload-time = "2026-03-10T21:30:57.142Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/23/f6c6112a04d28eed765e374435fb1a9198f73e1ec4b4024184f21faeb1ad/tornado-6.5.5-cp39-abi3-win_amd64.whl", hash = "sha256:6443a794ba961a9f619b1ae926a2e900ac20c34483eea67be4ed8f1e58d3ef7b", size = 448990, upload-time = "2026-03-10T21:30:58.857Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/c8/876602cbc96469911f0939f703453c1157b0c826ecb05bdd32e023397d4e/tornado-6.5.5-cp39-abi3-win_arm64.whl", hash = "sha256:2c9a876e094109333f888539ddb2de4361743e5d21eece20688e3e351e4990a6", size = 448016, upload-time = "2026-03-10T21:31:00.43Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/dc/c7043cab6fed8ae159fc1923ce829ada35c4dbd797d408a43858ffaf9639/tornado-6.5.7-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:148b2eb15c2c765a50796172c1e499649b35f30d2e3c3d3e15913cfa56bfb163", size = 448543, upload-time = "2026-06-08T17:34:38.052Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/4f/090b1431e5a43df696feceffc268c5383cc079ecb5f08ce58f917109aafe/tornado-6.5.7-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9da38de27f1da3b78a966f0dae12b5a1ea9afe72ca805d84ff06508272ddf100", size = 446707, upload-time = "2026-06-08T17:34:39.594Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/37/d8/ef374952fd5da67d4463122c2b8e5a96536ec10b4b339254c6dcde81d01c/tornado-6.5.7-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8d759e71906ee783f8867b93bf26a265743da4c1e2f4a018464c1ba019862972", size = 449774, upload-time = "2026-06-08T17:34:41.204Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/35/37/d434c73f4c6e014b745b9b37085f34f40c022f007efff3d7fe65991899f3/tornado-6.5.7-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a46347a18f23fb92b396beebe0fb78f61dda0cc302445202c16203d8a18848b", size = 450745, upload-time = "2026-06-08T17:34:42.531Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/2b/56b9aff361d7f1ab728a805ec7d7ea835f8807afa9f5cc690ea0e630efb9/tornado-6.5.7-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7778b30bef919231265e91c69963ce0f49a1e9c07ac900bbe75b19ce2575ba92", size = 450578, upload-time = "2026-06-08T17:34:43.787Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/30/a7444fb23aa76860a14198fab96ac79f1866b0a6e19e26c4381b0938e50f/tornado-6.5.7-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e726f0c75da7726eec023aa62751ff8878bd2737e34fbdd33b1ae5897d2200f5", size = 449985, upload-time = "2026-06-08T17:34:45.326Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/42/5f0e56c01e8d9d36f4e23f367b85ae6cae0c1ecddd5e6977d8388ad27488/tornado-6.5.7-cp39-abi3-win32.whl", hash = "sha256:f8de3bf12d3efdd0cbe7c8887868198f8a91415e3f29fcf258d9b8eb7b1d9ae4", size = 451047, upload-time = "2026-06-08T17:34:46.784Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/a4/b393076ffb21b469eec5b328a0534cf03a3b90bfc6b1f09507cdd075d938/tornado-6.5.7-cp39-abi3-win_amd64.whl", hash = "sha256:de942f843533a039ef9fa3d9c88c7cd8a7c94553fb5ad0154270989b3d99a2c4", size = 451485, upload-time = "2026-06-08T17:34:48.248Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/2e/7b1c769803121b809112cf9a00681c472eae1d80e32d7ec0e0bd61d0d0e1/tornado-6.5.7-cp39-abi3-win_arm64.whl", hash = "sha256:ff934fce95643af5f11efdae618eaa73d469dc588641e5c8d19295a0c65c4796", size = 450506, upload-time = "2026-06-08T17:34:49.702Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -4677,11 +4679,11 @@ name = "vercel-workers"
|
|||
version = "0.0.25"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio", marker = "python_full_version >= '3.12'" },
|
||||
{ name = "httpx", marker = "python_full_version >= '3.12'" },
|
||||
{ name = "pydantic", marker = "python_full_version >= '3.12'" },
|
||||
{ name = "python-dotenv", marker = "python_full_version >= '3.12'" },
|
||||
{ name = "vercel", marker = "python_full_version >= '3.12'" },
|
||||
{ name = "anyio" },
|
||||
{ name = "httpx" },
|
||||
{ name = "pydantic" },
|
||||
{ name = "python-dotenv" },
|
||||
{ name = "vercel" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/30/df/04d37021ad7ca53b7599c313e411d91623c7a005c741f491d1eefb7a9f0c/vercel_workers-0.0.25.tar.gz", hash = "sha256:212ded01400b524be51d251df49f801caf115ad7d48cca7eb168cbeceda3def3", size = 64149, upload-time = "2026-06-20T19:26:27.177Z" }
|
||||
wheels = [
|
||||
|
|
|
|||
|
|
@ -16,44 +16,39 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@hermes/shared": "file:../apps/shared",
|
||||
"@nous-research/ui": "0.18.2",
|
||||
"@observablehq/plot": "^0.6.17",
|
||||
"@react-three/fiber": "^9.6.0",
|
||||
"@tailwindcss/vite": "^4.2.1",
|
||||
"@xterm/addon-fit": "^0.11.0",
|
||||
"@xterm/addon-unicode11": "^0.9.0",
|
||||
"@xterm/addon-web-links": "^0.12.0",
|
||||
"@xterm/addon-webgl": "^0.19.0",
|
||||
"@xterm/xterm": "^6.0.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"gsap": "^3.15.0",
|
||||
"leva": "^0.10.1",
|
||||
"lucide-react": "^0.577.0",
|
||||
"motion": "^12.38.0",
|
||||
"qrcode": "^1.5.4",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"react-router-dom": "^7.17.0",
|
||||
"tailwind-merge": "^3.5.0",
|
||||
"tailwindcss": "^4.2.1",
|
||||
"unicode-animations": "^1.0.3"
|
||||
"@nous-research/ui": "0.16.0",
|
||||
"@observablehq/plot": "0.6.17",
|
||||
"@react-three/fiber": "9.6.1",
|
||||
"@tailwindcss/vite": "4.3.3",
|
||||
"@xterm/addon-fit": "0.11.0",
|
||||
"@xterm/addon-unicode11": "0.9.0",
|
||||
"@xterm/addon-web-links": "0.12.0",
|
||||
"@xterm/addon-webgl": "0.19.0",
|
||||
"@xterm/xterm": "6.0.0",
|
||||
"class-variance-authority": "0.7.1",
|
||||
"clsx": "2.1.1",
|
||||
"gsap": "3.15.0",
|
||||
"leva": "0.10.1",
|
||||
"lucide-react": "0.577.0",
|
||||
"motion": "12.42.2",
|
||||
"qrcode": "1.5.4",
|
||||
"react": "19.2.7",
|
||||
"react-dom": "19.2.7",
|
||||
"react-router": "8.3.0",
|
||||
"tailwind-merge": "3.6.0",
|
||||
"tailwindcss": "4.3.3",
|
||||
"unicode-animations": "1.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.39.4",
|
||||
"@types/node": "^22.20.0",
|
||||
"@types/qrcode": "^1.5.6",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react": "^6.0.2",
|
||||
"eslint": "^9.39.4",
|
||||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"eslint-plugin-react-refresh": "^0.5.2",
|
||||
"globals": "^17.4.0",
|
||||
"three": "^0.180.0",
|
||||
"typescript": "^6.0.3",
|
||||
"typescript-eslint": "^8.56.1",
|
||||
"vite": "^8.0.16",
|
||||
"vitest": "^4.1.5"
|
||||
"@types/node": "22.20.1",
|
||||
"@types/qrcode": "1.5.6",
|
||||
"@types/react": "19.2.17",
|
||||
"@types/react-dom": "19.2.3",
|
||||
"@vitejs/plugin-react": "6.0.3",
|
||||
"eslint-plugin-react-refresh": "0.5.3",
|
||||
"three": "0.180.0",
|
||||
"typescript": "6.0.3",
|
||||
"vite": "8.2.0",
|
||||
"vitest": "4.1.10"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import {
|
|||
Navigate,
|
||||
useLocation,
|
||||
useNavigate,
|
||||
} from "react-router-dom";
|
||||
} from "react-router";
|
||||
import {
|
||||
Activity,
|
||||
BarChart3,
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import { ListItem } from "@nous-research/ui/ui/components/list-item";
|
|||
import { Spinner } from "@nous-research/ui/ui/components/spinner";
|
||||
import { AlertCircle, MessageSquarePlus, RefreshCw } from "lucide-react";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import { useSearchParams } from "react-router";
|
||||
|
||||
import { useI18n } from "@/i18n";
|
||||
import { api, type SessionInfo } from "@/lib/api";
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Link } from "react-router-dom";
|
||||
import { Link } from "react-router";
|
||||
import type { StatusResponse } from "@/lib/api";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useI18n } from "@/i18n";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useLayoutEffect, useMemo, useState, type ReactNode } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { useLocation } from "react-router";
|
||||
import { PageHeaderContext } from "./page-header-context";
|
||||
import { resolvePageTitle } from "@/lib/resolve-page-title";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
useState,
|
||||
type ReactNode,
|
||||
} from "react";
|
||||
import { useLocation, useSearchParams } from "react-router-dom";
|
||||
import { useLocation, useSearchParams } from "react-router";
|
||||
import { api, setManagementProfile } from "@/lib/api";
|
||||
import { ProfileContext } from "@/contexts/profile-context";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { createRoot } from "react-dom/client";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import { BrowserRouter } from "react-router";
|
||||
import "./index.css";
|
||||
import App from "./App";
|
||||
import { SystemActionsProvider } from "./contexts/SystemActions";
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import { cn } from "@/lib/utils";
|
|||
import { Copy, PanelRight, RotateCcw, X } from "lucide-react";
|
||||
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import { useSearchParams } from "react-router";
|
||||
|
||||
import { ChatSidebar } from "@/components/ChatSidebar";
|
||||
import { ChatSessionList } from "@/components/ChatSessionList";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { useCallback, useEffect, useState } from "react";
|
||||
import { ExternalLink, RefreshCw, Trash2, Eye, EyeOff } from "lucide-react";
|
||||
import type { Translations } from "@/i18n/types";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Link } from "react-router";
|
||||
import { api } from "@/lib/api";
|
||||
import type {
|
||||
HubAgentPluginRow,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useNavigate } from "react-router";
|
||||
import { H2 } from "@nous-research/ui/ui/components/typography/h2";
|
||||
import { Card, CardContent } from "@nous-research/ui/ui/components/card";
|
||||
import { Badge } from "@nous-research/ui/ui/components/badge";
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {
|
|||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useNavigate } from "react-router";
|
||||
import { useProfileScope } from "@/contexts/useProfileScope";
|
||||
import {
|
||||
AlignLeft,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {
|
|||
useCallback,
|
||||
useRef,
|
||||
} from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useNavigate } from "react-router";
|
||||
import {
|
||||
AlertTriangle,
|
||||
CheckCircle2,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useEffect, useLayoutEffect, useState, useMemo, useCallback } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useNavigate } from "react-router";
|
||||
import {
|
||||
Package,
|
||||
Search,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Link } from "react-router";
|
||||
import {
|
||||
Activity,
|
||||
Brain,
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ export default defineConfig({
|
|||
groups: [
|
||||
{
|
||||
name: "react-vendor",
|
||||
test: /node_modules[\\/](react|react-dom|scheduler|react-router|react-router-dom)([\\/]|$)/,
|
||||
test: /node_modules[\\/](react|react-dom|scheduler|react-router|react-router)([\\/]|$)/,
|
||||
},
|
||||
{
|
||||
name: "xterm",
|
||||
|
|
|
|||
13
website/.npmrc
Normal file
13
website/.npmrc
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# needed to prevent bad npm that has min-release-age but not exclude
|
||||
engine-strict=true
|
||||
|
||||
min-release-age=14
|
||||
|
||||
# fast-uri 3.1.4 includes fixes for vulns. remove this when 3.1.4 is > 2wks old
|
||||
min-release-age-exclude[]=fast-uri
|
||||
|
||||
# minimatch 10.2.6 includes fixes for vulns. remove this when 10.2.6 is > 2wks old
|
||||
min-release-age-exclude[]=minimatch
|
||||
|
||||
# brace-expansion 5.0.8 includes fixes for vulns. remove this when 5.0.8 is > 2wks old
|
||||
min-release-age-exclude[]=brace-expansion
|
||||
3537
website/package-lock.json
generated
3537
website/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -18,26 +18,27 @@
|
|||
"lint:diagrams": "ascii-guard lint --exclude-code-blocks docs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.9.2",
|
||||
"@docusaurus/plugin-client-redirects": "3.9.2",
|
||||
"@docusaurus/preset-classic": "3.9.2",
|
||||
"@docusaurus/theme-mermaid": "^3.9.2",
|
||||
"@easyops-cn/docusaurus-search-local": "^0.55.1",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^2.0.0",
|
||||
"prism-react-renderer": "^2.3.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0"
|
||||
"@docusaurus/core": "3.10.2",
|
||||
"@docusaurus/plugin-client-redirects": "3.10.2",
|
||||
"@docusaurus/preset-classic": "3.10.2",
|
||||
"@docusaurus/theme-mermaid": "3.10.2",
|
||||
"@easyops-cn/docusaurus-search-local": "0.55.2",
|
||||
"@mdx-js/react": "3.1.1",
|
||||
"clsx": "2.1.1",
|
||||
"prism-react-renderer": "2.3.0",
|
||||
"react": "19.2.7",
|
||||
"react-dom": "19.2.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "3.9.2",
|
||||
"@docusaurus/tsconfig": "3.9.2",
|
||||
"@docusaurus/types": "3.9.2",
|
||||
"typescript": "^6.0.3"
|
||||
"@docusaurus/module-type-aliases": "3.10.2",
|
||||
"@docusaurus/tsconfig": "3.10.2",
|
||||
"@docusaurus/types": "3.10.2",
|
||||
"typescript": "6.0.3"
|
||||
},
|
||||
"overrides": {
|
||||
"serialize-javascript": "^7.0.5",
|
||||
"uuid": "^14.0.0"
|
||||
"serialize-javascript": "7.0.7",
|
||||
"uuid": "14.0.1",
|
||||
"minimatch": "10.2.6"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
|
|
@ -52,6 +53,11 @@
|
|||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0"
|
||||
"node": ">=20.0",
|
||||
"npm": "<11.10.0 || >=12.0.0"
|
||||
},
|
||||
"allowScripts": {
|
||||
"core-js@3.49.0": true,
|
||||
"core-js-pure@3.49.0": true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue