@mseep/open-computer-use 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.coderabbit.yaml +25 -0
- package/.dockerignore +95 -0
- package/.env.example +137 -0
- package/.githooks/pre-commit +68 -0
- package/.github/CODEOWNERS +125 -0
- package/.github/ISSUE_TEMPLATE/adr-proposal.md +41 -0
- package/.github/ISSUE_TEMPLATE/bug-report.md +49 -0
- package/.github/ISSUE_TEMPLATE/component-proposal.md +38 -0
- package/.github/ISSUE_TEMPLATE/config.yml +15 -0
- package/.github/ISSUE_TEMPLATE/dependency-proposal.md +59 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +15 -0
- package/.github/ISSUE_TEMPLATE/nfr-proposal.md +44 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +15 -0
- package/.github/codeql/codeql-config.yml +11 -0
- package/.github/codeql/extensions/security-models/python-sanitizers.model.yml +17 -0
- package/.github/codeql/extensions/security-models/qlpack.yml +7 -0
- package/.github/dependabot.yml +23 -0
- package/.github/security-exceptions.yml +23 -0
- package/.github/workflows/build.yml +420 -0
- package/.github/workflows/codeql.yml +33 -0
- package/.github/workflows/contracts-lint.yml +90 -0
- package/.github/workflows/docs-lint.yml +151 -0
- package/.github/workflows/helm.yml +131 -0
- package/.github/workflows/identity-lint.yml +30 -0
- package/.github/workflows/release-chart.yml +177 -0
- package/.github/workflows/release.yml +95 -0
- package/.github/workflows/security.yml +332 -0
- package/.github/workflows/stale.yml +31 -0
- package/.github/workflows/supply-chain.yml +242 -0
- package/.gitleaks.toml +53 -0
- package/.markdownlint.yaml +51 -0
- package/.semgrepignore +85 -0
- package/.vale/styles/Architecture/ap13-data-class-substrate.yml +12 -0
- package/.vale/styles/Architecture/banned-phrases.yml +23 -0
- package/.vale/styles/Architecture/banned-vocab.yml +23 -0
- package/.vale/styles/Architecture/marketing-tone.yml +19 -0
- package/.vale.ini +18 -0
- package/CHANGELOG.md +411 -0
- package/CLAUDE.md +218 -0
- package/CONTRIBUTING.md +82 -0
- package/Dockerfile +676 -0
- package/LICENSE +98 -0
- package/LICENSE-APACHE +202 -0
- package/LICENSE-MIT +21 -0
- package/NOTICE +36 -0
- package/README.md +516 -0
- package/SECURITY.md +45 -0
- package/THIRD-PARTY-LICENSES.md +14 -0
- package/apt-packages.txt +108 -0
- package/computer-use-server/.dockerignore +13 -0
- package/computer-use-server/Dockerfile +44 -0
- package/computer-use-server/README.md +84 -0
- package/computer-use-server/app.py +1544 -0
- package/computer-use-server/bin/list-subagent-models +449 -0
- package/computer-use-server/cli-defaults/README.md +31 -0
- package/computer-use-server/cli-defaults/codex.json +7 -0
- package/computer-use-server/cli-defaults/opencode.json +18 -0
- package/computer-use-server/cli_adapters/__init__.py +46 -0
- package/computer-use-server/cli_adapters/claude.py +163 -0
- package/computer-use-server/cli_adapters/codex.py +163 -0
- package/computer-use-server/cli_adapters/opencode.py +169 -0
- package/computer-use-server/cli_adapters/result.py +34 -0
- package/computer-use-server/cli_runtime.py +316 -0
- package/computer-use-server/context_vars.py +24 -0
- package/computer-use-server/docker_manager.py +1100 -0
- package/computer-use-server/docs_html.py +12 -0
- package/computer-use-server/mcp_resources.py +170 -0
- package/computer-use-server/mcp_tools.py +1430 -0
- package/computer-use-server/requirements.txt +17 -0
- package/computer-use-server/security.py +50 -0
- package/computer-use-server/skill_manager.py +664 -0
- package/computer-use-server/static/browser-viewer.js +445 -0
- package/computer-use-server/static/chart.umd.js +14 -0
- package/computer-use-server/static/docs.html +203 -0
- package/computer-use-server/static/github-dark.min.css +10 -0
- package/computer-use-server/static/github.min.css +10 -0
- package/computer-use-server/static/highlight.min.js +1213 -0
- package/computer-use-server/static/highlightjs-line-numbers.min.js +1 -0
- package/computer-use-server/static/icons.js +74 -0
- package/computer-use-server/static/jszip.min.js +13 -0
- package/computer-use-server/static/katex/auto-render.min.js +1 -0
- package/computer-use-server/static/katex/fonts/KaTeX_AMS-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_AMS-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Bold.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Bold.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Bold.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-BoldItalic.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Italic.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Italic.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Math-BoldItalic.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Math-Italic.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Math-Italic.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Bold.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Italic.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Script-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Script-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size1-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size1-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size2-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size2-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size3-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size3-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size4-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size4-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Typewriter-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/katex.min.css +1 -0
- package/computer-use-server/static/katex/katex.min.js +1 -0
- package/computer-use-server/static/locale.js +242 -0
- package/computer-use-server/static/mammoth.browser.min.js +21 -0
- package/computer-use-server/static/marked.min.js +6 -0
- package/computer-use-server/static/mermaid.min.js +2811 -0
- package/computer-use-server/static/pdf.min.js +22 -0
- package/computer-use-server/static/pdf.worker.min.js +22 -0
- package/computer-use-server/static/pptxviewjs.min.js +1 -0
- package/computer-use-server/static/preact-htm.min.js +1 -0
- package/computer-use-server/static/preview.css +1030 -0
- package/computer-use-server/static/preview.js +1522 -0
- package/computer-use-server/static/xlsx.full.min.js +22 -0
- package/computer-use-server/static/xterm-addon-fit.min.js +2 -0
- package/computer-use-server/static/xterm-addon-web-links.min.js +2 -0
- package/computer-use-server/static/xterm.css +218 -0
- package/computer-use-server/static/xterm.min.js +2 -0
- package/computer-use-server/system_prompt.py +761 -0
- package/computer-use-server/uploads.py +82 -0
- package/contracts/README.md +53 -0
- package/contracts/audit/audit-fanin.asyncapi.yaml +407 -0
- package/contracts/exec/exec-channel.schema.json +240 -0
- package/contracts/mcp/2025-06-18/ocu-constraints.schema.json +178 -0
- package/contracts/storage/file-artifact-api.schema.json +390 -0
- package/contracts/storage/file-ops.schema.json +217 -0
- package/contracts/storage/mount-config.schema.json +197 -0
- package/cron/Dockerfile +15 -0
- package/cron/cleanup-quick.sh +21 -0
- package/cron/cleanup.sh +127 -0
- package/data/outputs/.gitkeep +0 -0
- package/data/uploads/.gitkeep +0 -0
- package/docker-compose.test.yml +54 -0
- package/docker-compose.webui.yml +77 -0
- package/docker-compose.yml +96 -0
- package/docs/CLOUD.md +29 -0
- package/docs/COMPARISON.md +128 -0
- package/docs/DOCKER.md +469 -0
- package/docs/DYNAMIC-SKILLS.md +77 -0
- package/docs/FEATURES.md +100 -0
- package/docs/INSTALL.md +111 -0
- package/docs/KNOWN-BUGS.md +86 -0
- package/docs/MCP.md +320 -0
- package/docs/SCREENSHOTS.md +39 -0
- package/docs/SKILLS-USER-GUIDE.md +86 -0
- package/docs/SKILLS.md +483 -0
- package/docs/TERMINAL-TAB.md +56 -0
- package/docs/architecture/02-trust-boundaries.md +224 -0
- package/docs/architecture/03-c4-context.md +61 -0
- package/docs/architecture/04-bounded-contexts.md +119 -0
- package/docs/architecture/05-c4-container.md +88 -0
- package/docs/architecture/06-threat-model.md +172 -0
- package/docs/architecture/08-contracts.md +105 -0
- package/docs/architecture/MANIFESTO.md +38 -0
- package/docs/architecture/PROCESS.md +64 -0
- package/docs/architecture/README.md +37 -0
- package/docs/architecture/adr/0000-template.md +65 -0
- package/docs/architecture/adr/0001-layer-0-gate-legacy-exclusion.md +75 -0
- package/docs/architecture/adr/0002-session-view-descriptor.md +57 -0
- package/docs/architecture/adr/0003-sandbox-runtime-tier-ladder.md +63 -0
- package/docs/architecture/adr/0004-operator-authentication-substrate.md +63 -0
- package/docs/architecture/adr/0005-egress-credential-delivery-envoy-sds.md +62 -0
- package/docs/architecture/adr/0006-egress-forward-proxy-substrate.md +65 -0
- package/docs/architecture/adr/0007-egress-auth-mechanism.md +72 -0
- package/docs/architecture/adr/0008-session-egress-attribution.md +59 -0
- package/docs/architecture/adr/0009-audit-pipeline-pluggable-by-contract.md +76 -0
- package/docs/architecture/adr/0010-storage-backend-pluggable-adapter.md +60 -0
- package/docs/architecture/adr/0011-storage-egress-lane.md +67 -0
- package/docs/architecture/adr/0012-implementation-language.md +67 -0
- package/docs/architecture/adr/0020-sandbox-image-provisioning.md +82 -0
- package/docs/architecture/adr/README.md +53 -0
- package/docs/architecture/compliance/.gitkeep +0 -0
- package/docs/architecture/components/00-overview.md +42 -0
- package/docs/architecture/components/0000-template.md +50 -0
- package/docs/architecture/components/01-mcp-gateway.md +80 -0
- package/docs/architecture/components/02-control-operator-api.md +80 -0
- package/docs/architecture/components/04-storage-broker.md +104 -0
- package/docs/architecture/components/05-session-sandbox.md +93 -0
- package/docs/architecture/components/06-egress-trust-edge.md +95 -0
- package/docs/architecture/components/07-audit-pipeline.md +110 -0
- package/docs/architecture/diagrams/.gitkeep +0 -0
- package/docs/architecture/diagrams/02-trust-boundaries.mmd +111 -0
- package/docs/architecture/diagrams/06-threat-model.mmd +41 -0
- package/docs/architecture/diagrams/08-contracts.mmd +47 -0
- package/docs/architecture/diagrams/c4-container.mmd +59 -0
- package/docs/architecture/diagrams/c4-context.mmd +46 -0
- package/docs/architecture/glossary.md +172 -0
- package/docs/architecture/manifesto/.gitkeep +0 -0
- package/docs/architecture/manifesto/01-audience-and-buyer.md +57 -0
- package/docs/architecture/manifesto/02-nfrs.md +325 -0
- package/docs/architecture/manifesto/03-non-negotiables.md +35 -0
- package/docs/architecture/manifesto/04-non-goals.md +23 -0
- package/docs/architecture/manifesto/05-licensing-posture.md +61 -0
- package/docs/architecture/manifesto/06-starter-mode-policy.md +49 -0
- package/docs/architecture/manifesto/07-governance.md +60 -0
- package/docs/architecture/primitives-backlog.md +51 -0
- package/docs/architecture.svg +117 -0
- package/docs/claude-code-gateway.md +173 -0
- package/docs/cli-config-templates.md +240 -0
- package/docs/data-flow.svg +72 -0
- package/docs/demo-landing-page.gif +0 -0
- package/docs/demo-qwen-trending.gif +0 -0
- package/docs/dynamic-skills.svg +77 -0
- package/docs/file-flow.svg +126 -0
- package/docs/future-architecture/README.md +152 -0
- package/docs/future-architecture/adr/0001-control-plane-language-go.md +80 -0
- package/docs/future-architecture/adr/0002-guest-agent-language-go.md +84 -0
- package/docs/future-architecture/adr/0003-docker-poc-first-then-k8s.md +37 -0
- package/docs/future-architecture/adr/0004-pluggable-runtime-via-runtimeclass.md +34 -0
- package/docs/future-architecture/adr/0005-mcp-as-control-plane-gateway.md +34 -0
- package/docs/future-architecture/adr/0006-no-agpl-no-bsl-dependencies.md +41 -0
- package/docs/future-architecture/adr/0007-superseded-by-future-architecture.md +37 -0
- package/docs/future-architecture/adr/0008-internal-grpc-external-rest-mcp.md +106 -0
- package/docs/future-architecture/adr/0009-external-protocol-dialects.md +94 -0
- package/docs/future-architecture/adr/0010-lambda-as-inspiration-not-runtime.md +86 -0
- package/docs/future-architecture/adr/0011-kata-as-first-class-dind-runtime.md +84 -0
- package/docs/future-architecture/antipatterns.md +552 -0
- package/docs/future-architecture/architecture/01-layers.md +109 -0
- package/docs/future-architecture/architecture/02-layer4-control-plane.md +122 -0
- package/docs/future-architecture/architecture/03-layer3-providers.md +174 -0
- package/docs/future-architecture/architecture/04-layer2-runtimes.md +114 -0
- package/docs/future-architecture/architecture/04b-credential-broker.md +153 -0
- package/docs/future-architecture/architecture/05-layer1-guest-agent.md +138 -0
- package/docs/future-architecture/architecture/06-storage.md +134 -0
- package/docs/future-architecture/architecture/07-security.md +194 -0
- package/docs/future-architecture/architecture/08-networking.md +149 -0
- package/docs/future-architecture/architecture/09-templates.md +122 -0
- package/docs/future-architecture/architecture/10-observability.md +121 -0
- package/docs/future-architecture/design-notes.md +72 -0
- package/docs/future-architecture/gaps.md +281 -0
- package/docs/future-architecture/phase-template.md +123 -0
- package/docs/future-architecture/references.md +225 -0
- package/docs/future-architecture/research/01-kata-containers.md +100 -0
- package/docs/future-architecture/research/02-e2b-infra.md +133 -0
- package/docs/future-architecture/research/03-coder.md +115 -0
- package/docs/future-architecture/research/04-cloud-hypervisor.md +99 -0
- package/docs/future-architecture/research/05-firecracker.md +114 -0
- package/docs/future-architecture/research/06-agent-sandbox.md +142 -0
- package/docs/future-architecture/research/07-chromedp.md +78 -0
- package/docs/future-architecture/research/08-microsandbox.md +78 -0
- package/docs/future-architecture/research/09-agentbox.md +135 -0
- package/docs/future-architecture/research/10-sysbox.md +100 -0
- package/docs/future-architecture/research/11-firecracker-containerd.md +93 -0
- package/docs/future-architecture/research/12-docker-socket-proxy.md +59 -0
- package/docs/future-architecture/research/14-e2b-desktop-and-surf.md +107 -0
- package/docs/future-architecture/research/18-open-webui-terminals-observed.md +135 -0
- package/docs/future-architecture/research/bank-buyer.md +96 -0
- package/docs/future-architecture/research/enthusiast-audience.md +106 -0
- package/docs/future-architecture/research/proof-uipath-anthropic-2026-05.md +76 -0
- package/docs/future-architecture/research/widemoat-thesis-advisor.md +124 -0
- package/docs/future-architecture/roadmap.md +438 -0
- package/docs/kata-runtime.md +267 -0
- package/docs/kubernetes.md +86 -0
- package/docs/logo.png +0 -0
- package/docs/multi-cli.md +161 -0
- package/docs/openwebui-filter.md +134 -0
- package/docs/roadmap/implementation-roadmap.md +104 -0
- package/docs/sandbox-contents.svg +229 -0
- package/docs/screenshots/01-create-document.png +0 -0
- package/docs/screenshots/02-file-preview.png +0 -0
- package/docs/screenshots/03-browser-viewer.png +0 -0
- package/docs/screenshots/04-sub-agent-terminal.png +0 -0
- package/docs/screenshots/05-chat-overview.png +0 -0
- package/docs/screenshots/06-sub-agent-dashboard.png +0 -0
- package/docs/screenshots/07-frontend-design-skill.png +0 -0
- package/docs/screenshots/08-pptx-skill.png +0 -0
- package/docs/screenshots/09-skill-creator.png +0 -0
- package/docs/screenshots/10-data-chart.png +0 -0
- package/docs/shared-browser.svg +102 -0
- package/docs/system-prompt.md +113 -0
- package/docs/terminal-flow.svg +69 -0
- package/examples/helm/README.md +20 -0
- package/examples/helm/standalone/values.yaml +49 -0
- package/examples/helm/with-open-webui/README.md +99 -0
- package/examples/helm/with-open-webui/values-computer-use.yaml +32 -0
- package/examples/helm/with-open-webui/values-open-webui.yaml +67 -0
- package/fonts/NotoEmoji-Regular.ttf +0 -0
- package/helm/computer-use-server/.helmignore +17 -0
- package/helm/computer-use-server/Chart.yaml +32 -0
- package/helm/computer-use-server/README.md +211 -0
- package/helm/computer-use-server/templates/NOTES.txt +66 -0
- package/helm/computer-use-server/templates/_helpers.tpl +115 -0
- package/helm/computer-use-server/templates/configmap-dind-init.yaml +82 -0
- package/helm/computer-use-server/templates/configmap.yaml +18 -0
- package/helm/computer-use-server/templates/deployment.yaml +248 -0
- package/helm/computer-use-server/templates/ingress.yaml +38 -0
- package/helm/computer-use-server/templates/networkpolicy.yaml +50 -0
- package/helm/computer-use-server/templates/pdb.yaml +16 -0
- package/helm/computer-use-server/templates/pvc-data.yaml +20 -0
- package/helm/computer-use-server/templates/pvc-skills-cache.yaml +20 -0
- package/helm/computer-use-server/templates/pvc-user-data.yaml +20 -0
- package/helm/computer-use-server/templates/pvc-var-lib-docker.yaml +27 -0
- package/helm/computer-use-server/templates/secret.yaml +23 -0
- package/helm/computer-use-server/templates/service.yaml +22 -0
- package/helm/computer-use-server/templates/serviceaccount.yaml +15 -0
- package/helm/computer-use-server/templates/tests/test-health.yaml +23 -0
- package/helm/computer-use-server/values.schema.json +183 -0
- package/helm/computer-use-server/values.yaml +297 -0
- package/lychee.toml +36 -0
- package/openwebui/Dockerfile +52 -0
- package/openwebui/README.md +38 -0
- package/openwebui/functions/README.md +48 -0
- package/openwebui/functions/computer_link_filter.py +487 -0
- package/openwebui/init.sh +305 -0
- package/openwebui/patches/README.md +44 -0
- package/openwebui/patches/fix_artifacts_auto_show.py +441 -0
- package/openwebui/patches/fix_attached_files_position.py +87 -0
- package/openwebui/patches/fix_large_tool_args.py +156 -0
- package/openwebui/patches/fix_large_tool_results.py +289 -0
- package/openwebui/patches/fix_preview_url_detection.py +230 -0
- package/openwebui/patches/fix_skip_embedding_chat_files.py +229 -0
- package/openwebui/patches/fix_skip_rag_files_native_fc.py +100 -0
- package/openwebui/patches/fix_tool_loop_errors.py +510 -0
- package/package.json +39 -0
- package/requirements.txt +112 -0
- package/scripts/check-config.sh +141 -0
- package/scripts/docs-lint/ai-slop-detector.sh +202 -0
- package/scripts/docs-lint/architecture-tree-whitelist.sh +131 -0
- package/scripts/docs-lint/ascii-diagram-detector.sh +58 -0
- package/scripts/docs-lint/front-matter-validator.sh +97 -0
- package/scripts/docs-lint/gitignored-ref-detector.sh +122 -0
- package/scripts/docs-lint/identity-email-detector.sh +48 -0
- package/scripts/docs-lint/test-linters.sh +354 -0
- package/scripts/docs-lint/wc-budget.sh +61 -0
- package/scripts/githooks/pre-push +75 -0
- package/server.json +13 -0
- package/settings-wrapper/Dockerfile +9 -0
- package/settings-wrapper/README.md +119 -0
- package/settings-wrapper/app.py +113 -0
- package/settings-wrapper/requirements.txt +2 -0
- package/settings-wrapper/skills.json +25 -0
- package/skills/README.md +46 -0
- package/skills/examples/algorithmic-art/SKILL.md +405 -0
- package/skills/examples/algorithmic-art/templates/generator_template.js +223 -0
- package/skills/examples/algorithmic-art/templates/viewer.html +601 -0
- package/skills/examples/artifacts-builder/SKILL.md +74 -0
- package/skills/examples/artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/skills/examples/artifacts-builder/scripts/init-artifact.sh +322 -0
- package/skills/examples/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/skills/examples/canvas-design/LICENSE.txt +202 -0
- package/skills/examples/canvas-design/SKILL.md +130 -0
- package/skills/examples/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/skills/examples/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/skills/examples/copy-editing/SKILL.md +447 -0
- package/skills/examples/copy-editing/evals/evals.json +89 -0
- package/skills/examples/copy-editing/references/plain-english-alternatives.md +394 -0
- package/skills/examples/internal-comms/LICENSE.txt +202 -0
- package/skills/examples/internal-comms/SKILL.md +32 -0
- package/skills/examples/internal-comms/examples/3p-updates.md +47 -0
- package/skills/examples/internal-comms/examples/company-newsletter.md +65 -0
- package/skills/examples/internal-comms/examples/faq-answers.md +30 -0
- package/skills/examples/internal-comms/examples/general-comms.md +16 -0
- package/skills/examples/mcp-builder/SKILL.md +328 -0
- package/skills/examples/mcp-builder/reference/evaluation.md +602 -0
- package/skills/examples/mcp-builder/reference/mcp_best_practices.md +915 -0
- package/skills/examples/mcp-builder/reference/node_mcp_server.md +916 -0
- package/skills/examples/mcp-builder/reference/python_mcp_server.md +752 -0
- package/skills/examples/mcp-builder/scripts/connections.py +151 -0
- package/skills/examples/mcp-builder/scripts/evaluation.py +373 -0
- package/skills/examples/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/skills/examples/mcp-builder/scripts/requirements.txt +2 -0
- package/skills/examples/product-marketing-context/SKILL.md +241 -0
- package/skills/examples/product-marketing-context/evals/evals.json +85 -0
- package/skills/examples/single-cell-rna-qc/SKILL.md +175 -0
- package/skills/examples/single-cell-rna-qc/references/scverse_qc_guidelines.md +186 -0
- package/skills/examples/single-cell-rna-qc/scripts/qc_analysis.py +232 -0
- package/skills/examples/single-cell-rna-qc/scripts/qc_core.py +233 -0
- package/skills/examples/single-cell-rna-qc/scripts/qc_plotting.py +235 -0
- package/skills/examples/skill-creator/SKILL.md +355 -0
- package/skills/examples/skill-creator/references/output-patterns.md +82 -0
- package/skills/examples/skill-creator/references/workflows.md +28 -0
- package/skills/examples/skill-creator/scripts/init_skill.py +303 -0
- package/skills/examples/skill-creator/scripts/package_skill.py +110 -0
- package/skills/examples/skill-creator/scripts/quick_validate.py +95 -0
- package/skills/examples/slack-gif-creator/SKILL.md +254 -0
- package/skills/examples/slack-gif-creator/core/easing.py +234 -0
- package/skills/examples/slack-gif-creator/core/frame_composer.py +176 -0
- package/skills/examples/slack-gif-creator/core/gif_builder.py +269 -0
- package/skills/examples/slack-gif-creator/core/validators.py +136 -0
- package/skills/examples/slack-gif-creator/requirements.txt +4 -0
- package/skills/examples/social-content/SKILL.md +278 -0
- package/skills/examples/social-content/evals/evals.json +92 -0
- package/skills/examples/social-content/references/platforms.md +170 -0
- package/skills/examples/social-content/references/post-templates.md +177 -0
- package/skills/examples/social-content/references/reverse-engineering.md +195 -0
- package/skills/examples/theme-factory/SKILL.md +59 -0
- package/skills/examples/theme-factory/theme-showcase.pdf +0 -0
- package/skills/examples/theme-factory/themes/arctic-frost.md +19 -0
- package/skills/examples/theme-factory/themes/botanical-garden.md +19 -0
- package/skills/examples/theme-factory/themes/desert-rose.md +19 -0
- package/skills/examples/theme-factory/themes/forest-canopy.md +19 -0
- package/skills/examples/theme-factory/themes/golden-hour.md +19 -0
- package/skills/examples/theme-factory/themes/midnight-galaxy.md +19 -0
- package/skills/examples/theme-factory/themes/modern-minimalist.md +19 -0
- package/skills/examples/theme-factory/themes/ocean-depths.md +19 -0
- package/skills/examples/theme-factory/themes/sunset-boulevard.md +19 -0
- package/skills/examples/theme-factory/themes/tech-innovation.md +19 -0
- package/skills/examples/web-artifacts-builder/LICENSE.txt +202 -0
- package/skills/examples/web-artifacts-builder/SKILL.md +74 -0
- package/skills/examples/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/skills/examples/web-artifacts-builder/scripts/init-artifact.sh +322 -0
- package/skills/examples/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/skills/examples/writing-skills/SKILL.md +655 -0
- package/skills/examples/writing-skills/anthropic-best-practices.md +1150 -0
- package/skills/examples/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- package/skills/examples/writing-skills/graphviz-conventions.dot +172 -0
- package/skills/examples/writing-skills/persuasion-principles.md +187 -0
- package/skills/examples/writing-skills/render-graphs.js +168 -0
- package/skills/examples/writing-skills/testing-skills-with-subagents.md +384 -0
- package/skills/public/describe-image/SKILL.md +105 -0
- package/skills/public/describe-image/scripts/describe.py +389 -0
- package/skills/public/doc-coauthoring/SKILL.md +375 -0
- package/skills/public/docx/LICENSE.txt +30 -0
- package/skills/public/docx/SKILL.md +199 -0
- package/skills/public/docx/docx-js.md +350 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/skills/public/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/skills/public/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/skills/public/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/skills/public/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/skills/public/docx/ooxml/schemas/mce/mc.xsd +75 -0
- package/skills/public/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/skills/public/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/skills/public/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/skills/public/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/skills/public/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/skills/public/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/skills/public/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/skills/public/docx/ooxml/scripts/pack.py +159 -0
- package/skills/public/docx/ooxml/scripts/unpack.py +29 -0
- package/skills/public/docx/ooxml/scripts/validate.py +69 -0
- package/skills/public/docx/ooxml/scripts/validation/__init__.py +15 -0
- package/skills/public/docx/ooxml/scripts/validation/base.py +951 -0
- package/skills/public/docx/ooxml/scripts/validation/docx.py +274 -0
- package/skills/public/docx/ooxml/scripts/validation/pptx.py +315 -0
- package/skills/public/docx/ooxml/scripts/validation/redlining.py +279 -0
- package/skills/public/docx/ooxml.md +632 -0
- package/skills/public/docx/scripts/__init__.py +1 -0
- package/skills/public/docx/scripts/document.py +1292 -0
- package/skills/public/docx/scripts/templates/comments.xml +3 -0
- package/skills/public/docx/scripts/templates/commentsExtended.xml +3 -0
- package/skills/public/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/skills/public/docx/scripts/templates/commentsIds.xml +3 -0
- package/skills/public/docx/scripts/templates/people.xml +3 -0
- package/skills/public/docx/scripts/utilities.py +374 -0
- package/skills/public/file-reading/LICENSE.txt +30 -0
- package/skills/public/file-reading/SKILL.md +350 -0
- package/skills/public/frontend-design/LICENSE.txt +177 -0
- package/skills/public/frontend-design/SKILL.md +42 -0
- package/skills/public/gitlab-explorer/SKILL.md +174 -0
- package/skills/public/gitlab-explorer/references/git-commands.md +323 -0
- package/skills/public/gitlab-explorer/references/glab-commands.md +282 -0
- package/skills/public/gitlab-explorer/scripts/check_gitlab_auth.sh +109 -0
- package/skills/public/pdf/FORMS.md +205 -0
- package/skills/public/pdf/REFERENCE.md +612 -0
- package/skills/public/pdf/SKILL.md +364 -0
- package/skills/public/pdf/scripts/check_bounding_boxes.py +70 -0
- package/skills/public/pdf/scripts/check_bounding_boxes_test.py +226 -0
- package/skills/public/pdf/scripts/check_fillable_fields.py +12 -0
- package/skills/public/pdf/scripts/convert_pdf_to_images.py +35 -0
- package/skills/public/pdf/scripts/create_validation_image.py +41 -0
- package/skills/public/pdf/scripts/extract_form_field_info.py +152 -0
- package/skills/public/pdf/scripts/fill_fillable_fields.py +114 -0
- package/skills/public/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
- package/skills/public/pdf-reading/LICENSE.txt +30 -0
- package/skills/public/pdf-reading/REFERENCE.md +196 -0
- package/skills/public/pdf-reading/SKILL.md +305 -0
- package/skills/public/playwright-cli/SKILL.md +278 -0
- package/skills/public/playwright-cli/references/request-mocking.md +87 -0
- package/skills/public/playwright-cli/references/running-code.md +232 -0
- package/skills/public/playwright-cli/references/session-management.md +169 -0
- package/skills/public/playwright-cli/references/storage-state.md +275 -0
- package/skills/public/playwright-cli/references/test-generation.md +88 -0
- package/skills/public/playwright-cli/references/tracing.md +139 -0
- package/skills/public/playwright-cli/references/video-recording.md +43 -0
- package/skills/public/pptx/LICENSE.txt +30 -0
- package/skills/public/pptx/SKILL.md +484 -0
- package/skills/public/pptx/css.md +335 -0
- package/skills/public/pptx/html2pptx.md +893 -0
- package/skills/public/pptx/html2pptx.tgz +0 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/skills/public/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/skills/public/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/skills/public/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/skills/public/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/skills/public/pptx/ooxml/schemas/mce/mc.xsd +75 -0
- package/skills/public/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/skills/public/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/skills/public/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/skills/public/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/skills/public/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/skills/public/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/skills/public/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/skills/public/pptx/ooxml/scripts/pack.py +159 -0
- package/skills/public/pptx/ooxml/scripts/unpack.py +29 -0
- package/skills/public/pptx/ooxml/scripts/validate.py +69 -0
- package/skills/public/pptx/ooxml/scripts/validation/__init__.py +15 -0
- package/skills/public/pptx/ooxml/scripts/validation/base.py +951 -0
- package/skills/public/pptx/ooxml/scripts/validation/docx.py +274 -0
- package/skills/public/pptx/ooxml/scripts/validation/pptx.py +315 -0
- package/skills/public/pptx/ooxml/scripts/validation/redlining.py +279 -0
- package/skills/public/pptx/ooxml.md +427 -0
- package/skills/public/pptx/scripts/inventory.py +1020 -0
- package/skills/public/pptx/scripts/rearrange.py +231 -0
- package/skills/public/pptx/scripts/replace.py +385 -0
- package/skills/public/pptx/scripts/thumbnail.py +450 -0
- package/skills/public/skill-creator/SKILL.md +356 -0
- package/skills/public/skill-creator/references/output-patterns.md +82 -0
- package/skills/public/skill-creator/references/workflows.md +28 -0
- package/skills/public/skill-creator/scripts/init_skill.py +303 -0
- package/skills/public/skill-creator/scripts/package_skill.py +110 -0
- package/skills/public/skill-creator/scripts/quick_validate.py +95 -0
- package/skills/public/sub-agent/SKILL.md +186 -0
- package/skills/public/sub-agent/references/security-review.md +153 -0
- package/skills/public/sub-agent/references/usage.md +207 -0
- package/skills/public/sub-agent/scripts/list_subagent_models.sh +22 -0
- package/skills/public/test-driven-development/SKILL.md +371 -0
- package/skills/public/test-driven-development/testing-anti-patterns.md +299 -0
- package/skills/public/webapp-testing/LICENSE.txt +202 -0
- package/skills/public/webapp-testing/SKILL.md +96 -0
- package/skills/public/webapp-testing/examples/console_logging.py +35 -0
- package/skills/public/webapp-testing/examples/element_discovery.py +40 -0
- package/skills/public/webapp-testing/examples/static_html_automation.py +33 -0
- package/skills/public/webapp-testing/scripts/with_server.py +106 -0
- package/skills/public/xlsx/LICENSE.txt +30 -0
- package/skills/public/xlsx/SKILL.md +316 -0
- package/skills/public/xlsx/preview_data.py +93 -0
- package/skills/public/xlsx/recalc.py +178 -0
- package/tests/README.md +42 -0
- package/tests/fixtures/cli/claude_v0.9.2.0_argv.json +46 -0
- package/tests/fixtures/cli/claude_v0.9.2.0_stdout.json +32 -0
- package/tests/fixtures/cli/codex_run.jsonl +4 -0
- package/tests/fixtures/cli/opencode_run.jsonl +6 -0
- package/tests/integration/README.md +56 -0
- package/tests/integration/conftest.py +280 -0
- package/tests/integration/pytest.ini +13 -0
- package/tests/integration/test_mcp_auth.py +85 -0
- package/tests/integration/test_mcp_tools.py +101 -0
- package/tests/integration/test_workspace_lifecycle.py +125 -0
- package/tests/orchestrator/mock_llm_server.py +343 -0
- package/tests/orchestrator/test_cli_adapters.py +566 -0
- package/tests/orchestrator/test_cli_adapters_live.py +527 -0
- package/tests/orchestrator/test_cli_runtime.py +451 -0
- package/tests/orchestrator/test_docker_manager.py +302 -0
- package/tests/orchestrator/test_dynamic_instructions.py +69 -0
- package/tests/orchestrator/test_mcp_resources.py +140 -0
- package/tests/orchestrator/test_mcp_tools.py +224 -0
- package/tests/orchestrator/test_passthrough_isolation.py +201 -0
- package/tests/orchestrator/test_readme_in_container.py +76 -0
- package/tests/orchestrator/test_render_cache.py +84 -0
- package/tests/orchestrator/test_runtime_cli_endpoint.py +108 -0
- package/tests/orchestrator/test_single_user_mode.py +212 -0
- package/tests/orchestrator/test_startup_warnings.py +123 -0
- package/tests/orchestrator/test_sub_agent_dispatch.py +327 -0
- package/tests/orchestrator/test_subagent_claude_compat.py +367 -0
- package/tests/orchestrator/test_system_prompt_endpoint.py +191 -0
- package/tests/orchestrator/test_tool_descriptions.py +52 -0
- package/tests/orchestrator/test_view_image.py +201 -0
- package/tests/patches/conftest.py +30 -0
- package/tests/patches/fixtures/__init__.py +10 -0
- package/tests/patches/fixtures/middleware_v0.9.1.py +5057 -0
- package/tests/patches/fixtures/middleware_v0.9.2.py +5120 -0
- package/tests/patches/fixtures/retrieval_v0.9.1.py +2684 -0
- package/tests/patches/fixtures/retrieval_v0.9.2.py +2700 -0
- package/tests/patches/test_fix_attached_files_position.py +118 -0
- package/tests/patches/test_fix_large_tool_args.py +130 -0
- package/tests/patches/test_fix_large_tool_results.py +531 -0
- package/tests/patches/test_fix_skip_embedding_chat_files.py +160 -0
- package/tests/patches/test_fix_skip_rag_files_native_fc.py +120 -0
- package/tests/patches/test_fix_tool_loop_errors.py +128 -0
- package/tests/security/test_path_traversal_app.py +132 -0
- package/tests/security/test_path_traversal_docker.py +36 -0
- package/tests/security/test_path_traversal_settings.py +87 -0
- package/tests/security/test_safe_path_util.py +166 -0
- package/tests/security/test_xss_preview.py +46 -0
- package/tests/test-default-model-resolution.py +136 -0
- package/tests/test-docker-image.sh +358 -0
- package/tests/test-list-subagent-models.sh +421 -0
- package/tests/test-mcp-endpoint-live.sh +92 -0
- package/tests/test-mcp-native-surface.sh +213 -0
- package/tests/test-no-cyrillic.sh +135 -0
- package/tests/test-opencode-error-mapping.py +130 -0
- package/tests/test-pr88-skills.sh +305 -0
- package/tests/test-project-structure.sh +202 -0
- package/tests/test-single-user-mode.sh +269 -0
- package/tests/test-skill-no-hardcoded-models.sh +65 -0
- package/tests/test-subagent-cli-surface.py +137 -0
- package/tests/test-subagent-runtime.sh +109 -0
- package/tests/test_codex_toml_converter.py +204 -0
- package/tests/test_default_resolver_no_legacy_global.py +159 -0
- package/tests/test_filter.py +648 -0
- package/tests/test_init_sh_unchanged.sh +49 -0
- package/tests/test_opencode_alias_map_drop.py +144 -0
- package/tests/test_requirements.py +91 -0
- package/tests/test_subagent_docstring.py +193 -0
- package/tests/test_tools.py +34 -0
- package/vendor/extract-text/README.md +46 -0
- package/vendor/extract-text/extract-text +0 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased — `next/v1` branch
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- **License migration: BUSL-1.1 → FSL-1.1-Apache-2.0.** All future releases ship under the Functional Source License, Version 1.1, Apache 2.0 Future License. Use, modification, forking, internal self-hosting, and redistribution remain permitted; offering a hosted or embedded service that competes with our paid version(s) requires a separate commercial agreement. Each release automatically converts to Apache-2.0 two years after publication under the Grant of Future License clause. Past releases retain their original BUSL-1.1 terms per the LICENSE file published at that tag. Affected: `LICENSE`, `NOTICE`, `README.md` badge + License section, `CLAUDE.md` License Headers section, `CONTRIBUTING.md`, `package.json`, SPDX headers across 176 source files, `helm/computer-use-server/`, `THIRD-PARTY-LICENSES.md`, `computer-use-server/cli-defaults/*.json`.
|
|
8
|
+
|
|
9
|
+
## v0.9.5.0 — bump Open WebUI base to 0.9.5 (2026-05-20)
|
|
10
|
+
|
|
11
|
+
Minor release: Open WebUI base bumped from `0.9.2` → `0.9.5` (upstream shipped 0.9.3, 0.9.4, 0.9.5 on 2026-05-09). All eight patches re-audited against the new source tree — none became obsolete (upstream did not natively address any of the eight problem domains in 0.9.3–0.9.5). Frontend patches (`fix_artifacts_auto_show`, `fix_preview_url_detection`) applied to the bumped base without changes; four backend patches needed updated SEARCH/REPLACE anchors to track upstream refactors.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- **`openwebui/Dockerfile`** — `ARG OPENWEBUI_VERSION=0.9.2` → `0.9.5`.
|
|
16
|
+
- **`fix_tool_loop_errors` Mod 1 (tool_loop)** — upstream wrapped `convert_output_to_messages(output, raw=True)` into a multi-line call with the new `reasoning_format=get_reasoning_format(model)` kwarg (introduced for OR-aligned reasoning emission). SEARCH/REPLACE updated to match the multi-line shape at both call sites (stateful Responses API branch and Chat Completions branch).
|
|
17
|
+
- **`fix_tool_loop_errors` Mod 2 (code_interp)** — upstream guarded the post-loop `title = await Chats.get_chat_title_by_id(metadata['chat_id'])` with a `channel:`-prefix check, turning the assignment into a multi-line parenthesized ternary. SEARCH/REPLACE updated to match.
|
|
18
|
+
- **`fix_large_tool_results` Mod 3 (history)** — same `reasoning_format` refactor: upstream `process_messages_with_output(form_data.get('messages', []))` is now a multi-line call with `reasoning_format=get_reasoning_format(model)`. SEARCH/REPLACE updated to match.
|
|
19
|
+
- **`fix_skip_embedding_chat_files` Patch 1 (early return for regular uploads)** — upstream inserted an `else: await _validate_collection_access([collection_name], user, access_type='write')` branch between `if collection_name is None:` and `if form_data.content:` (part of the v0.9.5 file-access enforcement, upstream PR #24524). SEARCH/REPLACE updated to preserve the new guard.
|
|
20
|
+
|
|
21
|
+
### Verified
|
|
22
|
+
|
|
23
|
+
- Backend dry-run: all six middleware/retrieval patches applied cleanly against a fresh `v0.9.5` source tree; resulting files parse with `ast.parse` (Python syntax intact).
|
|
24
|
+
- Docker build: `docker build --platform linux/amd64 -t open-webui-ocu:0.9.5.0-rc.2 -f openwebui/Dockerfile openwebui/` succeeds end-to-end; all eight patches' hard-fail guards (`sys.exit(1)`) green.
|
|
25
|
+
|
|
26
|
+
### Upstream behavior changes worth knowing
|
|
27
|
+
|
|
28
|
+
- New default `AIOHTTP_CLIENT_ALLOW_REDIRECTS=False` blocks 3xx redirects in web fetch / tool servers / OAuth (we don't rely on redirects through `host.docker.internal`, no action).
|
|
29
|
+
- `POST /api/v1/auth/signout` (was GET); `init.sh` does not call signout, no action.
|
|
30
|
+
- New `IFRAME_CSP` env var controls iframe Content-Security-Policy (Artifacts panel uses iframes); leave default unless smoke test shows blank Artifacts.
|
|
31
|
+
- Per-model `params` dict now stripped from non-write-access users in `models.py` GET responses; `init.sh` runs as admin, no action.
|
|
32
|
+
|
|
33
|
+
## v0.9.2.4 — fix xlsx upload hang on Open WebUI 0.9.x (2026-05-11)
|
|
34
|
+
|
|
35
|
+
Patch release on top of v0.9.2.3 (Open WebUI base unchanged). Fixes a regression from the OWUI v0.8 → v0.9 base bump: the `fix_skip_embedding_chat_files` patch was written against the v0.8 sync database/storage signatures and quietly broke when OWUI made `Files.update_file_data_by_id`, `Storage.get_file`, and `Loader.load` async.
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- **Open WebUI frontend spinner stuck forever after uploading an xlsx > 1 MB into a chat** (issue #96). `Files.update_file_data_by_id` went from `def` to `async def` between OWUI v0.8.x and v0.9.x; the skip-embedding patch was still calling it without `await`, so the coroutine was dropped without ever writing the `completed` status to the database. The HTTP response returned 200 immediately but the file row stayed in `pending`, and the OWUI frontend polled forever. Zip and other archive uploads were unaffected because they take a different code path that already used `await`. Fix is a one-line `await` on the patched call, plus a regression-guard test that asserts every patched `Files.update_file_data_by_id` call site is awaited.
|
|
40
|
+
- **KB-fallback path could freeze the OWUI backend for minutes during knowledge-base ingestion.** Patch 2 of `fix_skip_embedding_chat_files` called `Storage.get_file()` and `Loader.load()` directly inside the async `process_file` handler. Both are sync and CPU/IO-bound (PyMuPDF, Unstructured, Tika, etc.) and would block the OWUI event loop for the entire read/parse — no other request could be served until extraction finished. Upstream OWUI explicitly switched to `await asyncio.to_thread(Storage.get_file, ...)` and `await loader.aload(...)` at v0.9.1 for exactly this reason. The patch now does the same. New regression-guard test rejects any non-offloaded `Storage.get_file(` / `_fb_loader.load(` call site.
|
|
41
|
+
|
|
42
|
+
### Internal
|
|
43
|
+
|
|
44
|
+
- Audited every patch in `openwebui/patches/` against the OWUI v0.8 → v0.9 sync→async migration. Only `fix_skip_embedding_chat_files` regressed; the others either do not touch async-ified APIs (`fix_artifacts_auto_show`, `fix_attached_files_position`, `fix_large_tool_args`, `fix_large_tool_results`, `fix_preview_url_detection`, `fix_skip_rag_files_native_fc`) or were already updated for the migration in earlier releases (`fix_tool_loop_errors`, which has an inline `v0.9.1: async-ified` note).
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
## v0.9.2.3 — extract-text + bundled GSD/Superpowers skills (2026-05-03)
|
|
48
|
+
|
|
49
|
+
Patch release on top of v0.9.2.2 (Open WebUI base unchanged). Adds Anthropic's `extract-text` CLI for unified plain-text extraction across document formats, the `file-reading` and `pdf-reading` skills built on top of it, and bundled GSD + Superpowers skill packs auto-wired for Claude Code subagents. PyMuPDF and xlrd added to support the new skills (third-party licensing tracked in `THIRD-PARTY-LICENSES.md`). Hardened `settings.json` permissions — agent can no longer overwrite its own hook scripts.
|
|
50
|
+
|
|
51
|
+
### Added
|
|
52
|
+
|
|
53
|
+
- **`extract-text` CLI** — Anthropic's Rust-based unified plain-text extractor at `/usr/local/bin/extract-text`. Handles docx/odt/epub/xlsx/pptx/rtf/html/htm/ipynb in a single call. Vendored at `vendor/extract-text/` (see README there for licensing). Used by the new `file-reading` and `pdf-reading` skills.
|
|
54
|
+
- **`file-reading` skill** (`/mnt/skills/public/file-reading/`) — dispatch table telling the model which tool to use for each upload type, so it doesn't `cat` a PDF or slurp a 100MB CSV.
|
|
55
|
+
- **`pdf-reading` skill** (`/mnt/skills/public/pdf-reading/`) — content inventory, text extraction, page rasterization, embedded image / attachment / form-field extraction, and document-type-aware reading strategies.
|
|
56
|
+
- **`PyMuPDF==1.24.10`** and **`xlrd==2.0.1`** added to `requirements.txt` for PDF positional image extraction (`pdf-reading`) and legacy `.xls` parsing (`file-reading`).
|
|
57
|
+
- **GSD + Superpowers bundled for Claude Code** — pinned to `v1.9.9` (`gsd-build/get-shit-done`) and `v5.0.7` (`obra/superpowers`). Override at build time with `--build-arg GSD_REF=… --build-arg SUPERPOWERS_REF=…`. Cloned to `/opt/skills-external/`, then symlinked into `~/.claude/{skills,agents,commands,hooks}` from the entrypoint. Inside the container Claude Code gains `/gsd:*` slash-commands, `gsd-*` agents, superpowers skills, and SessionStart/Pre/PostToolUse hooks. Main AI is unaffected (still reads `/mnt/skills/`). `settings.json` hook commands are guarded with `[ -f … ] && … || true` so missing upstream files do not error every session.
|
|
58
|
+
- **`skills/README.md`** — licensing matrix and disclaimer for Anthropic-authored skills (`docx`, `pdf`, `pptx`, `xlsx`, `file-reading`, `pdf-reading`). Spells out that those directories are bundled for operators with a valid Anthropic agreement and points to the open-source fallbacks already documented in each `SKILL.md`.
|
|
59
|
+
- **`THIRD-PARTY-LICENSES.md`** — explicit licensing notice for bundled third-party deps. Calls out PyMuPDF AGPL-3.0 conveyance obligations, Anthropic Skill License materials, Apache-2.0 GSD/Superpowers, and the BSD-3-Clause Open WebUI base. Linked from the README License section.
|
|
60
|
+
|
|
61
|
+
### Security
|
|
62
|
+
|
|
63
|
+
- **Narrowed agent Write permissions inside the sandbox.** Previously `settings.json` granted `Write(/home/assistant/.claude/**)`, which let the agent overwrite the same `gsd-*.js` / `gsd-*.sh` hook scripts that run automatically on `SessionStart`, `PreToolUse`, and `PostToolUse` — a self-mutation / persistence path. Allowed writes are now narrowed to `Write(.claude/CLAUDE.md)` and `Write(.claude/settings.json)` only; `hooks/`, `agents/`, `commands/`, and `skills/` stay read-only. `tests/test-pr88-skills.sh` asserts the regression. (CodeRabbit PR #88.)
|
|
64
|
+
|
|
65
|
+
### Known followups
|
|
66
|
+
|
|
67
|
+
- The `extract-text` binary is vendored under `vendor/extract-text/` (~2MB blob). A future patch should fetch it at build time with sha256 verification and remove the blob from git. Source release URL TBD — Anthropic does not currently publish a public release for this CLI.
|
|
68
|
+
- GSD and Superpowers are pinned via upstream tags (`v1.9.9`, `v5.0.7`). Tags are mutable. `git clone --branch` does not accept raw commit SHAs; for strict reproducibility a future patch should switch to `git clone --no-checkout && git fetch <sha> && git checkout <sha>`.
|
|
69
|
+
|
|
70
|
+
## v0.9.2.2 — Multi-CLI Sub-Agent runtime followups (2026-04-26)
|
|
71
|
+
|
|
72
|
+
Patch release on top of v0.9.2.1 covering the v0.9.2.1 audit followups (Phases 9.1–9.6): real-CLI smoke harness, two production Dockerfile bug fixes (`opencode` schema, `codex` `model_provider` selector), Preview SPA active-CLI badge, CLI config templates with `OPENCODE_CONFIG_EXTRA` / `CODEX_CONFIG_EXTRA` env hooks, plus CodeRabbit review followups (resume-session CLI gate, opencode docs schema, dead helper, MD040 fences). Security: `pillow` 12.1.1 → 12.2.0 (CVE-2026-40192), `python-multipart` 0.0.22 → 0.0.26.
|
|
73
|
+
|
|
74
|
+
### Fixed
|
|
75
|
+
|
|
76
|
+
- **`opencode` runtime was non-functional in v0.9.2.1.** The Dockerfile entrypoint rendered `/tmp/opencode.json` with top-level key `"providers"` (plural) and a flat `"apiKey"` per provider. Current opencode (1.14.25) schema requires `"provider"` (singular) with credentials nested under `"options": { "apiKey": ... }`. Pre-fix containers exited with `Error: Configuration is invalid at /tmp/opencode.json ↳ Unrecognized key: "providers"` before reaching the model. Caught by Phase 9.1 real-CLI smoke (`tests/orchestrator/test_cli_adapters_live.py`).
|
|
77
|
+
- **`codex` `OPENAI_BASE_URL` was silently ignored in v0.9.2.1.** The Dockerfile heredoc declared `[model_providers.custom]` when `OPENAI_BASE_URL` is set but never set the top-level `model_provider = "custom"` selector, so codex always fell through to the default `openai` provider (api.openai.com) regardless. Fixed by prepending the selector line. Operators pointing codex at a corporate gateway are unblocked.
|
|
78
|
+
|
|
79
|
+
### Added
|
|
80
|
+
|
|
81
|
+
- **Real-CLI smoke suite** — `tests/orchestrator/test_cli_adapters_live.py` (gated by `RUN_LIVE_CLI=1`) plus `tests/orchestrator/mock_llm_server.py`. Runs each adapter end-to-end against a hermetic stdlib HTTP server speaking three wire protocols (Anthropic Messages SSE, OpenAI Responses SSE, OpenAI Chat Completions SSE) inside a docker-network sidecar. Closes audit concern #1 from `.planning/milestones/v0.9.2.1-AUDIT.md`. Also includes two regression guards that load the entrypoint-rendered configs (not test-side configs) so future heredoc regressions trip immediately.
|
|
82
|
+
- **Preview SPA active-CLI surface** — new `GET /api/runtime/cli` orchestrator endpoint returning `{cli, default_model, supports_cost}`. The preview UI (`computer-use-server/static/preview.js`) now renders an `ActiveCliBadge` pill in the toolbar showing the resolved sub-agent CLI; for codex/opencode it adds a "cost n/a" indicator so operators understand `cost_usd: null` is not a `$0.00` rendering bug. Pure progressive enhancement — silently disappears against older orchestrators without the endpoint. Endpoint contract pinned by `tests/orchestrator/test_runtime_cli_endpoint.py`. Closes audit concern #3.
|
|
83
|
+
- **CLI config templates companion** — `docs/cli-config-templates.md` with copy-paste recipes for codex+Azure, codex+approval/sandbox modes, codex+custom OpenAI-compat gateways, opencode+instructions, opencode+MCP federation, opencode+custom openai-compat providers, opencode+agent personas, plus a verification recipe. Backed by two new env hooks in the Dockerfile entrypoint: **`OPENCODE_CONFIG_EXTRA`** (replaces `/tmp/opencode.json` verbatim) and **`CODEX_CONFIG_EXTRA`** (appended to `~/.codex/config.toml` after the canonical block). Both backwards-compatible — unset = today's behaviour. Cross-linked from `docs/multi-cli.md` under `## Advanced configs`. Closes audit concern #2.
|
|
84
|
+
|
|
85
|
+
### Docs
|
|
86
|
+
|
|
87
|
+
- `docs/multi-cli.md` cross-links the new templates companion under the `## Advanced configs` section.
|
|
88
|
+
- `.planning/REQUIREMENTS.md` `DOCS-MULTICLI-01..04` checkboxes flipped from `[ ]` → `[x]` (cosmetic-only sync; the docs themselves shipped in commit `245d1b6`).
|
|
89
|
+
|
|
90
|
+
## v0.9.2.1 — Multi-CLI Sub-Agent Runtime (2026-04-26)
|
|
91
|
+
|
|
92
|
+
Adds OpenAI Codex CLI (`@openai/codex@0.125.0`) and OpenCode (`opencode-ai@1.14.25`, sst fork) as drop-in alternatives to Claude Code across the entire sub-agent surface. A single `SUBAGENT_CLI=claude|codex|opencode` env switch routes every sub-agent invocation through the chosen CLI with identical operator UX. Default unset = `claude` (byte-identical backwards-compat with v0.9.2.0).
|
|
93
|
+
|
|
94
|
+
### Added
|
|
95
|
+
|
|
96
|
+
- **`SUBAGENT_CLI` env switch** with hard-fail allowlist validation (typo → orchestrator refuses to start) (CLI-01, CLI-02, CLI-03)
|
|
97
|
+
- **`cli_runtime.py` resolver + `cli_adapters/` package** (Protocol, `SubAgentResult` dataclass, three adapters) (ADAPT-01)
|
|
98
|
+
- **CodexAdapter** — `codex exec --ephemeral --json --output-last-message` with `--cd /tmp/codex-agents-<uuid>/` workdir (ADAPT-03)
|
|
99
|
+
- **OpenCodeAdapter** — `opencode run --model <provider/model> --format json --dangerously-skip-permissions` (ADAPT-04)
|
|
100
|
+
- **Per-CLI model resolution** with hard-fail on cross-CLI alias misuse (e.g. `sonnet` on codex → actionable ValueError) (ADAPT-06)
|
|
101
|
+
- **`cli_runtime.dispatch(...)` single entry point**; `mcp_tools.sub_agent` rewritten as thin orchestration over it; production claude path is byte-identical to v0.9.2.0 (golden-snapshot tested) (ADAPT-02, ADAPT-05)
|
|
102
|
+
- **Per-CLI auth allowlists** in `_create_container` prevent cross-CLI key leak (Pitfall 1) (AUTH-01)
|
|
103
|
+
- **OpenCode config rendered to `/tmp/opencode.json`** (NOT volume) with `{env:VAR}` substitution syntax — zero plaintext secrets on disk (Pitfall 7) (AUTH-02)
|
|
104
|
+
- **Codex `~/.codex/config.toml`** rendered conditionally with `[model_providers.custom]` block when `OPENAI_BASE_URL` is set (AUTH-03)
|
|
105
|
+
- **Marker-gated entrypoint heredoc** (`/tmp/.cli-runtime-initialised`) — config rendering fires once per container lifetime (AUTH-04)
|
|
106
|
+
- **`.bashrc` autostart honours `${SUBAGENT_CLI:-claude}`** with `NO_AUTOSTART=1` env + `/tmp/.no_autostart` sentinel escape hatches; marker renamed `CLAUDE_AUTOSTARTED → SUBAGENT_AUTOSTARTED` (TERM-01, TERM-02, TERM-03)
|
|
107
|
+
- **Cost-guardrail caveat** — `cost_usd=None` rendered as `cost: unavailable` (never `$0.00`) for non-claude CLIs; `SUB_AGENT_TIMEOUT` documented as backstop
|
|
108
|
+
- **`docs/multi-cli.md`** — operator guide with worked OpenCode + qwen3-coder + OpenRouter recipe (DOCS-MULTICLI-01, DOCS-MULTICLI-02)
|
|
109
|
+
|
|
110
|
+
### Tests (mandatory, ship with the code)
|
|
111
|
+
|
|
112
|
+
- **TEST-01** — Docker image installs all three CLIs; `claude --version`, `codex --version`, `opencode --version` smoke (image build + `tests/test-docker-image.sh`)
|
|
113
|
+
- **TEST-02** — `cli_runtime.resolve_cli` resolver suite (`tests/orchestrator/test_cli_runtime.py`, ~23 cases inc. invalid SystemExit + per-CLI passthrough)
|
|
114
|
+
- **TEST-03** — `cli_adapters` adapter argv + parse_result coverage with per-CLI fixtures under `tests/fixtures/cli/` (`tests/orchestrator/test_cli_adapters.py`)
|
|
115
|
+
- **TEST-04** — end-to-end `sub_agent(...)` dispatch suite parametrized over all 3 CLIs, signature regression guard, cost-rendering "unavailable" gate (`tests/orchestrator/test_sub_agent_dispatch.py`)
|
|
116
|
+
- **TEST-05** — `openwebui/init.sh` byte-equals v0.9.2.0 baseline regression (`tests/test_init_sh_unchanged.sh`, hardcoded sha256 `31ce03b6...c27a7`)
|
|
117
|
+
- **TEST-06** — per-CLI dispatch + marker-gating (`GATED-SENTINEL`) + `NO_AUTOSTART` escape-hatch smoke in `tests/test-docker-image.sh`
|
|
118
|
+
|
|
119
|
+
### Backwards compatibility
|
|
120
|
+
|
|
121
|
+
- `SUBAGENT_CLI` unset / empty / `claude` → byte-identical to v0.9.2.0 (verified by golden-snapshot test of `claude_command` argv + end-to-end dispatch shell-command equality)
|
|
122
|
+
- `mcp_tools.sub_agent(task, max_turns=25, model="sonnet")` MCP signature unchanged — every existing skill caller works without modification
|
|
123
|
+
- Existing volumes with old `CLAUDE_AUTOSTARTED=1` markers continue to work — autostart fires once on next session via the new independent `SUBAGENT_AUTOSTARTED` check; no double-firing, no regression
|
|
124
|
+
- `dangerous_mode` terminal flow (`app.py:847`) migrated from injecting `CLAUDE_AUTOSTARTED=1` to the new documented `NO_AUTOSTART=1` escape hatch
|
|
125
|
+
- `openwebui/init.sh` unchanged (CI-enforced)
|
|
126
|
+
|
|
127
|
+
### Documentation
|
|
128
|
+
|
|
129
|
+
- `docs/multi-cli.md` (DOCS-MULTICLI-01, DOCS-MULTICLI-02) — full operator guide with switch matrix, worked recipes, troubleshooting, prior-art credits
|
|
130
|
+
- `README.md` cross-link in the Sub-agent / Pro tip area (DOCS-MULTICLI-03)
|
|
131
|
+
- `docs/INSTALL.md` cross-link in the env configuration section (DOCS-MULTICLI-03)
|
|
132
|
+
- `.env.example` — `# === Optional: Multi-CLI sub-agent runtime ===` block with `SUBAGENT_CLI=` (commented) + per-CLI auth env templates (DOCS-MULTICLI-03)
|
|
133
|
+
- `CHANGELOG.md` v0.9.2.1 entry (this entry) (DOCS-MULTICLI-04)
|
|
134
|
+
|
|
135
|
+
### Prior art
|
|
136
|
+
|
|
137
|
+
- [OpenAI Codex CLI documentation](https://developers.openai.com/codex/cli/reference) — `codex exec` flag spec + JSONL event schema
|
|
138
|
+
- [sst/opencode documentation](https://opencode.ai/docs/) — `opencode run`, `{env:VAR}` config substitution, providers list
|
|
139
|
+
- [OpenRouter qwen3-coder model page](https://openrouter.ai/qwen/qwen3-coder)
|
|
140
|
+
- Issue #40 / PR #41 (community contribution by `rahxam`) — informed Phase 3 (Claude Code gateway compatibility), the foundation this milestone builds on
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## v0.9.2.0 (2026-04-25)
|
|
145
|
+
|
|
146
|
+
### Breaking Changes — Open WebUI base bump 0.8.12 → 0.9.2
|
|
147
|
+
|
|
148
|
+
- **Base image bumped**: `openwebui/Dockerfile` default `ARG OPENWEBUI_VERSION=0.8.12` → `0.9.2`; `docker-compose.webui.yml` default `OPENWEBUI_VERSION:-0.8.12` → `OPENWEBUI_VERSION:-0.9.2`. A plain `docker compose -f docker-compose.webui.yml up --build` on a fresh clone now builds against `ghcr.io/open-webui/open-webui:0.9.2`. No v0.9.1 release was cut — the 0.9.1-era patches were rewritten as the v0.9.2 baseline (Phases 4–6), and only the v0.9.2 re-verification (Phases 7–9) was carried into this release.
|
|
149
|
+
- **Strict version pinning**: this build (`v0.9.2.X`) is strictly built and verified against Open WebUI 0.9.2. The first 3 segments of our build version always equal the Open WebUI base version. Operators on Open WebUI 0.8.12 or 0.9.1 must use the corresponding `v0.8.12.Y` / `v0.9.1.Y` build (the latter was never publicly cut — 0.9.1-era fixtures remain green in `tests/patches/` only as regression coverage for the in-memory `V091_SHIM` inside `fix_tool_loop_errors`, not as a supported runtime target).
|
|
150
|
+
|
|
151
|
+
### Features — Open WebUI 0.9.2 compatibility (Phases 4–9)
|
|
152
|
+
|
|
153
|
+
Eight patches re-verified against Open WebUI v0.9.2, zero dropped. Each patch carries a `sys.exit(1)` fail-loud on anchor miss and an idempotency marker so re-running the patch on an already-patched layer is a no-op.
|
|
154
|
+
|
|
155
|
+
- **fix_artifacts_auto_show** (FE) — matches at v0.9.2. Auto-opens the Artifacts panel when an assistant message contains an HTML code block. Marker: `FIX_ARTIFACTS_AUTO_SHOW` baked into the compiled SvelteKit chunks.
|
|
156
|
+
- **fix_preview_url_detection** (FE) — matches at v0.9.2. Auto-inserts the preview iframe for `{server}/preview/{chat_id}` and `{server}/files/{chat_id}/...` URLs. Host-agnostic: iframe src reconstructed at runtime from the matched URL's own origin. Marker: `FIX_PREVIEW_URL_DETECTION`.
|
|
157
|
+
- **fix_tool_loop_errors** (BE) — rewritten for v0.9.2. SEARCH/REPLACE extended with the new `'metadata': metadata,` key that v0.9.2 upstream added to `new_form_data = {…}` inside the tool-call retry loop. A 10-line in-memory `V091_SHIM → V092_SHIM` keeps v0.9.1 fixtures green as regression coverage only. Marker: `FIX_TOOL_LOOP_ERRORS`.
|
|
158
|
+
- **fix_large_tool_results** (BE, cascade on patch 3) — rewritten for v0.9.2. SEARCH_TOOL_LOOP extended through the full `new_form_data = {…}` closing brace with `'metadata': metadata,` to keep the 3+4 cascade atomic. `tests/patches/test_fix_large_tool_results.py::test_cascade_with_patch_3_on_v092` pins the invariant. Marker: `FIX_LARGE_TOOL_RESULTS`.
|
|
159
|
+
- **fix_large_tool_args** (BE) — matches at v0.9.2. Count-assertion `content.count(OLD_ARGS) == 2` still holds. Truncates oversized tool-call arguments in HTML attributes to prevent browser freeze on large tool outputs. Marker: `FIX_LARGE_TOOL_ARGS`.
|
|
160
|
+
- **fix_attached_files_position** (BE) — matches at v0.9.2. Moves file context to the end of messages to improve prompt-cache hit rates with large file attachments. Marker: `FIX_ATTACHED_FILES_POSITION`.
|
|
161
|
+
- **fix_skip_embedding_chat_files** (BE) — matches at v0.9.2. Both retrieval.py anchors byte-identical; skips expensive text extraction + embedding for >1MB chat uploads, using the knowledge-base fallback instead. Marker: `FIX_SKIP_EMBEDDING_CHAT_FILES`.
|
|
162
|
+
- **fix_skip_rag_files_native_fc** (BE) — matches at v0.9.2. Skips the RAG pipeline for chat files when the Computer Use tool is enabled, avoiding unnecessary processing for native-function-calling models. Marker: `FIX_SKIP_RAG_FILES_NATIVE_FC` (filename / marker-name mismatch is deliberate — documented in Phase 6 verdict).
|
|
163
|
+
|
|
164
|
+
Build proof: `open-computer-use:0.9.2-test` built from the full production `openwebui/Dockerfile` with `--build-arg OPENWEBUI_VERSION=0.9.2` emits 8 `PATCHED: fix_* applied successfully.` lines and 0 `ERROR:` lines. Test proof: `python -m pytest tests/` green in `python:3.13-slim` — 248 passed, 0 failed.
|
|
165
|
+
|
|
166
|
+
### Features — Claude Code gateway compatibility rollup (Phase 3, GATEWAY-01..12)
|
|
167
|
+
|
|
168
|
+
Phase 3 code shipped on `main` on 2026-04-12 (commit `38347fd`) but never had its own release — it is cut here. Fixes issue [#40](https://github.com/Wide-Moat/open-computer-use/issues/40); inspired by PR [#41](https://github.com/Wide-Moat/open-computer-use/pull/41), rewritten with tests and without deploy-specific churn. Full operator guide in [docs/claude-code-gateway.md](docs/claude-code-gateway.md).
|
|
169
|
+
|
|
170
|
+
- **GATEWAY-01** — Root-cause bug fix. `computer-use-server/context_vars.py:14` `current_anthropic_base_url` default changed from `"https://api.anthropic.com/"` to `None`, restoring the `or ANTHROPIC_BASE_URL` env fallback at `docker_manager.py:359`. Previously the truthy default blocked every env override silently.
|
|
171
|
+
- **GATEWAY-02** — Ten module-level env constants added to `docker_manager.py` (captured at import time via `os.getenv(NAME, "")`): `ANTHROPIC_MODEL`, `ANTHROPIC_DEFAULT_{SONNET,OPUS,HAIKU}_MODEL`, `CLAUDE_CODE_SUBAGENT_MODEL`, `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS`, `DISABLE_PROMPT_CACHING{,_SONNET,_OPUS,_HAIKU}`. Organised into model-IDs and compat-flags sub-groups.
|
|
172
|
+
- **GATEWAY-03** — `CLAUDE_CODE_PASSTHROUGH_ENVS` tuple + deterministic passthrough loop in `_create_container`: each of the ten (NAME, VALUE) pairs injects into `extra_env` only when truthy. Empty / unset vars never reach the sandbox.
|
|
173
|
+
- **GATEWAY-04** — `mcp_tools.sub_agent` widened: aliases (`sonnet` / `opus` / `haiku`) honour `ANTHROPIC_DEFAULT_{SONNET,OPUS,HAIKU}_MODEL` when set; direct IDs (`claude-sonnet-4-6`, LiteLLM-style `anthropic/claude-sonnet-4-6`) pass through unchanged; empty/None falls back to Sonnet default. Case-insensitive after `strip()`.
|
|
174
|
+
- **GATEWAY-05..07** — Test coverage: new `tests/orchestrator/test_docker_manager.py` (three operator paths — no vars / auth-only / full gateway), `tests/orchestrator/test_sub_agent_model_resolution.py` (seven alias + direct-ID cases), and a regression test proving `ANTHROPIC_CUSTOM_HEADERS` injection at `docker_manager.py:378` is unchanged.
|
|
175
|
+
- **GATEWAY-08..09** — `docker-compose.yml` declares `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_BASE_URL`, and the 10 gateway vars under the `${VAR:-}` pattern; `.env.example` grows a `# === Optional: Claude Code sub-agent gateway overrides ===` block. Adding `ANTHROPIC_AUTH_TOKEN` + `ANTHROPIC_BASE_URL` is itself a bug fix — they were missing from compose, so Path B (auth-only) never worked end-to-end on a vanilla `docker compose up`.
|
|
176
|
+
- **GATEWAY-10** — New `docs/claude-code-gateway.md`: three-path operator table (zero-config Claude Code `/login` → auth-only → full gateway), worked LiteLLM recipe with `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1` + `DISABLE_PROMPT_CACHING=1`, Azure/Bedrock-via-LiteLLM cross-reference, verification checklist, troubleshooting pointer to issue #40.
|
|
177
|
+
- **GATEWAY-11** — README.md "Open WebUI Integration" section + `docs/INSTALL.md` configuration table cross-link the new doc.
|
|
178
|
+
- **GATEWAY-12** — `python -m pytest tests/ -v` green in `python:3.13-slim` with zero new warnings; the three project shell tests remain green.
|
|
179
|
+
|
|
180
|
+
### Known Limitations
|
|
181
|
+
|
|
182
|
+
- **Live UI UAT for v0.9.2 deferred to the user**: Phase 5's Artifacts-panel + preview-iframe screenshots were captured against a v0.9.1-era image. For v0.9.2 the automation proves (a) patch markers are baked into `/app/build/_app/immutable/chunks/*.js` of the built `open-computer-use:0.9.2-test` image, (b) the patched middleware and retrieval modules parse as valid Python AST, (c) cascade 3+4 on v0.9.2 fixtures is atomic — but end-to-end localhost UX verification (open a chat, request an HTML artifact, request a file preview) is the user's post-release UAT step. It does not block the release; the mechanical proof that the v0.9.2 patched chunks carry their fail-loud markers and parse cleanly is in place.
|
|
183
|
+
|
|
184
|
+
## v0.8.12.8 (2026-04-19)
|
|
185
|
+
|
|
186
|
+
### Breaking Changes — filter v4.1.0, preview-mode surface narrowed
|
|
187
|
+
- **`PREVIEW_MODE="artifact"` and `PREVIEW_MODE="both"` removed** (closes #43). `outlet()` no longer emits a fenced ```html `<iframe>` block — it only appends a markdown preview link. The extra html block was redundant *and* actively harmful: the `fix_preview_url_detection` frontend patch is guarded by `!htmlGroups.some(o=>o.html)`, so pre-emitting an html block from the filter caused the patch to skip detection, leaving the iframe rendered as a raw code fence in chat (the #43 symptom that had been reappearing since v3.2.0). Only `"button"` and `"off"` remain; `"button"` is the new default. Matches the internal prod v3.8.0 behaviour — the long-standing production reference was never using artifact mode to begin with.
|
|
188
|
+
- **Migration**: saved `"artifact"` / `"both"` values now fail Pydantic validation on load. Re-seed Valves with `rm /app/backend/data/.computer-use-initialized` + container restart. `init.sh` will write the new `"button"` default.
|
|
189
|
+
|
|
190
|
+
### Breaking Changes — single public URL on the server
|
|
191
|
+
- **Server env renamed**: `FILE_SERVER_URL` → `PUBLIC_BASE_URL`. It's now the *single source of truth* for the browser-facing URL — baked into `/system-prompt` text and returned to the Open WebUI filter via the new `X-Public-Base-URL` response header. Rename in your `.env`.
|
|
192
|
+
- **Tool Valve renamed**: `FILE_SERVER_URL` → `ORCHESTRATOR_URL` (same semantics — internal URL for MCP forwarding).
|
|
193
|
+
- **Filter Valves changed**: `FILE_SERVER_URL` and `SYSTEM_PROMPT_URL` Valves *removed*. Replaced with a single `ORCHESTRATOR_URL` Valve (internal URL for server→server fetch). The filter reads the public URL from the server's response header — no more "two `FILE_SERVER_URL` settings that must match" footgun.
|
|
194
|
+
- **Filter `_fetch_system_prompt()` signature**: now returns `tuple[public_url, prompt] | None` instead of `str | None`. `outlet()` reads `public_url` from the cache.
|
|
195
|
+
- **`DOCKER_AI_UPLOAD_URL` env var renamed**: → `ORCHESTRATOR_URL` (consistent with the Valves).
|
|
196
|
+
- **`docker-compose.webui.yml`**: dropped `MCP_SERVER_EXTERNAL_URL` and `extra_hosts: host.docker.internal:host-gateway`. The open-webui and computer-use-server containers now talk over the shared Compose default network using Docker service DNS (`http://computer-use-server:8081`).
|
|
197
|
+
|
|
198
|
+
**Migration:**
|
|
199
|
+
1. Rename `FILE_SERVER_URL=...` → `PUBLIC_BASE_URL=...` in your `.env`.
|
|
200
|
+
2. If you run `docker-compose.webui.yml` / `init.sh`: the init script re-seeds Valves with the new names automatically — delete `/app/backend/data/.computer-use-initialized` and restart `open-webui` so it re-runs.
|
|
201
|
+
3. If you configured Valves manually in the Open WebUI admin UI, re-enter them: tool `ORCHESTRATOR_URL`, filter `ORCHESTRATOR_URL`. The old `FILE_SERVER_URL` / `SYSTEM_PROMPT_URL` entries in the DB are ignored by the new Pydantic model and can be left in place.
|
|
202
|
+
|
|
203
|
+
### Features
|
|
204
|
+
- **Filter v3.2.0 → v3.4.0 — simpler Valves**: the three boolean preview/archive Valves (`ENABLE_PREVIEW_ARTIFACT`, `ENABLE_PREVIEW_BUTTON`, `ENABLE_ARCHIVE_BUTTON`) were first collapsed in v3.3.0 into two Literal Valves (`PREVIEW_MODE` ∈ `artifact | button | both | off`, `ARCHIVE_BUTTON` ∈ `on | off`), then removed entirely in v3.4.0 along with their `@model_validator` bridge. Users upgrading straight from v3.2.0 revert to defaults — upgrade via v3.3.0 first if you need to preserve saved preferences.
|
|
205
|
+
- **Filter v4.0.0 — public URL owned by server**: the filter no longer carries a public-URL Valve. The server's new `/system-prompt` response header `X-Public-Base-URL` delivers it to the filter per request; `_fetch_system_prompt()` caches the (public_url, prompt) pair so `outlet()` can decorate with browser-facing preview/archive links without its own Valve.
|
|
206
|
+
- **Startup warning for default `PUBLIC_BASE_URL`** (closes #59): the orchestrator logs a one-time warning when the env var is still the hardcoded internal-DNS default (`http://computer-use-server:8081`), catching the #43-class "preview panel never appears" misconfiguration at boot rather than silently in production.
|
|
207
|
+
|
|
208
|
+
### Fixes
|
|
209
|
+
- **Filter — browser-only sessions got no preview**: `outlet()` previously required a `/files/{chat_id}/…` URL in the assistant message to inject preview decorations, so pure browser sessions (playwright / chromium with no downloadable file) saw nothing. Detection now also fires on a `<details type="tool_calls">` block that references a browser tool. Scoped to the tag — free-text keyword mentions never false-trigger. Archive button stays gated on file URLs (unchanged).
|
|
210
|
+
- **sub-agent `max_turns` default inconsistency**: the Open WebUI tool's `sub_agent(max_turns=...)` signature defaulted to 50, silently overriding the server's 25 default on every call. Unified to 25 alongside a sweep of stale doc references (docs/SKILLS.md, skills/public/sub-agent/references/usage.md).
|
|
211
|
+
|
|
212
|
+
### Tests
|
|
213
|
+
- **Filter — `BrowserToolTrigger` class** (10 tests): exercises the new browser-tool trigger — every keyword, html-escaped `arguments="…"` (production delivery form), free-text scoping, non-tool_calls `<details>` blocks, empty content, preview-button injection, archive button still gated on files, invariant that no fenced-html or raw iframe is ever emitted, idempotency across repeated `outlet()` calls.
|
|
214
|
+
- **Filter — legacy-value guard**: `test_legacy_preview_mode_values_rejected_on_construction` asserts that saved `"artifact"` / `"both"` Valve values from v3.x / v4.0.0 DBs fail Pydantic validation loudly instead of silently falling through.
|
|
215
|
+
- **Server — `test_startup_warnings.py`** (3 tests): env unset → warn; custom URL → silent; explicit default literal → warn.
|
|
216
|
+
|
|
217
|
+
### Documentation
|
|
218
|
+
- `docs/openwebui-filter.md`: Valves reference updated for v3.4.0 (legacy rows removed), "Preview UX: which PREVIEW_MODE fits you?" retained.
|
|
219
|
+
- `openwebui/functions/README.md` Valve table refreshed.
|
|
220
|
+
- `openwebui/init.sh` bootstrap payload updated to new schema field names so fresh deployments start with new names in the DB.
|
|
221
|
+
|
|
222
|
+
### Features — maximum MCP-native system-prompt surface (six tiers)
|
|
223
|
+
|
|
224
|
+
The same per-session system prompt is now delivered through six channels backed by a single cached renderer (`computer-use-server/system_prompt.py::render_system_prompt`, 60s TTL per `(chat_id, user_email)`). Redundancy is by design — a client may skip any one channel and still get the prompt somewhere. Complete map at `docs/system-prompt.md`.
|
|
225
|
+
|
|
226
|
+
1. **Tool descriptions** — `bash_tool` + `view` docstrings point at `/home/assistant/README.md` as a recovery hint (`tools/list` surface).
|
|
227
|
+
2. **`/home/assistant/README.md` in sandbox** — rendered on container creation via `container.put_archive`, survives container removals via the `chat-{chat_id}-workspace` volume.
|
|
228
|
+
3. **Static `InitializeResult.instructions=` hint** — one-liner pointing at README + `resources/list` for clients that render the initialize-result field directly.
|
|
229
|
+
4. **Dynamic `InitializeResult.instructions`** — per-request content via `current_instructions` ContextVar + `_DynamicInstructionsServer` subclass swapped onto `mcp._mcp_server`. Works thanks to `stateless_http=True` + per-request `create_initialization_options()`.
|
|
230
|
+
5. **`resources/list` + `resources/read`** — uploaded files surfaced as `FunctionResource` per chat, URI shape `file://uploads/{chat_id}/{url-encoded rel_path}`. Registered on container creation AND on `POST /api/uploads` so new uploads appear without client reconnect. Upload itself stays on HTTP (MCP has no upload primitive).
|
|
231
|
+
6. **`GET /system-prompt` HTTP endpoint** — backward compat for the Open WebUI filter. Now reads `X-Chat-Id` / `X-User-Email` (plus `X-OpenWebUI-*` aliases) with header priority over query params; delegates to the shared renderer; `X-Public-Base-URL` response header preserved.
|
|
232
|
+
|
|
233
|
+
All four "dynamic" tiers (2, 4, 5, 6) hit the same `render_system_prompt` cache — one render per `(chat_id, user_email)` per minute regardless of fan-out.
|
|
234
|
+
|
|
235
|
+
**Deliberately NOT using `@mcp.prompt("system")`.** We considered exposing the prompt via the MCP `prompts/*` primitive (OpenAI Agents SDK's documented fallback `server.get_prompt(...)`), but the 2025-11-25 spec restricts `PromptMessage.role` to `{user, assistant}` and positions prompts as user-controlled slash commands. Naming a prompt `"system"` clashes with both, and `InitializeResult.instructions` is the canonical field for server-supplied instructions. Tier 4 covers that canonically — a `prompts/get("system")` entry would have been off-spec duplication.
|
|
236
|
+
|
|
237
|
+
Duplication analysis (per-scenario): Open WebUI through LiteLLM sees the prompt **once** via the filter's `inlet()` inject — `InitializeResult.instructions` is not forwarded by LiteLLM. MCP-native clients (Agents SDK, Inspector, Claude Desktop) see it **once** via `InitializeResult.instructions`. In both paths a second copy appears only if the model follows the Tier 1 recovery-nudge and calls `view /home/assistant/README.md`. Worst case: 2 copies; typical case: 1. The nudge stays to help pathological clients that strip system prompts — see `docs/system-prompt.md` for tightening options.
|
|
238
|
+
|
|
239
|
+
Private-API touchpoints are pinned by tests (`tests/orchestrator/test_dynamic_instructions.py`, `test_mcp_resources.py`) and documented at their call sites with SDK line references; when bumping `mcp` minor, re-run these tests first.
|
|
240
|
+
|
|
241
|
+
### Reliability — post-review hardening (PR #65 follow-ups)
|
|
242
|
+
|
|
243
|
+
After independent review of the six-tier surface a series of regression and
|
|
244
|
+
silent-failure fixes landed. Each one closed a real path that was broken in
|
|
245
|
+
production *or* in the upgrade story:
|
|
246
|
+
|
|
247
|
+
- **`/mcp` returned HTTP 500 in production builds**. Dockerfile didn't `COPY` `mcp_resources.py` and `uploads.py`, the lifespan caught the resulting `ImportError` and yielded WITHOUT calling `session_manager.run()`, and from then on every MCP call hit `Task group is not initialized`. uvicorn's default error path returned a body-less 500 with no traceback — the failure was 100% silent server-side and surfaced only as empty tool output in the chat. Three changes prevent recurrence:
|
|
248
|
+
- `Dockerfile` now copies the missing modules.
|
|
249
|
+
- Lifespan no longer swallows `ImportError` — boot crashes loud if anything required is missing, with the matching dead `try/except` in `_init_mcp()` and the module-level `get_mcp_app` import removed for a single failure mode.
|
|
250
|
+
- New CI job `Smoke — POST /mcp returns 200` builds the server image, boots it, and POSTs an `initialize` request. Catches this exact regression in one run.
|
|
251
|
+
- **Open WebUI tool now classifies every failure mode loudly**. `openwebui/tools/computer_use_tools.py` previously returned `"[No output]"` on empty results and a single `"[Error] MCP call failed"` for any exception, often without firing the `status="error"` SSE event — the chat tool-call collapsible looked green and empty, and the AI concluded the tool was broken. New behaviour:
|
|
252
|
+
- Pre-flight probes both `GET /health` AND `POST /mcp initialize` (the second is what catches the silent 500 above). 30s cache, 3s timeout.
|
|
253
|
+
- Tiered exception classes: `[CONFIG ERROR]`, `[NETWORK ERROR]`, `[MCP TRANSPORT ERROR]`, `[UNEXPECTED ERROR]`, `[TOOL ERROR]`.
|
|
254
|
+
- Empty-result disambiguation: `"[Command produced no output. Exit was successful — this is not an error.]"` instead of `"[No output]"`. Phrasing is deliberate — AI models read the string literally.
|
|
255
|
+
- `Tools._run_tool` consolidates the five per-tool wrappers; `_looks_like_error()` replaces five drifted heuristics so `view`/`str_replace`/`create_file` now report errors with the same fidelity as `bash_tool`.
|
|
256
|
+
- **Filter `outlet()` no longer drops preview/archive buttons silently** when the inlet cache is cold (Open WebUI restart between inlet and outlet). It re-fetches `/system-prompt` to recover the public URL — same `_fetch_system_prompt` stale-cache fallback path, so a truly down server still skips decoration ("broken links worse than no links" invariant preserved).
|
|
257
|
+
- **`/system-prompt` legacy n8n contract restored**. PR #65 had auto-substituted `chat_id="default"` when no chat_id was supplied; now it returns the template with `{file_base_url}` / `{archive_url}` / `{chat_id}` placeholders intact when nothing is supplied, matching pre-v4.0.0 behaviour for external integrators that do their own substitution.
|
|
258
|
+
- **Per-`(chat_id, user_email)` render lock**. Slow `skill_manager` providers no longer serialize all MCP requests across all chats — only the matching key blocks.
|
|
259
|
+
- **Atomic resource sync window**. `mcp_resources.sync_chat_resources` builds the new resource set outside the lock and swaps in one synchronous critical section; `asyncio.Lock` swapped to `threading.Lock` so the worker-thread `asyncio.run()` path actually serializes against the request-loop path.
|
|
260
|
+
- **Defensive shape assertions** on `mcp._mcp_server` and the lowlevel `Server` before the Tier 4 class swap. SDK rename now fails at import with a pointer to re-pin, instead of silently dropping Tier 4 to static instructions.
|
|
261
|
+
- **`mcp` SDK pinned** to `1.27.0` with a comment listing the three private-API touchpoints the pin guards.
|
|
262
|
+
- **`docker_manager.put_archive` checked** for `False` return — README write failures surface as exceptions instead of false-success log lines.
|
|
263
|
+
- **Sanitization at boundaries**: `sync_chat_resources(chat_id)` calls `sanitize_chat_id` so case variants (`"Chat"` vs `"chat"`) share the same stale-uri set; `/system-prompt` does the same on header/query chat_id.
|
|
264
|
+
|
|
265
|
+
### CI
|
|
266
|
+
|
|
267
|
+
- New job `Pytest — orchestrator` runs `pytest tests/orchestrator/` (97 tests) on every push. Existed in repo, never wired to CI.
|
|
268
|
+
- New job `Smoke — POST /mcp returns 200` boots the server image and runs `tests/test-mcp-endpoint-live.sh` — the smoke that would have caught the silent 500 bug in one CI run.
|
|
269
|
+
|
|
270
|
+
### Dependencies
|
|
271
|
+
- `claude-code` pinned to `2.1.114` in the sandbox `Dockerfile` for reproducible builds. `latest` still available as an override.
|
|
272
|
+
- `mcp` Python SDK pinned to `1.27.0` in `computer-use-server/requirements.txt` (was `>=1.0.0`). Required because the orchestrator uses three private attributes (`mcp._mcp_server`, `mcp._resource_manager._resources`, `mcp._mcp_server.request_context.session`) that have no public equivalent. Tests `test_dynamic_instructions.py` and `test_mcp_resources.py` pin the contract — re-run them on every minor bump.
|
|
273
|
+
|
|
274
|
+
## v0.8.12.7 (2026-04-13)
|
|
275
|
+
|
|
276
|
+
### Features
|
|
277
|
+
- **System prompt extraction**: the ~460-line hardcoded Computer Use system prompt has been moved from `computer_link_filter` into the orchestrator's `GET /system-prompt` endpoint (ported from the internal fork's v3.7/v3.8 architecture). The server now performs full substitution: `{file_base_url}`, `{archive_url}`, `{chat_id}` placeholders from an optional `chat_id` query param, and the `<available_skills>` XML block from an optional `user_email` query param. Per-user skill lookup falls back gracefully to `DEFAULT_PUBLIC_SKILLS` when no external skill provider is configured (community default).
|
|
278
|
+
- **Filter rewrite (v3.0.2 → v3.1.0)**: `openwebui/functions/computer_link_filter.py` is now a thin HTTP client — it fetches the fully-baked prompt from the server and injects it as-is. No more client-side URL substitution. File size dropped from 636 lines to under 250.
|
|
279
|
+
- **LRU cache with stale-cache fallback**: the filter keeps an `OrderedDict` LRU keyed by `chat_id`, 5-minute TTL, max 100 entries, O(1) eviction. On fetch failure (server down, timeout, non-200), it serves the stale entry for the same chat if present; otherwise it skips injection (same safe no-op path as the missing-`chat_id` case). No broken URLs ever reach the model.
|
|
280
|
+
- **New Valve `SYSTEM_PROMPT_URL`**: optional override for the endpoint URL (empty = derive from `FILE_SERVER_URL`).
|
|
281
|
+
- **Filter v3.1.0 → v3.2.0 — preview panel**: new Valves expose `/preview/{chat_id}` so the archive button can open the preview iframe on stock Open WebUI installs without the project's artifact patch.
|
|
282
|
+
- **Claude Code gateway compatibility** (fixes #40, PR #46): the orchestrator now passes `ANTHROPIC_BASE_URL`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_MODEL`, and related gateway env vars through to the sandbox container; `sub_agent` model resolution widened to accept direct model IDs in addition to aliases. Docker Compose gets a gateway-overrides block and `.env.example` documents the full set.
|
|
283
|
+
|
|
284
|
+
### Fixes
|
|
285
|
+
- **Filter — cross-user prompt cache leak**: cache key now scoped so one user's baked prompt can't be served to another user; archive-button detection restricted to assistant messages and the current `chat_id` only.
|
|
286
|
+
- **Filter — URL scheme validation**: `/system-prompt` fetch now validates the URL scheme (http/https only) and narrows the exception surface so a misconfigured Valve can't SSRF or hang.
|
|
287
|
+
- **Filter — non-string system content**: `inlet()` no longer crashes when Open WebUI hands it a non-string system message.
|
|
288
|
+
- **sub-agent — delegation scope**: restricted to code-only tasks; stops wasting API calls on non-code delegations.
|
|
289
|
+
|
|
290
|
+
### Tests
|
|
291
|
+
- 5 new pinning tests in `tests/orchestrator/test_system_prompt_endpoint.py` cover the `/system-prompt` contract: `chat_id` substitution, `user_email` default-skills fallback, legacy `file_base_url` / `archive_url` params, no-param degraded path, `text/plain` content-type.
|
|
292
|
+
- 7 new cache tests in `tests/test_filter.py::SystemPromptFetchCache`: fresh fetch populates cache, cache hit within TTL skips HTTP, TTL expiry triggers refetch, LRU eviction at 100 entries, stale-cache fallback on server down, cold-cache skip when server down, `user_email` propagation to query string.
|
|
293
|
+
- The 7 pre-existing filter tests continue to pass. Two of them (which reach the injection path) now use a `setUp` fixture that mocks `urllib.request.urlopen`.
|
|
294
|
+
- `/system-prompt` endpoint test made hermetic (no reliance on ambient env).
|
|
295
|
+
- New `docker_manager` env-injection matrix tests and `sub_agent` model-resolution tests covering the Claude Code gateway path.
|
|
296
|
+
|
|
297
|
+
### CI
|
|
298
|
+
- **Sandbox smoke tests in build pipeline** (PR #48): the build workflow now boots the sandbox image and verifies Chromium launches end-to-end before accepting the image.
|
|
299
|
+
|
|
300
|
+
### Documentation
|
|
301
|
+
- `.env.example` now documents `MCP_TOKENS_URL` (optional external skill-provider URL; empty default → graceful fallback to `DEFAULT_PUBLIC_SKILLS`).
|
|
302
|
+
- New `docs/claude-code-gateway.md` guide cross-linked from README and INSTALL covering gateway configuration.
|
|
303
|
+
- FILE_SERVER_URL: two-setting behaviour documented (PR #58) so operators understand the server-side vs. filter-side URLs.
|
|
304
|
+
- sub-agent docs: explicit-override precedence clarified; cutoff wording unified; presentation examples pruned; non-code delegation policy aligned across the system prompt.
|
|
305
|
+
|
|
306
|
+
### Dependencies
|
|
307
|
+
- `playwright` repinned to `1.57.0` (briefly bumped to `1.59.1` then reverted in PR #47 to stay aligned with the base image).
|
|
308
|
+
- `psutil` 7.1.0 → 7.2.2.
|
|
309
|
+
- `beautifulsoup4` 4.14.2 → 4.14.3.
|
|
310
|
+
- `reportlab` 4.4.4 → 4.4.10.
|
|
311
|
+
|
|
312
|
+
### Privacy / packaging
|
|
313
|
+
- `.planning/` gitignored on the public GitHub remote; pre-push hook enforces the rule.
|
|
314
|
+
- Internal-fork references scrubbed; `tests/test-no-corporate.sh` extended to catch regressions.
|
|
315
|
+
- MCP Registry: added project logo, fixed `server.json` schema, simplified manifest for publication as `io.github.Wide-Moat/open-computer-use`.
|
|
316
|
+
|
|
317
|
+
### Code removed
|
|
318
|
+
- Filter's hardcoded ~460-line prompt f-string.
|
|
319
|
+
- Filter's client-side URL substitution (`{file_base_url}` / `{archive_url}` / `{chat_id}` replacement).
|
|
320
|
+
- Filter's timestamp-based file-injection heuristic (handled natively by Open WebUI middleware).
|
|
321
|
+
|
|
322
|
+
## v0.8.12.6 (2026-04-04)
|
|
323
|
+
|
|
324
|
+
### Features
|
|
325
|
+
- **SINGLE_USER_MODE**: new env var for easy onboarding without `X-Chat-Id` header
|
|
326
|
+
- Not set (default): lenient — uses shared container + warning in tool response and server logs
|
|
327
|
+
- `true`: single-user — one container, no headers needed (recommended for Claude Desktop)
|
|
328
|
+
- `false`: strict multi-user — `X-Chat-Id` required, error if missing
|
|
329
|
+
- **MCP Registry manifest** (`server.json`): published as `io.github.Wide-Moat/open-computer-use`
|
|
330
|
+
- **Dynamic config endpoints**: documented `/system-prompt`, `/skill-list`, `/mcp-info` in docs/MCP.md
|
|
331
|
+
- **System prompt reference**: new `docs/system-prompt.md` with prompt structure documentation
|
|
332
|
+
|
|
333
|
+
### Tests
|
|
334
|
+
- 13 unit tests for single-user mode (`tests/orchestrator/test_single_user_mode.py`)
|
|
335
|
+
- 6 Docker integration tests (`tests/test-single-user-mode.sh`)
|
|
336
|
+
|
|
337
|
+
## v0.8.12.5 (2026-04-04)
|
|
338
|
+
|
|
339
|
+
### License
|
|
340
|
+
- **License change**: core code migrated from MIT to Business Source License 1.1 (BSL 1.1)
|
|
341
|
+
- Change License: Apache 2.0 (auto-converts after Change Date: 2029-04-04)
|
|
342
|
+
- Additional Use Grant: free for all use except offering as a competing managed/hosted service
|
|
343
|
+
- Attribution required: project name + link to repository
|
|
344
|
+
- Skills `describe-image` and `sub-agent` remain MIT; third-party skills unchanged
|
|
345
|
+
- Added SPDX license headers to all core source files
|
|
346
|
+
- Added NOTICE file documenting multi-license model
|
|
347
|
+
- Added LICENSE-MIT and LICENSE-APACHE alongside BSL LICENSE
|
|
348
|
+
|
|
349
|
+
## v0.8.12.4 (2026-04-02)
|
|
350
|
+
|
|
351
|
+
### Security
|
|
352
|
+
- **Pillow 11 → 12.1.1**: fixes PSD out-of-bounds write CVE; migrated `Image.LANCZOS` → `Image.Resampling.LANCZOS` for Pillow 12 API compatibility
|
|
353
|
+
- **urllib3 → 2.6.3**: decompression bomb + redirect bypass fix
|
|
354
|
+
- **cryptography → 46.0.6**: SECT curves subgroup attack fix
|
|
355
|
+
- **PyJWT → 2.12.1**: critical header extensions bypass fix
|
|
356
|
+
- **pdfminer.six → 20251230**: pickle deserialization RCE fix
|
|
357
|
+
- **pdfplumber → 0.11.9**: constraint resolution with pdfminer.six
|
|
358
|
+
- **python-multipart → 0.0.22** (orchestrator): CVE patch
|
|
359
|
+
|
|
360
|
+
### Tests
|
|
361
|
+
- 15 new unit tests for `view()` image processing path (`tests/orchestrator/test_view_image.py`)
|
|
362
|
+
- Pillow 12 API guard: fails if deprecated `Image.LANCZOS` form is used
|
|
363
|
+
- Structured content return format (`[text, image_url]`)
|
|
364
|
+
- All 5 image extensions + case-insensitive matching
|
|
365
|
+
- Container failure error handling
|
|
366
|
+
- 7 new version regression tests (`tests/test_requirements.py`)
|
|
367
|
+
- Prevents accidental downgrade of CVE-patched dependencies
|
|
368
|
+
|
|
369
|
+
## v0.8.12.3 (2026-04-01)
|
|
370
|
+
|
|
371
|
+
### Security
|
|
372
|
+
- Fix 28 GitHub CodeQL security alerts: path traversal, XSS, URL redirect vulnerabilities
|
|
373
|
+
- Centralized input sanitization via `security.py` (sanitize_chat_id, safe_path)
|
|
374
|
+
- XSS prevention in file preview with same-origin checks
|
|
375
|
+
- SRI integrity for CDN resources
|
|
376
|
+
- 40+ security tests
|
|
377
|
+
|
|
378
|
+
### MCP Tools Best Practices
|
|
379
|
+
- **Output truncation**: bash_tool output capped at 30K chars (head+tail) to protect context window
|
|
380
|
+
- **Command semantics**: grep/find/diff exit code 1 is no longer treated as error (matches Claude Code behavior)
|
|
381
|
+
- **str_replace uniqueness**: errors when old_str matches multiple times, preventing accidental edits
|
|
382
|
+
- **view threshold**: increased from 16K to 30K for consistency with bash_tool
|
|
383
|
+
- **System prompt**: added tool usage tips (prefer view over cat, grep exit codes explained)
|
|
384
|
+
- 15 new unit tests for MCP tools
|
|
385
|
+
|
|
386
|
+
### Open WebUI Patches
|
|
387
|
+
- **fix_large_tool_results**: truncates large MCP tool results (>50K chars) to prevent context window exhaustion
|
|
388
|
+
- Handles both Chat Completions and Responses API formats
|
|
389
|
+
- Truncates current results in tool loop AND historical results from DB
|
|
390
|
+
- Optional upload of full results via DOCKER_AI_UPLOAD_URL
|
|
391
|
+
- Config: `TOOL_RESULT_MAX_CHARS` (default 50000), `TOOL_RESULT_PREVIEW_CHARS` (default 2000)
|
|
392
|
+
- 10 new unit tests
|
|
393
|
+
|
|
394
|
+
## v1.0.0 - Initial Open Source Release (2026-03-30)
|
|
395
|
+
|
|
396
|
+
### Features
|
|
397
|
+
- **MCP Server**: Computer Use orchestrator with full MCP (Model Context Protocol) support
|
|
398
|
+
- **Docker Sandbox**: Isolated Ubuntu 24.04 containers with Python 3.12, Node.js 22, Java 21
|
|
399
|
+
- **CDP Browser**: Live browser viewer via Chrome DevTools Protocol proxy
|
|
400
|
+
- **Terminal**: Interactive terminal via ttyd + tmux + xterm.js
|
|
401
|
+
- **Claude Code**: Pre-installed Claude Code CLI with TTY support
|
|
402
|
+
- **Skills System**: 13 built-in public skills + 14 examples (pptx, docx, xlsx, pdf, sub-agent, playwright-cli, and more)
|
|
403
|
+
- **Open WebUI Integration**: Docker-compose stack with patched Open WebUI + PostgreSQL
|
|
404
|
+
- **Tools**: bash, str_replace, create_file, view, sub_agent
|
|
405
|
+
- **File Server**: Upload/download with archive support
|
|
406
|
+
|
|
407
|
+
### Included Tools
|
|
408
|
+
- Playwright (Chromium), LibreOffice, Tesseract OCR, FFmpeg, Pandoc
|
|
409
|
+
- ImageMagick, Graphviz, Mermaid CLI
|
|
410
|
+
- Python: docx, pptx, openpyxl, pypdf, Pillow, OpenCV, pandas, numpy
|
|
411
|
+
- Node.js: React, TypeScript, pdf-lib, pptxgenjs, sharp
|