@openhands/agent-canvas 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.windows.md +2 -2
- package/build/assets/{active-backend-context-DRFevVIj.js → active-backend-context-u2tdYRgH.js} +1 -1
- package/build/assets/{add-backend-modal-DzuB9zlG.js → add-backend-modal-DIEyAkA4.js} +1 -1
- package/build/assets/{agent-profiles-settings-BfAwTshW.js → agent-profiles-settings-BovdV4N8.js} +1 -1
- package/build/assets/{agent-server-conversation-service.api-DfH2k6Sx.js → agent-server-conversation-service.api-BP73yONA.js} +1 -1
- package/build/assets/agent-settings-FGL3Yvkp.js +1 -0
- package/build/assets/{agent-settings-DjVlKgaP.js → agent-settings-Ofbh6UTD.js} +1 -1
- package/build/assets/{api-key-entry-screen-O8gS-fnF.js → api-key-entry-screen-CZIdRmUJ.js} +1 -1
- package/build/assets/{app-settings-SlZvaXlk.js → app-settings-BHJ9nKti.js} +1 -1
- package/build/assets/{automation-detail-CwsNJ9AM.js → automation-detail-DwYGzLkp.js} +1 -1
- package/build/assets/{automations-list-B9cPtugh.js → automations-list-CuAfJmMW.js} +1 -1
- package/build/assets/{backend-form-modal-D2EDGVAc.js → backend-form-modal-BiaOB2C4.js} +1 -1
- package/build/assets/{backend-synced-settings-badge-6OCwIuLY.js → backend-synced-settings-badge-Bs3FSXsS.js} +1 -1
- package/build/assets/{color-themes-Dd1sO5U6.js → color-themes-DPBzNtVg.js} +3 -3
- package/build/assets/{condenser-settings-BhxvlfoY.js → condenser-settings-D_5vY4m3.js} +1 -1
- package/build/assets/conversation-DnVC6vRV.js +1 -0
- package/build/assets/conversation-panel-ZEz-z3az.js +1 -0
- package/build/assets/{conversation-service.api-Ch9kR9aE.js → conversation-service.api-CqZcHr1c.js} +1 -1
- package/build/assets/{conversation-B8prFAZF.js → conversation-xkBS3AHC.js} +3 -3
- package/build/assets/{edit-automation-modal-BoibW8cd.js → edit-automation-modal-B6U96gVV.js} +1 -1
- package/build/assets/{entry.client-BgWj9jL_.js → entry.client-Dy--3GeA.js} +1 -1
- package/build/assets/{extensions-hub-MtC8lK3A.js → extensions-hub-CksKNpP9.js} +1 -1
- package/build/assets/{extensions-navigation-BtV14oQL.js → extensions-navigation-Di9rJ-b5.js} +1 -1
- package/build/assets/{files-tab-DHqtsKLy.js → files-tab-61Vaihc6.js} +1 -1
- package/build/assets/{git-provider-icon-CGU7_KiU.js → git-provider-icon-aQRcUVI-.js} +1 -1
- package/build/assets/{home-BgjWP_UN.js → home-5gOtUe-n.js} +1 -1
- package/build/assets/{install-server-modal-J_eQ6lhG.js → install-server-modal-BRab9inF.js} +1 -1
- package/build/assets/{launch-DamfAY5L.js → launch-1TJRKkkX.js} +1 -1
- package/build/assets/{lesson-plan-HD886V64.js → lesson-plan-BtrZUCuj.js} +1 -1
- package/build/assets/{llm-not-configured-banner-DTrLsVr_.js → llm-not-configured-banner-BrU5uHto.js} +1 -1
- package/build/assets/{llm-settings-BgSFkbHC.js → llm-settings-BpdU51Jo.js} +1 -1
- package/build/assets/llm-settings-DsInf6yD.js +1 -0
- package/build/assets/{manage-backends-modal-BUzj5_Lq.js → manage-backends-modal-BREySP-J.js} +1 -1
- package/build/assets/{manifest-4d6a1552.js → manifest-a5bb7568.js} +1 -1
- package/build/assets/{mcp-DvqJYDbz.js → mcp-XXf8k6mb.js} +1 -1
- package/build/assets/{messages-C4KEFkPk.js → messages-D2oZb47Z.js} +1 -1
- package/build/assets/{onboarding-gGIqoxvA.js → onboarding-D32kiGME.js} +1 -1
- package/build/assets/{onboarding-modal-CGHPoMp7.js → onboarding-modal-C084vkv7.js} +1 -1
- package/build/assets/{option-service.api-Dz7Eomnx.js → option-service.api-Cl5VLGyw.js} +1 -1
- package/build/assets/{path-utils-CBaRYg35.js → path-utils-BeOmjIcE.js} +1 -1
- package/build/assets/{planner-tab-G4j36bJk.js → planner-tab-AZMjJx31.js} +1 -1
- package/build/assets/{providers-CPoq0VXm.js → providers-vX9jk9Vy.js} +1 -1
- package/build/assets/recommended-automations-launcher-Bk8tQ-Cn.js +58 -0
- package/build/assets/{root-layout-CvxdHJ6j.js → root-layout-CoWw4kpz.js} +2 -2
- package/build/assets/{root-S6CfVoNm.js → root-tuEPDx-i.js} +2 -2
- package/build/assets/{schema-field-DwUzlw6b.js → schema-field-nvq_Juo2.js} +1 -1
- package/build/assets/{sdk-section-page-BUXONTx6.js → sdk-section-page-CgT70FaZ.js} +1 -1
- package/build/assets/{secrets-settings-ZxyfRBgx.js → secrets-settings-BCxk9p9s.js} +1 -1
- package/build/assets/{settings-Bx6vn-g8.js → settings-CedTdtb5.js} +1 -1
- package/build/assets/{settings-index-D4SM26d5.js → settings-index-Cct3PJSP.js} +1 -1
- package/build/assets/{settings-modal-BoC8oMlg.js → settings-modal-DwLybV_O.js} +1 -1
- package/build/assets/{shared-conversation-DMiaQFsj.js → shared-conversation-DnDwfLgg.js} +1 -1
- package/build/assets/{sidebar-mobile-menu-toggle-CaV3tQFF.js → sidebar-mobile-menu-toggle-B8k3qu84.js} +1 -1
- package/build/assets/{skills-plugins-D2WkrXkr.js → skills-plugins-B68ay6Pu.js} +1 -1
- package/build/assets/{skills-settings-CZGVOp_t.js → skills-settings-A6sUy0T7.js} +1 -1
- package/build/assets/{terminal-B0aL_iDZ.js → terminal-BmT0_gIH.js} +1 -1
- package/build/assets/{use-acp-credential-form-rzaqkJ1n.js → use-acp-credential-form-Bs6s0DTU.js} +1 -1
- package/build/assets/{use-activate-agent-profile-DY0txItX.js → use-activate-agent-profile-CKtTToSx.js} +1 -1
- package/build/assets/{use-active-agent-profile-Cp5AFONR.js → use-active-agent-profile-CWLPpOtK.js} +1 -1
- package/build/assets/{use-active-conversation-DvcFBqFe.js → use-active-conversation-DI5S5M1w.js} +1 -1
- package/build/assets/{use-agent-profiles-DnH16_Vm.js → use-agent-profiles-DPcaYLpm.js} +1 -1
- package/build/assets/{use-agent-state-BvRcEzY4.js → use-agent-state-Buh3bQDh.js} +1 -1
- package/build/assets/{use-backends-health-e-Ull4wz.js → use-backends-health-CxkvJy2N.js} +1 -1
- package/build/assets/{use-can-manage-org-profiles-OIhplvQ0.js → use-can-manage-org-profiles-DeX2Mfje.js} +1 -1
- package/build/assets/{use-cloud-current-user-id-ekU7UXDT.js → use-cloud-current-user-id-D_PQGfmT.js} +1 -1
- package/build/assets/{use-config-Dwf5gla-.js → use-config-ur0RbjCP.js} +1 -1
- package/build/assets/{use-create-conversation-CvAXfA3T.js → use-create-conversation-D9OWYcte.js} +1 -1
- package/build/assets/{use-create-secret-BKeXCo__.js → use-create-secret-CVFSlhlR.js} +1 -1
- package/build/assets/{use-handle-plan-click-cAXS-Hft.js → use-handle-plan-click-Dug8egQl.js} +1 -1
- package/build/assets/{use-llm-profiles-BcLibtGb.js → use-llm-profiles-DjackuP1.js} +1 -1
- package/build/assets/use-runtime-is-ready-Diiq65Q-.js +1 -0
- package/build/assets/{use-save-agent-profile-DFjxHhNx.js → use-save-agent-profile-aKKLqDJM.js} +1 -1
- package/build/assets/{use-save-settings-5xPYpSQM.js → use-save-settings-CChDyjOB.js} +1 -1
- package/build/assets/{use-settings-B07msZ2Z.js → use-settings-dX4fKUPF.js} +1 -1
- package/build/assets/{use-settings-nav-items-CswsOEyw.js → use-settings-nav-items-D6pHnvxg.js} +1 -1
- package/build/assets/{use-skills-Aoaoq_ei.js → use-skills-Dqo-pDDx.js} +1 -1
- package/build/assets/{use-tracking-CqODdfO4.js → use-tracking-GtXCHmTv.js} +1 -1
- package/build/assets/{use-user-conversation-BPHQ-dm-.js → use-user-conversation-6uOXFP95.js} +1 -1
- package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~launch~skills-settings~automations-~ki5qnp0d-DJHl5b-B.js → vendor~root-layout~home~conversation-panel~conversation~launch~skills-settings~automations-~ki5qnp0d-rV6d1Iv_.js} +267 -27
- package/build/assets/vendor~root-layout~home~mcp~automations-list~onboarding-modal-CXyYYvYh.js +1 -0
- package/build/assets/{verification-settings-DZQ-JvKH.js → verification-settings-D_zsNB_c.js} +1 -1
- package/build/index.html +4 -4
- package/config/defaults.json +1 -1
- package/dist/config/defaults.cjs +1 -1
- package/dist/config/defaults.cjs.map +1 -1
- package/dist/config/defaults.js +1 -1
- package/dist/config/defaults.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/atlassian.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/atlassian.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/atlassian.js +70 -3
- package/dist/node_modules/@openhands/extensions/integrations/catalog/atlassian.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js +27 -2
- package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/superhuman-mail.cjs +2 -0
- package/dist/node_modules/@openhands/extensions/integrations/catalog/superhuman-mail.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/integrations/catalog/superhuman-mail.js +33 -0
- package/dist/node_modules/@openhands/extensions/integrations/catalog/superhuman-mail.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/integrations/catalog-index.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog-index.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog-index.js +48 -46
- package/dist/node_modules/@openhands/extensions/integrations/catalog-index.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/skills/index.cjs +267 -27
- package/dist/node_modules/@openhands/extensions/skills/index.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/skills/index.js +36 -30
- package/dist/node_modules/@openhands/extensions/skills/index.js.map +1 -1
- package/dist/package.cjs +1 -1
- package/dist/package.cjs.map +1 -1
- package/dist/package.js +2 -2
- package/dist/package.js.map +1 -1
- package/dist/themes/color-themes.cjs +3 -3
- package/dist/themes/color-themes.cjs.map +1 -1
- package/dist/themes/color-themes.d.ts +13 -2
- package/dist/themes/color-themes.js +2 -2
- package/dist/themes/color-themes.js.map +1 -1
- package/package.json +2 -2
- package/build/assets/agent-settings-CMMms-0q.js +0 -1
- package/build/assets/conversation-DGVDwGn8.js +0 -1
- package/build/assets/conversation-panel-C7DC4Cxx.js +0 -1
- package/build/assets/llm-settings-Bkc8C5Bi.js +0 -1
- package/build/assets/recommended-automations-launcher-CXaEK1rW.js +0 -50
- package/build/assets/use-runtime-is-ready-CBFe69Ew.js +0 -1
- package/build/assets/vendor~root-layout~home~mcp~automations-list~onboarding-modal-L2sdihTY.js +0 -1
package/dist/package.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require(`./_virtual/_rolldown/runtime.cjs`);var e={name:`@openhands/agent-canvas`,version:`1.2.
|
|
1
|
+
require(`./_virtual/_rolldown/runtime.cjs`);var e={name:`@openhands/agent-canvas`,version:`1.2.1`,description:`Agent Canvas UI for OpenHands - run AI coding agents with a visual interface`,license:`MIT`,private:!1,type:`module`,repository:{type:`git`,url:`https://github.com/OpenHands/agent-canvas`},homepage:`https://github.com/OpenHands/agent-canvas#readme`,bugs:{url:`https://github.com/OpenHands/agent-canvas/issues`},bin:{"agent-canvas":`bin/agent-canvas.mjs`},engines:{node:`>=22.12.0`},dependencies:{"@heroui/react":`2.8.10`,"@microlink/react-json-view":`1.31.20`,"@monaco-editor/react":`4.7.0`,"@openhands/extensions":`0.9.0`,"@openhands/typescript-client":`1.32.1`,"@react-router/node":`7.17.0`,"@react-router/serve":`7.17.0`,"@tailwindcss/vite":`4.2.4`,"@tanstack/react-query":`5.100.9`,"@types/shell-quote":`1.7.5`,"@uidotdev/usehooks":`2.4.1`,"@xterm/addon-fit":`0.11.0`,"@xterm/xterm":`6.0.0`,axios:`1.16.0`,"class-variance-authority":`0.7.1`,clsx:`2.1.1`,downshift:`9.3.2`,"framer-motion":`12.38.0`,httpxy:`0.5.3`,i18next:`26.0.8`,"i18next-browser-languagedetector":`8.2.1`,"i18next-http-backend":`4.0.0`,isbot:`5.1.39`,"lucide-react":`1.14.0`,"monaco-editor":`0.55.1`,"posthog-js":`1.372.6`,react:`19.2.5`,"react-dom":`19.2.5`,"react-hot-toast":`2.6.0`,"react-i18next":`17.0.6`,"react-icons":`5.6.0`,"react-markdown":`10.1.0`,"react-router":`7.17.0`,"react-syntax-highlighter":`16.1.1`,"rehype-raw":`7.0.0`,"rehype-sanitize":`6.0.0`,"remark-breaks":`4.0.0`,"remark-gfm":`4.0.1`,"shell-quote":`1.8.4`,sirv:`3.0.2`,"sirv-cli":`3.0.1`,"socket.io-client":`4.8.3`,"tailwind-merge":`3.5.0`,"tailwind-scrollbar":`4.0.2`,"unist-util-visit":`5.1.0`,uuid:`14.0.0`,vite:`8.0.10`,winston:`3.19.0`,"winston-daily-rotate-file":`5.0.0`,zustand:`5.0.12`},scripts:{dev:`node --env-file-if-exists=.env scripts/dev-with-automation.mjs`,"dev:static":`node --env-file-if-exists=.env scripts/dev-static.mjs`,"dev:extra-backend":`node --env-file-if-exists=.env scripts/dev-extra-backend.mjs`,"dev:minimal":`node --env-file-if-exists=.env scripts/dev-safe.mjs`,"dev:frontend":`npm run make-i18n && cross-env VITE_MOCK_API=false react-router dev`,"dev:mock":`npm run make-i18n && cross-env VITE_MOCK_API=true react-router dev`,build:`npm run build:app`,"build:mock":`npm run make-i18n && cross-env VITE_MOCK_API=true react-router build`,start:`npx sirv-cli build/ --single`,test:`npm run make-i18n && vitest run`,"test:e2e":`playwright test --pass-with-no-tests`,"test:e2e:live":`node --env-file-if-exists=.env tests/e2e/live/scripts/run-live-e2e.mjs`,"test:e2e:mock-llm":`playwright test --config=playwright.mock-llm.config.ts`,"test:e2e:mock-llm:docker":`playwright test --config=playwright.mock-llm-docker.config.ts`,"test:coverage":`npm run make-i18n && vitest run --coverage`,dev_wsl:`VITE_WATCH_USE_POLLING=true vite`,preview:`vite preview`,"make-i18n":`node scripts/make-i18n-translations.cjs`,prelint:`npm run make-i18n`,lint:`npm run typecheck && eslint src && prettier --check src/**/*.{ts,tsx}`,"lint:fix":`eslint src --fix && prettier --write src/**/*.{ts,tsx}`,prepare:`husky`,typecheck:`react-router typegen && tsc`,"typecheck:staged":`react-router typegen && npx tsc --noEmit --skipLibCheck`,"check-translation-completeness":`node scripts/check-translation-completeness.cjs`,"build:app":`npm run make-i18n && react-router build`,"build:lib":`npm run make-i18n && react-router typegen && cross-env BUILD_LIB=true VITE_APP_ENV=production vite build && tsc -p tsconfig.lib.json`,"build:docker":`node scripts/docker-build.mjs`,"example:acp-docker:env":`node scripts/gen-acp-docker-env.mjs`},"lint-staged":{"src/**/*.{ts,tsx,js}":[`eslint --fix`,`prettier --write`],"src/**/*.{ts,tsx}":[`node scripts/run-staged-typecheck.mjs`],"src/**/*":[`npm run check-translation-completeness`]},devDependencies:{"@eslint/eslintrc":`3.3.1`,"@eslint/js":`9.39.4`,"@mswjs/socket.io-binding":`0.2.0`,"@playwright/test":`1.59.1`,"@react-router/dev":`7.17.0`,"@tailwindcss/typography":`0.5.19`,"@tanstack/eslint-plugin-query":`5.100.9`,"@testing-library/dom":`10.4.1`,"@testing-library/jest-dom":`6.9.1`,"@testing-library/react":`16.3.2`,"@testing-library/user-event":`14.6.1`,"@types/mdast":`4.0.4`,"@types/node":`25.6.0`,"@types/react":`19.2.14`,"@types/react-dom":`19.2.3`,"@types/react-syntax-highlighter":`15.5.13`,"@typescript-eslint/eslint-plugin":`8.59.2`,"@typescript-eslint/parser":`8.59.2`,"@vercel/react-router":`1.3.0`,"@vitest/coverage-v8":`4.1.5`,"cross-env":`10.1.0`,eslint:`9.39.4`,"eslint-config-prettier":`10.1.8`,"eslint-import-resolver-typescript":`4.4.4`,"eslint-plugin-i18next":`6.1.4`,"eslint-plugin-import-x":`4.16.2`,"eslint-plugin-jsx-a11y":`6.10.2`,"eslint-plugin-prettier":`5.5.5`,"eslint-plugin-react":`7.37.5`,"eslint-plugin-react-hooks":`7.1.1`,"eslint-plugin-unused-imports":`4.4.1`,globals:`16.5.0`,husky:`9.1.7`,jsdom:`29.1.1`,"lint-staged":`16.4.0`,msw:`2.14.2`,"postcss-prefix-selector":`2.1.1`,prettier:`3.8.3`,tailwindcss:`4.2.4`,typescript:`6.0.3`,"vite-plugin-svgr":`5.2.0`,vitest:`4.1.5`},packageManager:`npm@10.5.0`,volta:{node:`22.12.0`},msw:{workerDirectory:[`public`]},overrides:{"@vercel/static-config":{ajv:`8.20.0`},dompurify:`3.4.7`},main:`./dist/index.cjs`,module:`./dist/index.js`,types:`./dist/index.d.ts`,files:[`dist`,`bin`,`build`,`config`,`scripts`,`tools`],exports:{".":{types:`./dist/index.d.ts`,import:`./dist/index.js`,require:`./dist/index.cjs`},"./browser":{types:`./dist/components/browser/index.d.ts`,import:`./dist/components/browser/index.js`,require:`./dist/components/browser/index.cjs`},"./conversation":{types:`./dist/components/conversation/index.d.ts`,import:`./dist/components/conversation/index.js`,require:`./dist/components/conversation/index.cjs`},"./files":{types:`./dist/components/files/index.d.ts`,import:`./dist/components/files/index.js`,require:`./dist/components/files/index.cjs`},"./settings":{types:`./dist/components/settings/index.d.ts`,import:`./dist/components/settings/index.js`,require:`./dist/components/settings/index.cjs`},"./sidebar":{types:`./dist/components/sidebar/index.d.ts`,import:`./dist/components/sidebar/index.js`,require:`./dist/components/sidebar/index.cjs`},"./terminal":{types:`./dist/components/terminal/index.d.ts`,import:`./dist/components/terminal/index.js`,require:`./dist/components/terminal/index.cjs`},"./i18n":{types:`./dist/i18n/index.d.ts`,import:`./dist/i18n/index.js`,require:`./dist/i18n/index.cjs`},"./package.json":`./package.json`},peerDependencies:{react:`19.2.5`,"react-dom":`19.2.5`,"react-router":`7.17.0`}};exports.default=e;
|
|
2
2
|
//# sourceMappingURL=package.cjs.map
|
package/dist/package.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package.cjs","names":[],"sources":["../package.json"],"sourcesContent":["{\n \"name\": \"@openhands/agent-canvas\",\n \"version\": \"1.2.
|
|
1
|
+
{"version":3,"file":"package.cjs","names":[],"sources":["../package.json"],"sourcesContent":["{\n \"name\": \"@openhands/agent-canvas\",\n \"version\": \"1.2.1\",\n \"description\": \"Agent Canvas UI for OpenHands - run AI coding agents with a visual interface\",\n \"license\": \"MIT\",\n \"private\": false,\n \"type\": \"module\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/OpenHands/agent-canvas\"\n },\n \"homepage\": \"https://github.com/OpenHands/agent-canvas#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/OpenHands/agent-canvas/issues\"\n },\n \"bin\": {\n \"agent-canvas\": \"bin/agent-canvas.mjs\"\n },\n \"engines\": {\n \"node\": \">=22.12.0\"\n },\n \"dependencies\": {\n \"@heroui/react\": \"2.8.10\",\n \"@microlink/react-json-view\": \"1.31.20\",\n \"@monaco-editor/react\": \"4.7.0\",\n \"@openhands/extensions\": \"0.9.0\",\n \"@openhands/typescript-client\": \"1.32.1\",\n \"@react-router/node\": \"7.17.0\",\n \"@react-router/serve\": \"7.17.0\",\n \"@tailwindcss/vite\": \"4.2.4\",\n \"@tanstack/react-query\": \"5.100.9\",\n \"@types/shell-quote\": \"1.7.5\",\n \"@uidotdev/usehooks\": \"2.4.1\",\n \"@xterm/addon-fit\": \"0.11.0\",\n \"@xterm/xterm\": \"6.0.0\",\n \"axios\": \"1.16.0\",\n \"class-variance-authority\": \"0.7.1\",\n \"clsx\": \"2.1.1\",\n \"downshift\": \"9.3.2\",\n \"framer-motion\": \"12.38.0\",\n \"httpxy\": \"0.5.3\",\n \"i18next\": \"26.0.8\",\n \"i18next-browser-languagedetector\": \"8.2.1\",\n \"i18next-http-backend\": \"4.0.0\",\n \"isbot\": \"5.1.39\",\n \"lucide-react\": \"1.14.0\",\n \"monaco-editor\": \"0.55.1\",\n \"posthog-js\": \"1.372.6\",\n \"react\": \"19.2.5\",\n \"react-dom\": \"19.2.5\",\n \"react-hot-toast\": \"2.6.0\",\n \"react-i18next\": \"17.0.6\",\n \"react-icons\": \"5.6.0\",\n \"react-markdown\": \"10.1.0\",\n \"react-router\": \"7.17.0\",\n \"react-syntax-highlighter\": \"16.1.1\",\n \"rehype-raw\": \"7.0.0\",\n \"rehype-sanitize\": \"6.0.0\",\n \"remark-breaks\": \"4.0.0\",\n \"remark-gfm\": \"4.0.1\",\n \"shell-quote\": \"1.8.4\",\n \"sirv\": \"3.0.2\",\n \"sirv-cli\": \"3.0.1\",\n \"socket.io-client\": \"4.8.3\",\n \"tailwind-merge\": \"3.5.0\",\n \"tailwind-scrollbar\": \"4.0.2\",\n \"unist-util-visit\": \"5.1.0\",\n \"uuid\": \"14.0.0\",\n \"vite\": \"8.0.10\",\n \"winston\": \"3.19.0\",\n \"winston-daily-rotate-file\": \"5.0.0\",\n \"zustand\": \"5.0.12\"\n },\n \"scripts\": {\n \"dev\": \"node --env-file-if-exists=.env scripts/dev-with-automation.mjs\",\n \"dev:static\": \"node --env-file-if-exists=.env scripts/dev-static.mjs\",\n \"dev:extra-backend\": \"node --env-file-if-exists=.env scripts/dev-extra-backend.mjs\",\n \"dev:minimal\": \"node --env-file-if-exists=.env scripts/dev-safe.mjs\",\n \"dev:frontend\": \"npm run make-i18n && cross-env VITE_MOCK_API=false react-router dev\",\n \"dev:mock\": \"npm run make-i18n && cross-env VITE_MOCK_API=true react-router dev\",\n \"build\": \"npm run build:app\",\n \"build:mock\": \"npm run make-i18n && cross-env VITE_MOCK_API=true react-router build\",\n \"start\": \"npx sirv-cli build/ --single\",\n \"test\": \"npm run make-i18n && vitest run\",\n \"test:e2e\": \"playwright test --pass-with-no-tests\",\n \"test:e2e:live\": \"node --env-file-if-exists=.env tests/e2e/live/scripts/run-live-e2e.mjs\",\n \"test:e2e:mock-llm\": \"playwright test --config=playwright.mock-llm.config.ts\",\n \"test:e2e:mock-llm:docker\": \"playwright test --config=playwright.mock-llm-docker.config.ts\",\n \"test:coverage\": \"npm run make-i18n && vitest run --coverage\",\n \"dev_wsl\": \"VITE_WATCH_USE_POLLING=true vite\",\n \"preview\": \"vite preview\",\n \"make-i18n\": \"node scripts/make-i18n-translations.cjs\",\n \"prelint\": \"npm run make-i18n\",\n \"lint\": \"npm run typecheck && eslint src && prettier --check src/**/*.{ts,tsx}\",\n \"lint:fix\": \"eslint src --fix && prettier --write src/**/*.{ts,tsx}\",\n \"prepare\": \"husky\",\n \"typecheck\": \"react-router typegen && tsc\",\n \"typecheck:staged\": \"react-router typegen && npx tsc --noEmit --skipLibCheck\",\n \"check-translation-completeness\": \"node scripts/check-translation-completeness.cjs\",\n \"build:app\": \"npm run make-i18n && react-router build\",\n \"build:lib\": \"npm run make-i18n && react-router typegen && cross-env BUILD_LIB=true VITE_APP_ENV=production vite build && tsc -p tsconfig.lib.json\",\n \"build:docker\": \"node scripts/docker-build.mjs\",\n \"example:acp-docker:env\": \"node scripts/gen-acp-docker-env.mjs\"\n },\n \"lint-staged\": {\n \"src/**/*.{ts,tsx,js}\": [\n \"eslint --fix\",\n \"prettier --write\"\n ],\n \"src/**/*.{ts,tsx}\": [\n \"node scripts/run-staged-typecheck.mjs\"\n ],\n \"src/**/*\": [\n \"npm run check-translation-completeness\"\n ]\n },\n \"devDependencies\": {\n \"@eslint/eslintrc\": \"3.3.1\",\n \"@eslint/js\": \"9.39.4\",\n \"@mswjs/socket.io-binding\": \"0.2.0\",\n \"@playwright/test\": \"1.59.1\",\n \"@react-router/dev\": \"7.17.0\",\n \"@tailwindcss/typography\": \"0.5.19\",\n \"@tanstack/eslint-plugin-query\": \"5.100.9\",\n \"@testing-library/dom\": \"10.4.1\",\n \"@testing-library/jest-dom\": \"6.9.1\",\n \"@testing-library/react\": \"16.3.2\",\n \"@testing-library/user-event\": \"14.6.1\",\n \"@types/mdast\": \"4.0.4\",\n \"@types/node\": \"25.6.0\",\n \"@types/react\": \"19.2.14\",\n \"@types/react-dom\": \"19.2.3\",\n \"@types/react-syntax-highlighter\": \"15.5.13\",\n \"@typescript-eslint/eslint-plugin\": \"8.59.2\",\n \"@typescript-eslint/parser\": \"8.59.2\",\n \"@vercel/react-router\": \"1.3.0\",\n \"@vitest/coverage-v8\": \"4.1.5\",\n \"cross-env\": \"10.1.0\",\n \"eslint\": \"9.39.4\",\n \"eslint-config-prettier\": \"10.1.8\",\n \"eslint-import-resolver-typescript\": \"4.4.4\",\n \"eslint-plugin-i18next\": \"6.1.4\",\n \"eslint-plugin-import-x\": \"4.16.2\",\n \"eslint-plugin-jsx-a11y\": \"6.10.2\",\n \"eslint-plugin-prettier\": \"5.5.5\",\n \"eslint-plugin-react\": \"7.37.5\",\n \"eslint-plugin-react-hooks\": \"7.1.1\",\n \"eslint-plugin-unused-imports\": \"4.4.1\",\n \"globals\": \"16.5.0\",\n \"husky\": \"9.1.7\",\n \"jsdom\": \"29.1.1\",\n \"lint-staged\": \"16.4.0\",\n \"msw\": \"2.14.2\",\n \"postcss-prefix-selector\": \"2.1.1\",\n \"prettier\": \"3.8.3\",\n \"tailwindcss\": \"4.2.4\",\n \"typescript\": \"6.0.3\",\n \"vite-plugin-svgr\": \"5.2.0\",\n \"vitest\": \"4.1.5\"\n },\n \"packageManager\": \"npm@10.5.0\",\n \"volta\": {\n \"node\": \"22.12.0\"\n },\n \"msw\": {\n \"workerDirectory\": [\n \"public\"\n ]\n },\n \"overrides\": {\n \"@vercel/static-config\": {\n \"ajv\": \"8.20.0\"\n },\n \"dompurify\": \"3.4.7\"\n },\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"files\": [\n \"dist\",\n \"bin\",\n \"build\",\n \"config\",\n \"scripts\",\n \"tools\"\n ],\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n },\n \"./browser\": {\n \"types\": \"./dist/components/browser/index.d.ts\",\n \"import\": \"./dist/components/browser/index.js\",\n \"require\": \"./dist/components/browser/index.cjs\"\n },\n \"./conversation\": {\n \"types\": \"./dist/components/conversation/index.d.ts\",\n \"import\": \"./dist/components/conversation/index.js\",\n \"require\": \"./dist/components/conversation/index.cjs\"\n },\n \"./files\": {\n \"types\": \"./dist/components/files/index.d.ts\",\n \"import\": \"./dist/components/files/index.js\",\n \"require\": \"./dist/components/files/index.cjs\"\n },\n \"./settings\": {\n \"types\": \"./dist/components/settings/index.d.ts\",\n \"import\": \"./dist/components/settings/index.js\",\n \"require\": \"./dist/components/settings/index.cjs\"\n },\n \"./sidebar\": {\n \"types\": \"./dist/components/sidebar/index.d.ts\",\n \"import\": \"./dist/components/sidebar/index.js\",\n \"require\": \"./dist/components/sidebar/index.cjs\"\n },\n \"./terminal\": {\n \"types\": \"./dist/components/terminal/index.d.ts\",\n \"import\": \"./dist/components/terminal/index.js\",\n \"require\": \"./dist/components/terminal/index.cjs\"\n },\n \"./i18n\": {\n \"types\": \"./dist/i18n/index.d.ts\",\n \"import\": \"./dist/i18n/index.js\",\n \"require\": \"./dist/i18n/index.cjs\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"peerDependencies\": {\n \"react\": \"19.2.5\",\n \"react-dom\": \"19.2.5\",\n \"react-router\": \"7.17.0\"\n }\n}\n"],"mappings":""}
|
package/dist/package.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var e = {
|
|
2
2
|
name: "@openhands/agent-canvas",
|
|
3
|
-
version: "1.2.
|
|
3
|
+
version: "1.2.1",
|
|
4
4
|
description: "Agent Canvas UI for OpenHands - run AI coding agents with a visual interface",
|
|
5
5
|
license: "MIT",
|
|
6
6
|
private: !1,
|
|
@@ -17,7 +17,7 @@ var e = {
|
|
|
17
17
|
"@heroui/react": "2.8.10",
|
|
18
18
|
"@microlink/react-json-view": "1.31.20",
|
|
19
19
|
"@monaco-editor/react": "4.7.0",
|
|
20
|
-
"@openhands/extensions": "0.
|
|
20
|
+
"@openhands/extensions": "0.9.0",
|
|
21
21
|
"@openhands/typescript-client": "1.32.1",
|
|
22
22
|
"@react-router/node": "7.17.0",
|
|
23
23
|
"@react-router/serve": "7.17.0",
|
package/dist/package.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package.js","names":[],"sources":["../package.json"],"sourcesContent":["{\n \"name\": \"@openhands/agent-canvas\",\n \"version\": \"1.2.
|
|
1
|
+
{"version":3,"file":"package.js","names":[],"sources":["../package.json"],"sourcesContent":["{\n \"name\": \"@openhands/agent-canvas\",\n \"version\": \"1.2.1\",\n \"description\": \"Agent Canvas UI for OpenHands - run AI coding agents with a visual interface\",\n \"license\": \"MIT\",\n \"private\": false,\n \"type\": \"module\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/OpenHands/agent-canvas\"\n },\n \"homepage\": \"https://github.com/OpenHands/agent-canvas#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/OpenHands/agent-canvas/issues\"\n },\n \"bin\": {\n \"agent-canvas\": \"bin/agent-canvas.mjs\"\n },\n \"engines\": {\n \"node\": \">=22.12.0\"\n },\n \"dependencies\": {\n \"@heroui/react\": \"2.8.10\",\n \"@microlink/react-json-view\": \"1.31.20\",\n \"@monaco-editor/react\": \"4.7.0\",\n \"@openhands/extensions\": \"0.9.0\",\n \"@openhands/typescript-client\": \"1.32.1\",\n \"@react-router/node\": \"7.17.0\",\n \"@react-router/serve\": \"7.17.0\",\n \"@tailwindcss/vite\": \"4.2.4\",\n \"@tanstack/react-query\": \"5.100.9\",\n \"@types/shell-quote\": \"1.7.5\",\n \"@uidotdev/usehooks\": \"2.4.1\",\n \"@xterm/addon-fit\": \"0.11.0\",\n \"@xterm/xterm\": \"6.0.0\",\n \"axios\": \"1.16.0\",\n \"class-variance-authority\": \"0.7.1\",\n \"clsx\": \"2.1.1\",\n \"downshift\": \"9.3.2\",\n \"framer-motion\": \"12.38.0\",\n \"httpxy\": \"0.5.3\",\n \"i18next\": \"26.0.8\",\n \"i18next-browser-languagedetector\": \"8.2.1\",\n \"i18next-http-backend\": \"4.0.0\",\n \"isbot\": \"5.1.39\",\n \"lucide-react\": \"1.14.0\",\n \"monaco-editor\": \"0.55.1\",\n \"posthog-js\": \"1.372.6\",\n \"react\": \"19.2.5\",\n \"react-dom\": \"19.2.5\",\n \"react-hot-toast\": \"2.6.0\",\n \"react-i18next\": \"17.0.6\",\n \"react-icons\": \"5.6.0\",\n \"react-markdown\": \"10.1.0\",\n \"react-router\": \"7.17.0\",\n \"react-syntax-highlighter\": \"16.1.1\",\n \"rehype-raw\": \"7.0.0\",\n \"rehype-sanitize\": \"6.0.0\",\n \"remark-breaks\": \"4.0.0\",\n \"remark-gfm\": \"4.0.1\",\n \"shell-quote\": \"1.8.4\",\n \"sirv\": \"3.0.2\",\n \"sirv-cli\": \"3.0.1\",\n \"socket.io-client\": \"4.8.3\",\n \"tailwind-merge\": \"3.5.0\",\n \"tailwind-scrollbar\": \"4.0.2\",\n \"unist-util-visit\": \"5.1.0\",\n \"uuid\": \"14.0.0\",\n \"vite\": \"8.0.10\",\n \"winston\": \"3.19.0\",\n \"winston-daily-rotate-file\": \"5.0.0\",\n \"zustand\": \"5.0.12\"\n },\n \"scripts\": {\n \"dev\": \"node --env-file-if-exists=.env scripts/dev-with-automation.mjs\",\n \"dev:static\": \"node --env-file-if-exists=.env scripts/dev-static.mjs\",\n \"dev:extra-backend\": \"node --env-file-if-exists=.env scripts/dev-extra-backend.mjs\",\n \"dev:minimal\": \"node --env-file-if-exists=.env scripts/dev-safe.mjs\",\n \"dev:frontend\": \"npm run make-i18n && cross-env VITE_MOCK_API=false react-router dev\",\n \"dev:mock\": \"npm run make-i18n && cross-env VITE_MOCK_API=true react-router dev\",\n \"build\": \"npm run build:app\",\n \"build:mock\": \"npm run make-i18n && cross-env VITE_MOCK_API=true react-router build\",\n \"start\": \"npx sirv-cli build/ --single\",\n \"test\": \"npm run make-i18n && vitest run\",\n \"test:e2e\": \"playwright test --pass-with-no-tests\",\n \"test:e2e:live\": \"node --env-file-if-exists=.env tests/e2e/live/scripts/run-live-e2e.mjs\",\n \"test:e2e:mock-llm\": \"playwright test --config=playwright.mock-llm.config.ts\",\n \"test:e2e:mock-llm:docker\": \"playwright test --config=playwright.mock-llm-docker.config.ts\",\n \"test:coverage\": \"npm run make-i18n && vitest run --coverage\",\n \"dev_wsl\": \"VITE_WATCH_USE_POLLING=true vite\",\n \"preview\": \"vite preview\",\n \"make-i18n\": \"node scripts/make-i18n-translations.cjs\",\n \"prelint\": \"npm run make-i18n\",\n \"lint\": \"npm run typecheck && eslint src && prettier --check src/**/*.{ts,tsx}\",\n \"lint:fix\": \"eslint src --fix && prettier --write src/**/*.{ts,tsx}\",\n \"prepare\": \"husky\",\n \"typecheck\": \"react-router typegen && tsc\",\n \"typecheck:staged\": \"react-router typegen && npx tsc --noEmit --skipLibCheck\",\n \"check-translation-completeness\": \"node scripts/check-translation-completeness.cjs\",\n \"build:app\": \"npm run make-i18n && react-router build\",\n \"build:lib\": \"npm run make-i18n && react-router typegen && cross-env BUILD_LIB=true VITE_APP_ENV=production vite build && tsc -p tsconfig.lib.json\",\n \"build:docker\": \"node scripts/docker-build.mjs\",\n \"example:acp-docker:env\": \"node scripts/gen-acp-docker-env.mjs\"\n },\n \"lint-staged\": {\n \"src/**/*.{ts,tsx,js}\": [\n \"eslint --fix\",\n \"prettier --write\"\n ],\n \"src/**/*.{ts,tsx}\": [\n \"node scripts/run-staged-typecheck.mjs\"\n ],\n \"src/**/*\": [\n \"npm run check-translation-completeness\"\n ]\n },\n \"devDependencies\": {\n \"@eslint/eslintrc\": \"3.3.1\",\n \"@eslint/js\": \"9.39.4\",\n \"@mswjs/socket.io-binding\": \"0.2.0\",\n \"@playwright/test\": \"1.59.1\",\n \"@react-router/dev\": \"7.17.0\",\n \"@tailwindcss/typography\": \"0.5.19\",\n \"@tanstack/eslint-plugin-query\": \"5.100.9\",\n \"@testing-library/dom\": \"10.4.1\",\n \"@testing-library/jest-dom\": \"6.9.1\",\n \"@testing-library/react\": \"16.3.2\",\n \"@testing-library/user-event\": \"14.6.1\",\n \"@types/mdast\": \"4.0.4\",\n \"@types/node\": \"25.6.0\",\n \"@types/react\": \"19.2.14\",\n \"@types/react-dom\": \"19.2.3\",\n \"@types/react-syntax-highlighter\": \"15.5.13\",\n \"@typescript-eslint/eslint-plugin\": \"8.59.2\",\n \"@typescript-eslint/parser\": \"8.59.2\",\n \"@vercel/react-router\": \"1.3.0\",\n \"@vitest/coverage-v8\": \"4.1.5\",\n \"cross-env\": \"10.1.0\",\n \"eslint\": \"9.39.4\",\n \"eslint-config-prettier\": \"10.1.8\",\n \"eslint-import-resolver-typescript\": \"4.4.4\",\n \"eslint-plugin-i18next\": \"6.1.4\",\n \"eslint-plugin-import-x\": \"4.16.2\",\n \"eslint-plugin-jsx-a11y\": \"6.10.2\",\n \"eslint-plugin-prettier\": \"5.5.5\",\n \"eslint-plugin-react\": \"7.37.5\",\n \"eslint-plugin-react-hooks\": \"7.1.1\",\n \"eslint-plugin-unused-imports\": \"4.4.1\",\n \"globals\": \"16.5.0\",\n \"husky\": \"9.1.7\",\n \"jsdom\": \"29.1.1\",\n \"lint-staged\": \"16.4.0\",\n \"msw\": \"2.14.2\",\n \"postcss-prefix-selector\": \"2.1.1\",\n \"prettier\": \"3.8.3\",\n \"tailwindcss\": \"4.2.4\",\n \"typescript\": \"6.0.3\",\n \"vite-plugin-svgr\": \"5.2.0\",\n \"vitest\": \"4.1.5\"\n },\n \"packageManager\": \"npm@10.5.0\",\n \"volta\": {\n \"node\": \"22.12.0\"\n },\n \"msw\": {\n \"workerDirectory\": [\n \"public\"\n ]\n },\n \"overrides\": {\n \"@vercel/static-config\": {\n \"ajv\": \"8.20.0\"\n },\n \"dompurify\": \"3.4.7\"\n },\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"files\": [\n \"dist\",\n \"bin\",\n \"build\",\n \"config\",\n \"scripts\",\n \"tools\"\n ],\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n },\n \"./browser\": {\n \"types\": \"./dist/components/browser/index.d.ts\",\n \"import\": \"./dist/components/browser/index.js\",\n \"require\": \"./dist/components/browser/index.cjs\"\n },\n \"./conversation\": {\n \"types\": \"./dist/components/conversation/index.d.ts\",\n \"import\": \"./dist/components/conversation/index.js\",\n \"require\": \"./dist/components/conversation/index.cjs\"\n },\n \"./files\": {\n \"types\": \"./dist/components/files/index.d.ts\",\n \"import\": \"./dist/components/files/index.js\",\n \"require\": \"./dist/components/files/index.cjs\"\n },\n \"./settings\": {\n \"types\": \"./dist/components/settings/index.d.ts\",\n \"import\": \"./dist/components/settings/index.js\",\n \"require\": \"./dist/components/settings/index.cjs\"\n },\n \"./sidebar\": {\n \"types\": \"./dist/components/sidebar/index.d.ts\",\n \"import\": \"./dist/components/sidebar/index.js\",\n \"require\": \"./dist/components/sidebar/index.cjs\"\n },\n \"./terminal\": {\n \"types\": \"./dist/components/terminal/index.d.ts\",\n \"import\": \"./dist/components/terminal/index.js\",\n \"require\": \"./dist/components/terminal/index.cjs\"\n },\n \"./i18n\": {\n \"types\": \"./dist/i18n/index.d.ts\",\n \"import\": \"./dist/i18n/index.js\",\n \"require\": \"./dist/i18n/index.cjs\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"peerDependencies\": {\n \"react\": \"19.2.5\",\n \"react-dom\": \"19.2.5\",\n \"react-router\": \"7.17.0\"\n }\n}\n"],"mappings":""}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../styles/agent-server-ui-style-scope.cjs`);var t={50:`0 0% 96.86%`,100:`0 0% 92.55%`,200:`0 0% 86.27%`,300:`0 0% 74.51%`,400:`0 0% 59.22%`,500:`0 0% 45.1%`,600:`0 0% 33.73%`,700:`0 0% 25.1%`,800:`0 0% 19.22%`,850:`0 0% 15.69%`,900:`0 0% 12.55%`,950:`0 0% 9.41%`,975:`0 0% 6.27%`},n={"--cool-grey-50":`#F7F7F7`,"--cool-grey-100":`#ECECEC`,"--cool-grey-200":`#DCDCDC`,"--cool-grey-300":`#BEBEBE`,"--cool-grey-400":`#979797`,"--cool-grey-500":`#737373`,"--cool-grey-600":`#565656`,"--cool-grey-700":`#404040`,"--cool-grey-800":`#313131`,"--cool-grey-900":`#282828`,"--cool-grey-925":`#202020`,"--cool-grey-950":`#181818`,"--cool-grey-975":`#101010`},r={"--heroui-background":t[950],"--heroui-background-foreground":t[50],"--heroui-foreground-50":t[975],"--heroui-foreground-100":t[950],"--heroui-foreground-200":t[900],"--heroui-foreground-300":t[850],"--heroui-foreground-400":t[800],"--heroui-foreground-500":t[700],"--heroui-foreground-600":t[600],"--heroui-foreground-700":t[500],"--heroui-foreground-800":t[400],"--heroui-foreground-900":t[300],"--heroui-foreground":t[300],"--heroui-content1":t[900],"--heroui-content1-foreground":t[100],"--heroui-content2":t[850],"--heroui-content2-foreground":t[200],"--heroui-content3":t[800],"--heroui-content3-foreground":t[300],"--heroui-content4":t[700],"--heroui-content4-foreground":t[400],"--heroui-default-50":t[975],"--heroui-default-100":t[950],"--heroui-default-200":t[900],"--heroui-default-300":t[850],"--heroui-default-400":t[800],"--heroui-default-500":t[700],"--heroui-default-600":t[600],"--heroui-default-700":t[500],"--heroui-default-800":t[400],"--heroui-default-900":t[300],"--heroui-default-foreground":t[50],"--heroui-default":t[800]},i=e.AGENT_SERVER_UI_THEMEABLE_BRAND_VARIABLES,a={"openhands-deepsea":{label:`OpenHands-DeepSea`,scale:{"--cool-grey-50":`#F7F9FC`,"--cool-grey-100":`#EEF2F7`,"--cool-grey-200":`#DCE3EE`,"--cool-grey-300":`#C3CDDC`,"--cool-grey-400":`#A3B0C4`,"--cool-grey-500":`#7E8A9E`,"--cool-grey-600":`#626D82`,"--cool-grey-700":`#4B5468`,"--cool-grey-800":`#383F50`,"--cool-grey-900":`#2C313F`,"--cool-grey-925":`#21252F`,"--cool-grey-950":`#0B0E14`,"--cool-grey-975":`#05070A`},heroui:{"--heroui-background":`220 29.03% 6.08%`,"--heroui-background-foreground":`216 45.45% 97.84%`,"--heroui-foreground-50":`216 33.33% 2.94%`,"--heroui-foreground-100":`220 29.03% 6.08%`,"--heroui-foreground-200":`222.86 17.5% 15.69%`,"--heroui-foreground-300":`224.21 17.76% 20.98%`,"--heroui-foreground-400":`222.5 17.65% 26.67%`,"--heroui-foreground-500":`221.38 16.2% 35.1%`,"--heroui-foreground-600":`219.38 14.04% 44.71%`,"--heroui-foreground-700":`217.5 14.16% 55.69%`,"--heroui-foreground-800":`216.36 21.85% 70.39%`,"--heroui-foreground-900":`216 26.32% 81.37%`,"--heroui-foreground":`216 26.32% 81.37%`,"--heroui-content1":`222.86 17.5% 15.69%`,"--heroui-content1-foreground":`213.33 36% 95.1%`,"--heroui-content2":`224.21 17.76% 20.98%`,"--heroui-content2-foreground":`216.67 34.62% 89.8%`,"--heroui-content3":`222.5 17.65% 26.67%`,"--heroui-content3-foreground":`216 26.32% 81.37%`,"--heroui-content4":`221.38 16.2% 35.1%`,"--heroui-content4-foreground":`216.36 21.85% 70.39%`,"--heroui-default-50":`216 33.33% 2.94%`,"--heroui-default-100":`220 29.03% 6.08%`,"--heroui-default-200":`222.86 17.5% 15.69%`,"--heroui-default-300":`224.21 17.76% 20.98%`,"--heroui-default-400":`222.5 17.65% 26.67%`,"--heroui-default-500":`221.38 16.2% 35.1%`,"--heroui-default-600":`219.38 14.04% 44.71%`,"--heroui-default-700":`217.5 14.16% 55.69%`,"--heroui-default-800":`216.36 21.85% 70.39%`,"--heroui-default-900":`216 26.32% 81.37%`,"--heroui-default-foreground":`216 45.45% 97.84%`,"--heroui-default":`222.5 17.65% 26.67%`}},"openhands-neutral":{label:`OpenHands-Neutral`,scale:n,heroui:r},"openhands-neo":{label:`OpenHands-Neo`,scale:n,heroui:r,tokens:{"--oh-color-primary":`#ffffff`,"--oh-accent":`#ffffff`,"--oh-warning":`#ffffff`}}},o=`openhands-neutral`,s=Object.entries(a).map(([e,t])=>({key:e,label:t.label})),c=`openhands-color-theme`;function l(){if(typeof window>`u`)return o;try{let e=window.localStorage.getItem(c);if(e&&e in a)return e}catch{}return o}function u(e){try{window.localStorage.setItem(c,e)}catch{}}var d=`oh-color-theme-override`;function f(e){if(typeof document>`u`)return;let{scale:t,heroui:n,tokens:r={}}=a[e],i=Object.entries(t).map(([e,t])=>` ${e}: ${t};`).join(`
|
|
2
2
|
`),o=Object.entries(n).map(([e,t])=>` ${e}: ${t};`).join(`
|
|
3
|
-
`),s=[`[data-agent-server-ui] {\n${i}\n${o}\n${Object.entries(r).map(([e,t])=>` ${e}: ${t};`).join(`
|
|
4
|
-
`)}\n}`,`[data-theme=dark] {\n${o}\n}`].join(`
|
|
5
|
-
`),c=document.getElementById(d);c||(c=document.createElement(`style`),c.id=d,document.head.appendChild(c)
|
|
3
|
+
`),s=[`[data-agent-server-ui][data-agent-server-ui] {\n${i}\n${o}\n${Object.entries(r).map(([e,t])=>` ${e}: ${t};`).join(`
|
|
4
|
+
`)}\n}`,`[data-theme=dark][data-theme=dark] {\n${o}\n}`].join(`
|
|
5
|
+
`),c=document.getElementById(d);c||(c=document.createElement(`style`),c.id=d),c.textContent=s,document.head.appendChild(c),p(r)}function p(e){let t=document.querySelectorAll(`[data-agent-server-ui]`);for(let n of t)if(n instanceof HTMLElement)for(let t of i){let r=e[t];r?n.style.setProperty(t,r):n.style.removeProperty(t)}}exports.AVAILABLE_COLOR_THEMES=s,exports.applyColorTheme=f,exports.persistColorTheme=u,exports.readPersistedColorTheme=l;
|
|
6
6
|
//# sourceMappingURL=color-themes.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"color-themes.cjs","names":[],"sources":["../../src/themes/color-themes.ts"],"sourcesContent":["export type ColorThemeKey =\n | \"openhands-deepsea\"\n | \"openhands-neutral\"\n | \"openhands-neo\";\n\nexport interface ColorThemeDefinition {\n label: string;\n /** Overrides for --cool-grey-* CSS custom properties (our semantic scale) */\n scale: Record<string, string>;\n /**\n * Overrides for --heroui-* CSS custom properties.\n * HeroUI stores colors as space-separated HSL channels (\"H S% L%\") so Tailwind\n * utilities like bg-default-200 resolve to hsl(var(--heroui-default-200)).\n * These vars are set by the heroui() plugin on :root, [data-theme=dark] at\n * build time, so they must be overridden at the same or lower specificity\n * from a later stylesheet to pick up theme changes at runtime.\n */\n heroui: Record<string, string>;\n /** Overrides for --oh-* semantic tokens such as brand / button colors. */\n tokens?: Record<string, string>;\n}\n\n// HSL channel strings for the neutral grey palette (H=0, S=0%, L=hex/255*100)\n// prettier-ignore\nconst NEUTRAL_HSL = {\n 50: \"0 0% 96.86%\", // #F7F7F7\n 100: \"0 0% 92.55%\", // #ECECEC\n 200: \"0 0% 86.27%\", // #DCDCDC\n 300: \"0 0% 74.51%\", // #BEBEBE\n 400: \"0 0% 59.22%\", // #979797\n 500: \"0 0% 45.1%\", // #737373\n 600: \"0 0% 33.73%\", // #565656\n 700: \"0 0% 25.1%\", // #404040\n 800: \"0 0% 19.22%\", // #313131\n 850: \"0 0% 15.69%\", // #282828\n 900: \"0 0% 12.55%\", // #202020\n 950: \"0 0% 9.41%\", // #181818\n 975: \"0 0% 6.27%\", // #101010\n};\n\nconst NEUTRAL_SCALE = {\n \"--cool-grey-50\": \"#F7F7F7\",\n \"--cool-grey-100\": \"#ECECEC\",\n \"--cool-grey-200\": \"#DCDCDC\",\n \"--cool-grey-300\": \"#BEBEBE\",\n \"--cool-grey-400\": \"#979797\",\n \"--cool-grey-500\": \"#737373\",\n \"--cool-grey-600\": \"#565656\",\n \"--cool-grey-700\": \"#404040\",\n \"--cool-grey-800\": \"#313131\",\n \"--cool-grey-900\": \"#282828\",\n \"--cool-grey-925\": \"#202020\",\n \"--cool-grey-950\": \"#181818\",\n \"--cool-grey-975\": \"#101010\",\n};\n\nconst NEUTRAL_HEROUI = {\n \"--heroui-background\": NEUTRAL_HSL[950],\n \"--heroui-background-foreground\": NEUTRAL_HSL[50],\n \"--heroui-foreground-50\": NEUTRAL_HSL[975],\n \"--heroui-foreground-100\": NEUTRAL_HSL[950],\n \"--heroui-foreground-200\": NEUTRAL_HSL[900],\n \"--heroui-foreground-300\": NEUTRAL_HSL[850],\n \"--heroui-foreground-400\": NEUTRAL_HSL[800],\n \"--heroui-foreground-500\": NEUTRAL_HSL[700],\n \"--heroui-foreground-600\": NEUTRAL_HSL[600],\n \"--heroui-foreground-700\": NEUTRAL_HSL[500],\n \"--heroui-foreground-800\": NEUTRAL_HSL[400],\n \"--heroui-foreground-900\": NEUTRAL_HSL[300],\n \"--heroui-foreground\": NEUTRAL_HSL[300],\n \"--heroui-content1\": NEUTRAL_HSL[900],\n \"--heroui-content1-foreground\": NEUTRAL_HSL[100],\n \"--heroui-content2\": NEUTRAL_HSL[850],\n \"--heroui-content2-foreground\": NEUTRAL_HSL[200],\n \"--heroui-content3\": NEUTRAL_HSL[800],\n \"--heroui-content3-foreground\": NEUTRAL_HSL[300],\n \"--heroui-content4\": NEUTRAL_HSL[700],\n \"--heroui-content4-foreground\": NEUTRAL_HSL[400],\n \"--heroui-default-50\": NEUTRAL_HSL[975],\n \"--heroui-default-100\": NEUTRAL_HSL[950],\n \"--heroui-default-200\": NEUTRAL_HSL[900],\n \"--heroui-default-300\": NEUTRAL_HSL[850],\n \"--heroui-default-400\": NEUTRAL_HSL[800],\n \"--heroui-default-500\": NEUTRAL_HSL[700],\n \"--heroui-default-600\": NEUTRAL_HSL[600],\n \"--heroui-default-700\": NEUTRAL_HSL[500],\n \"--heroui-default-800\": NEUTRAL_HSL[400],\n \"--heroui-default-900\": NEUTRAL_HSL[300],\n \"--heroui-default-foreground\": NEUTRAL_HSL[50],\n \"--heroui-default\": NEUTRAL_HSL[800],\n};\n\nimport { AGENT_SERVER_UI_THEMEABLE_BRAND_VARIABLES } from \"#/styles/agent-server-ui-style-scope\";\n\n/** CSS custom properties overridden by color themes (see applyColorTheme). */\nexport const COLOR_THEME_TOKEN_KEYS = AGENT_SERVER_UI_THEMEABLE_BRAND_VARIABLES;\n\n/** White primary/accent tokens — used by OpenHands-Neo for button surfaces. */\nconst NEO_WHITE_BUTTON_TOKENS: Record<\n (typeof COLOR_THEME_TOKEN_KEYS)[number],\n string\n> = {\n \"--oh-color-primary\": \"#ffffff\",\n \"--oh-accent\": \"#ffffff\",\n \"--oh-warning\": \"#ffffff\",\n};\n\nexport const COLOR_THEMES: Record<ColorThemeKey, ColorThemeDefinition> = {\n \"openhands-deepsea\": {\n label: \"OpenHands-DeepSea\",\n // Matches the values already set by index.css; included so switching back\n // from another theme restores the original palette explicitly.\n scale: {\n \"--cool-grey-50\": \"#F7F9FC\",\n \"--cool-grey-100\": \"#EEF2F7\",\n \"--cool-grey-200\": \"#DCE3EE\",\n \"--cool-grey-300\": \"#C3CDDC\",\n \"--cool-grey-400\": \"#A3B0C4\",\n \"--cool-grey-500\": \"#7E8A9E\",\n \"--cool-grey-600\": \"#626D82\",\n \"--cool-grey-700\": \"#4B5468\",\n \"--cool-grey-800\": \"#383F50\",\n \"--cool-grey-900\": \"#2C313F\",\n \"--cool-grey-925\": \"#21252F\",\n \"--cool-grey-950\": \"#0B0E14\",\n \"--cool-grey-975\": \"#05070A\",\n },\n // Values generated by heroui() from hero.ts — restore them explicitly when\n // switching back from another theme.\n heroui: {\n \"--heroui-background\": \"220 29.03% 6.08%\",\n \"--heroui-background-foreground\": \"216 45.45% 97.84%\",\n \"--heroui-foreground-50\": \"216 33.33% 2.94%\",\n \"--heroui-foreground-100\": \"220 29.03% 6.08%\",\n \"--heroui-foreground-200\": \"222.86 17.5% 15.69%\",\n \"--heroui-foreground-300\": \"224.21 17.76% 20.98%\",\n \"--heroui-foreground-400\": \"222.5 17.65% 26.67%\",\n \"--heroui-foreground-500\": \"221.38 16.2% 35.1%\",\n \"--heroui-foreground-600\": \"219.38 14.04% 44.71%\",\n \"--heroui-foreground-700\": \"217.5 14.16% 55.69%\",\n \"--heroui-foreground-800\": \"216.36 21.85% 70.39%\",\n \"--heroui-foreground-900\": \"216 26.32% 81.37%\",\n \"--heroui-foreground\": \"216 26.32% 81.37%\",\n \"--heroui-content1\": \"222.86 17.5% 15.69%\",\n \"--heroui-content1-foreground\": \"213.33 36% 95.1%\",\n \"--heroui-content2\": \"224.21 17.76% 20.98%\",\n \"--heroui-content2-foreground\": \"216.67 34.62% 89.8%\",\n \"--heroui-content3\": \"222.5 17.65% 26.67%\",\n \"--heroui-content3-foreground\": \"216 26.32% 81.37%\",\n \"--heroui-content4\": \"221.38 16.2% 35.1%\",\n \"--heroui-content4-foreground\": \"216.36 21.85% 70.39%\",\n \"--heroui-default-50\": \"216 33.33% 2.94%\",\n \"--heroui-default-100\": \"220 29.03% 6.08%\",\n \"--heroui-default-200\": \"222.86 17.5% 15.69%\",\n \"--heroui-default-300\": \"224.21 17.76% 20.98%\",\n \"--heroui-default-400\": \"222.5 17.65% 26.67%\",\n \"--heroui-default-500\": \"221.38 16.2% 35.1%\",\n \"--heroui-default-600\": \"219.38 14.04% 44.71%\",\n \"--heroui-default-700\": \"217.5 14.16% 55.69%\",\n \"--heroui-default-800\": \"216.36 21.85% 70.39%\",\n \"--heroui-default-900\": \"216 26.32% 81.37%\",\n \"--heroui-default-foreground\": \"216 45.45% 97.84%\",\n \"--heroui-default\": \"222.5 17.65% 26.67%\",\n },\n },\n\n \"openhands-neutral\": {\n label: \"OpenHands-Neutral\",\n scale: NEUTRAL_SCALE,\n // Each stop follows the same positional mapping as hero.ts:\n // heroui-default-100 ← cool-grey-950 position ← neutral-950 (#181818)\n // heroui-default-200 ← cool-grey-925 position ← neutral-900 (#202020)\n // ...etc.\n heroui: NEUTRAL_HEROUI,\n },\n\n \"openhands-neo\": {\n label: \"OpenHands-Neo\",\n scale: NEUTRAL_SCALE,\n heroui: NEUTRAL_HEROUI,\n tokens: NEO_WHITE_BUTTON_TOKENS,\n },\n};\n\nexport const DEFAULT_COLOR_THEME: ColorThemeKey = \"openhands-neutral\";\n\nexport const AVAILABLE_COLOR_THEMES = Object.entries(COLOR_THEMES).map(\n ([key, def]) => ({ key: key as ColorThemeKey, label: def.label }),\n);\n\nconst STORAGE_KEY = \"openhands-color-theme\";\n\n/** Read the persisted theme key from localStorage, falling back to the default. */\nexport function readPersistedColorTheme(): ColorThemeKey {\n if (typeof window === \"undefined\") return DEFAULT_COLOR_THEME;\n try {\n const stored = window.localStorage.getItem(STORAGE_KEY);\n if (stored && stored in COLOR_THEMES) return stored as ColorThemeKey;\n } catch {\n // ignore quota / privacy-mode failures\n }\n return DEFAULT_COLOR_THEME;\n}\n\n/** Persist the theme key to localStorage. */\nexport function persistColorTheme(key: ColorThemeKey): void {\n try {\n window.localStorage.setItem(STORAGE_KEY, key);\n } catch {\n // ignore\n }\n}\n\nconst THEME_STYLE_TAG_ID = \"oh-color-theme-override\";\n\n/**\n * Apply a theme by injecting (or replacing) a <style> tag that overrides\n * both our custom --cool-grey-* primitives and HeroUI's --heroui-* tokens.\n *\n * Why a <style> tag:\n * PostCSS transforms :root / body to [data-agent-server-ui], so --cool-grey-*\n * is set on EVERY element carrying that attribute. A body inline-style only\n * overrides body itself — inner matching elements keep the stylesheet value.\n * Injecting a stylesheet appended to <head> wins on equal specificity because\n * later sheets take precedence in the cascade.\n *\n * Why heroui variables:\n * HeroUI stores colors as HSL channels in --heroui-* vars on [data-theme=dark].\n * They reference their own token system and are unaffected by --cool-grey-*\n * changes, so we override them from the same injected sheet.\n */\nexport function applyColorTheme(key: ColorThemeKey): void {\n if (typeof document === \"undefined\") return;\n const { scale, heroui, tokens = {} } = COLOR_THEMES[key];\n\n const scaleDecls = Object.entries(scale)\n .map(([p, v]) => ` ${p}: ${v};`)\n .join(\"\\n\");\n\n const herouiDecls = Object.entries(heroui)\n .map(([p, v]) => ` ${p}: ${v};`)\n .join(\"\\n\");\n\n const tokenDecls = Object.entries(tokens)\n .map(([p, v]) => ` ${p}: ${v};`)\n .join(\"\\n\");\n\n // Target both selectors for heroui vars:\n // [data-agent-server-ui] — covers document.body (portal destination) so\n // portalled popover/listbox content inherits the overridden values.\n // [data-theme=dark] — covers the inner AgentServerUIRoot wrapper so\n // components scoped inside the dark theme wrapper also pick them up.\n const css = [\n `[data-agent-server-ui] {\\n${scaleDecls}\\n${herouiDecls}\\n${tokenDecls}\\n}`,\n `[data-theme=dark] {\\n${herouiDecls}\\n}`,\n ].join(\"\\n\");\n\n let styleEl = document.getElementById(\n THEME_STYLE_TAG_ID,\n ) as HTMLStyleElement | null;\n if (!styleEl) {\n styleEl = document.createElement(\"style\");\n styleEl.id = THEME_STYLE_TAG_ID;\n document.head.appendChild(styleEl);\n }\n styleEl.textContent = css;\n\n syncColorThemeTokensOnScopeRoots(tokens);\n}\n\nfunction syncColorThemeTokensOnScopeRoots(\n tokens: Record<string, string>,\n): void {\n const roots = document.querySelectorAll(\"[data-agent-server-ui]\");\n for (const root of roots) {\n if (!(root instanceof HTMLElement)) continue;\n\n for (const key of COLOR_THEME_TOKEN_KEYS) {\n const value = tokens[key];\n if (value) {\n root.style.setProperty(key, value);\n } else {\n root.style.removeProperty(key);\n }\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"color-themes.cjs","names":[],"sources":["../../src/themes/color-themes.ts"],"sourcesContent":["export type ColorThemeKey =\n | \"openhands-deepsea\"\n | \"openhands-neutral\"\n | \"openhands-neo\";\n\nexport interface ColorThemeDefinition {\n label: string;\n /** Overrides for --cool-grey-* CSS custom properties (our semantic scale) */\n scale: Record<string, string>;\n /**\n * Overrides for --heroui-* CSS custom properties.\n * HeroUI stores colors as space-separated HSL channels (\"H S% L%\") so Tailwind\n * utilities like bg-default-200 resolve to hsl(var(--heroui-default-200)).\n * These vars are set by the heroui() plugin on :root, [data-theme=dark] at\n * build time, so they must be overridden at the same or lower specificity\n * from a later stylesheet to pick up theme changes at runtime.\n */\n heroui: Record<string, string>;\n /** Overrides for --oh-* semantic tokens such as brand / button colors. */\n tokens?: Record<string, string>;\n}\n\n// HSL channel strings for the neutral grey palette (H=0, S=0%, L=hex/255*100)\n// prettier-ignore\nconst NEUTRAL_HSL = {\n 50: \"0 0% 96.86%\", // #F7F7F7\n 100: \"0 0% 92.55%\", // #ECECEC\n 200: \"0 0% 86.27%\", // #DCDCDC\n 300: \"0 0% 74.51%\", // #BEBEBE\n 400: \"0 0% 59.22%\", // #979797\n 500: \"0 0% 45.1%\", // #737373\n 600: \"0 0% 33.73%\", // #565656\n 700: \"0 0% 25.1%\", // #404040\n 800: \"0 0% 19.22%\", // #313131\n 850: \"0 0% 15.69%\", // #282828\n 900: \"0 0% 12.55%\", // #202020\n 950: \"0 0% 9.41%\", // #181818\n 975: \"0 0% 6.27%\", // #101010\n};\n\nconst NEUTRAL_SCALE = {\n \"--cool-grey-50\": \"#F7F7F7\",\n \"--cool-grey-100\": \"#ECECEC\",\n \"--cool-grey-200\": \"#DCDCDC\",\n \"--cool-grey-300\": \"#BEBEBE\",\n \"--cool-grey-400\": \"#979797\",\n \"--cool-grey-500\": \"#737373\",\n \"--cool-grey-600\": \"#565656\",\n \"--cool-grey-700\": \"#404040\",\n \"--cool-grey-800\": \"#313131\",\n \"--cool-grey-900\": \"#282828\",\n \"--cool-grey-925\": \"#202020\",\n \"--cool-grey-950\": \"#181818\",\n \"--cool-grey-975\": \"#101010\",\n};\n\nconst NEUTRAL_HEROUI = {\n \"--heroui-background\": NEUTRAL_HSL[950],\n \"--heroui-background-foreground\": NEUTRAL_HSL[50],\n \"--heroui-foreground-50\": NEUTRAL_HSL[975],\n \"--heroui-foreground-100\": NEUTRAL_HSL[950],\n \"--heroui-foreground-200\": NEUTRAL_HSL[900],\n \"--heroui-foreground-300\": NEUTRAL_HSL[850],\n \"--heroui-foreground-400\": NEUTRAL_HSL[800],\n \"--heroui-foreground-500\": NEUTRAL_HSL[700],\n \"--heroui-foreground-600\": NEUTRAL_HSL[600],\n \"--heroui-foreground-700\": NEUTRAL_HSL[500],\n \"--heroui-foreground-800\": NEUTRAL_HSL[400],\n \"--heroui-foreground-900\": NEUTRAL_HSL[300],\n \"--heroui-foreground\": NEUTRAL_HSL[300],\n \"--heroui-content1\": NEUTRAL_HSL[900],\n \"--heroui-content1-foreground\": NEUTRAL_HSL[100],\n \"--heroui-content2\": NEUTRAL_HSL[850],\n \"--heroui-content2-foreground\": NEUTRAL_HSL[200],\n \"--heroui-content3\": NEUTRAL_HSL[800],\n \"--heroui-content3-foreground\": NEUTRAL_HSL[300],\n \"--heroui-content4\": NEUTRAL_HSL[700],\n \"--heroui-content4-foreground\": NEUTRAL_HSL[400],\n \"--heroui-default-50\": NEUTRAL_HSL[975],\n \"--heroui-default-100\": NEUTRAL_HSL[950],\n \"--heroui-default-200\": NEUTRAL_HSL[900],\n \"--heroui-default-300\": NEUTRAL_HSL[850],\n \"--heroui-default-400\": NEUTRAL_HSL[800],\n \"--heroui-default-500\": NEUTRAL_HSL[700],\n \"--heroui-default-600\": NEUTRAL_HSL[600],\n \"--heroui-default-700\": NEUTRAL_HSL[500],\n \"--heroui-default-800\": NEUTRAL_HSL[400],\n \"--heroui-default-900\": NEUTRAL_HSL[300],\n \"--heroui-default-foreground\": NEUTRAL_HSL[50],\n \"--heroui-default\": NEUTRAL_HSL[800],\n};\n\nimport { AGENT_SERVER_UI_THEMEABLE_BRAND_VARIABLES } from \"#/styles/agent-server-ui-style-scope\";\n\n/** CSS custom properties overridden by color themes (see applyColorTheme). */\nexport const COLOR_THEME_TOKEN_KEYS = AGENT_SERVER_UI_THEMEABLE_BRAND_VARIABLES;\n\n/** White primary/accent tokens — used by OpenHands-Neo for button surfaces. */\nconst NEO_WHITE_BUTTON_TOKENS: Record<\n (typeof COLOR_THEME_TOKEN_KEYS)[number],\n string\n> = {\n \"--oh-color-primary\": \"#ffffff\",\n \"--oh-accent\": \"#ffffff\",\n \"--oh-warning\": \"#ffffff\",\n};\n\nexport const COLOR_THEMES: Record<ColorThemeKey, ColorThemeDefinition> = {\n \"openhands-deepsea\": {\n label: \"OpenHands-DeepSea\",\n // Matches the values already set by index.css; included so switching back\n // from another theme restores the original palette explicitly.\n scale: {\n \"--cool-grey-50\": \"#F7F9FC\",\n \"--cool-grey-100\": \"#EEF2F7\",\n \"--cool-grey-200\": \"#DCE3EE\",\n \"--cool-grey-300\": \"#C3CDDC\",\n \"--cool-grey-400\": \"#A3B0C4\",\n \"--cool-grey-500\": \"#7E8A9E\",\n \"--cool-grey-600\": \"#626D82\",\n \"--cool-grey-700\": \"#4B5468\",\n \"--cool-grey-800\": \"#383F50\",\n \"--cool-grey-900\": \"#2C313F\",\n \"--cool-grey-925\": \"#21252F\",\n \"--cool-grey-950\": \"#0B0E14\",\n \"--cool-grey-975\": \"#05070A\",\n },\n // Values generated by heroui() from hero.ts — restore them explicitly when\n // switching back from another theme.\n heroui: {\n \"--heroui-background\": \"220 29.03% 6.08%\",\n \"--heroui-background-foreground\": \"216 45.45% 97.84%\",\n \"--heroui-foreground-50\": \"216 33.33% 2.94%\",\n \"--heroui-foreground-100\": \"220 29.03% 6.08%\",\n \"--heroui-foreground-200\": \"222.86 17.5% 15.69%\",\n \"--heroui-foreground-300\": \"224.21 17.76% 20.98%\",\n \"--heroui-foreground-400\": \"222.5 17.65% 26.67%\",\n \"--heroui-foreground-500\": \"221.38 16.2% 35.1%\",\n \"--heroui-foreground-600\": \"219.38 14.04% 44.71%\",\n \"--heroui-foreground-700\": \"217.5 14.16% 55.69%\",\n \"--heroui-foreground-800\": \"216.36 21.85% 70.39%\",\n \"--heroui-foreground-900\": \"216 26.32% 81.37%\",\n \"--heroui-foreground\": \"216 26.32% 81.37%\",\n \"--heroui-content1\": \"222.86 17.5% 15.69%\",\n \"--heroui-content1-foreground\": \"213.33 36% 95.1%\",\n \"--heroui-content2\": \"224.21 17.76% 20.98%\",\n \"--heroui-content2-foreground\": \"216.67 34.62% 89.8%\",\n \"--heroui-content3\": \"222.5 17.65% 26.67%\",\n \"--heroui-content3-foreground\": \"216 26.32% 81.37%\",\n \"--heroui-content4\": \"221.38 16.2% 35.1%\",\n \"--heroui-content4-foreground\": \"216.36 21.85% 70.39%\",\n \"--heroui-default-50\": \"216 33.33% 2.94%\",\n \"--heroui-default-100\": \"220 29.03% 6.08%\",\n \"--heroui-default-200\": \"222.86 17.5% 15.69%\",\n \"--heroui-default-300\": \"224.21 17.76% 20.98%\",\n \"--heroui-default-400\": \"222.5 17.65% 26.67%\",\n \"--heroui-default-500\": \"221.38 16.2% 35.1%\",\n \"--heroui-default-600\": \"219.38 14.04% 44.71%\",\n \"--heroui-default-700\": \"217.5 14.16% 55.69%\",\n \"--heroui-default-800\": \"216.36 21.85% 70.39%\",\n \"--heroui-default-900\": \"216 26.32% 81.37%\",\n \"--heroui-default-foreground\": \"216 45.45% 97.84%\",\n \"--heroui-default\": \"222.5 17.65% 26.67%\",\n },\n },\n\n \"openhands-neutral\": {\n label: \"OpenHands-Neutral\",\n scale: NEUTRAL_SCALE,\n // Each stop follows the same positional mapping as hero.ts:\n // heroui-default-100 ← cool-grey-950 position ← neutral-950 (#181818)\n // heroui-default-200 ← cool-grey-925 position ← neutral-900 (#202020)\n // ...etc.\n heroui: NEUTRAL_HEROUI,\n },\n\n \"openhands-neo\": {\n label: \"OpenHands-Neo\",\n scale: NEUTRAL_SCALE,\n heroui: NEUTRAL_HEROUI,\n tokens: NEO_WHITE_BUTTON_TOKENS,\n },\n};\n\nexport const DEFAULT_COLOR_THEME: ColorThemeKey = \"openhands-neutral\";\n\nexport const AVAILABLE_COLOR_THEMES = Object.entries(COLOR_THEMES).map(\n ([key, def]) => ({ key: key as ColorThemeKey, label: def.label }),\n);\n\nconst STORAGE_KEY = \"openhands-color-theme\";\n\n/** Read the persisted theme key from localStorage, falling back to the default. */\nexport function readPersistedColorTheme(): ColorThemeKey {\n if (typeof window === \"undefined\") return DEFAULT_COLOR_THEME;\n try {\n const stored = window.localStorage.getItem(STORAGE_KEY);\n if (stored && stored in COLOR_THEMES) return stored as ColorThemeKey;\n } catch {\n // ignore quota / privacy-mode failures\n }\n return DEFAULT_COLOR_THEME;\n}\n\n/** Persist the theme key to localStorage. */\nexport function persistColorTheme(key: ColorThemeKey): void {\n try {\n window.localStorage.setItem(STORAGE_KEY, key);\n } catch {\n // ignore\n }\n}\n\nconst THEME_STYLE_TAG_ID = \"oh-color-theme-override\";\n\n/**\n * Apply a theme by injecting (or replacing) a <style> tag that overrides\n * both our custom --cool-grey-* primitives and HeroUI's --heroui-* tokens.\n *\n * Why a <style> tag:\n * PostCSS transforms :root / body to [data-agent-server-ui], so --cool-grey-*\n * is set on EVERY element carrying that attribute. A body inline-style only\n * overrides body itself — inner matching elements keep the stylesheet value.\n *\n * Why heroui variables:\n * HeroUI stores colors as HSL channels in --heroui-* vars on [data-theme=dark].\n * They reference their own token system and are unaffected by --cool-grey-*\n * changes, so we override them from the same injected sheet.\n *\n * Why doubled selectors + re-append on every call:\n * \"Later sheet wins the tie\" cannot be relied on: in the built SPA\n * (ssr:false, prerendered shell) React 19 re-creates the <head> elements it\n * manages (<Meta/>/<Links/>) whenever the tree above the router remounts —\n * e.g. PostHogWrapper swapping in <PostHogProvider> once the analytics key\n * resolves, which only happens in builds with VITE_POSTHOG_CLIENT_KEY baked\n * (the published npm package / tagged Docker images). That re-inserts the\n * base stylesheet <link> AFTER this tag, which would let the base sheet's\n * unlayered [data-agent-server-ui] variable rules (0,1,0) win every tie.\n * Doubling the attribute selectors ([x][x], 0,2,0) beats them from any\n * position in <head>; re-appending on each apply keeps document order\n * favorable as well.\n */\nexport function applyColorTheme(key: ColorThemeKey): void {\n if (typeof document === \"undefined\") return;\n const { scale, heroui, tokens = {} } = COLOR_THEMES[key];\n\n const scaleDecls = Object.entries(scale)\n .map(([p, v]) => ` ${p}: ${v};`)\n .join(\"\\n\");\n\n const herouiDecls = Object.entries(heroui)\n .map(([p, v]) => ` ${p}: ${v};`)\n .join(\"\\n\");\n\n const tokenDecls = Object.entries(tokens)\n .map(([p, v]) => ` ${p}: ${v};`)\n .join(\"\\n\");\n\n // Target both selectors for heroui vars:\n // [data-agent-server-ui] — covers document.body (portal destination) so\n // portalled popover/listbox content inherits the overridden values.\n // [data-theme=dark] — covers the inner AgentServerUIRoot wrapper so\n // components scoped inside the dark theme wrapper also pick them up.\n // Both are doubled to out-specify the base sheet regardless of stylesheet\n // order (see the doc comment above).\n const css = [\n `[data-agent-server-ui][data-agent-server-ui] {\\n${scaleDecls}\\n${herouiDecls}\\n${tokenDecls}\\n}`,\n `[data-theme=dark][data-theme=dark] {\\n${herouiDecls}\\n}`,\n ].join(\"\\n\");\n\n let styleEl = document.getElementById(\n THEME_STYLE_TAG_ID,\n ) as HTMLStyleElement | null;\n if (!styleEl) {\n styleEl = document.createElement(\"style\");\n styleEl.id = THEME_STYLE_TAG_ID;\n }\n styleEl.textContent = css;\n // Re-append even when the tag already exists (appendChild relocates a\n // connected node) so the override also stays after any re-inserted <link>.\n document.head.appendChild(styleEl);\n\n syncColorThemeTokensOnScopeRoots(tokens);\n}\n\nfunction syncColorThemeTokensOnScopeRoots(\n tokens: Record<string, string>,\n): void {\n const roots = document.querySelectorAll(\"[data-agent-server-ui]\");\n for (const root of roots) {\n if (!(root instanceof HTMLElement)) continue;\n\n for (const key of COLOR_THEME_TOKEN_KEYS) {\n const value = tokens[key];\n if (value) {\n root.style.setProperty(key, value);\n } else {\n root.style.removeProperty(key);\n }\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -35,12 +35,23 @@ export declare function persistColorTheme(key: ColorThemeKey): void;
|
|
|
35
35
|
* PostCSS transforms :root / body to [data-agent-server-ui], so --cool-grey-*
|
|
36
36
|
* is set on EVERY element carrying that attribute. A body inline-style only
|
|
37
37
|
* overrides body itself — inner matching elements keep the stylesheet value.
|
|
38
|
-
* Injecting a stylesheet appended to <head> wins on equal specificity because
|
|
39
|
-
* later sheets take precedence in the cascade.
|
|
40
38
|
*
|
|
41
39
|
* Why heroui variables:
|
|
42
40
|
* HeroUI stores colors as HSL channels in --heroui-* vars on [data-theme=dark].
|
|
43
41
|
* They reference their own token system and are unaffected by --cool-grey-*
|
|
44
42
|
* changes, so we override them from the same injected sheet.
|
|
43
|
+
*
|
|
44
|
+
* Why doubled selectors + re-append on every call:
|
|
45
|
+
* "Later sheet wins the tie" cannot be relied on: in the built SPA
|
|
46
|
+
* (ssr:false, prerendered shell) React 19 re-creates the <head> elements it
|
|
47
|
+
* manages (<Meta/>/<Links/>) whenever the tree above the router remounts —
|
|
48
|
+
* e.g. PostHogWrapper swapping in <PostHogProvider> once the analytics key
|
|
49
|
+
* resolves, which only happens in builds with VITE_POSTHOG_CLIENT_KEY baked
|
|
50
|
+
* (the published npm package / tagged Docker images). That re-inserts the
|
|
51
|
+
* base stylesheet <link> AFTER this tag, which would let the base sheet's
|
|
52
|
+
* unlayered [data-agent-server-ui] variable rules (0,1,0) win every tie.
|
|
53
|
+
* Doubling the attribute selectors ([x][x], 0,2,0) beats them from any
|
|
54
|
+
* position in <head>; re-appending on each apply keeps document order
|
|
55
|
+
* favorable as well.
|
|
45
56
|
*/
|
|
46
57
|
export declare function applyColorTheme(key: ColorThemeKey): void;
|
|
@@ -151,8 +151,8 @@ function u(e) {
|
|
|
151
151
|
var d = "oh-color-theme-override";
|
|
152
152
|
function f(e) {
|
|
153
153
|
if (typeof document > "u") return;
|
|
154
|
-
let { scale: t, heroui: n, tokens: r = {} } = a[e], i = Object.entries(t).map(([e, t]) => ` ${e}: ${t};`).join("\n"), o = Object.entries(n).map(([e, t]) => ` ${e}: ${t};`).join("\n"), s = [`[data-agent-server-ui] {\n${i}\n${o}\n${Object.entries(r).map(([e, t]) => ` ${e}: ${t};`).join("\n")}\n}`, `[data-theme=dark] {\n${o}\n}`].join("\n"), c = document.getElementById(d);
|
|
155
|
-
c || (c = document.createElement("style"), c.id = d, document.head.appendChild(c)
|
|
154
|
+
let { scale: t, heroui: n, tokens: r = {} } = a[e], i = Object.entries(t).map(([e, t]) => ` ${e}: ${t};`).join("\n"), o = Object.entries(n).map(([e, t]) => ` ${e}: ${t};`).join("\n"), s = [`[data-agent-server-ui][data-agent-server-ui] {\n${i}\n${o}\n${Object.entries(r).map(([e, t]) => ` ${e}: ${t};`).join("\n")}\n}`, `[data-theme=dark][data-theme=dark] {\n${o}\n}`].join("\n"), c = document.getElementById(d);
|
|
155
|
+
c || (c = document.createElement("style"), c.id = d), c.textContent = s, document.head.appendChild(c), p(r);
|
|
156
156
|
}
|
|
157
157
|
function p(e) {
|
|
158
158
|
let t = document.querySelectorAll("[data-agent-server-ui]");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"color-themes.js","names":[],"sources":["../../src/themes/color-themes.ts"],"sourcesContent":["export type ColorThemeKey =\n | \"openhands-deepsea\"\n | \"openhands-neutral\"\n | \"openhands-neo\";\n\nexport interface ColorThemeDefinition {\n label: string;\n /** Overrides for --cool-grey-* CSS custom properties (our semantic scale) */\n scale: Record<string, string>;\n /**\n * Overrides for --heroui-* CSS custom properties.\n * HeroUI stores colors as space-separated HSL channels (\"H S% L%\") so Tailwind\n * utilities like bg-default-200 resolve to hsl(var(--heroui-default-200)).\n * These vars are set by the heroui() plugin on :root, [data-theme=dark] at\n * build time, so they must be overridden at the same or lower specificity\n * from a later stylesheet to pick up theme changes at runtime.\n */\n heroui: Record<string, string>;\n /** Overrides for --oh-* semantic tokens such as brand / button colors. */\n tokens?: Record<string, string>;\n}\n\n// HSL channel strings for the neutral grey palette (H=0, S=0%, L=hex/255*100)\n// prettier-ignore\nconst NEUTRAL_HSL = {\n 50: \"0 0% 96.86%\", // #F7F7F7\n 100: \"0 0% 92.55%\", // #ECECEC\n 200: \"0 0% 86.27%\", // #DCDCDC\n 300: \"0 0% 74.51%\", // #BEBEBE\n 400: \"0 0% 59.22%\", // #979797\n 500: \"0 0% 45.1%\", // #737373\n 600: \"0 0% 33.73%\", // #565656\n 700: \"0 0% 25.1%\", // #404040\n 800: \"0 0% 19.22%\", // #313131\n 850: \"0 0% 15.69%\", // #282828\n 900: \"0 0% 12.55%\", // #202020\n 950: \"0 0% 9.41%\", // #181818\n 975: \"0 0% 6.27%\", // #101010\n};\n\nconst NEUTRAL_SCALE = {\n \"--cool-grey-50\": \"#F7F7F7\",\n \"--cool-grey-100\": \"#ECECEC\",\n \"--cool-grey-200\": \"#DCDCDC\",\n \"--cool-grey-300\": \"#BEBEBE\",\n \"--cool-grey-400\": \"#979797\",\n \"--cool-grey-500\": \"#737373\",\n \"--cool-grey-600\": \"#565656\",\n \"--cool-grey-700\": \"#404040\",\n \"--cool-grey-800\": \"#313131\",\n \"--cool-grey-900\": \"#282828\",\n \"--cool-grey-925\": \"#202020\",\n \"--cool-grey-950\": \"#181818\",\n \"--cool-grey-975\": \"#101010\",\n};\n\nconst NEUTRAL_HEROUI = {\n \"--heroui-background\": NEUTRAL_HSL[950],\n \"--heroui-background-foreground\": NEUTRAL_HSL[50],\n \"--heroui-foreground-50\": NEUTRAL_HSL[975],\n \"--heroui-foreground-100\": NEUTRAL_HSL[950],\n \"--heroui-foreground-200\": NEUTRAL_HSL[900],\n \"--heroui-foreground-300\": NEUTRAL_HSL[850],\n \"--heroui-foreground-400\": NEUTRAL_HSL[800],\n \"--heroui-foreground-500\": NEUTRAL_HSL[700],\n \"--heroui-foreground-600\": NEUTRAL_HSL[600],\n \"--heroui-foreground-700\": NEUTRAL_HSL[500],\n \"--heroui-foreground-800\": NEUTRAL_HSL[400],\n \"--heroui-foreground-900\": NEUTRAL_HSL[300],\n \"--heroui-foreground\": NEUTRAL_HSL[300],\n \"--heroui-content1\": NEUTRAL_HSL[900],\n \"--heroui-content1-foreground\": NEUTRAL_HSL[100],\n \"--heroui-content2\": NEUTRAL_HSL[850],\n \"--heroui-content2-foreground\": NEUTRAL_HSL[200],\n \"--heroui-content3\": NEUTRAL_HSL[800],\n \"--heroui-content3-foreground\": NEUTRAL_HSL[300],\n \"--heroui-content4\": NEUTRAL_HSL[700],\n \"--heroui-content4-foreground\": NEUTRAL_HSL[400],\n \"--heroui-default-50\": NEUTRAL_HSL[975],\n \"--heroui-default-100\": NEUTRAL_HSL[950],\n \"--heroui-default-200\": NEUTRAL_HSL[900],\n \"--heroui-default-300\": NEUTRAL_HSL[850],\n \"--heroui-default-400\": NEUTRAL_HSL[800],\n \"--heroui-default-500\": NEUTRAL_HSL[700],\n \"--heroui-default-600\": NEUTRAL_HSL[600],\n \"--heroui-default-700\": NEUTRAL_HSL[500],\n \"--heroui-default-800\": NEUTRAL_HSL[400],\n \"--heroui-default-900\": NEUTRAL_HSL[300],\n \"--heroui-default-foreground\": NEUTRAL_HSL[50],\n \"--heroui-default\": NEUTRAL_HSL[800],\n};\n\nimport { AGENT_SERVER_UI_THEMEABLE_BRAND_VARIABLES } from \"#/styles/agent-server-ui-style-scope\";\n\n/** CSS custom properties overridden by color themes (see applyColorTheme). */\nexport const COLOR_THEME_TOKEN_KEYS = AGENT_SERVER_UI_THEMEABLE_BRAND_VARIABLES;\n\n/** White primary/accent tokens — used by OpenHands-Neo for button surfaces. */\nconst NEO_WHITE_BUTTON_TOKENS: Record<\n (typeof COLOR_THEME_TOKEN_KEYS)[number],\n string\n> = {\n \"--oh-color-primary\": \"#ffffff\",\n \"--oh-accent\": \"#ffffff\",\n \"--oh-warning\": \"#ffffff\",\n};\n\nexport const COLOR_THEMES: Record<ColorThemeKey, ColorThemeDefinition> = {\n \"openhands-deepsea\": {\n label: \"OpenHands-DeepSea\",\n // Matches the values already set by index.css; included so switching back\n // from another theme restores the original palette explicitly.\n scale: {\n \"--cool-grey-50\": \"#F7F9FC\",\n \"--cool-grey-100\": \"#EEF2F7\",\n \"--cool-grey-200\": \"#DCE3EE\",\n \"--cool-grey-300\": \"#C3CDDC\",\n \"--cool-grey-400\": \"#A3B0C4\",\n \"--cool-grey-500\": \"#7E8A9E\",\n \"--cool-grey-600\": \"#626D82\",\n \"--cool-grey-700\": \"#4B5468\",\n \"--cool-grey-800\": \"#383F50\",\n \"--cool-grey-900\": \"#2C313F\",\n \"--cool-grey-925\": \"#21252F\",\n \"--cool-grey-950\": \"#0B0E14\",\n \"--cool-grey-975\": \"#05070A\",\n },\n // Values generated by heroui() from hero.ts — restore them explicitly when\n // switching back from another theme.\n heroui: {\n \"--heroui-background\": \"220 29.03% 6.08%\",\n \"--heroui-background-foreground\": \"216 45.45% 97.84%\",\n \"--heroui-foreground-50\": \"216 33.33% 2.94%\",\n \"--heroui-foreground-100\": \"220 29.03% 6.08%\",\n \"--heroui-foreground-200\": \"222.86 17.5% 15.69%\",\n \"--heroui-foreground-300\": \"224.21 17.76% 20.98%\",\n \"--heroui-foreground-400\": \"222.5 17.65% 26.67%\",\n \"--heroui-foreground-500\": \"221.38 16.2% 35.1%\",\n \"--heroui-foreground-600\": \"219.38 14.04% 44.71%\",\n \"--heroui-foreground-700\": \"217.5 14.16% 55.69%\",\n \"--heroui-foreground-800\": \"216.36 21.85% 70.39%\",\n \"--heroui-foreground-900\": \"216 26.32% 81.37%\",\n \"--heroui-foreground\": \"216 26.32% 81.37%\",\n \"--heroui-content1\": \"222.86 17.5% 15.69%\",\n \"--heroui-content1-foreground\": \"213.33 36% 95.1%\",\n \"--heroui-content2\": \"224.21 17.76% 20.98%\",\n \"--heroui-content2-foreground\": \"216.67 34.62% 89.8%\",\n \"--heroui-content3\": \"222.5 17.65% 26.67%\",\n \"--heroui-content3-foreground\": \"216 26.32% 81.37%\",\n \"--heroui-content4\": \"221.38 16.2% 35.1%\",\n \"--heroui-content4-foreground\": \"216.36 21.85% 70.39%\",\n \"--heroui-default-50\": \"216 33.33% 2.94%\",\n \"--heroui-default-100\": \"220 29.03% 6.08%\",\n \"--heroui-default-200\": \"222.86 17.5% 15.69%\",\n \"--heroui-default-300\": \"224.21 17.76% 20.98%\",\n \"--heroui-default-400\": \"222.5 17.65% 26.67%\",\n \"--heroui-default-500\": \"221.38 16.2% 35.1%\",\n \"--heroui-default-600\": \"219.38 14.04% 44.71%\",\n \"--heroui-default-700\": \"217.5 14.16% 55.69%\",\n \"--heroui-default-800\": \"216.36 21.85% 70.39%\",\n \"--heroui-default-900\": \"216 26.32% 81.37%\",\n \"--heroui-default-foreground\": \"216 45.45% 97.84%\",\n \"--heroui-default\": \"222.5 17.65% 26.67%\",\n },\n },\n\n \"openhands-neutral\": {\n label: \"OpenHands-Neutral\",\n scale: NEUTRAL_SCALE,\n // Each stop follows the same positional mapping as hero.ts:\n // heroui-default-100 ← cool-grey-950 position ← neutral-950 (#181818)\n // heroui-default-200 ← cool-grey-925 position ← neutral-900 (#202020)\n // ...etc.\n heroui: NEUTRAL_HEROUI,\n },\n\n \"openhands-neo\": {\n label: \"OpenHands-Neo\",\n scale: NEUTRAL_SCALE,\n heroui: NEUTRAL_HEROUI,\n tokens: NEO_WHITE_BUTTON_TOKENS,\n },\n};\n\nexport const DEFAULT_COLOR_THEME: ColorThemeKey = \"openhands-neutral\";\n\nexport const AVAILABLE_COLOR_THEMES = Object.entries(COLOR_THEMES).map(\n ([key, def]) => ({ key: key as ColorThemeKey, label: def.label }),\n);\n\nconst STORAGE_KEY = \"openhands-color-theme\";\n\n/** Read the persisted theme key from localStorage, falling back to the default. */\nexport function readPersistedColorTheme(): ColorThemeKey {\n if (typeof window === \"undefined\") return DEFAULT_COLOR_THEME;\n try {\n const stored = window.localStorage.getItem(STORAGE_KEY);\n if (stored && stored in COLOR_THEMES) return stored as ColorThemeKey;\n } catch {\n // ignore quota / privacy-mode failures\n }\n return DEFAULT_COLOR_THEME;\n}\n\n/** Persist the theme key to localStorage. */\nexport function persistColorTheme(key: ColorThemeKey): void {\n try {\n window.localStorage.setItem(STORAGE_KEY, key);\n } catch {\n // ignore\n }\n}\n\nconst THEME_STYLE_TAG_ID = \"oh-color-theme-override\";\n\n/**\n * Apply a theme by injecting (or replacing) a <style> tag that overrides\n * both our custom --cool-grey-* primitives and HeroUI's --heroui-* tokens.\n *\n * Why a <style> tag:\n * PostCSS transforms :root / body to [data-agent-server-ui], so --cool-grey-*\n * is set on EVERY element carrying that attribute. A body inline-style only\n * overrides body itself — inner matching elements keep the stylesheet value.\n * Injecting a stylesheet appended to <head> wins on equal specificity because\n * later sheets take precedence in the cascade.\n *\n * Why heroui variables:\n * HeroUI stores colors as HSL channels in --heroui-* vars on [data-theme=dark].\n * They reference their own token system and are unaffected by --cool-grey-*\n * changes, so we override them from the same injected sheet.\n */\nexport function applyColorTheme(key: ColorThemeKey): void {\n if (typeof document === \"undefined\") return;\n const { scale, heroui, tokens = {} } = COLOR_THEMES[key];\n\n const scaleDecls = Object.entries(scale)\n .map(([p, v]) => ` ${p}: ${v};`)\n .join(\"\\n\");\n\n const herouiDecls = Object.entries(heroui)\n .map(([p, v]) => ` ${p}: ${v};`)\n .join(\"\\n\");\n\n const tokenDecls = Object.entries(tokens)\n .map(([p, v]) => ` ${p}: ${v};`)\n .join(\"\\n\");\n\n // Target both selectors for heroui vars:\n // [data-agent-server-ui] — covers document.body (portal destination) so\n // portalled popover/listbox content inherits the overridden values.\n // [data-theme=dark] — covers the inner AgentServerUIRoot wrapper so\n // components scoped inside the dark theme wrapper also pick them up.\n const css = [\n `[data-agent-server-ui] {\\n${scaleDecls}\\n${herouiDecls}\\n${tokenDecls}\\n}`,\n `[data-theme=dark] {\\n${herouiDecls}\\n}`,\n ].join(\"\\n\");\n\n let styleEl = document.getElementById(\n THEME_STYLE_TAG_ID,\n ) as HTMLStyleElement | null;\n if (!styleEl) {\n styleEl = document.createElement(\"style\");\n styleEl.id = THEME_STYLE_TAG_ID;\n document.head.appendChild(styleEl);\n }\n styleEl.textContent = css;\n\n syncColorThemeTokensOnScopeRoots(tokens);\n}\n\nfunction syncColorThemeTokensOnScopeRoots(\n tokens: Record<string, string>,\n): void {\n const roots = document.querySelectorAll(\"[data-agent-server-ui]\");\n for (const root of roots) {\n if (!(root instanceof HTMLElement)) continue;\n\n for (const key of COLOR_THEME_TOKEN_KEYS) {\n const value = tokens[key];\n if (value) {\n root.style.setProperty(key, value);\n } else {\n root.style.removeProperty(key);\n }\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"color-themes.js","names":[],"sources":["../../src/themes/color-themes.ts"],"sourcesContent":["export type ColorThemeKey =\n | \"openhands-deepsea\"\n | \"openhands-neutral\"\n | \"openhands-neo\";\n\nexport interface ColorThemeDefinition {\n label: string;\n /** Overrides for --cool-grey-* CSS custom properties (our semantic scale) */\n scale: Record<string, string>;\n /**\n * Overrides for --heroui-* CSS custom properties.\n * HeroUI stores colors as space-separated HSL channels (\"H S% L%\") so Tailwind\n * utilities like bg-default-200 resolve to hsl(var(--heroui-default-200)).\n * These vars are set by the heroui() plugin on :root, [data-theme=dark] at\n * build time, so they must be overridden at the same or lower specificity\n * from a later stylesheet to pick up theme changes at runtime.\n */\n heroui: Record<string, string>;\n /** Overrides for --oh-* semantic tokens such as brand / button colors. */\n tokens?: Record<string, string>;\n}\n\n// HSL channel strings for the neutral grey palette (H=0, S=0%, L=hex/255*100)\n// prettier-ignore\nconst NEUTRAL_HSL = {\n 50: \"0 0% 96.86%\", // #F7F7F7\n 100: \"0 0% 92.55%\", // #ECECEC\n 200: \"0 0% 86.27%\", // #DCDCDC\n 300: \"0 0% 74.51%\", // #BEBEBE\n 400: \"0 0% 59.22%\", // #979797\n 500: \"0 0% 45.1%\", // #737373\n 600: \"0 0% 33.73%\", // #565656\n 700: \"0 0% 25.1%\", // #404040\n 800: \"0 0% 19.22%\", // #313131\n 850: \"0 0% 15.69%\", // #282828\n 900: \"0 0% 12.55%\", // #202020\n 950: \"0 0% 9.41%\", // #181818\n 975: \"0 0% 6.27%\", // #101010\n};\n\nconst NEUTRAL_SCALE = {\n \"--cool-grey-50\": \"#F7F7F7\",\n \"--cool-grey-100\": \"#ECECEC\",\n \"--cool-grey-200\": \"#DCDCDC\",\n \"--cool-grey-300\": \"#BEBEBE\",\n \"--cool-grey-400\": \"#979797\",\n \"--cool-grey-500\": \"#737373\",\n \"--cool-grey-600\": \"#565656\",\n \"--cool-grey-700\": \"#404040\",\n \"--cool-grey-800\": \"#313131\",\n \"--cool-grey-900\": \"#282828\",\n \"--cool-grey-925\": \"#202020\",\n \"--cool-grey-950\": \"#181818\",\n \"--cool-grey-975\": \"#101010\",\n};\n\nconst NEUTRAL_HEROUI = {\n \"--heroui-background\": NEUTRAL_HSL[950],\n \"--heroui-background-foreground\": NEUTRAL_HSL[50],\n \"--heroui-foreground-50\": NEUTRAL_HSL[975],\n \"--heroui-foreground-100\": NEUTRAL_HSL[950],\n \"--heroui-foreground-200\": NEUTRAL_HSL[900],\n \"--heroui-foreground-300\": NEUTRAL_HSL[850],\n \"--heroui-foreground-400\": NEUTRAL_HSL[800],\n \"--heroui-foreground-500\": NEUTRAL_HSL[700],\n \"--heroui-foreground-600\": NEUTRAL_HSL[600],\n \"--heroui-foreground-700\": NEUTRAL_HSL[500],\n \"--heroui-foreground-800\": NEUTRAL_HSL[400],\n \"--heroui-foreground-900\": NEUTRAL_HSL[300],\n \"--heroui-foreground\": NEUTRAL_HSL[300],\n \"--heroui-content1\": NEUTRAL_HSL[900],\n \"--heroui-content1-foreground\": NEUTRAL_HSL[100],\n \"--heroui-content2\": NEUTRAL_HSL[850],\n \"--heroui-content2-foreground\": NEUTRAL_HSL[200],\n \"--heroui-content3\": NEUTRAL_HSL[800],\n \"--heroui-content3-foreground\": NEUTRAL_HSL[300],\n \"--heroui-content4\": NEUTRAL_HSL[700],\n \"--heroui-content4-foreground\": NEUTRAL_HSL[400],\n \"--heroui-default-50\": NEUTRAL_HSL[975],\n \"--heroui-default-100\": NEUTRAL_HSL[950],\n \"--heroui-default-200\": NEUTRAL_HSL[900],\n \"--heroui-default-300\": NEUTRAL_HSL[850],\n \"--heroui-default-400\": NEUTRAL_HSL[800],\n \"--heroui-default-500\": NEUTRAL_HSL[700],\n \"--heroui-default-600\": NEUTRAL_HSL[600],\n \"--heroui-default-700\": NEUTRAL_HSL[500],\n \"--heroui-default-800\": NEUTRAL_HSL[400],\n \"--heroui-default-900\": NEUTRAL_HSL[300],\n \"--heroui-default-foreground\": NEUTRAL_HSL[50],\n \"--heroui-default\": NEUTRAL_HSL[800],\n};\n\nimport { AGENT_SERVER_UI_THEMEABLE_BRAND_VARIABLES } from \"#/styles/agent-server-ui-style-scope\";\n\n/** CSS custom properties overridden by color themes (see applyColorTheme). */\nexport const COLOR_THEME_TOKEN_KEYS = AGENT_SERVER_UI_THEMEABLE_BRAND_VARIABLES;\n\n/** White primary/accent tokens — used by OpenHands-Neo for button surfaces. */\nconst NEO_WHITE_BUTTON_TOKENS: Record<\n (typeof COLOR_THEME_TOKEN_KEYS)[number],\n string\n> = {\n \"--oh-color-primary\": \"#ffffff\",\n \"--oh-accent\": \"#ffffff\",\n \"--oh-warning\": \"#ffffff\",\n};\n\nexport const COLOR_THEMES: Record<ColorThemeKey, ColorThemeDefinition> = {\n \"openhands-deepsea\": {\n label: \"OpenHands-DeepSea\",\n // Matches the values already set by index.css; included so switching back\n // from another theme restores the original palette explicitly.\n scale: {\n \"--cool-grey-50\": \"#F7F9FC\",\n \"--cool-grey-100\": \"#EEF2F7\",\n \"--cool-grey-200\": \"#DCE3EE\",\n \"--cool-grey-300\": \"#C3CDDC\",\n \"--cool-grey-400\": \"#A3B0C4\",\n \"--cool-grey-500\": \"#7E8A9E\",\n \"--cool-grey-600\": \"#626D82\",\n \"--cool-grey-700\": \"#4B5468\",\n \"--cool-grey-800\": \"#383F50\",\n \"--cool-grey-900\": \"#2C313F\",\n \"--cool-grey-925\": \"#21252F\",\n \"--cool-grey-950\": \"#0B0E14\",\n \"--cool-grey-975\": \"#05070A\",\n },\n // Values generated by heroui() from hero.ts — restore them explicitly when\n // switching back from another theme.\n heroui: {\n \"--heroui-background\": \"220 29.03% 6.08%\",\n \"--heroui-background-foreground\": \"216 45.45% 97.84%\",\n \"--heroui-foreground-50\": \"216 33.33% 2.94%\",\n \"--heroui-foreground-100\": \"220 29.03% 6.08%\",\n \"--heroui-foreground-200\": \"222.86 17.5% 15.69%\",\n \"--heroui-foreground-300\": \"224.21 17.76% 20.98%\",\n \"--heroui-foreground-400\": \"222.5 17.65% 26.67%\",\n \"--heroui-foreground-500\": \"221.38 16.2% 35.1%\",\n \"--heroui-foreground-600\": \"219.38 14.04% 44.71%\",\n \"--heroui-foreground-700\": \"217.5 14.16% 55.69%\",\n \"--heroui-foreground-800\": \"216.36 21.85% 70.39%\",\n \"--heroui-foreground-900\": \"216 26.32% 81.37%\",\n \"--heroui-foreground\": \"216 26.32% 81.37%\",\n \"--heroui-content1\": \"222.86 17.5% 15.69%\",\n \"--heroui-content1-foreground\": \"213.33 36% 95.1%\",\n \"--heroui-content2\": \"224.21 17.76% 20.98%\",\n \"--heroui-content2-foreground\": \"216.67 34.62% 89.8%\",\n \"--heroui-content3\": \"222.5 17.65% 26.67%\",\n \"--heroui-content3-foreground\": \"216 26.32% 81.37%\",\n \"--heroui-content4\": \"221.38 16.2% 35.1%\",\n \"--heroui-content4-foreground\": \"216.36 21.85% 70.39%\",\n \"--heroui-default-50\": \"216 33.33% 2.94%\",\n \"--heroui-default-100\": \"220 29.03% 6.08%\",\n \"--heroui-default-200\": \"222.86 17.5% 15.69%\",\n \"--heroui-default-300\": \"224.21 17.76% 20.98%\",\n \"--heroui-default-400\": \"222.5 17.65% 26.67%\",\n \"--heroui-default-500\": \"221.38 16.2% 35.1%\",\n \"--heroui-default-600\": \"219.38 14.04% 44.71%\",\n \"--heroui-default-700\": \"217.5 14.16% 55.69%\",\n \"--heroui-default-800\": \"216.36 21.85% 70.39%\",\n \"--heroui-default-900\": \"216 26.32% 81.37%\",\n \"--heroui-default-foreground\": \"216 45.45% 97.84%\",\n \"--heroui-default\": \"222.5 17.65% 26.67%\",\n },\n },\n\n \"openhands-neutral\": {\n label: \"OpenHands-Neutral\",\n scale: NEUTRAL_SCALE,\n // Each stop follows the same positional mapping as hero.ts:\n // heroui-default-100 ← cool-grey-950 position ← neutral-950 (#181818)\n // heroui-default-200 ← cool-grey-925 position ← neutral-900 (#202020)\n // ...etc.\n heroui: NEUTRAL_HEROUI,\n },\n\n \"openhands-neo\": {\n label: \"OpenHands-Neo\",\n scale: NEUTRAL_SCALE,\n heroui: NEUTRAL_HEROUI,\n tokens: NEO_WHITE_BUTTON_TOKENS,\n },\n};\n\nexport const DEFAULT_COLOR_THEME: ColorThemeKey = \"openhands-neutral\";\n\nexport const AVAILABLE_COLOR_THEMES = Object.entries(COLOR_THEMES).map(\n ([key, def]) => ({ key: key as ColorThemeKey, label: def.label }),\n);\n\nconst STORAGE_KEY = \"openhands-color-theme\";\n\n/** Read the persisted theme key from localStorage, falling back to the default. */\nexport function readPersistedColorTheme(): ColorThemeKey {\n if (typeof window === \"undefined\") return DEFAULT_COLOR_THEME;\n try {\n const stored = window.localStorage.getItem(STORAGE_KEY);\n if (stored && stored in COLOR_THEMES) return stored as ColorThemeKey;\n } catch {\n // ignore quota / privacy-mode failures\n }\n return DEFAULT_COLOR_THEME;\n}\n\n/** Persist the theme key to localStorage. */\nexport function persistColorTheme(key: ColorThemeKey): void {\n try {\n window.localStorage.setItem(STORAGE_KEY, key);\n } catch {\n // ignore\n }\n}\n\nconst THEME_STYLE_TAG_ID = \"oh-color-theme-override\";\n\n/**\n * Apply a theme by injecting (or replacing) a <style> tag that overrides\n * both our custom --cool-grey-* primitives and HeroUI's --heroui-* tokens.\n *\n * Why a <style> tag:\n * PostCSS transforms :root / body to [data-agent-server-ui], so --cool-grey-*\n * is set on EVERY element carrying that attribute. A body inline-style only\n * overrides body itself — inner matching elements keep the stylesheet value.\n *\n * Why heroui variables:\n * HeroUI stores colors as HSL channels in --heroui-* vars on [data-theme=dark].\n * They reference their own token system and are unaffected by --cool-grey-*\n * changes, so we override them from the same injected sheet.\n *\n * Why doubled selectors + re-append on every call:\n * \"Later sheet wins the tie\" cannot be relied on: in the built SPA\n * (ssr:false, prerendered shell) React 19 re-creates the <head> elements it\n * manages (<Meta/>/<Links/>) whenever the tree above the router remounts —\n * e.g. PostHogWrapper swapping in <PostHogProvider> once the analytics key\n * resolves, which only happens in builds with VITE_POSTHOG_CLIENT_KEY baked\n * (the published npm package / tagged Docker images). That re-inserts the\n * base stylesheet <link> AFTER this tag, which would let the base sheet's\n * unlayered [data-agent-server-ui] variable rules (0,1,0) win every tie.\n * Doubling the attribute selectors ([x][x], 0,2,0) beats them from any\n * position in <head>; re-appending on each apply keeps document order\n * favorable as well.\n */\nexport function applyColorTheme(key: ColorThemeKey): void {\n if (typeof document === \"undefined\") return;\n const { scale, heroui, tokens = {} } = COLOR_THEMES[key];\n\n const scaleDecls = Object.entries(scale)\n .map(([p, v]) => ` ${p}: ${v};`)\n .join(\"\\n\");\n\n const herouiDecls = Object.entries(heroui)\n .map(([p, v]) => ` ${p}: ${v};`)\n .join(\"\\n\");\n\n const tokenDecls = Object.entries(tokens)\n .map(([p, v]) => ` ${p}: ${v};`)\n .join(\"\\n\");\n\n // Target both selectors for heroui vars:\n // [data-agent-server-ui] — covers document.body (portal destination) so\n // portalled popover/listbox content inherits the overridden values.\n // [data-theme=dark] — covers the inner AgentServerUIRoot wrapper so\n // components scoped inside the dark theme wrapper also pick them up.\n // Both are doubled to out-specify the base sheet regardless of stylesheet\n // order (see the doc comment above).\n const css = [\n `[data-agent-server-ui][data-agent-server-ui] {\\n${scaleDecls}\\n${herouiDecls}\\n${tokenDecls}\\n}`,\n `[data-theme=dark][data-theme=dark] {\\n${herouiDecls}\\n}`,\n ].join(\"\\n\");\n\n let styleEl = document.getElementById(\n THEME_STYLE_TAG_ID,\n ) as HTMLStyleElement | null;\n if (!styleEl) {\n styleEl = document.createElement(\"style\");\n styleEl.id = THEME_STYLE_TAG_ID;\n }\n styleEl.textContent = css;\n // Re-append even when the tag already exists (appendChild relocates a\n // connected node) so the override also stays after any re-inserted <link>.\n document.head.appendChild(styleEl);\n\n syncColorThemeTokensOnScopeRoots(tokens);\n}\n\nfunction syncColorThemeTokensOnScopeRoots(\n tokens: Record<string, string>,\n): void {\n const roots = document.querySelectorAll(\"[data-agent-server-ui]\");\n for (const root of roots) {\n if (!(root instanceof HTMLElement)) continue;\n\n for (const key of COLOR_THEME_TOKEN_KEYS) {\n const value = tokens[key];\n if (value) {\n root.style.setProperty(key, value);\n } else {\n root.style.removeProperty(key);\n }\n }\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openhands/agent-canvas",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Agent Canvas UI for OpenHands - run AI coding agents with a visual interface",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"@heroui/react": "2.8.10",
|
|
24
24
|
"@microlink/react-json-view": "1.31.20",
|
|
25
25
|
"@monaco-editor/react": "4.7.0",
|
|
26
|
-
"@openhands/extensions": "0.
|
|
26
|
+
"@openhands/extensions": "0.9.0",
|
|
27
27
|
"@openhands/typescript-client": "1.32.1",
|
|
28
28
|
"@react-router/node": "7.17.0",
|
|
29
29
|
"@react-router/serve": "7.17.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e,r as t}from"./agent-settings-DjVlKgaP.js";export{e as default,t as handle};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./conversation-B8prFAZF.js";export{e as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./conversation-B8prFAZF.js";export{e as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e}from"./llm-settings-BgSFkbHC.js";export{e as default};
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import{a as e}from"./rolldown-runtime-BFRubm34.js";import{Ct as t,bt as n}from"./vendor-styling-CI0PQ3ab.js";import{t as r}from"./useMutationState-BUab8Kxr.js";import{t as i}from"./useTranslation-Cgy4JA_g.js";import{t as a}from"./declaration-B9kpCaYl.js";import{n as o}from"./active-backend-context-DRFevVIj.js";import{P as s,t as c}from"./utils-CE0lDWtb.js";import{t as l}from"./modal-backdrop-zVwfOJZr.js";import{n as u}from"./modal-classes-DPqxSyuP.js";import{t as d}from"./brand-button-DKPMEKcW.js";import{n as f}from"./navigation-context-DPs2G0X8.js";import{a as p,o as ee}from"./conversation-local-storage-F6zVMM--.js";import{t as m}from"./conversation-store-LptbOvKa.js";import{t as h}from"./modal-close-button-CTCX4nCH.js";import{i as g}from"./settings-service.api-DldkFI1x.js";import{r as _}from"./use-settings-B07msZ2Z.js";import{t as v}from"./use-tracking-CqODdfO4.js";import{t as y}from"./use-create-conversation-CvAXfA3T.js";import{i as b,n as x,r as S,t as C}from"./extension-module-card-classes-9V3J9J_b.js";import{c as w,d as T,f as E,h as D,o as O,t as k}from"./install-server-modal-J_eQ6lhG.js";import{t as A}from"./vendor~root-layout~home~mcp~automations-list~onboarding-modal-L2sdihTY.js";import{n as j}from"./skill-card-pill-row-D2bUe2kB.js";import{t as M}from"./circle-plus-check-toggle-T3eAIuPQ.js";var N=e(t(),1),P=()=>{let e=f(),t=r({mutationKey:[`create-conversation`]}),{isNavigating:n}=e;return t>0||n},F=`${s.PRODUCTION}/settings/integrations`,I=[`github`,`slack`];function L(e){let t=e.requiredIntegrationIds;return t.length>0&&t.every(e=>I.includes(e))}function R(e){switch(e){case`local`:return{target:e,testId:`responder-deployment-option-local`,titleKey:a.RESPONDER_DEPLOYMENT$LOCAL_TITLE,descriptionKey:a.RESPONDER_DEPLOYMENT$LOCAL_DESCRIPTION,primaryActionKey:a.RESPONDER_DEPLOYMENT$LOCAL_ACTION,primaryActionTestId:`responder-deployment-continue-local`,action:{kind:`launch-local`}};case`openhands-cloud`:return{target:e,testId:`responder-deployment-option-openhands-cloud`,titleKey:a.RESPONDER_DEPLOYMENT$OPENHANDS_CLOUD_TITLE,descriptionKey:a.RESPONDER_DEPLOYMENT$OPENHANDS_CLOUD_DESCRIPTION,primaryActionKey:a.RESPONDER_DEPLOYMENT$OPENHANDS_CLOUD_ACTION,primaryActionTestId:`responder-deployment-open-openhands-cloud`,action:{kind:`open-url`,url:F}};case`user-cloud`:throw Error(`User Cloud responder deployment is not yet supported`);default:return e}}var z=[`local`,`openhands-cloud`],B=[{id:`github-pr-reviewer`,name:`GitHub Code Review Agent`,category:`Code review`,description:`Watch for a configurable label on GitHub pull requests, inspect full PR and repository context, and post an AI review comment once per label event.`,requiredIntegrationIds:[`github`],popularityRank:100,estimatedSetupMinutes:4,prompt:`/pr-reviewer:setup`,exampleImplementation:`Trigger: cron polling for open GitHub PRs with a configured label such as openhands-review
|
|
2
|
-
Required secret: GITHUB_PERSONAL_ACCESS_TOKEN
|
|
3
|
-
|
|
4
|
-
1. Read repository, trigger label, review tone, and polling schedule from setup.
|
|
5
|
-
2. List open PRs and find the latest matching GitHub labeled issue event for each labeled PR.
|
|
6
|
-
3. Deduplicate on the label event ID so every label application queues exactly one review.
|
|
7
|
-
4. Start an OpenHands conversation that clones the repo, checks out the exact PR head SHA, and inspects PR discussion, review comments, changed files, diff, and surrounding code.
|
|
8
|
-
5. Post an acknowledgement with the conversation link, then post the final AI review comment only if the PR is still open and the head SHA has not changed.`},{id:`github-repo-monitor`,name:`GitHub repository monitor`,category:`Developer tools`,description:`Watch a repository for @OpenHands mentions in issues and PR comments, start a conversation, and post the agent's reply back to GitHub.`,requiredIntegrationIds:[`github`],popularityRank:98,estimatedSetupMinutes:5,prompt:`/github-monitor:poll`,exampleImplementation:`Trigger: cron, every minute (configurable)
|
|
9
|
-
Required secret: GITHUB_PERSONAL_ACCESS_TOKEN
|
|
10
|
-
|
|
11
|
-
1. Poll GitHub for new issue and PR comments since the last run.
|
|
12
|
-
2. Match comments containing the trigger phrase (case-insensitive, default: @OpenHands).
|
|
13
|
-
3. Post an acknowledgment comment with a link to the new OpenHands conversation.
|
|
14
|
-
4. Forward follow-up replies in the same thread to the running conversation.
|
|
15
|
-
5. Post the agent's final response back to GitHub when the conversation completes.`},{id:`slack-standup-digest`,name:`Slack standup digest`,category:`Team updates`,description:`Summarize yesterday’s Slack activity into an async standup note with blockers, decisions, and owners.`,requiredIntegrationIds:[`slack`],popularityRank:94,estimatedSetupMinutes:5,prompt:`/standup-digest:setup`,exampleImplementation:`Trigger: cron, weekday mornings
|
|
16
|
-
Required MCP: Slack
|
|
17
|
-
|
|
18
|
-
1. Search configured channels for messages since the last digest window.
|
|
19
|
-
2. Cluster updates into shipped work, active work, blockers, and decisions.
|
|
20
|
-
3. TODO: choose a safe allowlist for channels and whether DMs are excluded.
|
|
21
|
-
4. Draft a Slack message with owners, links, and unanswered questions.
|
|
22
|
-
5. Optionally post to the configured standup channel.`},{id:`slack-channel-monitor`,name:`Slack channel monitor`,category:`Team communication`,description:`Watch Slack channels for @openhands mentions, open a conversation with the message context, reply when the agent finishes, and continue the same conversation from triggered Slack thread follow-ups.`,requiredIntegrationIds:[`slack`],popularityRank:92,estimatedSetupMinutes:7,prompt:`/slack-monitor:poll`,exampleImplementation:`Trigger: cron, every minute
|
|
23
|
-
Required secret: SLACK_BOT_TOKEN or SLACK_USER_TOKEN
|
|
24
|
-
|
|
25
|
-
1. Poll up to 10 configured Slack channels for new messages since the last run.
|
|
26
|
-
2. Match messages containing the trigger phrase (default: @openhands).
|
|
27
|
-
3. React with 👀 and start an OpenHands conversation with the message and recent channel context.
|
|
28
|
-
4. Post a thread reply with a link to the conversation, then post the agent response when done.
|
|
29
|
-
5. Keep the thread in a short follow-up watch window and forward only replies that repeat the trigger phrase to the same conversation, with per-thread backoff for quiet threads.`},{id:`linear-triage-assistant`,name:`Linear issue triage assistant`,category:`Project management`,description:`Classify new Linear issues, suggest labels, find duplicates, and ask clarifying questions.`,requiredIntegrationIds:[`linear`],popularityRank:90,estimatedSetupMinutes:3,prompt:`/linear-triage:setup`,exampleImplementation:`Trigger: linear Issue create
|
|
30
|
-
Required MCP: Linear
|
|
31
|
-
|
|
32
|
-
1. Load the new issue, team context, project, labels, and recent similar issues.
|
|
33
|
-
2. Score priority and classify the request as bug, feature, support, or chore.
|
|
34
|
-
3. TODO: map local team labels and priority conventions.
|
|
35
|
-
4. Add a triage comment with rationale and suggested next actions.
|
|
36
|
-
5. Optionally update labels, priority, and assignee.`},{id:`research-brief-writer`,name:`Research brief writer`,category:`Research`,description:`Monitor a topic, gather sources from the web, and publish a short brief for your team.`,requiredIntegrationIds:[`tavily`,`notion`],popularityRank:84,estimatedSetupMinutes:7,prompt:`/research-brief:setup`,exampleImplementation:`Trigger: cron, weekly or daily
|
|
37
|
-
Required MCPs: Tavily, Notion
|
|
38
|
-
|
|
39
|
-
1. Run focused Tavily searches for configured topics and competitors.
|
|
40
|
-
2. Deduplicate sources and rank them by freshness and authority.
|
|
41
|
-
3. TODO: confirm citation format and destination Notion database schema.
|
|
42
|
-
4. Write an executive summary, implications, and recommended actions.
|
|
43
|
-
5. Create or update a Notion page with citations and source links.`},{id:`incident-retrospective-drafter`,name:`Incident retrospective drafter`,category:`Reliability`,description:`Collect incident chatter and issue updates, then draft a timeline and follow-up checklist.`,requiredIntegrationIds:[`slack`,`linear`,`notion`],popularityRank:78,estimatedSetupMinutes:8,prompt:`/incident-retro:setup`,exampleImplementation:`Trigger: manual, cron, or incident label added
|
|
44
|
-
Required MCPs: Slack, Linear, Notion
|
|
45
|
-
|
|
46
|
-
1. Gather incident messages, timestamps, and linked issue references.
|
|
47
|
-
2. Pull Linear follow-up tickets, owners, and status.
|
|
48
|
-
3. TODO: define the incident identifier format and approved Notion template.
|
|
49
|
-
4. Build a timeline, impact summary, root-cause hypotheses, and action items.
|
|
50
|
-
5. Publish a draft retrospective and notify the incident owner.`}],V=n(),H=`inline-flex h-10 w-10 shrink-0 overflow-hidden rounded-lg border border-white/10 bg-surface-raised shadow-[inset_0_1px_0_rgba(255,255,255,0.18)]`;function U(e){return e.slice(0,4)}function W({entries:e,className:t,testId:n}){let r=U(e);if(r.length===0)return(0,V.jsx)(O,{entry:null,size:`md`,className:t,testId:n});if(r.length===1)return(0,V.jsx)(O,{entry:r[0],size:`md`,className:t,testId:n});if(r.length===2)return(0,V.jsx)(`span`,{"aria-hidden":`true`,"data-testid":n,"data-layout":`overlap`,className:c(H,`items-center justify-center`,t),children:(0,V.jsx)(`span`,{className:`flex items-center justify-center -space-x-2`,children:r.map(e=>(0,V.jsx)(O,{entry:e,size:`sm`,className:`ring-2 ring-surface-raised`},e.id))})});let i=[r[0]??null,r[1]??null,r[2]??null,r[3]??null];return(0,V.jsx)(`span`,{"aria-hidden":`true`,"data-testid":n,"data-layout":`quadrants`,className:c(H,`grid grid-cols-2 grid-rows-2 gap-0.5 p-1`,t),children:i.map((e,t)=>e?(0,V.jsx)(`span`,{className:`flex items-center justify-center`,children:(0,V.jsx)(O,{entry:e,size:`xs`})},e.id):(0,V.jsx)(`span`,{"aria-hidden":`true`},`empty-${t}`))})}function G({count:e}){return(0,V.jsx)(`span`,{className:`ml-2 inline-flex items-center justify-center rounded-full bg-surface-raised px-2 py-0.5 text-xs text-foreground`,children:e})}function K(e){return e.map((e,t)=>({automation:e,index:t})).sort((e,t)=>(t.automation.popularityRank??0)-(e.automation.popularityRank??0)||e.index-t.index).map(({automation:e})=>e)}var q=K(B),J=[`github-pr-reviewer`,`github-repo-monitor`,`slack-channel-monitor`];function Y(e){return J.includes(e.id)}function X(e){let t=E(A);return e.requiredIntegrationIds.map(e=>T(e,t)).filter(e=>!!e)}function Z(e,t,n){let r=n.trim().toLowerCase();return r?[e.name,e.category,e.description,e.prompt,...t.map(e=>e.name),...t.flatMap(e=>e.keywords??[])].join(` `).toLowerCase().includes(r):!0}function Q(e){return X(e).length>0}function te(e,t,n,r){let i=e.map(e=>{let n=!!w(e,t);return{id:`mcp-${e.id}`,node:(0,V.jsxs)(`span`,{className:c(b,`gap-1`),children:[(0,V.jsx)(O,{entry:e,size:`xs`}),e.name,n?(0,V.jsx)(`span`,{className:`text-white`,children:r(a.RECOMMENDED_AUTOMATIONS$CONNECTED)}):null]})}});return n>0&&i.push({id:`missing-connect`,node:(0,V.jsx)(`span`,{className:b,children:r(a.RECOMMENDED_AUTOMATIONS$MISSING_CONNECT,{count:n})})}),i}function $({automations:e,installedServers:t,onSelect:n,translate:r}){return(0,V.jsx)(`div`,{className:c(`mt-3`,C),children:e.map(e=>{let i=X(e),a=i.filter(e=>!w(e,t)).length;return(0,V.jsx)(`button`,{type:`button`,"data-testid":`recommended-automation-card-${e.id}`,onClick:()=>n(e),className:c(`flex min-w-0 overflow-hidden p-4 text-left rounded-xl bg-surface-raised`,S),children:(0,V.jsxs)(`div`,{className:`flex min-w-0 flex-1 items-start gap-3`,children:[(0,V.jsx)(W,{entries:i,testId:`recommended-automation-icon-${e.id}`}),(0,V.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-col gap-3`,children:[(0,V.jsxs)(`header`,{className:`flex items-start justify-between gap-3`,children:[(0,V.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,V.jsx)(`h3`,{className:`truncate text-sm font-semibold text-white`,children:e.name}),(0,V.jsx)(`p`,{className:`mt-0.5 truncate text-xs text-tertiary-alt`,children:e.category})]}),(0,V.jsx)(M,{testId:`recommended-automation-plus-${e.id}`})]}),(0,V.jsx)(`p`,{className:`line-clamp-2 text-xs leading-relaxed text-tertiary-light`,children:e.description}),(0,V.jsx)(j,{pills:te(i,t,a,r),testId:`recommended-automation-pills-${e.id}`})]})]})},e.id)})})}function ne({backendKind:e,installedServers:t,query:n=``,onSelect:r,scrollableGrid:o=!1}){let{t:s}=i(`openhands`),l=q.filter(e=>{let t=X(e);return Q(e)&&Z(e,t,n)});if(l.length===0)return null;let u=l.filter(Y),d=l.filter(e=>!Y(e));return(0,V.jsx)(`section`,{"data-testid":`recommended-automations-section`,className:c(o&&`flex min-h-0 flex-1 flex-col`),children:(0,V.jsxs)(`div`,{"data-testid":o?`recommended-automations-scroll-area`:void 0,className:c(`mt-3`,x,o&&`min-h-0 flex-1 overflow-y-auto custom-scrollbar-always`),children:[u.length>0&&(0,V.jsxs)(V.Fragment,{children:[(0,V.jsxs)(`div`,{className:`flex items-center`,children:[(0,V.jsx)(`h2`,{className:`text-base font-semibold text-foreground`,children:s(a.RECOMMENDED_AUTOMATIONS$SECTION_TITLE)}),(0,V.jsx)(G,{count:u.length})]}),(0,V.jsx)(`p`,{className:`mt-1 text-sm text-muted`,children:s(a.RECOMMENDED_AUTOMATIONS$SECTION_DESCRIPTION)}),(0,V.jsx)($,{automations:u,installedServers:t,onSelect:r,translate:s})]}),d.length>0&&(0,V.jsxs)(`section`,{"data-testid":`recommended-automations-beta-section`,className:c(u.length>0&&`mt-8`),children:[(0,V.jsxs)(`div`,{"data-testid":`recommended-automations-beta-heading`,className:`flex items-center`,children:[(0,V.jsx)(`h2`,{className:`text-base font-semibold text-foreground`,children:s(a.RECOMMENDED_AUTOMATIONS$BETA_LABEL)}),(0,V.jsx)(G,{count:d.length})]}),(0,V.jsx)($,{automations:d,installedServers:t,onSelect:r,translate:s})]})]})})}function re({isOpen:e,onClose:t,onContinueLocal:n,onOpenUrl:r}){let{t:o}=i(`openhands`);return e?(0,V.jsx)(l,{onClose:t,"aria-label":o(a.RESPONDER_DEPLOYMENT$TITLE),children:(0,V.jsxs)(`div`,{"data-testid":`responder-deployment-modal`,className:`relative flex w-full max-w-3xl flex-col rounded-xl border border-[var(--oh-border)] bg-base-secondary`,children:[(0,V.jsx)(h,{onClose:t,testId:`responder-deployment-modal-close`}),(0,V.jsxs)(`header`,{className:`flex-shrink-0 px-6 pb-4 pt-6`,children:[(0,V.jsx)(`h2`,{className:c(`pr-6`,u),children:o(a.RESPONDER_DEPLOYMENT$TITLE)}),(0,V.jsx)(`p`,{className:`mt-2 text-sm text-muted`,children:o(a.RESPONDER_DEPLOYMENT$DESCRIPTION)})]}),(0,V.jsx)(`div`,{className:`flex flex-col gap-3 px-6 pb-6 sm:flex-row`,children:z.map(e=>{let t=R(e),{action:i}=t;return(0,V.jsxs)(`div`,{"data-testid":t.testId,className:`flex flex-1 flex-col gap-3 rounded-xl border border-[var(--oh-border)] bg-surface-raised p-4`,children:[(0,V.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,V.jsx)(`h3`,{className:`text-sm font-semibold text-white`,children:o(t.titleKey)}),(0,V.jsx)(`p`,{className:`text-xs leading-relaxed text-tertiary-light`,children:o(t.descriptionKey)})]}),(0,V.jsx)(d,{type:`button`,variant:`primary`,className:`mt-auto`,testId:t.primaryActionTestId,onClick:()=>{i.kind===`launch-local`?n():r(i.url)},children:o(t.primaryActionKey)})]},t.target)})})]})}):null}function ie(e){let t=E(A);return e.requiredIntegrationIds.map(e=>T(e,t)).filter(e=>!!e)}function ae(e){return e}function oe({query:e,onLaunched:t,scrollableGrid:n=!1}){let r=o(),{navigate:i}=f(),{data:a}=_(),{trackPrebuiltAutomationEnabled:s}=v(),c=y(),l=P(),u=m(e=>e.setMessageToSend),[d,h]=(0,N.useState)(null),[b,x]=(0,N.useState)(null),[S,C]=(0,N.useState)([]),T=(0,N.useRef)(!1),E=(0,N.useRef)(!1),O=(0,N.useMemo)(()=>D(g(a?.agent_settings?.mcp_config)),[a?.agent_settings?.mcp_config]),A=(0,N.useCallback)(e=>{if(E.current||c.isPending||l)return;E.current=!0;let n=ae(e.prompt);c.mutate({},{onSuccess:r=>{s({automationName:e.name,automationCategory:e.category}),r.conversation_id.startsWith(`task-`)&&r.task_id?ee(r.task_id,n):p(r.conversation_id,{draftMessage:n}),i?.(`/conversations/${r.conversation_id}`),t?.(),window.setTimeout(()=>u(n),0)},onError:()=>{E.current=!1}})},[r.backend.kind,c,l,i,t,u,s]),j=(0,N.useCallback)(e=>ie(e).filter(e=>!w(e,O)),[O]),M=e=>{let t=j(e);if(t.length===0){A(e);return}h(e),C(t)},F=e=>{if(!(E.current||c.isPending||l||S.length>0||b!==null)){if(L(e)){x(e);return}M(e)}},I=()=>{let e=b;x(null),e&&M(e)},R=e=>{x(null),window.open(e,`_blank`,`noopener,noreferrer`)},z=()=>{x(null)},B=()=>{if(T.current){T.current=!1;return}h(null),C([])},H=()=>{T.current=!0,C(e=>{let t=e.slice(1);if(t.length===0){let e=d;window.setTimeout(()=>{h(null),e&&A(e)},0)}return t})},U=S[0]??null;return r.backend.kind===`cloud`?null:(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(ne,{backendKind:r.backend.kind,installedServers:O,query:e,onSelect:F,scrollableGrid:n}),U&&(0,V.jsx)(k,{entry:U,onClose:B,onSuccess:H},U.id),(0,V.jsx)(re,{isOpen:b!==null,onClose:z,onContinueLocal:I,onOpenUrl:R})]})}export{G as n,P as r,oe as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{T as e,b as t,w as n}from"./utils-CE0lDWtb.js";import{t as r}from"./use-active-conversation-DvcFBqFe.js";import{t as i}from"./use-agent-state-BvRcEzY4.js";var a=({allowAgentError:a=!1}={})=>{let{data:o}=r(),{curAgentState:s}=i(),c=a?e:n;return t(o?.execution_status)&&!c.includes(s)};export{a as t};
|