minima-cli 0.7.1__tar.gz → 0.8.0__tar.gz
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.
- {minima_cli-0.7.1 → minima_cli-0.8.0}/.gitignore +4 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/CHANGELOG.md +32 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/Makefile +12 -1
- {minima_cli-0.7.1 → minima_cli-0.8.0}/PKG-INFO +1 -1
- minima_cli-0.8.0/docs/feature-gap-analysis.md +190 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/README.md +18 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/bun.lock +1 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/package.json +3 -2
- minima_cli-0.8.0/packages/tui/scripts/pty_capture.py +203 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/ai/providers/anthropic.ts +8 -3
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/ai/providers/google.ts +8 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/cli/main.ts +58 -13
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/minima/memory.ts +6 -1
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/minima/router.ts +6 -1
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/minima/spawn.ts +3 -4
- minima_cli-0.8.0/packages/tui/src/tools/_exa.ts +141 -0
- minima_cli-0.8.0/packages/tui/src/tools/apply_patch.ts +354 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tools/builtin.ts +6 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tools/index.ts +3 -0
- minima_cli-0.8.0/packages/tui/src/tools/question.ts +177 -0
- minima_cli-0.8.0/packages/tui/src/tools/web_fetch.ts +77 -0
- minima_cli-0.8.0/packages/tui/src/tools/web_search.ts +62 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tui/app.tsx +537 -186
- minima_cli-0.8.0/packages/tui/src/tui/busy.tsx +96 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tui/child_tree.tsx +12 -6
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tui/config_store.ts +12 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tui/context.ts +3 -0
- minima_cli-0.8.0/packages/tui/src/tui/current_action.ts +36 -0
- minima_cli-0.8.0/packages/tui/src/tui/layout.ts +326 -0
- minima_cli-0.8.0/packages/tui/src/tui/messages.tsx +199 -0
- minima_cli-0.8.0/packages/tui/src/tui/mouse-scroll.ts +87 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tui/permissions.ts +44 -7
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tui/status.tsx +9 -6
- minima_cli-0.8.0/packages/tui/src/tui/tips.ts +104 -0
- minima_cli-0.8.0/packages/tui/tests/apply_patch.test.ts +208 -0
- minima_cli-0.8.0/packages/tui/tests/busy.test.ts +38 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/config_store.test.ts +17 -0
- minima_cli-0.8.0/packages/tui/tests/current_action.test.ts +143 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/google.test.ts +50 -0
- minima_cli-0.8.0/packages/tui/tests/layout.test.ts +248 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/memory.test.ts +5 -1
- minima_cli-0.8.0/packages/tui/tests/mouse-scroll.test.ts +52 -0
- minima_cli-0.8.0/packages/tui/tests/permissions.test.ts +128 -0
- minima_cli-0.8.0/packages/tui/tests/render-buffer.test.ts +29 -0
- minima_cli-0.8.0/packages/tui/tests/tips.test.ts +93 -0
- minima_cli-0.8.0/packages/tui/tests/tools.test.ts +323 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/pyproject.toml +1 -1
- {minima_cli-0.7.1 → minima_cli-0.8.0}/uv.lock +1 -1
- minima_cli-0.7.1/packages/tui/src/tools/web_fetch.ts +0 -116
- minima_cli-0.7.1/packages/tui/src/tui/layout.ts +0 -164
- minima_cli-0.7.1/packages/tui/src/tui/messages.tsx +0 -232
- minima_cli-0.7.1/packages/tui/src/tui/mouse-scroll.ts +0 -72
- minima_cli-0.7.1/packages/tui/tests/layout.test.ts +0 -150
- minima_cli-0.7.1/packages/tui/tests/tools.test.ts +0 -164
- {minima_cli-0.7.1 → minima_cli-0.8.0}/.dockerignore +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/.env.example +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/.github/workflows/catalog-snapshot.yml +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/.github/workflows/ci.yml +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/.github/workflows/prod.yml +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/.github/workflows/release-cli.yml +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/.github/workflows/staging.yml +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/AGENTS.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/Dockerfile +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/LICENSE +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/README.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/client_sdk/minima_client/__init__.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/client_sdk/minima_client/autocapture.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/client_sdk/minima_client/client.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/client_sdk/minima_client/errors.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs/README.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs/agent-core-architecture.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs/agent-core-implementation-plan.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs/api-reference.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs/client-sdk.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs/concepts.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs/configuration.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs/examples.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs/getting-started.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs/goals-feature-plan.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs/harness.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs/multi-tenancy.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs/operations.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs/publishing.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs/seeding.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/.dockerignore +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/Dockerfile +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/components/Accordion.tsx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/components/Badge.tsx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/components/Card.tsx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/components/CardGroup.tsx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/components/Frame.tsx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/components/Note.tsx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/components/PageHeader.tsx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/components/Steps.tsx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/components/Tabs.tsx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/components/index.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/components/sidebar.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/netlify.toml +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/nginx.conf +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/package-lock.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/package.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/pages/api-reference/endpoints.mdx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/pages/harness/cli.mdx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/pages/harness/configuration.mdx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/pages/harness/installation.mdx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/pages/harness/interactive.mdx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/pages/harness/overview.mdx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/pages/harness/routing.mdx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/pages/harness/sessions.mdx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/pages/harness/tools.mdx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/pages/harness/troubleshooting.mdx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/pages/index.mdx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/pages/sdk/client-sdk.mdx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/pages/sdk/concepts.mdx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/pages/sdk/examples.mdx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/pages/sdk/getting-started.mdx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/public/images/favicon.png +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/public/images/logo-dark.svg +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/public/images/logo-light.svg +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/public/styles/global.css +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/tsconfig.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/docs-site/vocs.config.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/examples/01_quickstart.sh +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/examples/02_recommend_and_feedback.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/examples/03_constraints_and_tradeoff.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/examples/04_workflow.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/examples/05_autocapture.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/examples/06_routed_llm_call.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/examples/07_multitenant_admin.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/examples/README.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/examples/agent_escalation.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/examples/agent_escalation_learn.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/examples/agent_gemini.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/examples/agent_retention.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/examples/agent_warmup.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/examples/agent_warmup_vary.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/examples/metrics_demo.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/examples/smoke_test.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/maybe.js +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/maybe.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/.gitignore +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/biome.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/scripts/build-all.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/scripts/build.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/scripts/install.sh +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/scripts/stub-devtools.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/agent/agent.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/agent/events.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/agent/index.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/agent/loop.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/agent/state.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/agent/tools.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/ai/compat.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/ai/events.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/ai/index.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/ai/provider_catalog.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/ai/provider_quirks.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/ai/providers/_common.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/ai/providers/base.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/ai/providers/faux.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/ai/providers/index.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/ai/providers/openai_compat.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/ai/registry.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/ai/stream.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/ai/types.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/ai/usage.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/db/metrics.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/db/minima_db.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/db/rehydrate.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/db/sink.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/errtext.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/index.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/minima/budget.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/minima/catalog.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/minima/client.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/minima/config.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/minima/errors.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/minima/index.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/minima/judge.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/minima/mapping.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/minima/meter.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/minima/mubit_memory_factory.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/minima/runtime.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/minima/schemas.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/run_modes.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/session/index.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/session/store.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tools/_io.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tools/at_mentions.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tools/bash.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tools/edit.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tools/glob.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tools/grep.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tools/ls.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tools/read.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tools/schema.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tools/task.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tools/todowrite.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tools/types.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tools/write.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tui/auth.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tui/compact.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tui/model-picker.tsx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tui/projects.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tui/routing-warnings.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/tui/text-input.tsx +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/types.d.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/src/version.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/agent.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/ai.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/anthropic.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/auth.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/budget.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/candidate-filter.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/catalog.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/client.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/db.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/effort.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/error-ux.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/isolation.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/judge.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/ladder.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/minima.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/minima_memory.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/openai_compat.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/run_modes.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/session.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/spawn.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/task.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tests/thinking.test.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packages/tui/tsconfig.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packaging/homebrew/README.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/packaging/homebrew/render_formula.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_125009/recall_debug.jsonl +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_125009/strategies_run1.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_125009/strategies_run2.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_125009/strategies_run3.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_125009/tasks.jsonl +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_130252/REPORT.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_130252/recall_debug.jsonl +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_130252/strategies_run1.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_130252/strategies_run2.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_130252/strategies_run3.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_130252/strategies_run4.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_130252/strategies_run5.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_130252/summary.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_130252/tasks.jsonl +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_182838/recall_debug.jsonl +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_182838/strategies_run1.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_182838/strategies_run2.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_182838/tasks.jsonl +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_183343/REPORT.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_183343/memory_audit.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_183343/recall_debug.jsonl +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_183343/strategies_run1.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_183343/strategies_run2.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_183343/strategies_run3.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_183343/strategies_run4.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_183343/strategies_run5.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_183343/summary.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260612_183343/tasks.jsonl +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260615_101732/REPORT.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260615_101732/memory_audit.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260615_101732/recall_debug.jsonl +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260615_101732/strategies_run1.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260615_101732/strategies_run2.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260615_101732/strategies_run3.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260615_101732/strategies_run4.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260615_101732/strategies_run5.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260615_101732/summary.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260615_101732/tasks.jsonl +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260624_103307/memory_audit.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260624_103307/recall_debug.jsonl +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/20260624_103307/tasks.jsonl +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/escalate_20260615_133108/cold_probe.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/escalate_20260615_133108/summary.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/escalate_20260615_133108/tasks.jsonl +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/escalate_20260615_134209/REPORT.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/escalate_20260615_134209/cold_probe.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/escalate_20260615_134209/summary.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/escalate_20260615_134209/tasks.jsonl +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/escalation_20260612_201825/REPORT.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/escalation_20260612_201825/results.jsonl +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/escalation_20260612_201825/summary.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/playground_p1/_manifest.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/playground_p1/calibration.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/playground_p1/feedback.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/playground_p1/health.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/playground_p1/models.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/playground_p1/recommend.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/playground_p1/savings.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/playground_p1/strategies.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/playground_p1/workflow.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/retention_20260612_201828/REPORT.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/retention_20260612_201828/results.jsonl +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/retention_20260612_201828/summary.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/warmupvary_20260615_123818/REPORT.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/warmupvary_20260615_123818/summary.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/runs/warmupvary_20260615_123818/tasks.jsonl +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/scripts/eval/classify_dataset.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/scripts/eval/eval_classify.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/scripts/test-routing-web.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/scripts/test-routing.sh +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/scripts/test-routing.ts +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/__init__.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/api/__init__.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/api/auth.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/api/errors.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/api/routers/__init__.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/api/routers/calibration.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/api/routers/capabilities.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/api/routers/feedback.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/api/routers/health.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/api/routers/models.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/api/routers/recommend.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/api/routers/savings.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/api/routers/strategies.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/catalog/__init__.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/catalog/data/capability_priors.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/catalog/data/model_aliases.json +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/catalog/merge.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/catalog/refresh.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/catalog/sources/__init__.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/catalog/sources/litellm.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/catalog/sources/openrouter.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/catalog/store.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/config.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/deps.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/llm/__init__.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/llm/anthropic.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/llm/base.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/llm/gemini.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/llm/registry.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/logging.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/main.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/memory/__init__.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/memory/adapter.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/memory/keys.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/memory/records.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/memory/threadpool.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/metrics/__init__.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/metrics/calibration.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/metrics/report.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/metrics/savings.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/recommender/__init__.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/recommender/_pg_pool.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/recommender/_redis_client.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/recommender/aggregate.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/recommender/classify.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/recommender/decisionlog.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/recommender/durablerefs.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/recommender/engine.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/recommender/escalation.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/recommender/propensity.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/recommender/recstore.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/recommender/score.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/recommender/types.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/schemas/__init__.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/schemas/capabilities.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/schemas/common.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/schemas/feedback.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/schemas/models_catalog.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/schemas/recommend.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/schemas/savings.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/schemas/strategies.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/schemas/workflow.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/seeding/__init__.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/seeding/items.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/seeding/llmrouterbench.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/seeding/routerbench.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/seeding/run_seed.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/seeding/synthetic.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/tenancy/__init__.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/tenancy/context.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/tenancy/passthrough.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/src/minima/version.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/__init__.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/conftest.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/eval/BENCHMARKS.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/eval/CRITERIA.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/eval/RESULTS.md +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/eval/__init__.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/eval/harness.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/eval/llmrouterbench_config.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/eval/prompt_length_benchmark.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/eval/test_llmrouterbench_savings.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/eval/test_routerbench_savings.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/factories.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/integration/test_auth.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/integration/test_escalation_reasoner.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/integration/test_feedback_loop.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/integration/test_lesson_promotion.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/integration/test_measurement_api.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/integration/test_observed_cost_ranking.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/integration/test_recommend_api.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/integration/test_strategies_api.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/integration/test_workflow_models_health.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/live/test_cost_savings_spotcheck_live.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/live/test_escalation_fixes.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/live/test_full_surface_live.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/live/test_mubit_roundtrip.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/live/test_phase3_live.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/live/test_reasoner_live.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/live/test_recall_params_live.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_aggregate.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_aggregate_decay.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_autocapture.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_calibration_fit.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_capabilities.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_classify_benchmark.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_classify_keys.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_cluster.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_collapse_guard.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_cost_band.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_decisionlog.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_escalation.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_exploration.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_ipw.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_iterations.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_latency_quality.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_lever_cost.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_metrics.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_metrics_demo.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_neighbor_classify.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_prompt_length_benchmark.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_reasoner.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_records_catalog.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_recstore_sqlite.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_score.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_shadow_bandit.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_store_backends.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_strategies.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_tenancy.py +0 -0
- {minima_cli-0.7.1 → minima_cli-0.8.0}/tests/unit/test_thompson.py +0 -0
|
@@ -4,6 +4,38 @@ All notable changes to Minima are documented here. The format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/), and the project aims to follow
|
|
5
5
|
[Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [0.8.0] - 2026-07-06
|
|
8
|
+
|
|
9
|
+
### Added (TUI)
|
|
10
|
+
- **Fullscreen renderer (new default)** — alternate screen buffer with the prompt glued
|
|
11
|
+
to the bottom row, height-accurate transcript windowing, and in-app history scrolling
|
|
12
|
+
(mouse wheel / trackpad on by default; PgUp/PgDn always work). Opt out with
|
|
13
|
+
`--no-fullscreen` or `MINIMA_TUI_INLINE=1` for the classic inline renderer with native
|
|
14
|
+
terminal scrollback.
|
|
15
|
+
- **Live current-action line** — while a tool runs, the footer shows what the agent is
|
|
16
|
+
doing right now (e.g. `⚙ bash: git diff --stat`), with `(+N more)` for parallel tools.
|
|
17
|
+
- **New tools**: `question` (ask the user mid-run, never permission-gated),
|
|
18
|
+
`apply_patch` (multi-file add/update/delete/move), and Exa-backed `web_search` +
|
|
19
|
+
`web_fetch` (require `EXA_API_KEY`).
|
|
20
|
+
- `--thinking LEVEL` is now actually applied (was parsed but ignored).
|
|
21
|
+
- Busy indicator with rotating tips; thinking states renamed to `reasoning`/`running`.
|
|
22
|
+
|
|
23
|
+
### Fixed (TUI)
|
|
24
|
+
- **Esc / Ctrl+C abort a running turn** (was dead code behind the busy guard); a second
|
|
25
|
+
Ctrl+C within 2.5s force-quits even if a provider stream cannot be cancelled.
|
|
26
|
+
- Plan mode (read-only) blocks `apply_patch` alongside write/edit/bash.
|
|
27
|
+
- Live streaming region can never outgrow the viewport: over-budget final lines are
|
|
28
|
+
hard-sliced (fixes the fullscreen garble class and inline scrollback wipes).
|
|
29
|
+
- `/fork` and `/clone` no longer claim fake success — they say they're not implemented.
|
|
30
|
+
- glob/grep are permission-scoped as directory READS (`read from <dir>`) instead of
|
|
31
|
+
generic `run glob` prompts.
|
|
32
|
+
|
|
33
|
+
### Changed (TUI)
|
|
34
|
+
- **Permission denials are reframed for the model** ("the user declined … do not retry
|
|
35
|
+
the call and do not attempt the same action through other tools") — stops the
|
|
36
|
+
sandbox-spiral where models retry or work around a deliberate user decline.
|
|
37
|
+
- Memory-recall block is annotated reference-only (do NOT run tools from recall).
|
|
38
|
+
|
|
7
39
|
## [0.7.1] - 2026-07-05
|
|
8
40
|
|
|
9
41
|
### Changed (API behavior — note for integrators)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.PHONY: install run test lint fmt live eval seed refresh-catalog tui-install tui-test tui-check tui-build tui tui-dev
|
|
1
|
+
.PHONY: install run test lint fmt live eval seed refresh-catalog tui-install tui-test tui-check tui-build tui tui-dev tui-shot
|
|
2
2
|
|
|
3
3
|
install:
|
|
4
4
|
uv sync --extra dev # dev pulls server + reasoner extras for the full test suite
|
|
@@ -30,6 +30,9 @@ seed:
|
|
|
30
30
|
|
|
31
31
|
TUI := packages/tui
|
|
32
32
|
TUI_BIN := $(TUI)/dist/minima
|
|
33
|
+
# Default PTY-capture spec: idle interactive UI at 100x30, run from the repo root so .env loads.
|
|
34
|
+
# Emits a PNG to the gitignored playground/ so the rendered UI can be inspected as an image.
|
|
35
|
+
SPEC ?= {"cmd":["bun","run","$(TUI)/src/cli/main.ts","--offline"],"cwd":"$(CURDIR)","cols":100,"rows":30,"duration":6,"png":"$(CURDIR)/playground/tui-shot.png"}
|
|
33
36
|
|
|
34
37
|
tui-install:
|
|
35
38
|
cd $(TUI) && bun install
|
|
@@ -54,3 +57,11 @@ tui:
|
|
|
54
57
|
# Run from source via Bun (no compile step) — fastest dev loop.
|
|
55
58
|
tui-dev:
|
|
56
59
|
cd $(TUI) && bun run src/cli/main.ts $(ARGS)
|
|
60
|
+
|
|
61
|
+
# Capture a text "screenshot" of the TUI in a real PTY (pyte emulator). No committed venv — uv pulls
|
|
62
|
+
# pyte on demand. Override SPEC to size the terminal / send keystrokes; see the script's docstring:
|
|
63
|
+
# make tui-shot
|
|
64
|
+
# make tui-shot SPEC='{"cmd":["bun","run","packages/tui/src/cli/main.ts","--offline","--model","claude-haiku-4-5","--provider","anthropic"],"cwd":"'"$$PWD"'","cols":80,"rows":24,"duration":8,"steps":[{"after":2,"send":"hi<CR>"}]}'
|
|
65
|
+
tui-shot:
|
|
66
|
+
@mkdir -p $(CURDIR)/playground
|
|
67
|
+
uv run --with pyte --with pillow python $(TUI)/scripts/pty_capture.py '$(SPEC)'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: minima-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0
|
|
4
4
|
Summary: Minima CLI: cost-aware LLM model routing — recommend cheaper models, backed by Mubit memory.
|
|
5
5
|
Project-URL: Homepage, https://docs.minima.sh
|
|
6
6
|
Project-URL: Documentation, https://docs.minima.sh
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Feature Gap Analysis: minima vs. Claude Code, Codex CLI & OpenCode
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-07-02
|
|
4
|
+
**Scope:** The minima **coding agent** (`src/minima_harness/`, the `minima` CLI/TUI, v0.5.0 "Beta"). The routing service in `src/minima/` is minima's wedge, not the comparison surface.
|
|
5
|
+
**Comparators:** Claude Code (Anthropic), Codex CLI (OpenAI), OpenCode (open source).
|
|
6
|
+
**Goal:** Rank the features these three have that minima lacks, by **popularity/usability**, **time to build**, and **compatibility with minima's architecture**.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## How to read this
|
|
11
|
+
|
|
12
|
+
- **Popularity / Usability (1–5):** How strongly users expect the feature in 2026. 5 = table-stakes.
|
|
13
|
+
- **Build effort:** Engineer-days for a first solid version, with a T‑shirt size. *Lower is better.*
|
|
14
|
+
- **Compatibility (1–5):** How cleanly it slots into minima's existing architecture (tools system, routing loop, session store, extensions). 5 = drop-in / synergistic.
|
|
15
|
+
- **Priority rank:** My recommended build order, balancing all three. High value + low effort + high fit floats to the top; a couple of high-effort items still rank high because they are table-stakes.
|
|
16
|
+
|
|
17
|
+
The ranking is a recommendation, not a formula output — the numeric columns are there so you can re-weight if your priorities differ (e.g., if enterprise security matters more, sandboxing jumps up).
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Executive summary
|
|
22
|
+
|
|
23
|
+
Minima's coding agent is a competent port of the PI agent toolkit with a **genuinely differentiated core**: cost-aware model routing across a large multi-provider pool, memory-backed learning from realized outcomes, and per-turn/per-goal cost tracking. Nothing in the comparators matches that wedge.
|
|
24
|
+
|
|
25
|
+
But on the *table-stakes agent surface*, it trails all three comparators in a few specific, high-visibility places. The biggest gaps, in order: **MCP support** (all three have it; minima has none), **sub-agents** (all three; minima is single-agent), **LSP feedback** (OpenCode's marquee feature; minima scaffolded then deleted it), **web search/fetch** (Claude Code + Codex; minima has none), and **plan mode** (all three; minima has a `# TODO` where it should be).
|
|
26
|
+
|
|
27
|
+
The good news: several of these are cheap because minima already has the substrate — the tools system, the routing/judge loop, image plumbing, and `/compact` all exist. Five of the top seven items are days-scale, not weeks-scale.
|
|
28
|
+
|
|
29
|
+
### Top-15 ranked table
|
|
30
|
+
|
|
31
|
+
| # | Feature (minima lacks) | Who has it | Popularity/Usability | Build effort | Compatibility | Notes / minima synergy |
|
|
32
|
+
|---|---|---|:--:|---|:--:|---|
|
|
33
|
+
| 1 | **MCP client support** | CC, Codex, OC | 5 | ~5–8d (**M**) | 5 | Table-stakes ecosystem. MCP tools map onto the existing tool interface; routing treats them as more tools. |
|
|
34
|
+
| 2 | **Web search / fetch tool** | CC, Codex | 5 | ~2–3d (**S**) | 5 | Two new builtin tools over a search API. Highest ROI after image input. |
|
|
35
|
+
| 3 | **Expose image/vision input** | Codex | 4 | ~1–2d (**XS**) | 5 | Already plumbed end-to-end (`ai/types.py:ImageContent`, all 3 providers); only the TUI attach path is missing. Fastest win in the doc. |
|
|
36
|
+
| 4 | **Plan mode (read-only)** | CC, Codex, OC | 5 | ~3–4d (**S**) | 5 | `ROUTE_MODES=("auto","confirm")` + tool gating exist; the plan/act split is already a documented **"Phase‑3"** item (`app.py:98`) — design intent exists, de-risking the build. |
|
|
37
|
+
| 5 | **Automatic context compaction** | CC | 4 | ~2–3d (**S**) | 5 | Notice site (`app.py:945`) + reusable `summarize()` both exist; wire an auto-trigger there. |
|
|
38
|
+
| 6 | **`/review` code-review command** | Codex | 4 | ~2–3d (**S**) | 5 | Diff vs. base/commit → review prompt routed to a strong model. Pure reuse of git(bash)+routing. |
|
|
39
|
+
| 7 | **Sub-agents / multi-agent** | CC, Codex, OC | 5 | ~8–15d (**L**) | 4 | Biggest *differentiation* opportunity: route **each subagent independently to the cheapest capable model**. No competitor does cost-routed fan-out. |
|
|
40
|
+
| 8 | **LSP integration (re-add)** | OC | 4 | ~8–12d (**L**) | 4 | Feeds compiler diagnostics back into the loop → sharper quality/judge signal → strengthens minima's feedback thesis. Was scaffolded (`lsp/` now stale `.pyc` only). |
|
|
41
|
+
| 9 | **Filesystem checkpoints / rewind** | CC, OC (undo), Codex (git) | 5 | ~6–10d (**M/L**) | 4 | Session tree branches *conversations*; extend to snapshot *files* per turn + restore. |
|
|
42
|
+
| 10 | **Dedicated git integration** | CC, Codex, OC | 4 | ~3–5d (**S/M**) | 4 | Status/diff/branch awareness in context + optional auto-commit. Today git is bash-only. |
|
|
43
|
+
| 11 | **Best-of-N / parallel attempts** | Codex (`--attempts`) | 3 | ~4–6d (**M**) | 5 | Natural fit: judge + routing already exist. Run N candidates across models, judge, pick. A routing differentiator. |
|
|
44
|
+
| 12 | **Sandboxing (OS-level)** | CC, Codex | 4 | ~10–15d (**L/XL**) | 3 | bash runs with full user perms today. Platform-specific (seatbelt/landlock/container). Enterprise value. |
|
|
45
|
+
| 13 | **Session sharing (`/share`)** | OC | 3 | ~5–8d (**M**) + infra | 3 | Needs a hosting backend — Mubit could host it (synergy), otherwise heavy. |
|
|
46
|
+
| 14 | **IDE integrations (VS Code/JetBrains)** | CC, Codex, OC | 5 | ~20–40d (**XL**) | 2 | High demand but a whole new product surface; needs an exposed agent server protocol. |
|
|
47
|
+
| 15 | **Desktop / web app** | CC, OC | 4 | ~25–40d (**XL**) | 2 | Long-term; large surface, low reuse of the TUI. |
|
|
48
|
+
|
|
49
|
+
**Micro-wins (do opportunistically, each < 1 day):** fuzzy `@`-file picker (Codex has autocomplete; minima's `@path` only inlines a known path), external prompt editor via `$EDITOR`/Ctrl+G (Codex), shell completions (`codex completion …`), `/copy` of last output (minima has `/copy`+`/export` already — mostly covered).
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Recommended roadmap (sequenced)
|
|
54
|
+
|
|
55
|
+
**Sprint 1 — Quick wins (≈2 weeks, all days-scale, high visibility):**
|
|
56
|
+
`#3 image input` → `#2 web search/fetch` → `#4 plan mode` → `#5 auto-compaction` → `#6 /review`. These close five obvious "why doesn't it do X" gaps for ~10–16 engineer-days total and touch only the tools/TUI/route-mode layers.
|
|
57
|
+
|
|
58
|
+
**Sprint 2 — Table-stakes core (≈2 weeks):**
|
|
59
|
+
`#1 MCP client` (the single most important gap; unlocks the whole external-tool ecosystem) + `#10 git integration`.
|
|
60
|
+
|
|
61
|
+
**Sprint 3 — Strategic differentiators (≈4–6 weeks):**
|
|
62
|
+
`#7 cost-routed sub-agents` and `#8 LSP re-add`. These are the two places where minima's wedge (routing + outcome feedback) turns a copied feature into a *better* feature. Add `#11 best-of-N` and `#9 checkpoints` as they fit.
|
|
63
|
+
|
|
64
|
+
**Backlog / heavy bets:** `#12 sandboxing`, `#13 sharing`, `#14 IDE`, `#15 desktop/web`.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Detail & build notes
|
|
69
|
+
|
|
70
|
+
### Tier 1 — Quick wins
|
|
71
|
+
|
|
72
|
+
- **Image/vision input (#3).** The hard part is done: `ImageContent(data: base64, mime_type)` is fully defined (`ai/types.py:104`) and all three providers (`anthropic-messages`, `google-generative-ai`, `openai-completions`) already serialize images. Missing: a user path to attach one — `editor.py:21` only inline-expands *text* `@path`. Add a `-i/--image` CLI flag and a paste/`@image.png` route that builds an `ImageContent` and injects it. ~1–2 days.
|
|
73
|
+
- **Web search / fetch (#2).** Append two `AgentTool`s to `default_toolset()` (`tools/builtin.py:13`) backed by a search API (Brave/Tavily/Exa) or provider-native grounding. Minima already routes to web-grounded models (Perplexity Sonar) but has no tool. ~2–3 days.
|
|
74
|
+
- **Plan mode (#4).** `ROUTE_MODES = ("auto","confirm")` at `app.py:99`; the plan/act split is explicitly deferred to "Phase‑3" in the comment at `app.py:98`, and tool gating (`-nt`, `--exclude-tools`) already exists. Add a read-only mode that restricts to `read/grep/find/ls`, produces a plan, and gates execution behind approval. ~3–4 days. (Team roadmap intent already documented — lower design risk.)
|
|
75
|
+
- **Auto-compaction (#5).** The trigger site already exists: `app.py:945` shows `"context near limit — /compact to free space"` today, and `summarize(messages, model, *, instructions="")` (`tui/compaction.py:8`) is a clean reusable async fn. Auto-compaction = call `summarize()` at that notice point instead of just warning. ~2–3 days (revised down from 4 — the hook and summarizer both exist).
|
|
76
|
+
- **`/review` (#6).** A slash command that diffs against a base branch / uncommitted changes (git via bash), builds a review prompt, and routes it to a strong model. Pure reuse. ~2–3 days.
|
|
77
|
+
|
|
78
|
+
### Tier 2 — Table-stakes core
|
|
79
|
+
|
|
80
|
+
- **MCP client (#1).** The highest-impact gap: all three comparators support MCP; minima has neither client nor server (grep-confirmed absent). Implement a stdio + streamable-HTTP client, register discovered tools into the existing tool registry, and add config. Because minima's tool interface is already pluggable (extensions register tools today), MCP tools slot in cleanly and are automatically eligible for routing/permissions. ~5–8 days. (A `codex mcp-server`-style server that exposes minima *as* an MCP tool is a separate, later item.)
|
|
81
|
+
- **Git integration (#10).** Surface `git status`/diff/branch into context, be gitignore-aware, optionally offer auto-commit with generated messages. ~3–5 days.
|
|
82
|
+
|
|
83
|
+
### Tier 3 — Strategic differentiators (lean into the wedge)
|
|
84
|
+
|
|
85
|
+
- **Cost-routed sub-agents (#7).** All three comparators spawn subagents; **none route each subagent to the cheapest capable model.** Minima can: a spawn tool + isolated context + result synthesis, with every child going through the recommend→judge→feedback loop. This makes "fan out 5 agents" measurably cheaper and is a story no competitor can tell. The loop is already anyio-parallel, so concurrency isn't from scratch. ~8–15 days.
|
|
86
|
+
- **LSP re-add (#8).** OpenCode's headline feature: feed compiler diagnostics back after each edit so the model self-corrects. This is *directly aligned* with minima's outcome-feedback thesis — diagnostics become a quality signal for the judge and for routing feedback. Source was scaffolded and deleted (`lsp/` and `tests/harness/lsp/` hold only stale `.pyc`), so prior design exists to mine. ~8–12 days.
|
|
87
|
+
- **Best-of-N routing (#11).** Codex Cloud has `--attempts` (1–4). Minima already has a judge and multi-model routing — run N candidates across models, judge, select the winner, and log outcomes. A routing-native version of a known feature. ~4–6 days.
|
|
88
|
+
- **Checkpoints / rewind (#9).** Users expect an undo net (Claude Code rewind, OpenCode undo/redo). Snapshot touched files per turn and restore on request; integrate with the existing session tree so a rewind can branch conversation *and* files together. ~6–10 days.
|
|
89
|
+
|
|
90
|
+
### Tier 4 — Heavy / long-term
|
|
91
|
+
|
|
92
|
+
- **Sandboxing (#12):** OS-level isolation for `bash` (seatbelt on macOS, landlock/seccomp on Linux, or containers). Real enterprise value but platform-specific and invasive. ~10–15 days.
|
|
93
|
+
- **Session sharing (#13):** `/share` link. Needs a hosting backend — a natural thing for Mubit to host, otherwise expensive. ~5–8 days + infra.
|
|
94
|
+
- **IDE integrations (#14) / Desktop-web app (#15):** New product surfaces requiring an exposed agent server protocol; high demand, weeks-to-months of work, low reuse of the current TUI.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## What minima already matches (not gaps)
|
|
99
|
+
|
|
100
|
+
So this doesn't read as "behind on everything" — minima is at parity or ahead here:
|
|
101
|
+
|
|
102
|
+
- **Slash commands** (~37), **skills** (Agent Skills standard + Mubit skills), **prompt templates** as `/commands`, **custom commands** — parity.
|
|
103
|
+
- **Hooks/extensibility:** Python extensions register tools/commands/event hooks (`text`/`tool_start`/`tool_end`/`turn`/`finish`) + a git-based **package manager** (`minima install <git-url>`) — comparable to plugins.
|
|
104
|
+
- **Permissions/approval modes:** PermissionRequest modal, always-allow, `/yolo`, `--dangerously-skip-permissions`, `/edits` forced diff review — parity (minus sandboxing).
|
|
105
|
+
- **Headless/scripting:** `--print` and `--mode json` event stream — matches `codex exec` / `claude -p`.
|
|
106
|
+
- **Sessions:** append-only JSONL session **tree** with continue/resume/fork/clone/branch + goals that survive resume — arguably *ahead* of the comparators on branching.
|
|
107
|
+
- **Themes, keybinds, mouse select+copy, `/export` to Markdown, diff preview, `/stats`+`/cost` analytics** — parity or better on cost analytics.
|
|
108
|
+
- **Multi-provider:** Anthropic, Google, and an OpenAI-compatible path covering OpenAI/OpenRouter/Groq/Together/Fireworks/DeepInfra/Cerebras/DeepSeek/Mistral/xAI/Perplexity, etc. — **plus first-class local-runtime specs for Ollama, LM Studio, vLLM, llama.cpp, and LocalAI** (`ai/provider_catalog.py:110–124`, no API key required, e.g. Ollama at `localhost:11434/v1`). This is *ahead* of most comparators on local-runtime breadth. *(Corrected in iteration 5 — the initial inventory wrongly reported no local provider.)*
|
|
109
|
+
|
|
110
|
+
## Minima's unique wedge (protect and lean into)
|
|
111
|
+
|
|
112
|
+
No comparator has: **cost-aware routing across a large candidate pool**, **memory-backed learning from realized outcomes** (`/recall`, `/optimize`, learned lessons), and **cost/budget tracking** (est-vs-actual-vs-baseline savings %, budgeted `/ledger` goals). The strategic read: build the table-stakes gaps to remove reasons *not* to use minima, but make sub-agents, best-of-N, and LSP feedback **routing-native** so the copied features are cheaper/smarter than the originals.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Validation notes (iteration 2 — 2026-07-02)
|
|
117
|
+
|
|
118
|
+
The Tier‑1 estimates were re-checked against source (not just inferred from the inventory). All held; a couple were revised down because the reuse points exist:
|
|
119
|
+
|
|
120
|
+
| Claim | Verified against | Result |
|
|
121
|
+
|---|---|---|
|
|
122
|
+
| Image plumbed but not exposed | `ai/types.py:104` (`ImageContent(data:base64, mime_type)`), `editor.py:21` (text-only `@path`) | ✅ Confirmed — only the TUI attach path is missing. |
|
|
123
|
+
| Plan mode absent, scaffold exists | `app.py:98–99` (`ROUTE_MODES=("auto","confirm")`, "Phase‑3 plan/act split" comment) | ✅ Confirmed — and it's already on the team roadmap. |
|
|
124
|
+
| Auto-compaction absent | `app.py:945` (warn-only notice), `_compact` at `app.py:1226`, reusable `summarize()` at `compaction.py:8` | ✅ Confirmed — **estimate revised 2–4d → 2–3d** (hook + summarizer exist). |
|
|
125
|
+
| Web search/fetch absent | grep across `src/minima_harness/` (empty); `default_toolset()` at `tools/builtin.py:13` is the clean insertion point | ✅ Confirmed absent, insertion point trivial. |
|
|
126
|
+
| MCP absent | grep across `src/minima_harness/` (empty) | ✅ Confirmed absent (client and server). |
|
|
127
|
+
|
|
128
|
+
### Tier‑2/3 validation (iteration 3 — 2026-07-02)
|
|
129
|
+
|
|
130
|
+
Source-checked the expensive roadmap-driving items. All estimates held; compatibility claims confirmed, with sharpened risk notes:
|
|
131
|
+
|
|
132
|
+
| Item | Verified against | Result / refinement |
|
|
133
|
+
|---|---|---|
|
|
134
|
+
| MCP client (#1, ~5–8d, fit 5) | `AgentTool` dataclass (`agent/tools.py:42`: `name`/`description`/`parameters: type[BaseModel]`/async `execute`); extensions already register `AgentTool`s dynamically (`extensions.py:30`) | ✅ Fit confirmed. The **one real risk** is bridging MCP's JSON-Schema tool params → a pydantic model (`pydantic.create_model` or a passthrough model). Everything else is wiring. |
|
|
135
|
+
| Cost-routed sub-agents (#7, ~8–15d, fit 4) | `agent_loop(...)` is a plain async fn over explicit `AgentState`/`AgentLoopConfig` (`loop.py:48`); tool exec already parallel via `anyio.create_task_group()` (`loop.py:245`) | ✅ Nesting a child loop is clean (no global refactor); concurrency primitives exist. The cost-routing-per-child synergy is real — each child re-enters the same runtime. |
|
|
136
|
+
| LSP re-add (#8, ~8–12d, fit 4) | Only `.pyc` survives (`lsp/__pycache__/` client+manager+protocol + compiled tests); no `.py` source | ✅ Estimate holds. Module split is a **design hint only** — py3.14 decompilers are immature, so don't count on recovering the deleted code. |
|
|
137
|
+
| Checkpoints/rewind (#9, ~6–10d, fit 4) | `SessionStore` is a conversation DAG (`store.py`: `append`/`set_tip`/`fork_to`/`path_to`), not file state | ✅ Estimate holds; **refinement:** the DAG is a clean anchor for rewind, but the per-turn **file-snapshot layer is net-new** (fit is really 3–4). |
|
|
138
|
+
| Git integration (#10, ~3–5d, fit 4) | No dedicated git code (bash-only); context assembled in `tui/context.py` | ✅ Pure context injection (shell out to git, summarize into context) + optional auto-commit. Low risk. |
|
|
139
|
+
|
|
140
|
+
Tier‑4 items (sandboxing, sharing, IDE, desktop/web) remain first-pass — deliberately, as they're backlog.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Changelog refresh (iteration 4 — 2026-07-02)
|
|
145
|
+
|
|
146
|
+
Swept the **June–July 2026** changelogs to keep the gap list current. Net: the existing top gaps got *reinforced* (the bar rose), a few new candidates appeared, and — notably — a competitor started copying minima's wedge.
|
|
147
|
+
|
|
148
|
+
**Existing gaps reinforced (the bar moved):**
|
|
149
|
+
- **Sub-agents (#7):** Claude Code now ships **nested sub-agents (3-level depth)**, `fallbackModel` chains, and background-subagent permission prompts routed to the main session. The expectation moved from "has subagents" to "has *nested, resilient* subagents" — which makes minima's cost-routed-fan-out angle more valuable, not less.
|
|
150
|
+
- **MCP (#1):** now table-stakes-plus — Claude `claude mcp login/logout`, Codex smarter MCP tool-search, OpenCode MCP OAuth + refresh tokens + resource autocomplete. Minima is still at zero; this remains the #1 gap.
|
|
151
|
+
- **Checkpoints/rewind (#9):** Claude `/rewind` can now restore from *before* `/clear` was run.
|
|
152
|
+
- **Web search (#2):** Codex added an **indexed mode** (live search but restricted to server-approved URLs) — a safer default worth copying when minima builds this.
|
|
153
|
+
|
|
154
|
+
**New candidate gaps (June 2026):**
|
|
155
|
+
|
|
156
|
+
| Candidate | Who shipped it | Pop. | Effort | Fit | Where it slots |
|
|
157
|
+
|---|---|:--:|---|:--:|---|
|
|
158
|
+
| Test-runner auto-detection + run | OpenCode (cargo/uv/bun/dotnet) | 3 | ~2–3d (**S**) | 5 | Confirmed absent in minima (no in-agent test integration; bash-only). A tool/context add that routes a "run tests" action. Tier-1-sized quick win. |
|
|
159
|
+
| Mobile / remote control | Codex Remote GA (QR pairing), CC remote | 4 | ~20–40d (**XL**) | 2 | New surface (server + device pairing). Backlog, alongside IDE. |
|
|
160
|
+
| Org/admin policy controls (default model, governance) | Claude Code org defaults | 2–3 | ~5–8d (**M**) | 3 | Enterprise/team governance. Backlog. |
|
|
161
|
+
|
|
162
|
+
*Dropped candidate (iteration 5):* "first-class Ollama support" — **minima already has it** (see parity list below). OpenCode's only edge here is *optimized* local streaming (Ollama streaming v2, ~−40% first-token latency) — a minor perf item, not a feature gap.
|
|
163
|
+
|
|
164
|
+
**Already at parity with newly-shipped features (no action needed):**
|
|
165
|
+
- OpenCode just added a **yolo mode** to auto-approve permissions — minima has `/yolo` + `--dangerously-skip-permissions` already.
|
|
166
|
+
- OpenCode's `--session` transcript pinning — minima has `--session` **plus** a full session tree.
|
|
167
|
+
- **Local models** — OpenCode/Ollama focus notwithstanding, minima ships first-class specs for Ollama, LM Studio, vLLM, llama.cpp, and LocalAI (`ai/provider_catalog.py:110–124`). Minima is ahead here on breadth; the only competitor edge is streaming latency tuning.
|
|
168
|
+
- **Codex just shipped "rollout token budgets" that abort a turn when exhausted** — a step *toward* minima's existing cost/budget wedge (`/ledger` budgeted goals, per-turn est-vs-actual-vs-baseline savings). Signal: the market is moving toward minima's differentiator. **Suggested move:** add a hard budget-abort to `/ledger` to stay a step ahead of where Codex just landed.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Sources
|
|
173
|
+
|
|
174
|
+
- Claude Code — [25 Features Guide 2026 (MarkTechPost)](https://www.marktechpost.com/2026/06/14/claude-code-guide-2026-25-features-with-examples-demo/), [Subagents docs](https://code.claude.com/docs/en/sub-agents), [Hooks/Subagents/Skills guide](https://ofox.ai/blog/claude-code-hooks-subagents-skills-complete-guide-2026/)
|
|
175
|
+
- Codex CLI — [Features](https://developers.openai.com/codex/cli/features), [CLI docs](https://developers.openai.com/codex/cli), [Changelog](https://developers.openai.com/codex/changelog), [Codex as MCP server](https://codex.danielvaughan.com/2026/05/12/codex-cli-agents-sdk-mcp-server-multi-agent-workflows/)
|
|
176
|
+
- OpenCode — [Docs / intro](https://opencode.ai/docs/), [GitHub](https://github.com/opencode-ai/opencode), [Developer guide 2026](https://www.developersdigest.tech/blog/opencode-developer-guide-2026)
|
|
177
|
+
- June–July 2026 changelogs — [Codex changelog](https://developers.openai.com/codex/changelog), [Codex June 2026 recap](https://www.developersdigest.tech/blog/codex-changelog-june-2026), [Claude Code what's new](https://code.claude.com/docs/en/whats-new), [Claude Code June 2026 features](https://www.sitepoint.com/claude-code-june-2026-10-new-features-devs-need-to-know/), [OpenCode changelog](https://opencode.ai/changelog)
|
|
178
|
+
- minima — codebase inventory (`src/minima_harness/`), `docs/harness.md`, `README.md`
|
|
179
|
+
|
|
180
|
+
*Build estimates assume one engineer familiar with the codebase. Tier‑1 through Tier‑3 estimates have been source-validated (see Validation notes); Tier‑4 remains first-pass by design.*
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Revision history
|
|
185
|
+
|
|
186
|
+
- **Iteration 1** — Initial report: minima feature inventory + competitor research → ranked 15-item gap table + 3-sprint roadmap.
|
|
187
|
+
- **Iteration 2** — Source-validated Tier‑1 estimates; revised auto-compaction down (2–4d → 2–3d).
|
|
188
|
+
- **Iteration 3** — Source-validated Tier‑2/3 estimates (MCP JSON-Schema bridge risk, clean sub-agent nesting, LSP `.pyc`-only remnants, net-new checkpoint file layer).
|
|
189
|
+
- **Iteration 4** — June–July 2026 changelog refresh: reinforced gaps, new candidates, and the signal that Codex is converging on minima's cost-budget wedge.
|
|
190
|
+
- **Iteration 5** — Validated new candidates; **corrected a factual error** — minima already ships first-class local-runtime providers (Ollama/LM Studio/vLLM/llama.cpp/LocalAI); confirmed test-runner detection is a genuine gap. Report considered complete.
|
|
@@ -44,6 +44,24 @@ Tests are fully hermetic: the client injects a mock `fetch`, the faux provider s
|
|
|
44
44
|
LLM replies, and the Minima integration runs the full loop against an in-process mock
|
|
45
45
|
service — no network, no keys.
|
|
46
46
|
|
|
47
|
+
### Screenshot the TUI
|
|
48
|
+
|
|
49
|
+
To inspect the layout as a "screenshot", drive the TUI in a real PTY with `scripts/pty_capture.py`
|
|
50
|
+
(pyte emulator; no committed venv — `uv` pulls pyte/pillow on demand):
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# from the repo root (so .env / .env.harness load):
|
|
54
|
+
make tui-shot # idle UI at 100x30 -> playground/tui-shot.png
|
|
55
|
+
make tui-shot SPEC='{"cmd":["bun","run","packages/tui/src/cli/main.ts","--offline","--model","claude-haiku-4-5","--provider","anthropic"],"cwd":"'"$PWD"'","cols":80,"rows":24,"duration":8,"png":"'"$PWD"'/playground/shot.png","steps":[{"after":4,"send":"hi"},{"after":6,"send":"<CR>"}]}'
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
It prints the visible grid plus the **scrollback** (lines that scrolled off the top), and — when the
|
|
59
|
+
spec has a `"png"` key — rasterizes the visible grid (colors/bold, Menlo font) to a **PNG image** you
|
|
60
|
+
can open. Verifies "prompt at the bottom / clean render / scroll"; true wheel/trackpad scrolling is a
|
|
61
|
+
real-terminal, human check. Tips: give Ink ~4s to warm up and send the prompt text and `<CR>` as
|
|
62
|
+
separate `steps`. See the script's docstring for the full JSON spec and send-tokens
|
|
63
|
+
(`<CR> <UP> <PGUP> <CTRLC> …`).
|
|
64
|
+
|
|
47
65
|
## Use
|
|
48
66
|
|
|
49
67
|
```bash
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "minima-tui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Minima harness + TUI — the `minima` CLI (TypeScript/Ink; successor to the removed Python harness). Talks to the Python FastAPI recommender service over the /v1/* contract.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "FSL-1.1-Apache-2.0",
|
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
"@google/genai": "^0.3.0",
|
|
33
33
|
"@mubit-ai/sdk": "^0.10.0",
|
|
34
34
|
"ink": "^5.0.0",
|
|
35
|
-
"react": "^18.3.0"
|
|
35
|
+
"react": "^18.3.0",
|
|
36
|
+
"string-width": "^7.2.0"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
38
39
|
"@biomejs/biome": "^1.9.0",
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Capture a "screenshot" of the Minima TUI by driving it in a real PTY.
|
|
3
|
+
|
|
4
|
+
The TUI is an Ink/React app that renders inline in the terminal's MAIN screen buffer and commits
|
|
5
|
+
its finalized transcript to native scrollback via <Static>. A fixed-grid emulator alone can't show
|
|
6
|
+
that scrollback, so this uses pyte's HistoryScreen: the visible grid is the "screen", and lines that
|
|
7
|
+
scroll off the top land in history — which is exactly how we verify the transcript is scrollable.
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
uv run --with pyte python packages/tui/scripts/pty_capture.py '<json-spec>'
|
|
11
|
+
|
|
12
|
+
Spec (JSON):
|
|
13
|
+
{
|
|
14
|
+
"cmd": ["bun", "run", "src/cli/main.ts", "--offline"], # argv (required)
|
|
15
|
+
"cwd": "/path/to/repo", # optional; set to the repo root so .env(.harness) load
|
|
16
|
+
"cols": 100, "rows": 30, # terminal size (default 80x24)
|
|
17
|
+
"duration": 8, # seconds to run before SIGKILL (default 8)
|
|
18
|
+
"show_history": true, # also print scrollback above the screen (default true)
|
|
19
|
+
"steps": [ # timed keystrokes; "send" supports the tokens below
|
|
20
|
+
{"after": 2.0, "send": "hello"},
|
|
21
|
+
{"after": 3.0, "send": "<CR>"}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
Send tokens: <ESC> <CR> <ENTER> <TAB> <UP> <DOWN> <LEFT> <RIGHT> <PGUP> <PGDN> <BS>
|
|
26
|
+
<CTRLC> <CTRLL> <CTRLP> <CTRLR> <SPACE>
|
|
27
|
+
|
|
28
|
+
Notes:
|
|
29
|
+
- A present CI env var (even empty) flips Ink into non-interactive mode, so it is stripped.
|
|
30
|
+
- The child is SIGKILLed at `duration` (before it can emit its exit sequences), so the last Ink
|
|
31
|
+
paint stays on the emulated grid.
|
|
32
|
+
- pyte models a fixed grid + scrollback; it proves "prompt at the bottom / no void / clean render /
|
|
33
|
+
lines in scrollback". True wheel/trackpad scrolling is a real-terminal, human check.
|
|
34
|
+
"""
|
|
35
|
+
import fcntl
|
|
36
|
+
import json
|
|
37
|
+
import os
|
|
38
|
+
import select
|
|
39
|
+
import signal
|
|
40
|
+
import struct
|
|
41
|
+
import subprocess
|
|
42
|
+
import sys
|
|
43
|
+
import termios
|
|
44
|
+
import time
|
|
45
|
+
|
|
46
|
+
import pyte
|
|
47
|
+
|
|
48
|
+
TOKENS = {
|
|
49
|
+
"<ESC>": "\x1b", "<CR>": "\r", "<ENTER>": "\r", "<TAB>": "\t",
|
|
50
|
+
"<UP>": "\x1b[A", "<DOWN>": "\x1b[B", "<LEFT>": "\x1b[D", "<RIGHT>": "\x1b[C",
|
|
51
|
+
"<PGUP>": "\x1b[5~", "<PGDN>": "\x1b[6~", "<BS>": "\x7f",
|
|
52
|
+
"<CTRLC>": "\x03", "<CTRLL>": "\x0c", "<CTRLP>": "\x10", "<CTRLR>": "\x12",
|
|
53
|
+
"<SPACE>": " ",
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def expand(s: str) -> bytes:
|
|
58
|
+
for k, v in TOKENS.items():
|
|
59
|
+
s = s.replace(k, v)
|
|
60
|
+
return s.encode()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def render_row(row, cols: int) -> str:
|
|
64
|
+
"""A pyte row (sparse column->Char mapping) as a plain string, trailing space trimmed."""
|
|
65
|
+
return "".join(row[x].data for x in range(cols)).rstrip()
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# pyte's 16 ANSI color names -> RGB. Note pyte uses "brown" for SGR 33 (not "yellow"),
|
|
69
|
+
# and 256/truecolor come through as "RRGGBB" hex strings handled in _resolve().
|
|
70
|
+
_PALETTE = {
|
|
71
|
+
"black": (0, 0, 0), "red": (194, 54, 33), "green": (37, 188, 36),
|
|
72
|
+
"brown": (173, 173, 39), "blue": (73, 46, 225), "magenta": (211, 56, 211),
|
|
73
|
+
"cyan": (51, 187, 200), "white": (203, 204, 205),
|
|
74
|
+
"brightblack": (129, 131, 131), "brightred": (252, 57, 31),
|
|
75
|
+
"brightgreen": (49, 231, 34), "brightbrown": (234, 236, 35),
|
|
76
|
+
"brightblue": (88, 51, 255), "brightmagenta": (249, 53, 248),
|
|
77
|
+
"brightcyan": (20, 240, 240), "brightwhite": (233, 235, 235),
|
|
78
|
+
}
|
|
79
|
+
_DEFAULT_FG = (205, 205, 205)
|
|
80
|
+
_DEFAULT_BG = (13, 13, 13)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _resolve(color: str, default):
|
|
84
|
+
if color == "default":
|
|
85
|
+
return default
|
|
86
|
+
if color in _PALETTE:
|
|
87
|
+
return _PALETTE[color]
|
|
88
|
+
try: # 256/truecolor arrive as "RRGGBB" hex
|
|
89
|
+
return (int(color[0:2], 16), int(color[2:4], 16), int(color[4:6], 16))
|
|
90
|
+
except (ValueError, IndexError):
|
|
91
|
+
return default
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def render_png(screen, path: str, font_size: int = 18) -> None:
|
|
95
|
+
"""Rasterize the visible pyte grid (with colors/bold/reverse) to a PNG via Pillow + Menlo, so a
|
|
96
|
+
reader can visually inspect the TUI. Requires pillow (`uv run --with pillow`)."""
|
|
97
|
+
import unicodedata
|
|
98
|
+
|
|
99
|
+
from PIL import Image, ImageDraw, ImageFont
|
|
100
|
+
|
|
101
|
+
font_path = "/System/Library/Fonts/Menlo.ttc"
|
|
102
|
+
regular = ImageFont.truetype(font_path, font_size, index=0)
|
|
103
|
+
bold = ImageFont.truetype(font_path, font_size, index=1)
|
|
104
|
+
ascent, descent = regular.getmetrics()
|
|
105
|
+
cw = int(round(regular.getlength("M"))) # monospace advance width
|
|
106
|
+
ch = ascent + descent # cell height
|
|
107
|
+
cols, rows = screen.columns, screen.lines
|
|
108
|
+
|
|
109
|
+
img = Image.new("RGB", (cols * cw, rows * ch), _DEFAULT_BG)
|
|
110
|
+
d = ImageDraw.Draw(img)
|
|
111
|
+
for y in range(rows):
|
|
112
|
+
line = screen.buffer[y] # defaultdict; indexing empty cells returns default_char
|
|
113
|
+
x = 0
|
|
114
|
+
while x < cols:
|
|
115
|
+
c = line[x]
|
|
116
|
+
fg = _resolve(c.fg, _DEFAULT_FG)
|
|
117
|
+
bg = _resolve(c.bg, _DEFAULT_BG)
|
|
118
|
+
if c.reverse:
|
|
119
|
+
fg, bg = bg, fg
|
|
120
|
+
wide = 2 if (c.data and unicodedata.east_asian_width(c.data[0]) in "WF") else 1
|
|
121
|
+
px, py = x * cw, y * ch
|
|
122
|
+
if bg != _DEFAULT_BG:
|
|
123
|
+
d.rectangle([px, py, px + cw * wide - 1, py + ch - 1], fill=bg)
|
|
124
|
+
if c.data and c.data != " ":
|
|
125
|
+
d.text((px, py), c.data, font=(bold if c.bold else regular), fill=fg)
|
|
126
|
+
x += wide
|
|
127
|
+
img.save(path, "PNG")
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def main() -> int:
|
|
131
|
+
if len(sys.argv) < 2:
|
|
132
|
+
print("usage: pty_capture.py '<json-spec>'", file=sys.stderr)
|
|
133
|
+
return 2
|
|
134
|
+
spec = json.loads(sys.argv[1])
|
|
135
|
+
rows = spec.get("rows", 24)
|
|
136
|
+
cols = spec.get("cols", 80)
|
|
137
|
+
duration = spec.get("duration", 8)
|
|
138
|
+
steps = spec.get("steps", [])
|
|
139
|
+
show_history = spec.get("show_history", True)
|
|
140
|
+
|
|
141
|
+
master, slave = os.openpty()
|
|
142
|
+
fcntl.ioctl(slave, termios.TIOCSWINSZ, struct.pack("HHHH", rows, cols, 0, 0))
|
|
143
|
+
env = dict(os.environ)
|
|
144
|
+
env["TERM"] = "xterm-256color"
|
|
145
|
+
env["COLUMNS"] = str(cols)
|
|
146
|
+
env["LINES"] = str(rows)
|
|
147
|
+
env.pop("CI", None) # a present CI var (even empty) flips Ink into non-interactive mode
|
|
148
|
+
|
|
149
|
+
p = subprocess.Popen(
|
|
150
|
+
spec["cmd"], stdin=slave, stdout=slave, stderr=slave,
|
|
151
|
+
env=env, cwd=spec.get("cwd"), close_fds=True, preexec_fn=os.setsid,
|
|
152
|
+
)
|
|
153
|
+
os.close(slave)
|
|
154
|
+
|
|
155
|
+
start = time.time()
|
|
156
|
+
sent = [False] * len(steps)
|
|
157
|
+
raw = bytearray()
|
|
158
|
+
while time.time() - start < duration:
|
|
159
|
+
now = time.time() - start
|
|
160
|
+
for i, s in enumerate(steps):
|
|
161
|
+
if not sent[i] and now >= s["after"]:
|
|
162
|
+
os.write(master, expand(s["send"]))
|
|
163
|
+
sent[i] = True
|
|
164
|
+
r, _, _ = select.select([master], [], [], 0.1)
|
|
165
|
+
if r:
|
|
166
|
+
try:
|
|
167
|
+
data = os.read(master, 65536)
|
|
168
|
+
except OSError:
|
|
169
|
+
break
|
|
170
|
+
if not data:
|
|
171
|
+
break
|
|
172
|
+
raw += data
|
|
173
|
+
|
|
174
|
+
try:
|
|
175
|
+
os.killpg(os.getpgid(p.pid), signal.SIGKILL)
|
|
176
|
+
except Exception:
|
|
177
|
+
pass
|
|
178
|
+
|
|
179
|
+
# Feed the full accumulated stream once (robust vs. escapes split across reads). HistoryScreen
|
|
180
|
+
# keeps lines that scrolled off the top in `history.top` — that is the native scrollback.
|
|
181
|
+
screen = pyte.HistoryScreen(cols, rows, history=5000, ratio=0.5)
|
|
182
|
+
pyte.ByteStream(screen).feed(bytes(raw))
|
|
183
|
+
|
|
184
|
+
if show_history and screen.history.top:
|
|
185
|
+
hist = list(screen.history.top)
|
|
186
|
+
print(f"=== SCROLLBACK ({len(hist)} lines above the screen) ===")
|
|
187
|
+
for idx, row in enumerate(hist):
|
|
188
|
+
print(f"h{idx:03} |{render_row(row, cols)}")
|
|
189
|
+
|
|
190
|
+
print(f"=== SCREEN {cols}x{rows} (visible) ===")
|
|
191
|
+
for idx, line in enumerate(screen.display):
|
|
192
|
+
print(f"{idx:2} |{line.rstrip()}")
|
|
193
|
+
print(f"=== {len(screen.display)} visible rows; {len(screen.history.top)} in scrollback ===")
|
|
194
|
+
|
|
195
|
+
png = spec.get("png")
|
|
196
|
+
if png:
|
|
197
|
+
render_png(screen, png)
|
|
198
|
+
print(f"=== wrote PNG: {png} ===")
|
|
199
|
+
return 0
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
if __name__ == "__main__":
|
|
203
|
+
sys.exit(main())
|
|
@@ -48,7 +48,10 @@ const EPHEMERAL = { type: "ephemeral" };
|
|
|
48
48
|
/** Minimal client shape this provider consumes; the real SDK client satisfies it. */
|
|
49
49
|
export interface AnthropicClientLike {
|
|
50
50
|
messages: {
|
|
51
|
-
stream(
|
|
51
|
+
stream(
|
|
52
|
+
opts: Record<string, unknown>,
|
|
53
|
+
requestOptions?: { signal?: AbortSignal },
|
|
54
|
+
): AsyncIterable<AnthropicStreamEvent>;
|
|
52
55
|
};
|
|
53
56
|
}
|
|
54
57
|
export interface AnthropicStreamEvent {
|
|
@@ -85,7 +88,9 @@ export class AnthropicProvider {
|
|
|
85
88
|
|
|
86
89
|
yield startEv(assistant);
|
|
87
90
|
try {
|
|
88
|
-
|
|
91
|
+
// Forward the abort signal so Esc/Ctrl+C actually cancels the in-flight request — without
|
|
92
|
+
// it, agent.abort() sets the flag but the SDK keeps streaming to completion.
|
|
93
|
+
const s = client.messages.stream(kwargs, { signal: opts.signal });
|
|
89
94
|
for await (const ev of s) {
|
|
90
95
|
const etype = ev.type;
|
|
91
96
|
if (etype === "message_start") {
|
|
@@ -190,7 +195,7 @@ export class AnthropicProvider {
|
|
|
190
195
|
* SDK expects milliseconds. Passing seconds through gave every request a 30-60ms
|
|
191
196
|
* deadline: all Claude calls died with "Request timed out". */
|
|
192
197
|
export function sdkTimeoutMs(options: Record<string, unknown>): number {
|
|
193
|
-
return Math.round((
|
|
198
|
+
return Math.round(Number(options.timeout ?? 60) * 1000);
|
|
194
199
|
}
|
|
195
200
|
|
|
196
201
|
async function buildClient(options: Record<string, unknown>): Promise<AnthropicClientLike> {
|
|
@@ -100,6 +100,9 @@ export class GoogleProvider {
|
|
|
100
100
|
|
|
101
101
|
try {
|
|
102
102
|
const contents = toContents(context);
|
|
103
|
+
// NOTE: @google/genai 0.3.x exposes no abortSignal on generateContentStream, so opts.signal
|
|
104
|
+
// cannot cancel an in-flight Gemini stream here (unlike the Anthropic/OpenAI providers).
|
|
105
|
+
// Abort still stops the multi-turn loop between turns; mid-stream cancellation needs an SDK bump.
|
|
103
106
|
const stream = await client.models.generateContentStream({
|
|
104
107
|
model: model.id,
|
|
105
108
|
contents,
|
|
@@ -290,5 +293,10 @@ function convertSchema(node: Record<string, unknown>): Record<string, unknown> {
|
|
|
290
293
|
}
|
|
291
294
|
out.properties = props;
|
|
292
295
|
}
|
|
296
|
+
// Array element schema. Gemini REQUIRES `items` for an ARRAY type — omitting it makes the
|
|
297
|
+
// API reject the whole request with a 400 "exception parsing response", so recurse into it.
|
|
298
|
+
if (node.items && typeof node.items === "object") {
|
|
299
|
+
out.items = convertSchema(node.items as Record<string, unknown>);
|
|
300
|
+
}
|
|
293
301
|
return out;
|
|
294
302
|
}
|