marim-harness 0.1.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.
- marim_harness-0.1.0/.env.example +178 -0
- marim_harness-0.1.0/.gitea/workflows/ci.yml +71 -0
- marim_harness-0.1.0/.gitea/workflows/release.yml +55 -0
- marim_harness-0.1.0/.gitignore +56 -0
- marim_harness-0.1.0/CHANGELOG.md +39 -0
- marim_harness-0.1.0/CLAUDE.md +234 -0
- marim_harness-0.1.0/CONTRIBUTING.md +87 -0
- marim_harness-0.1.0/LICENSE +21 -0
- marim_harness-0.1.0/PKG-INFO +362 -0
- marim_harness-0.1.0/README.md +301 -0
- marim_harness-0.1.0/SECURITY.md +46 -0
- marim_harness-0.1.0/coding-guidelines.md +92 -0
- marim_harness-0.1.0/docs/README.md +52 -0
- marim_harness-0.1.0/docs/architecture.md +169 -0
- marim_harness-0.1.0/docs/assets/demo.gif +0 -0
- marim_harness-0.1.0/docs/embedding.md +89 -0
- marim_harness-0.1.0/docs/examples/agents/cli-worker.md +9 -0
- marim_harness-0.1.0/docs/guides/headless.md +322 -0
- marim_harness-0.1.0/docs/guides/hooks.md +322 -0
- marim_harness-0.1.0/docs/guides/mcp.md +254 -0
- marim_harness-0.1.0/docs/guides/sessions.md +246 -0
- marim_harness-0.1.0/docs/guides/skills-and-memory.md +236 -0
- marim_harness-0.1.0/docs/guides/subagents.md +269 -0
- marim_harness-0.1.0/docs/guides/trust.md +259 -0
- marim_harness-0.1.0/docs/guides/tui.md +343 -0
- marim_harness-0.1.0/docs/guides/workflows.md +240 -0
- marim_harness-0.1.0/docs/internal/context-management-report.md +415 -0
- marim_harness-0.1.0/docs/internal/review-coding-guidelines-2026-03-23.md +186 -0
- marim_harness-0.1.0/docs/internal/reviews/2026-07-03-codebase-review-no-interfaces.md +131 -0
- marim_harness-0.1.0/docs/internal/reviews/2026-07-03-codebase-review.md +192 -0
- marim_harness-0.1.0/docs/internal/reviews/2026-07-03-review-parallel-agents-3ef6c46.md +149 -0
- marim_harness-0.1.0/docs/internal/reviews/2026-07-21-full-codebase-review.md +223 -0
- marim_harness-0.1.0/docs/lsp-plugins.md +109 -0
- marim_harness-0.1.0/docs/plugins.md +75 -0
- marim_harness-0.1.0/docs/reference/configuration.md +330 -0
- marim_harness-0.1.0/docs/reference/serve-api.md +568 -0
- marim_harness-0.1.0/docs/sdk/README.md +94 -0
- marim_harness-0.1.0/docs/sdk/builder.md +153 -0
- marim_harness-0.1.0/docs/sdk/custom-tools.md +103 -0
- marim_harness-0.1.0/docs/sdk/getting-started.md +115 -0
- marim_harness-0.1.0/docs/sdk/integrations.md +108 -0
- marim_harness-0.1.0/docs/sdk/sessions-and-state.md +83 -0
- marim_harness-0.1.0/docs/sdk/subagents.md +84 -0
- marim_harness-0.1.0/docs/sdk/testing.md +128 -0
- marim_harness-0.1.0/docs/sdk/turns.md +123 -0
- marim_harness-0.1.0/docs/sdk/tutorial-daily-report.md +320 -0
- marim_harness-0.1.0/docs/superpowers/plans/2025-07-19-deps-refactor.md +386 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-03-23-coding-guidelines.md +178 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-15-marim-harness.md +1596 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-16-agent-refactor.md +988 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-16-multi-provider.md +1126 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-16-subagent-mcp.md +793 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-16-tui-aesthetics.md +777 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-17-lsp-integration.md +1568 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-17-marim-hooks-engine.md +1499 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-18-ask-user-tool.md +853 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-18-background-subagents-wake.md +859 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-18-decouple-claude-skill-roots.md +307 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-18-worktree-workflow.md +751 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-19-cli-lazy-imports.md +316 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-19-decompose-harnessapp.md +344 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-19-image-input.md +1382 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-19-output-offload.md +707 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-22-agentmemory-missing-hooks.md +730 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-22-plugin-system.md +2829 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-22-review-recommendations.md +988 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-22-review-refactor.md +68 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-22-token-efficiency-prompt-caching.md +346 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-23-checkpoint-rewind.md +1215 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-23-deps-services-split.md +324 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-23-harness-bind-ui.md +180 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-23-harness-init-extraction.md +252 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-23-message-queueing.md +640 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-23-message-steering.md +552 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-23-review-followups-2.md +98 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-23-steer-fallback-key.md +130 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-24-detached-card-fill.md +464 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-24-detached-fanout.md +538 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-24-harnessapp-decomposition.md +742 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-24-scrollable-panels.md +180 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-24-slash-command-autocomplete.md +798 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-24-subagents-screen.md +1472 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-24-tool-rendering-redesign.md +695 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-25-ask-user-chat-display.md +453 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-25-claude-cli-subagent.md +1161 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-25-marim-mcp-cli.md +718 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-25-resumable-subagent-transcripts.md +838 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-25-subagents-live-streaming.md +496 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-26-multi-provider-model-picker.md +730 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-26-native-deep-research.md +442 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-26-turn-controller-extraction.md +439 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-28-plan-mode.md +948 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-28-tool-catalog.md +451 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-28-tool-search.md +892 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-29-claude-cli-provider.md +1283 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-29-mcp-instructions-on-discovery.md +389 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-29-mcp-instructions-v2-cacheable.md +364 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-30-settings-screen-ux.md +565 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-06-30-subagent-hierarchy.md +663 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-01-inline-interaction-panels.md +807 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-01-shell-passthrough.md +898 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-01-stringified-tool-args-coercion.md +667 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-02-after-deps-tui.md +591 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-02-cli-subagent-demux.md +1530 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-02-context-window-budget.md +1151 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-02-job-poll-guard.md +399 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-02-paste-collapsing.md +484 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-02-scraper-gen-plugin.md +631 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-02-spawn-after-dependencies.md +751 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-02-subagent-context-masking.md +962 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-03-claude-md-fallback.md +284 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-03-cli-subagent-resume.md +691 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-03-subagent-resume.md +1413 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-06-marim-serve.md +2831 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-06-plan-presentation-tui.md +953 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-07-forge-tea-toolset.md +1338 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-07-lsp-toolset-deferral.md +491 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-07-plancard-feedback.md +424 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-08-embeddable-sdk-builder.md +1276 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-10-codemode-experiment.md +1415 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-10-decompose-runner-controller.md +579 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-11-cyclomatic-complexity-reduction.md +521 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-11-dynamic-workflows.md +1479 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-11-providers-settings.md +1352 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-11-scratchpad-directory.md +1160 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-11-tui-regroup.md +186 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-11-workflows-polish.md +1311 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-12-deep-research-workflows.md +810 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-12-workflow-resume-journal.md +1078 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-13-subagent-model-tiers.md +1017 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-21-advisor-tool.md +1780 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-21-compaction-pipeline.md +1292 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-21-lsp-plugins.md +1558 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-22-memory-gaps.md +616 -0
- marim_harness-0.1.0/docs/superpowers/plans/2026-07-22-thinking-level.md +2203 -0
- marim_harness-0.1.0/docs/superpowers/specs/2025-07-19-deps-refactor-design.md +195 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-15-marim-harness-design.md +219 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-16-agent-refactor-design.md +151 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-16-subagent-mcp-design.md +184 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-16-tui-aesthetics-design.md +175 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-17-lsp-integration-design.md +161 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-17-marim-hooks-engine-design.md +233 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-18-ask-user-tool-design.md +215 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-18-background-subagents-wake-design.md +270 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-18-decouple-claude-skill-roots-design.md +165 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-18-worktree-subagent-isolation-notes.md +110 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-18-worktree-workflow-design.md +290 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-19-cli-lazy-imports-design.md +175 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-19-decompose-harnessapp-design.md +138 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-19-edit-diff-rendering-design.md +111 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-19-grep-optimization-design.md +99 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-19-image-input-design.md +205 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-19-output-offload-design.md +164 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-19-session-turn-duration-design.md +88 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-19-title-idle-working-design.md +76 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-20-compaction-summary-widget-design.md +96 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-22-agentmemory-missing-hooks-design.md +153 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-22-plugin-system-design.md +314 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-22-token-efficiency-prompt-caching-design.md +175 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-23-message-queueing-design.md +82 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-23-message-steering-design.md +81 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-23-steer-fallback-key-design.md +42 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-24-detached-card-fill-design.md +119 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-24-detached-fanout-design.md +180 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-24-harnessapp-decomposition-design.md +159 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-24-slash-command-autocomplete-design.md +194 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-24-subagents-screen-design.md +205 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-24-tool-rendering-redesign-design.md +154 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-25-ask-user-chat-display-design.md +169 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-25-claude-cli-subagent-design.md +196 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-25-marim-mcp-cli-design.md +126 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-25-resumable-subagent-transcripts-design.md +194 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-25-subagents-live-streaming-design.md +117 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-26-multi-provider-model-picker-design.md +165 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-26-native-deep-research-design.md +185 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-28-plan-mode-design.md +156 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-28-tool-catalog-design.md +131 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-28-tool-search-design.md +143 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-29-claude-cli-provider-design.md +227 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-29-mcp-instructions-on-discovery-design.md +134 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-29-mcp-instructions-v2-cacheable-design.md +141 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-29-nested-subagents-design.md +141 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-30-settings-screen-ux-design.md +181 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-06-30-subagent-hierarchy-design.md +174 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-01-inline-interaction-panels-design.md +111 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-01-shell-passthrough-design.md +117 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-01-stringified-tool-args-coercion-design.md +117 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-02-after-deps-tui-design.md +129 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-02-context-window-budget-design.md +162 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-02-job-poll-guard-design.md +133 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-02-paste-collapsing-design.md +85 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-02-scraper-gen-plugin-design.md +165 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-02-spawn-after-dependencies-design.md +163 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-03-claude-md-fallback-design.md +101 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-03-cli-subagent-resume-design.md +167 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-03-subagent-resume-design.md +211 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-06-marim-serve-design.md +239 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-06-plan-presentation-tui-design.md +182 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-07-gitea-tea-toolset-design.md +156 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-07-lsp-toolset-deferral-design.md +145 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-07-plancard-feedback-design.md +171 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-08-embeddable-sdk-builder-design.md +207 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-10-acp-interface-design.md +226 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-10-codemode-experiment-design.md +155 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-11-dynamic-workflows-design.md +187 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-11-providers-settings-design.md +158 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-11-scratchpad-design.md +133 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-11-workflows-polish-design.md +184 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-12-deep-research-workflows-design.md +173 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-12-workflow-resumability-journal-design.md +199 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-13-subagent-model-tiers-design.md +152 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-21-advisor-tool-design.md +177 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-21-compaction-pipeline-design.md +208 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-21-lsp-plugins-design.md +221 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-22-memory-gaps-design.md +113 -0
- marim_harness-0.1.0/docs/superpowers/specs/2026-07-22-thinking-level-design.md +284 -0
- marim_harness-0.1.0/examples/README.md +49 -0
- marim_harness-0.1.0/examples/agentmemory/.marim-plugin/plugin.json +46 -0
- marim_harness-0.1.0/examples/agentmemory/README.md +79 -0
- marim_harness-0.1.0/examples/embedding/README.md +58 -0
- marim_harness-0.1.0/examples/embedding/assistant.py +132 -0
- marim_harness-0.1.0/examples/playwright/.marim-plugin/plugin.json +8 -0
- marim_harness-0.1.0/examples/playwright/AGENTS.md +30 -0
- marim_harness-0.1.0/examples/playwright/README.md +48 -0
- marim_harness-0.1.0/examples/playwright/agents/generator.md +67 -0
- marim_harness-0.1.0/examples/playwright/agents/healer.md +50 -0
- marim_harness-0.1.0/examples/playwright/agents/planner.md +55 -0
- marim_harness-0.1.0/examples/playwright/mcp.json +8 -0
- marim_harness-0.1.0/examples/playwright/skills/e2e-tests/SKILL.md +69 -0
- marim_harness-0.1.0/examples/scraper-gen/.marim-plugin/plugin.json +8 -0
- marim_harness-0.1.0/examples/scraper-gen/README.md +36 -0
- marim_harness-0.1.0/examples/scraper-gen/agents/generator.md +130 -0
- marim_harness-0.1.0/examples/scraper-gen/agents/healer.md +43 -0
- marim_harness-0.1.0/examples/scraper-gen/agents/planner.md +80 -0
- marim_harness-0.1.0/examples/scraper-gen/skills/web-scrapers/SKILL.md +131 -0
- marim_harness-0.1.0/examples/superpowers/.marim-plugin/plugin.json +34 -0
- marim_harness-0.1.0/examples/superpowers/LICENSE +21 -0
- marim_harness-0.1.0/examples/superpowers/README.md +52 -0
- marim_harness-0.1.0/examples/superpowers/hooks/marim-session-start.sh +32 -0
- marim_harness-0.1.0/examples/superpowers/skills/brainstorming/SKILL.md +159 -0
- marim_harness-0.1.0/examples/superpowers/skills/brainstorming/scripts/frame-template.html +213 -0
- marim_harness-0.1.0/examples/superpowers/skills/brainstorming/scripts/helper.js +167 -0
- marim_harness-0.1.0/examples/superpowers/skills/brainstorming/scripts/server.cjs +723 -0
- marim_harness-0.1.0/examples/superpowers/skills/brainstorming/scripts/start-server.sh +209 -0
- marim_harness-0.1.0/examples/superpowers/skills/brainstorming/scripts/stop-server.sh +120 -0
- marim_harness-0.1.0/examples/superpowers/skills/brainstorming/spec-document-reviewer-prompt.md +49 -0
- marim_harness-0.1.0/examples/superpowers/skills/brainstorming/visual-companion.md +291 -0
- marim_harness-0.1.0/examples/superpowers/skills/dispatching-parallel-agents/SKILL.md +185 -0
- marim_harness-0.1.0/examples/superpowers/skills/executing-plans/SKILL.md +70 -0
- marim_harness-0.1.0/examples/superpowers/skills/finishing-a-development-branch/SKILL.md +241 -0
- marim_harness-0.1.0/examples/superpowers/skills/receiving-code-review/SKILL.md +213 -0
- marim_harness-0.1.0/examples/superpowers/skills/requesting-code-review/SKILL.md +103 -0
- marim_harness-0.1.0/examples/superpowers/skills/requesting-code-review/code-reviewer.md +172 -0
- marim_harness-0.1.0/examples/superpowers/skills/subagent-driven-development/SKILL.md +418 -0
- marim_harness-0.1.0/examples/superpowers/skills/subagent-driven-development/implementer-prompt.md +139 -0
- marim_harness-0.1.0/examples/superpowers/skills/subagent-driven-development/scripts/review-package +44 -0
- marim_harness-0.1.0/examples/superpowers/skills/subagent-driven-development/scripts/sdd-workspace +22 -0
- marim_harness-0.1.0/examples/superpowers/skills/subagent-driven-development/scripts/task-brief +40 -0
- marim_harness-0.1.0/examples/superpowers/skills/subagent-driven-development/task-reviewer-prompt.md +188 -0
- marim_harness-0.1.0/examples/superpowers/skills/systematic-debugging/CREATION-LOG.md +119 -0
- marim_harness-0.1.0/examples/superpowers/skills/systematic-debugging/SKILL.md +296 -0
- marim_harness-0.1.0/examples/superpowers/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- marim_harness-0.1.0/examples/superpowers/skills/systematic-debugging/condition-based-waiting.md +115 -0
- marim_harness-0.1.0/examples/superpowers/skills/systematic-debugging/defense-in-depth.md +122 -0
- marim_harness-0.1.0/examples/superpowers/skills/systematic-debugging/find-polluter.sh +63 -0
- marim_harness-0.1.0/examples/superpowers/skills/systematic-debugging/root-cause-tracing.md +169 -0
- marim_harness-0.1.0/examples/superpowers/skills/systematic-debugging/test-academic.md +14 -0
- marim_harness-0.1.0/examples/superpowers/skills/systematic-debugging/test-pressure-1.md +58 -0
- marim_harness-0.1.0/examples/superpowers/skills/systematic-debugging/test-pressure-2.md +68 -0
- marim_harness-0.1.0/examples/superpowers/skills/systematic-debugging/test-pressure-3.md +69 -0
- marim_harness-0.1.0/examples/superpowers/skills/test-driven-development/SKILL.md +371 -0
- marim_harness-0.1.0/examples/superpowers/skills/test-driven-development/testing-anti-patterns.md +299 -0
- marim_harness-0.1.0/examples/superpowers/skills/using-git-worktrees/SKILL.md +202 -0
- marim_harness-0.1.0/examples/superpowers/skills/using-superpowers/SKILL.md +62 -0
- marim_harness-0.1.0/examples/superpowers/skills/using-superpowers/references/antigravity-tools.md +23 -0
- marim_harness-0.1.0/examples/superpowers/skills/using-superpowers/references/codex-tools.md +39 -0
- marim_harness-0.1.0/examples/superpowers/skills/using-superpowers/references/pi-tools.md +16 -0
- marim_harness-0.1.0/examples/superpowers/skills/verification-before-completion/SKILL.md +139 -0
- marim_harness-0.1.0/examples/superpowers/skills/writing-plans/SKILL.md +174 -0
- marim_harness-0.1.0/examples/superpowers/skills/writing-plans/plan-document-reviewer-prompt.md +49 -0
- marim_harness-0.1.0/examples/superpowers/skills/writing-skills/SKILL.md +689 -0
- marim_harness-0.1.0/examples/superpowers/skills/writing-skills/anthropic-best-practices.md +1150 -0
- marim_harness-0.1.0/examples/superpowers/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- marim_harness-0.1.0/examples/superpowers/skills/writing-skills/graphviz-conventions.dot +172 -0
- marim_harness-0.1.0/examples/superpowers/skills/writing-skills/persuasion-principles.md +187 -0
- marim_harness-0.1.0/examples/superpowers/skills/writing-skills/render-graphs.js +168 -0
- marim_harness-0.1.0/examples/superpowers/skills/writing-skills/testing-skills-with-subagents.md +384 -0
- marim_harness-0.1.0/examples/superpowers/update-from-upstream.sh +79 -0
- marim_harness-0.1.0/install.sh +115 -0
- marim_harness-0.1.0/pyproject.toml +124 -0
- marim_harness-0.1.0/src/marim_harness/__init__.py +36 -0
- marim_harness-0.1.0/src/marim_harness/__main__.py +4 -0
- marim_harness-0.1.0/src/marim_harness/advisor.py +150 -0
- marim_harness-0.1.0/src/marim_harness/ask_user.py +81 -0
- marim_harness-0.1.0/src/marim_harness/atomic_io.py +176 -0
- marim_harness-0.1.0/src/marim_harness/builtin/agents/researcher.md +40 -0
- marim_harness-0.1.0/src/marim_harness/builtin/skills/deep-research/SKILL.md +153 -0
- marim_harness-0.1.0/src/marim_harness/command_policy.py +84 -0
- marim_harness-0.1.0/src/marim_harness/compaction.py +699 -0
- marim_harness-0.1.0/src/marim_harness/config/__init__.py +26 -0
- marim_harness-0.1.0/src/marim_harness/config/claude_cli_model.py +901 -0
- marim_harness-0.1.0/src/marim_harness/config/context_limits.py +322 -0
- marim_harness-0.1.0/src/marim_harness/config/env.py +154 -0
- marim_harness-0.1.0/src/marim_harness/config/model.py +599 -0
- marim_harness-0.1.0/src/marim_harness/config/openrouter_cost.py +213 -0
- marim_harness-0.1.0/src/marim_harness/config/persist.py +99 -0
- marim_harness-0.1.0/src/marim_harness/forge/__init__.py +0 -0
- marim_harness-0.1.0/src/marim_harness/forge/backend.py +25 -0
- marim_harness-0.1.0/src/marim_harness/forge/gitref.py +50 -0
- marim_harness-0.1.0/src/marim_harness/forge/models.py +73 -0
- marim_harness-0.1.0/src/marim_harness/forge/select.py +21 -0
- marim_harness-0.1.0/src/marim_harness/forge/tea_backend.py +245 -0
- marim_harness-0.1.0/src/marim_harness/hooks/__init__.py +7 -0
- marim_harness-0.1.0/src/marim_harness/hooks/config.py +55 -0
- marim_harness-0.1.0/src/marim_harness/hooks/dispatch.py +164 -0
- marim_harness-0.1.0/src/marim_harness/hooks/events.py +20 -0
- marim_harness-0.1.0/src/marim_harness/hooks/runner.py +260 -0
- marim_harness-0.1.0/src/marim_harness/images.py +247 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/__init__.py +0 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/cli/__init__.py +0 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/cli/config.py +153 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/cli/default_cmd.py +178 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/cli/headless.py +141 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/cli/mcp.py +217 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/cli/models.py +50 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/cli/plugin.py +269 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/cli/router.py +73 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/cli/serve.py +64 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/cli/sessions.py +102 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/durations.py +20 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/history.py +71 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/prefs.py +49 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/__init__.py +0 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/app.py +1213 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/commands.py +635 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/interactions/__init__.py +15 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/interactions/approval.py +130 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/interactions/ask_user.py +222 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/interactions/ask_user_render.py +131 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/interactions/base.py +114 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/interactions/plan_card.py +100 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/model_picker.py +147 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/notify.py +36 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/plan_screen.py +63 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/providers.py +429 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/queue.py +88 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/session_view.py +537 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/settings.py +925 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/shell_passthrough.py +154 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/status.py +171 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/stream_render.py +1126 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/styles.tcss +147 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/subagents/__init__.py +18 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/subagents/card.py +427 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/subagents/list.py +52 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/subagents/pane.py +208 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/subagents/screen.py +255 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/subagents/stats.py +126 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/subagents/view.py +111 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/themes.py +55 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/thinking_picker.py +70 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/wake.py +57 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/widgets/__init__.py +64 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/widgets/autocomplete.py +106 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/widgets/diff.py +212 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/widgets/format.py +42 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/widgets/highlight.py +96 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/widgets/messages.py +347 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/widgets/panels.py +198 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/widgets/prompt.py +509 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/widgets/tool_summary.py +190 -0
- marim_harness-0.1.0/src/marim_harness/interfaces/tui/widgets/tools.py +506 -0
- marim_harness-0.1.0/src/marim_harness/jobs.py +517 -0
- marim_harness-0.1.0/src/marim_harness/lsp/__init__.py +1 -0
- marim_harness-0.1.0/src/marim_harness/lsp/basedpyright.py +155 -0
- marim_harness-0.1.0/src/marim_harness/lsp/bundled/cpp/.marim-plugin/plugin.json +12 -0
- marim_harness-0.1.0/src/marim_harness/lsp/bundled/java/.marim-plugin/plugin.json +12 -0
- marim_harness-0.1.0/src/marim_harness/lsp/bundled/python/.marim-plugin/plugin.json +12 -0
- marim_harness-0.1.0/src/marim_harness/lsp/bundled/typescript/.marim-plugin/plugin.json +12 -0
- marim_harness-0.1.0/src/marim_harness/lsp/bundled.py +52 -0
- marim_harness-0.1.0/src/marim_harness/lsp/checks.py +195 -0
- marim_harness-0.1.0/src/marim_harness/lsp/diagnostics.py +75 -0
- marim_harness-0.1.0/src/marim_harness/lsp/generic.py +163 -0
- marim_harness-0.1.0/src/marim_harness/lsp/manager.py +591 -0
- marim_harness-0.1.0/src/marim_harness/lsp/provider.py +220 -0
- marim_harness-0.1.0/src/marim_harness/lsp/registry.py +110 -0
- marim_harness-0.1.0/src/marim_harness/mcp/__init__.py +21 -0
- marim_harness-0.1.0/src/marim_harness/mcp/catalog.py +62 -0
- marim_harness-0.1.0/src/marim_harness/mcp/config.py +474 -0
- marim_harness-0.1.0/src/marim_harness/mcp/discovered_instructions_capability.py +84 -0
- marim_harness-0.1.0/src/marim_harness/mcp/manager.py +356 -0
- marim_harness-0.1.0/src/marim_harness/notifications.py +244 -0
- marim_harness-0.1.0/src/marim_harness/plugins/__init__.py +85 -0
- marim_harness-0.1.0/src/marim_harness/plugins/discovery.py +485 -0
- marim_harness-0.1.0/src/marim_harness/plugins/install.py +342 -0
- marim_harness-0.1.0/src/marim_harness/plugins/manifest.py +165 -0
- marim_harness-0.1.0/src/marim_harness/plugins/state.py +105 -0
- marim_harness-0.1.0/src/marim_harness/py.typed +0 -0
- marim_harness-0.1.0/src/marim_harness/read_only_commands.py +255 -0
- marim_harness-0.1.0/src/marim_harness/runtime/__init__.py +19 -0
- marim_harness-0.1.0/src/marim_harness/runtime/bootstrap.py +221 -0
- marim_harness-0.1.0/src/marim_harness/runtime/builder.py +458 -0
- marim_harness-0.1.0/src/marim_harness/runtime/context.py +169 -0
- marim_harness-0.1.0/src/marim_harness/runtime/controller.py +1092 -0
- marim_harness-0.1.0/src/marim_harness/runtime/deps.py +312 -0
- marim_harness-0.1.0/src/marim_harness/runtime/errors.py +389 -0
- marim_harness-0.1.0/src/marim_harness/runtime/harness.py +912 -0
- marim_harness-0.1.0/src/marim_harness/runtime/instructions.py +395 -0
- marim_harness-0.1.0/src/marim_harness/runtime/permissions.py +134 -0
- marim_harness-0.1.0/src/marim_harness/runtime/toolsets.py +74 -0
- marim_harness-0.1.0/src/marim_harness/runtime/ttft.py +63 -0
- marim_harness-0.1.0/src/marim_harness/server/__init__.py +5 -0
- marim_harness-0.1.0/src/marim_harness/server/auth.py +29 -0
- marim_harness-0.1.0/src/marim_harness/server/bus.py +124 -0
- marim_harness-0.1.0/src/marim_harness/server/host.py +309 -0
- marim_harness-0.1.0/src/marim_harness/server/http.py +480 -0
- marim_harness-0.1.0/src/marim_harness/server/schema.py +79 -0
- marim_harness-0.1.0/src/marim_harness/server/supervisor.py +219 -0
- marim_harness-0.1.0/src/marim_harness/server/workspaces.py +130 -0
- marim_harness-0.1.0/src/marim_harness/session/__init__.py +11 -0
- marim_harness-0.1.0/src/marim_harness/session/checkpoints.py +487 -0
- marim_harness-0.1.0/src/marim_harness/session/ctrl.py +860 -0
- marim_harness-0.1.0/src/marim_harness/session/store.py +508 -0
- marim_harness-0.1.0/src/marim_harness/session/transcripts.py +139 -0
- marim_harness-0.1.0/src/marim_harness/stream_events.py +44 -0
- marim_harness-0.1.0/src/marim_harness/subagents/__init__.py +14 -0
- marim_harness-0.1.0/src/marim_harness/subagents/backend.py +69 -0
- marim_harness-0.1.0/src/marim_harness/subagents/cli_backend.py +728 -0
- marim_harness-0.1.0/src/marim_harness/subagents/cli_demux.py +279 -0
- marim_harness-0.1.0/src/marim_harness/subagents/cli_spawn.py +269 -0
- marim_harness-0.1.0/src/marim_harness/subagents/isolation.py +117 -0
- marim_harness-0.1.0/src/marim_harness/subagents/masking.py +113 -0
- marim_harness-0.1.0/src/marim_harness/subagents/output_schema.py +42 -0
- marim_harness-0.1.0/src/marim_harness/subagents/persistence.py +99 -0
- marim_harness-0.1.0/src/marim_harness/subagents/policies.py +78 -0
- marim_harness-0.1.0/src/marim_harness/subagents/run_driver.py +274 -0
- marim_harness-0.1.0/src/marim_harness/subagents/runner.py +1165 -0
- marim_harness-0.1.0/src/marim_harness/subagents/tiers.py +25 -0
- marim_harness-0.1.0/src/marim_harness/tasks.py +99 -0
- marim_harness-0.1.0/src/marim_harness/thinking.py +79 -0
- marim_harness-0.1.0/src/marim_harness/tools/__init__.py +0 -0
- marim_harness-0.1.0/src/marim_harness/tools/advisor_tools.py +56 -0
- marim_harness-0.1.0/src/marim_harness/tools/edit_tools.py +141 -0
- marim_harness-0.1.0/src/marim_harness/tools/forge_tools.py +193 -0
- marim_harness-0.1.0/src/marim_harness/tools/fs_tools.py +127 -0
- marim_harness-0.1.0/src/marim_harness/tools/impl/__init__.py +10 -0
- marim_harness-0.1.0/src/marim_harness/tools/impl/coerce.py +150 -0
- marim_harness-0.1.0/src/marim_harness/tools/impl/fetch.py +405 -0
- marim_harness-0.1.0/src/marim_harness/tools/impl/fs.py +793 -0
- marim_harness-0.1.0/src/marim_harness/tools/impl/offload.py +96 -0
- marim_harness-0.1.0/src/marim_harness/tools/impl/shell.py +387 -0
- marim_harness-0.1.0/src/marim_harness/tools/impl/suggest.py +114 -0
- marim_harness-0.1.0/src/marim_harness/tools/impl/web.py +132 -0
- marim_harness-0.1.0/src/marim_harness/tools/job_tools.py +158 -0
- marim_harness-0.1.0/src/marim_harness/tools/lenient.py +35 -0
- marim_harness-0.1.0/src/marim_harness/tools/lsp_tools.py +78 -0
- marim_harness-0.1.0/src/marim_harness/tools/memory_tools.py +95 -0
- marim_harness-0.1.0/src/marim_harness/tools/names.py +56 -0
- marim_harness-0.1.0/src/marim_harness/tools/net_tools.py +37 -0
- marim_harness-0.1.0/src/marim_harness/tools/planning_tools.py +182 -0
- marim_harness-0.1.0/src/marim_harness/tools/provider.py +244 -0
- marim_harness-0.1.0/src/marim_harness/tools/skill_tools.py +49 -0
- marim_harness-0.1.0/src/marim_harness/tools/spawn_tools.py +378 -0
- marim_harness-0.1.0/src/marim_harness/tools/workflow_tools.py +140 -0
- marim_harness-0.1.0/src/marim_harness/trust.py +41 -0
- marim_harness-0.1.0/src/marim_harness/usage.py +137 -0
- marim_harness-0.1.0/src/marim_harness/workflows/__init__.py +6 -0
- marim_harness-0.1.0/src/marim_harness/workflows/engine.py +420 -0
- marim_harness-0.1.0/src/marim_harness/workflows/errors.py +13 -0
- marim_harness-0.1.0/src/marim_harness/workflows/schema.py +83 -0
- marim_harness-0.1.0/src/marim_harness/workspace/__init__.py +88 -0
- marim_harness-0.1.0/src/marim_harness/workspace/_discovery.py +46 -0
- marim_harness-0.1.0/src/marim_harness/workspace/_frontmatter.py +11 -0
- marim_harness-0.1.0/src/marim_harness/workspace/agents.py +499 -0
- marim_harness-0.1.0/src/marim_harness/workspace/catalog.py +281 -0
- marim_harness-0.1.0/src/marim_harness/workspace/fs.py +63 -0
- marim_harness-0.1.0/src/marim_harness/workspace/identifiers.py +16 -0
- marim_harness-0.1.0/src/marim_harness/workspace/memory.py +269 -0
- marim_harness-0.1.0/src/marim_harness/workspace/plans.py +72 -0
- marim_harness-0.1.0/src/marim_harness/workspace/scratchpad.py +115 -0
- marim_harness-0.1.0/src/marim_harness/workspace/skills.py +273 -0
- marim_harness-0.1.0/src/marim_harness/workspace/snapshot.py +357 -0
- marim_harness-0.1.0/src/marim_harness/workspace/worktree.py +208 -0
- marim_harness-0.1.0/tests/__init__.py +0 -0
- marim_harness-0.1.0/tests/conftest.py +228 -0
- marim_harness-0.1.0/tests/fake_lsp_server.py +62 -0
- marim_harness-0.1.0/tests/fixtures/plugins/demo-plugin/.marim-plugin/plugin.json +7 -0
- marim_harness-0.1.0/tests/fixtures/plugins/demo-plugin/AGENTS.md +1 -0
- marim_harness-0.1.0/tests/fixtures/plugins/demo-plugin/agents/reviewer.md +6 -0
- marim_harness-0.1.0/tests/fixtures/plugins/demo-plugin/hooks/hooks.json +7 -0
- marim_harness-0.1.0/tests/fixtures/plugins/demo-plugin/mcp.json +5 -0
- marim_harness-0.1.0/tests/fixtures/plugins/demo-plugin/skills/greet/SKILL.md +6 -0
- marim_harness-0.1.0/tests/fixtures/session_v1_pydantic_ai_1107.json +1 -0
- marim_harness-0.1.0/tests/test_advisor.py +94 -0
- marim_harness-0.1.0/tests/test_advisor_command.py +51 -0
- marim_harness-0.1.0/tests/test_advisor_instructions.py +26 -0
- marim_harness-0.1.0/tests/test_advisor_render.py +12 -0
- marim_harness-0.1.0/tests/test_advisor_session.py +54 -0
- marim_harness-0.1.0/tests/test_advisor_tool.py +106 -0
- marim_harness-0.1.0/tests/test_advisor_wiring.py +96 -0
- marim_harness-0.1.0/tests/test_agent.py +506 -0
- marim_harness-0.1.0/tests/test_agent_autoname.py +226 -0
- marim_harness-0.1.0/tests/test_agent_backend_field.py +44 -0
- marim_harness-0.1.0/tests/test_agent_checkpoints.py +53 -0
- marim_harness-0.1.0/tests/test_agent_consumables.py +156 -0
- marim_harness-0.1.0/tests/test_agent_hooks.py +526 -0
- marim_harness-0.1.0/tests/test_agent_instructions.py +247 -0
- marim_harness-0.1.0/tests/test_agent_mcp.py +465 -0
- marim_harness-0.1.0/tests/test_agent_sessions.py +598 -0
- marim_harness-0.1.0/tests/test_agent_subagents.py +593 -0
- marim_harness-0.1.0/tests/test_agents.py +462 -0
- marim_harness-0.1.0/tests/test_app.py +4167 -0
- marim_harness-0.1.0/tests/test_app_decomposition.py +104 -0
- marim_harness-0.1.0/tests/test_app_present_plan.py +73 -0
- marim_harness-0.1.0/tests/test_app_turn_race.py +224 -0
- marim_harness-0.1.0/tests/test_approval.py +173 -0
- marim_harness-0.1.0/tests/test_ask_user.py +41 -0
- marim_harness-0.1.0/tests/test_ask_user_panel.py +313 -0
- marim_harness-0.1.0/tests/test_ask_user_render.py +86 -0
- marim_harness-0.1.0/tests/test_ask_user_tool.py +132 -0
- marim_harness-0.1.0/tests/test_atomic_io.py +171 -0
- marim_harness-0.1.0/tests/test_autocomplete.py +305 -0
- marim_harness-0.1.0/tests/test_autocomplete_integration.py +278 -0
- marim_harness-0.1.0/tests/test_aux_model_clone.py +105 -0
- marim_harness-0.1.0/tests/test_bootstrap.py +460 -0
- marim_harness-0.1.0/tests/test_builder.py +278 -0
- marim_harness-0.1.0/tests/test_builder_turns.py +71 -0
- marim_harness-0.1.0/tests/test_catalog.py +392 -0
- marim_harness-0.1.0/tests/test_checkpoints.py +663 -0
- marim_harness-0.1.0/tests/test_claude_cli_model.py +804 -0
- marim_harness-0.1.0/tests/test_cli.py +286 -0
- marim_harness-0.1.0/tests/test_cli_backend.py +177 -0
- marim_harness-0.1.0/tests/test_cli_demux.py +211 -0
- marim_harness-0.1.0/tests/test_cli_serve.py +45 -0
- marim_harness-0.1.0/tests/test_cli_startup.py +49 -0
- marim_harness-0.1.0/tests/test_coerce.py +148 -0
- marim_harness-0.1.0/tests/test_command_policy.py +70 -0
- marim_harness-0.1.0/tests/test_commands.py +696 -0
- marim_harness-0.1.0/tests/test_compaction.py +666 -0
- marim_harness-0.1.0/tests/test_config.py +1027 -0
- marim_harness-0.1.0/tests/test_config_cli.py +265 -0
- marim_harness-0.1.0/tests/test_config_seams.py +170 -0
- marim_harness-0.1.0/tests/test_context.py +28 -0
- marim_harness-0.1.0/tests/test_context_limits.py +270 -0
- marim_harness-0.1.0/tests/test_deep_research_skill.py +37 -0
- marim_harness-0.1.0/tests/test_default_cmd.py +16 -0
- marim_harness-0.1.0/tests/test_deps.py +116 -0
- marim_harness-0.1.0/tests/test_deps_plan.py +25 -0
- marim_harness-0.1.0/tests/test_detach_fanout.py +236 -0
- marim_harness-0.1.0/tests/test_discovered_instructions_capability.py +109 -0
- marim_harness-0.1.0/tests/test_docs_reference.py +67 -0
- marim_harness-0.1.0/tests/test_env_blocklist.py +198 -0
- marim_harness-0.1.0/tests/test_errors_transient_precision.py +55 -0
- marim_harness-0.1.0/tests/test_examples_agentmemory_plugin.py +47 -0
- marim_harness-0.1.0/tests/test_examples_embedding.py +82 -0
- marim_harness-0.1.0/tests/test_examples_playwright_plugin.py +58 -0
- marim_harness-0.1.0/tests/test_examples_scraper_gen_plugin.py +54 -0
- marim_harness-0.1.0/tests/test_examples_superpowers_plugin.py +58 -0
- marim_harness-0.1.0/tests/test_fetch.py +682 -0
- marim_harness-0.1.0/tests/test_finished_job_notifier.py +44 -0
- marim_harness-0.1.0/tests/test_forge_gitref.py +41 -0
- marim_harness-0.1.0/tests/test_forge_models.py +28 -0
- marim_harness-0.1.0/tests/test_forge_select.py +20 -0
- marim_harness-0.1.0/tests/test_forge_tea_backend.py +335 -0
- marim_harness-0.1.0/tests/test_forge_tools.py +188 -0
- marim_harness-0.1.0/tests/test_forge_wiring.py +29 -0
- marim_harness-0.1.0/tests/test_fs.py +822 -0
- marim_harness-0.1.0/tests/test_headless.py +311 -0
- marim_harness-0.1.0/tests/test_history.py +71 -0
- marim_harness-0.1.0/tests/test_hooks_config.py +54 -0
- marim_harness-0.1.0/tests/test_hooks_events.py +35 -0
- marim_harness-0.1.0/tests/test_hooks_runner.py +352 -0
- marim_harness-0.1.0/tests/test_image_attachments.py +41 -0
- marim_harness-0.1.0/tests/test_image_paste.py +270 -0
- marim_harness-0.1.0/tests/test_images.py +155 -0
- marim_harness-0.1.0/tests/test_imports.py +26 -0
- marim_harness-0.1.0/tests/test_instructions.py +279 -0
- marim_harness-0.1.0/tests/test_interaction_panel.py +147 -0
- marim_harness-0.1.0/tests/test_jobs.py +681 -0
- marim_harness-0.1.0/tests/test_jobs_tools.py +205 -0
- marim_harness-0.1.0/tests/test_live_smoke.py +46 -0
- marim_harness-0.1.0/tests/test_logging.py +275 -0
- marim_harness-0.1.0/tests/test_lsp_basedpyright.py +147 -0
- marim_harness-0.1.0/tests/test_lsp_bootstrap_gate.py +39 -0
- marim_harness-0.1.0/tests/test_lsp_bundled.py +28 -0
- marim_harness-0.1.0/tests/test_lsp_checks.py +181 -0
- marim_harness-0.1.0/tests/test_lsp_diagnostics.py +91 -0
- marim_harness-0.1.0/tests/test_lsp_generic.py +50 -0
- marim_harness-0.1.0/tests/test_lsp_integration.py +34 -0
- marim_harness-0.1.0/tests/test_lsp_manager.py +545 -0
- marim_harness-0.1.0/tests/test_lsp_manager_registry.py +61 -0
- marim_harness-0.1.0/tests/test_lsp_plugin_discovery.py +68 -0
- marim_harness-0.1.0/tests/test_lsp_provider.py +196 -0
- marim_harness-0.1.0/tests/test_lsp_registry.py +165 -0
- marim_harness-0.1.0/tests/test_lsp_tools.py +180 -0
- marim_harness-0.1.0/tests/test_lsp_toolset.py +17 -0
- marim_harness-0.1.0/tests/test_lsp_wiring.py +29 -0
- marim_harness-0.1.0/tests/test_mcp.py +751 -0
- marim_harness-0.1.0/tests/test_mcp_cli.py +240 -0
- marim_harness-0.1.0/tests/test_mcp_enable_status.py +77 -0
- marim_harness-0.1.0/tests/test_mcp_tool_search.py +208 -0
- marim_harness-0.1.0/tests/test_memory.py +455 -0
- marim_harness-0.1.0/tests/test_memory_tool.py +210 -0
- marim_harness-0.1.0/tests/test_model_picker.py +179 -0
- marim_harness-0.1.0/tests/test_models_cli.py +94 -0
- marim_harness-0.1.0/tests/test_notifications.py +324 -0
- marim_harness-0.1.0/tests/test_notifications_async.py +137 -0
- marim_harness-0.1.0/tests/test_offload.py +97 -0
- marim_harness-0.1.0/tests/test_openrouter_cost.py +98 -0
- marim_harness-0.1.0/tests/test_openrouter_cost_live.py +49 -0
- marim_harness-0.1.0/tests/test_paste_collapse.py +214 -0
- marim_harness-0.1.0/tests/test_permissions.py +302 -0
- marim_harness-0.1.0/tests/test_persist.py +151 -0
- marim_harness-0.1.0/tests/test_plan_card.py +161 -0
- marim_harness-0.1.0/tests/test_plan_mode_e2e.py +145 -0
- marim_harness-0.1.0/tests/test_plan_screen.py +59 -0
- marim_harness-0.1.0/tests/test_plans.py +47 -0
- marim_harness-0.1.0/tests/test_plugin_agents.py +123 -0
- marim_harness-0.1.0/tests/test_plugin_cli.py +186 -0
- marim_harness-0.1.0/tests/test_plugin_command.py +82 -0
- marim_harness-0.1.0/tests/test_plugin_discovery.py +370 -0
- marim_harness-0.1.0/tests/test_plugin_hooks.py +106 -0
- marim_harness-0.1.0/tests/test_plugin_install.py +532 -0
- marim_harness-0.1.0/tests/test_plugin_instructions.py +158 -0
- marim_harness-0.1.0/tests/test_plugin_integration.py +44 -0
- marim_harness-0.1.0/tests/test_plugin_linked_elevation.py +129 -0
- marim_harness-0.1.0/tests/test_plugin_manifest.py +116 -0
- marim_harness-0.1.0/tests/test_plugin_mcp.py +82 -0
- marim_harness-0.1.0/tests/test_plugin_security.py +194 -0
- marim_harness-0.1.0/tests/test_plugin_skills.py +68 -0
- marim_harness-0.1.0/tests/test_plugin_state.py +68 -0
- marim_harness-0.1.0/tests/test_prefs.py +36 -0
- marim_harness-0.1.0/tests/test_present_plan_tool.py +100 -0
- marim_harness-0.1.0/tests/test_provider.py +1106 -0
- marim_harness-0.1.0/tests/test_provider_errors.py +694 -0
- marim_harness-0.1.0/tests/test_providers_section.py +663 -0
- marim_harness-0.1.0/tests/test_queue.py +300 -0
- marim_harness-0.1.0/tests/test_read_ledger.py +198 -0
- marim_harness-0.1.0/tests/test_read_only_commands.py +153 -0
- marim_harness-0.1.0/tests/test_recovery.py +693 -0
- marim_harness-0.1.0/tests/test_resume_transcript.py +51 -0
- marim_harness-0.1.0/tests/test_run_failure_recovery.py +187 -0
- marim_harness-0.1.0/tests/test_runtime_toolsets.py +123 -0
- marim_harness-0.1.0/tests/test_scratchpad.py +186 -0
- marim_harness-0.1.0/tests/test_server_auth.py +19 -0
- marim_harness-0.1.0/tests/test_server_bus.py +82 -0
- marim_harness-0.1.0/tests/test_server_host.py +212 -0
- marim_harness-0.1.0/tests/test_server_http.py +463 -0
- marim_harness-0.1.0/tests/test_server_schema.py +30 -0
- marim_harness-0.1.0/tests/test_server_supervisor.py +297 -0
- marim_harness-0.1.0/tests/test_server_workspaces.py +140 -0
- marim_harness-0.1.0/tests/test_server_ws.py +200 -0
- marim_harness-0.1.0/tests/test_session.py +1474 -0
- marim_harness-0.1.0/tests/test_session_duration.py +55 -0
- marim_harness-0.1.0/tests/test_session_persist_cache.py +280 -0
- marim_harness-0.1.0/tests/test_session_sanitize.py +100 -0
- marim_harness-0.1.0/tests/test_session_store_isolation.py +21 -0
- marim_harness-0.1.0/tests/test_session_store_lock.py +123 -0
- marim_harness-0.1.0/tests/test_session_tool_search_roundtrip.py +65 -0
- marim_harness-0.1.0/tests/test_session_v1_compat.py +56 -0
- marim_harness-0.1.0/tests/test_session_view_replay.py +754 -0
- marim_harness-0.1.0/tests/test_sessions_cli.py +128 -0
- marim_harness-0.1.0/tests/test_settings_screen.py +858 -0
- marim_harness-0.1.0/tests/test_shell.py +421 -0
- marim_harness-0.1.0/tests/test_shell_passthrough.py +125 -0
- marim_harness-0.1.0/tests/test_skills.py +339 -0
- marim_harness-0.1.0/tests/test_skills_tool.py +188 -0
- marim_harness-0.1.0/tests/test_snapshot.py +373 -0
- marim_harness-0.1.0/tests/test_spawn_transcripts.py +104 -0
- marim_harness-0.1.0/tests/test_spawn_worktree.py +100 -0
- marim_harness-0.1.0/tests/test_steering.py +448 -0
- marim_harness-0.1.0/tests/test_stream_events.py +61 -0
- marim_harness-0.1.0/tests/test_subagent_after.py +249 -0
- marim_harness-0.1.0/tests/test_subagent_card.py +163 -0
- marim_harness-0.1.0/tests/test_subagent_cli_spawn.py +234 -0
- marim_harness-0.1.0/tests/test_subagent_concurrency.py +83 -0
- marim_harness-0.1.0/tests/test_subagent_depth.py +307 -0
- marim_harness-0.1.0/tests/test_subagent_detail.py +310 -0
- marim_harness-0.1.0/tests/test_subagent_extra_agents.py +51 -0
- marim_harness-0.1.0/tests/test_subagent_isolation.py +406 -0
- marim_harness-0.1.0/tests/test_subagent_masking.py +194 -0
- marim_harness-0.1.0/tests/test_subagent_model.py +241 -0
- marim_harness-0.1.0/tests/test_subagent_output_schema.py +88 -0
- marim_harness-0.1.0/tests/test_subagent_plan_egress.py +446 -0
- marim_harness-0.1.0/tests/test_subagent_resume.py +466 -0
- marim_harness-0.1.0/tests/test_subagent_retry.py +594 -0
- marim_harness-0.1.0/tests/test_subagent_safety.py +128 -0
- marim_harness-0.1.0/tests/test_subagent_stats.py +213 -0
- marim_harness-0.1.0/tests/test_subagent_tiers.py +202 -0
- marim_harness-0.1.0/tests/test_subagent_timing.py +63 -0
- marim_harness-0.1.0/tests/test_subagent_tool.py +175 -0
- marim_harness-0.1.0/tests/test_subagent_transcript_capture.py +142 -0
- marim_harness-0.1.0/tests/test_subagents_cli.py +740 -0
- marim_harness-0.1.0/tests/test_subagents_screen.py +902 -0
- marim_harness-0.1.0/tests/test_switch_jobs_history.py +57 -0
- marim_harness-0.1.0/tests/test_task_panel_plan_title.py +87 -0
- marim_harness-0.1.0/tests/test_tasks.py +94 -0
- marim_harness-0.1.0/tests/test_tasks_tool.py +133 -0
- marim_harness-0.1.0/tests/test_themes.py +45 -0
- marim_harness-0.1.0/tests/test_thinking.py +72 -0
- marim_harness-0.1.0/tests/test_thinking_command.py +60 -0
- marim_harness-0.1.0/tests/test_thinking_controller.py +79 -0
- marim_harness-0.1.0/tests/test_thinking_session.py +53 -0
- marim_harness-0.1.0/tests/test_thinking_spawn_tool.py +45 -0
- marim_harness-0.1.0/tests/test_thinking_subagent.py +96 -0
- marim_harness-0.1.0/tests/test_thinking_subagent_ui.py +99 -0
- marim_harness-0.1.0/tests/test_thinking_wiring.py +25 -0
- marim_harness-0.1.0/tests/test_tool_catalog.py +74 -0
- marim_harness-0.1.0/tests/test_tool_suggest.py +118 -0
- marim_harness-0.1.0/tests/test_tool_summary.py +216 -0
- marim_harness-0.1.0/tests/test_transcript_cap.py +42 -0
- marim_harness-0.1.0/tests/test_transcript_store.py +110 -0
- marim_harness-0.1.0/tests/test_trust.py +37 -0
- marim_harness-0.1.0/tests/test_ttft_model.py +111 -0
- marim_harness-0.1.0/tests/test_turn_context.py +39 -0
- marim_harness-0.1.0/tests/test_turn_controller.py +520 -0
- marim_harness-0.1.0/tests/test_turn_queue.py +66 -0
- marim_harness-0.1.0/tests/test_usage.py +185 -0
- marim_harness-0.1.0/tests/test_wake.py +66 -0
- marim_harness-0.1.0/tests/test_web_search.py +367 -0
- marim_harness-0.1.0/tests/test_widgets.py +1803 -0
- marim_harness-0.1.0/tests/test_workflow_acceptance.py +59 -0
- marim_harness-0.1.0/tests/test_workflow_engine.py +728 -0
- marim_harness-0.1.0/tests/test_workflow_schema.py +87 -0
- marim_harness-0.1.0/tests/test_workflow_tool.py +123 -0
- marim_harness-0.1.0/tests/test_workflow_wiring.py +84 -0
- marim_harness-0.1.0/tests/test_workspace.py +20 -0
- marim_harness-0.1.0/tests/test_workspace_knobs.py +45 -0
- marim_harness-0.1.0/tests/test_worktree.py +186 -0
- marim_harness-0.1.0/uv.lock +2735 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Copy this file to .env and fill in your values. .env is gitignored.
|
|
2
|
+
# Real shell environment variables take priority over .env.
|
|
3
|
+
|
|
4
|
+
# --- OpenRouter (default provider) ---
|
|
5
|
+
OPENROUTER_API_KEY=
|
|
6
|
+
|
|
7
|
+
# Optional: override the default model (anthropic/claude-sonnet-4-6)
|
|
8
|
+
# MARIM_MODEL=anthropic/claude-sonnet-4-6
|
|
9
|
+
|
|
10
|
+
# --- Local provider (any OpenAI-compatible server) instead of OpenRouter ---
|
|
11
|
+
# The model picker (and `marim models list`) discovers models from the server's
|
|
12
|
+
# /v1/models endpoint, so MARIM_MODEL is optional once the server is reachable.
|
|
13
|
+
# Ollama:
|
|
14
|
+
# MARIM_PROVIDER=local
|
|
15
|
+
# MARIM_MODEL=qwen2.5-coder
|
|
16
|
+
# MARIM_BASE_URL=http://localhost:11434/v1
|
|
17
|
+
# MARIM_API_KEY=local
|
|
18
|
+
# LM Studio (note the 1234 port; start the server from the Developer tab):
|
|
19
|
+
# MARIM_PROVIDER=local
|
|
20
|
+
# MARIM_BASE_URL=http://localhost:1234/v1
|
|
21
|
+
# MARIM_API_KEY=lmstudio
|
|
22
|
+
|
|
23
|
+
# --- Multiple providers at once ---
|
|
24
|
+
# Any provider whose credentials are present is auto-detected and its models are
|
|
25
|
+
# merged into one tagged picker list (filter by id, name, or provider). Set
|
|
26
|
+
# several at once; MARIM_PROVIDER selects the default (startup model + the target
|
|
27
|
+
# for a typed model id with no provider prefix). Pick another provider's model in
|
|
28
|
+
# the picker, or type a qualified id like: local:qwen2.5-coder
|
|
29
|
+
|
|
30
|
+
# --- Claude subscription via the claude CLI (Claude Code) ---
|
|
31
|
+
# Use a Claude Pro/Max subscription via the `claude` CLI (Claude Code must be
|
|
32
|
+
# installed and logged in). In this provider marim delegates the whole turn to
|
|
33
|
+
# `claude -p`: Claude runs its own tools/loop, so marim's own tools, approval
|
|
34
|
+
# gating, LSP, and MCP do not apply. `auto`/`ask` map to acceptEdits, `plan` to
|
|
35
|
+
# read-only plan. MARIM_MODEL is optional (sonnet/opus/haiku; default: CLI's own).
|
|
36
|
+
# MARIM_PROVIDER=claude-cli
|
|
37
|
+
# MARIM_MODEL=sonnet
|
|
38
|
+
# MARIM_CLAUDE_CLI_BIN=claude # override the binary if not on PATH
|
|
39
|
+
|
|
40
|
+
# --- Context window & budget ---
|
|
41
|
+
# Compaction/masking trigger at min(budget, 0.8 × the model's context window).
|
|
42
|
+
# The window is discovered from the provider (catalog / LM Studio probe); the
|
|
43
|
+
# budget is your spend ceiling in tokens. 0 = unbudgeted (window-only).
|
|
44
|
+
# Replaces the deprecated MARIM_MAX_CONTEXT_TOKENS (same meaning).
|
|
45
|
+
# MARIM_CONTEXT_BUDGET=100000
|
|
46
|
+
# Manual window override (tokens) for servers discovery can't read, e.g. a
|
|
47
|
+
# non-LM-Studio local server; always wins over discovery.
|
|
48
|
+
# MARIM_CONTEXT_WINDOW=131072
|
|
49
|
+
# Per-model budgets: comma-separated fnmatch pattern=tokens pairs matched
|
|
50
|
+
# against the model id, first match wins; =0 means unbudgeted for that model.
|
|
51
|
+
# MARIM_CONTEXT_BUDGETS=anthropic/claude-opus*=60000,openrouter/*free*=0
|
|
52
|
+
|
|
53
|
+
# --- Web search (SearXNG) ---
|
|
54
|
+
# The web_search tool queries this SearXNG instance. Override to point at your
|
|
55
|
+
# own/self-hosted instance; defaults to https://searxng.marim.dev. The instance
|
|
56
|
+
# must have the JSON output format enabled (SearXNG disables it by default).
|
|
57
|
+
# MARIM_SEARXNG_URL=https://searxng.marim.dev
|
|
58
|
+
|
|
59
|
+
# --- Google (Gemini) ---
|
|
60
|
+
# MARIM_PROVIDER=google
|
|
61
|
+
# MARIM_MODEL=gemini-2.5-flash
|
|
62
|
+
# GOOGLE_API_KEY= # or GEMINI_API_KEY / MARIM_API_KEY
|
|
63
|
+
|
|
64
|
+
# --- Session & UI ---
|
|
65
|
+
# Initial approval mode for interactive sessions: ask (default), auto, or plan.
|
|
66
|
+
# Ignored when set from a project .env — a cloned repo must not self-elevate.
|
|
67
|
+
# MARIM_DEFAULT_MODE=ask
|
|
68
|
+
# DEBUG logging to the log file (also enables spawn timing lines).
|
|
69
|
+
# MARIM_DEBUG=1
|
|
70
|
+
# Detached fan-out: spawn_agent with `background` unset auto-detaches in the
|
|
71
|
+
# TUI (live cards + job handles) instead of running inline. On by default.
|
|
72
|
+
# MARIM_DETACH_FANOUT=1
|
|
73
|
+
# Desktop notifications: on by default; pick events from turn_complete,
|
|
74
|
+
# error, approval_needed, ask_user, job_done (default: all but job_done).
|
|
75
|
+
# MARIM_NOTIFICATIONS=0
|
|
76
|
+
# MARIM_NOTIFICATION_EVENTS=approval_needed,ask_user
|
|
77
|
+
# Autonomous wake: finished background jobs start a new turn to deliver their
|
|
78
|
+
# reports while you're away; the depth cap bounds chained wakes.
|
|
79
|
+
# MARIM_AUTONOMOUS_WAKE=1
|
|
80
|
+
# MARIM_WAKE_DEPTH_CAP=8
|
|
81
|
+
|
|
82
|
+
# --- Command policy (bash tool) ---
|
|
83
|
+
# Comma-separated command prefixes to always allow / always block, checked
|
|
84
|
+
# before the built-in policy.
|
|
85
|
+
# MARIM_COMMAND_ALLOWLIST=git status,ls
|
|
86
|
+
# MARIM_COMMAND_DENYLIST=rm -rf
|
|
87
|
+
|
|
88
|
+
# --- Trust (project-local executable config) ---
|
|
89
|
+
# Project-local hooks (.marim/hooks.json), MCP servers (.marim/mcp.json), and
|
|
90
|
+
# project-scope plugins launch code from the repo on startup. They load only
|
|
91
|
+
# when this is set — leave it unset for repos you don't fully trust.
|
|
92
|
+
# MARIM_TRUST_PROJECT_HOOKS=1
|
|
93
|
+
|
|
94
|
+
# --- LSP ---
|
|
95
|
+
# Language-server integration: MARIM_LSP gates the manager + diagnostics on
|
|
96
|
+
# write/edit; MARIM_LSP_TOOLS gates the six navigation tools. Both on by
|
|
97
|
+
# default; 0 disables.
|
|
98
|
+
# The four bundled language plugins (python, typescript, cpp, java; see
|
|
99
|
+
# docs/lsp-plugins.md) always load regardless of trust. Third-party plugins
|
|
100
|
+
# that add a language via an `lsp` manifest block follow the same
|
|
101
|
+
# MARIM_TRUST_PROJECT_HOOKS gate as project-local hooks/MCP servers above.
|
|
102
|
+
# MARIM_LSP=1
|
|
103
|
+
# MARIM_LSP_TOOLS=1
|
|
104
|
+
|
|
105
|
+
# --- Forge (Gitea/GitHub) ---
|
|
106
|
+
# Forge (Gitea/GitHub) tools via the tea CLI; on by default. Set to 0 to disable.
|
|
107
|
+
# MARIM_FORGE=1
|
|
108
|
+
|
|
109
|
+
# --- Scratchpad ---
|
|
110
|
+
# Session scratchpad: a per-session /tmp directory the agent uses for
|
|
111
|
+
# intermediate files (advertised in the prompt; writes there skip approval
|
|
112
|
+
# in ask mode). 1 (default) or 0.
|
|
113
|
+
# MARIM_SCRATCHPAD=1
|
|
114
|
+
|
|
115
|
+
# --- Dynamic workflows ---
|
|
116
|
+
# Dynamic workflows (the run_workflow tool; needs the [workflows] extra). Default on.
|
|
117
|
+
# MARIM_WORKFLOWS=1
|
|
118
|
+
# Ceiling (seconds) on the wall-clock budget one run_workflow call may request
|
|
119
|
+
# via its timeout_secs parameter. Default 1800 (30 min).
|
|
120
|
+
# MARIM_WORKFLOW_TIMEOUT=1800
|
|
121
|
+
|
|
122
|
+
# --- Compaction / observation masking ---
|
|
123
|
+
# Elide bulky, stale tool observations at compaction time (keep the newest N
|
|
124
|
+
# payloads; only bodies over the char floor are masked). On by default.
|
|
125
|
+
# MARIM_MASK_OBSERVATIONS=0
|
|
126
|
+
# MARIM_MASK_KEEP_RECENT=4
|
|
127
|
+
# MARIM_MASK_MIN_CHARS=200
|
|
128
|
+
|
|
129
|
+
# --- Sub-agents ---
|
|
130
|
+
# Cap concurrent spawn model-runs (default 8; 0 = unbounded) / per-spawn request
|
|
131
|
+
# budget (default 50) / persisted transcript size in messages (default 2000).
|
|
132
|
+
# MARIM_SUBAGENT_CONCURRENCY=8
|
|
133
|
+
# MARIM_SUBAGENT_REQUEST_LIMIT=50
|
|
134
|
+
# MARIM_SUBAGENT_TRANSCRIPT_CAP=2000
|
|
135
|
+
# Sub-agent model tiers: the model each tier routes to (qualified provider:model_id).
|
|
136
|
+
# A read-only spawn defaults to cheap, a mutating one to high; a spec's `tier:` or
|
|
137
|
+
# the spawner's tier= override picks explicitly. Unset ⇒ inherit the main model.
|
|
138
|
+
# MARIM_SUBAGENT_TIER_CHEAP=local:ornith-1.0-9b
|
|
139
|
+
# MARIM_SUBAGENT_TIER_MED=openrouter:anthropic/claude-sonnet-4-6
|
|
140
|
+
# MARIM_SUBAGENT_TIER_HIGH=openrouter:anthropic/claude-opus-4
|
|
141
|
+
# Master switch for tier routing. 0 ⇒ every spawn inherits the main model while
|
|
142
|
+
# the tier slugs above stay configured (toggle back on to restore routing). The
|
|
143
|
+
# TUI settings checkbox applies this live. Default on.
|
|
144
|
+
# MARIM_SUBAGENT_TIERING=1
|
|
145
|
+
|
|
146
|
+
# --- Advisor ---
|
|
147
|
+
# A model the agent can consult mid-task for strategic guidance (the advisor
|
|
148
|
+
# tool): qualified provider:model_id, or a bare slug for the default provider.
|
|
149
|
+
# Unset = no advisor (the tool is not offered to the model).
|
|
150
|
+
# MARIM_ADVISOR_MODEL=openrouter:anthropic/claude-opus-4.8
|
|
151
|
+
# Output cap per consultation (default 2048).
|
|
152
|
+
# MARIM_ADVISOR_MAX_TOKENS=2048
|
|
153
|
+
# Per-turn call cap. Unset or 0 = unlimited.
|
|
154
|
+
# MARIM_ADVISOR_MAX_USES=3
|
|
155
|
+
|
|
156
|
+
# --- Thinking level (reasoning effort) ---
|
|
157
|
+
# Reasoning effort applied to the model via ModelSettings.thinking. One of:
|
|
158
|
+
# off, minimal, low, medium, high, xhigh. Unset or 'off' = no reasoning effort
|
|
159
|
+
# (marim's default). /think overrides it per session, live.
|
|
160
|
+
# MARIM_THINKING=medium
|
|
161
|
+
|
|
162
|
+
# Claude Code model for `backend: claude-cli` sub-agents (alias or full id).
|
|
163
|
+
# MARIM_CLAUDE_CLI_MODEL=sonnet
|
|
164
|
+
# Proactive memory: the agent saves/recalls notes unprompted (off by default).
|
|
165
|
+
# MARIM_PROACTIVE_MEMORY=1
|
|
166
|
+
|
|
167
|
+
# --- MCP tool search ---
|
|
168
|
+
# Defer a large MCP/plugin tool surface behind a searchable index instead of
|
|
169
|
+
# advertising every tool: on, off, or auto (defer above the threshold).
|
|
170
|
+
# MARIM_TOOL_SEARCH=auto
|
|
171
|
+
# MARIM_TOOL_SEARCH_THRESHOLD=15
|
|
172
|
+
|
|
173
|
+
# --- Misc ---
|
|
174
|
+
# Combined `job(action, …)` tool instead of the four jobs/job_output/
|
|
175
|
+
# wait_for_job/cancel_job tools (for models that handle fewer tools better).
|
|
176
|
+
# MARIM_JOB_TOOL_COMBINED=1
|
|
177
|
+
# Where pasted-image bytes are cached (content-addressed, per session).
|
|
178
|
+
# MARIM_IMAGE_CACHE_DIR=~/.marim/image-cache
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: ci-${{ github.ref }}
|
|
10
|
+
cancel-in-progress: true
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
strategy:
|
|
16
|
+
fail-fast: false
|
|
17
|
+
matrix:
|
|
18
|
+
python-version: ["3.10", "3.12", "3.14"]
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
# Install uv via the official script rather than a marketplace action, so
|
|
23
|
+
# the job doesn't depend on the Gitea runner mirroring third-party actions.
|
|
24
|
+
- name: Install uv
|
|
25
|
+
run: |
|
|
26
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
27
|
+
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
|
|
28
|
+
|
|
29
|
+
# Cache uv's download/build cache (compiled wheels for grpcio, cryptography,
|
|
30
|
+
# pydantic-core, …) so a cold matrix leg doesn't rebuild them every run. Keyed
|
|
31
|
+
# on uv.lock; first-party actions/* already resolve here (see checkout above).
|
|
32
|
+
- name: Cache uv
|
|
33
|
+
uses: actions/cache@v4
|
|
34
|
+
with:
|
|
35
|
+
path: ~/.cache/uv
|
|
36
|
+
key: uv-${{ runner.os }}-py${{ matrix.python-version }}-${{ hashFiles('uv.lock') }}
|
|
37
|
+
restore-keys: |
|
|
38
|
+
uv-${{ runner.os }}-py${{ matrix.python-version }}-
|
|
39
|
+
|
|
40
|
+
- name: Sync dependencies
|
|
41
|
+
run: uv sync --python ${{ matrix.python-version }}
|
|
42
|
+
|
|
43
|
+
- name: Lint (ruff)
|
|
44
|
+
run: uv run ruff check src tests
|
|
45
|
+
|
|
46
|
+
- name: Type-check (pyright)
|
|
47
|
+
run: uv run pyright
|
|
48
|
+
|
|
49
|
+
- name: Test (pytest)
|
|
50
|
+
run: uv run pytest
|
|
51
|
+
|
|
52
|
+
# Catch packaging regressions (missing metadata, broken includes) before a
|
|
53
|
+
# release does. One leg is enough — the artifacts are version-independent.
|
|
54
|
+
- name: Build sdist + wheel
|
|
55
|
+
if: matrix.python-version == '3.12'
|
|
56
|
+
run: uv build
|
|
57
|
+
|
|
58
|
+
# Pinned to v3: upload-artifact@v4 uses the @actions/artifact v2 API, which
|
|
59
|
+
# the Gitea act_runner (GHES-like) does not support — it fails the step with
|
|
60
|
+
# "GHESNotSupportedError". v3 uses the older artifact protocol Gitea implements.
|
|
61
|
+
- name: Upload coverage
|
|
62
|
+
if: always()
|
|
63
|
+
uses: actions/upload-artifact@v3
|
|
64
|
+
with:
|
|
65
|
+
name: coverage-py${{ matrix.python-version }}
|
|
66
|
+
path: coverage.xml
|
|
67
|
+
|
|
68
|
+
# Trim cache to only what this run actually used, keeping the saved cache lean.
|
|
69
|
+
- name: Prune uv cache
|
|
70
|
+
if: always()
|
|
71
|
+
run: uv cache prune --ci
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Publish to PyPI when a version tag is pushed. Cut a release with:
|
|
4
|
+
# git tag v0.1.0 && git push origin v0.1.0
|
|
5
|
+
# Requires a repository secret PYPI_API_TOKEN (a PyPI API token scoped to the
|
|
6
|
+
# marim-harness project). Trusted publishing (OIDC) isn't available from a
|
|
7
|
+
# self-hosted Gitea, so a token it is.
|
|
8
|
+
|
|
9
|
+
on:
|
|
10
|
+
push:
|
|
11
|
+
tags: ["v*"]
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
publish:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
# Install uv via the official script rather than a marketplace action, so
|
|
20
|
+
# the job doesn't depend on the Gitea runner mirroring third-party actions.
|
|
21
|
+
- name: Install uv
|
|
22
|
+
run: |
|
|
23
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
24
|
+
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
|
|
25
|
+
|
|
26
|
+
- name: Sync dependencies
|
|
27
|
+
run: uv sync --python 3.12
|
|
28
|
+
|
|
29
|
+
# Re-run the full check sequence on the tagged commit — a tag can point
|
|
30
|
+
# anywhere, so don't assume a green CI run already covered it.
|
|
31
|
+
- name: Lint (ruff)
|
|
32
|
+
run: uv run ruff check src tests
|
|
33
|
+
|
|
34
|
+
- name: Type-check (pyright)
|
|
35
|
+
run: uv run pyright
|
|
36
|
+
|
|
37
|
+
- name: Test (pytest)
|
|
38
|
+
run: uv run pytest
|
|
39
|
+
|
|
40
|
+
# Refuse to publish a version that doesn't match the tag — catches the
|
|
41
|
+
# classic "tagged v0.2.0 but pyproject still says 0.1.0" mistake.
|
|
42
|
+
- name: Check tag matches project version
|
|
43
|
+
run: |
|
|
44
|
+
version=$(uv run python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
|
|
45
|
+
tag="${GITHUB_REF_NAME#v}"
|
|
46
|
+
if [ "$version" != "$tag" ]; then
|
|
47
|
+
echo "pyproject version ($version) != tag ($tag)" >&2
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
- name: Build sdist + wheel
|
|
52
|
+
run: uv build
|
|
53
|
+
|
|
54
|
+
- name: Publish to PyPI
|
|
55
|
+
run: uv publish --token "${{ secrets.PYPI_API_TOKEN }}"
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.pyc
|
|
3
|
+
.venv/
|
|
4
|
+
.env
|
|
5
|
+
|
|
6
|
+
# Tool caches / generated reports
|
|
7
|
+
.pytest_cache/
|
|
8
|
+
.ruff_cache/
|
|
9
|
+
.mypy_cache/
|
|
10
|
+
.VSCodeCounter/
|
|
11
|
+
|
|
12
|
+
# Coverage artifacts from the test runner
|
|
13
|
+
.coverage
|
|
14
|
+
coverage.xml
|
|
15
|
+
htmlcov/
|
|
16
|
+
|
|
17
|
+
# Python build / packaging artifacts (uv build, pip wheel, etc.)
|
|
18
|
+
build/
|
|
19
|
+
dist/
|
|
20
|
+
*.egg-info/
|
|
21
|
+
|
|
22
|
+
# Node / Playwright — the e2e-tests workflow runs @playwright/test via npx.
|
|
23
|
+
node_modules/
|
|
24
|
+
/test-results/
|
|
25
|
+
/playwright-report/
|
|
26
|
+
/blob-report/
|
|
27
|
+
.last-run.json
|
|
28
|
+
|
|
29
|
+
# OS / editor cruft.
|
|
30
|
+
.DS_Store
|
|
31
|
+
*.swp
|
|
32
|
+
|
|
33
|
+
# marim's per-project working dir: offloaded fetch bodies, sub-agent/output
|
|
34
|
+
# spill, the last-provider-error payload, and generated test reports — all local
|
|
35
|
+
# scratch. Ignored wholesale; commit a specific file with a negation (e.g.
|
|
36
|
+
# `!.marim/mcp.json`) if a project ever needs to track project-local config.
|
|
37
|
+
.marim/
|
|
38
|
+
|
|
39
|
+
# Git worktrees created by --worktree / the /worktree command.
|
|
40
|
+
.worktrees/
|
|
41
|
+
|
|
42
|
+
# Claude Code host config — per-machine and duplicated by marim's own plugins.
|
|
43
|
+
# marim never reads .claude/ (see test_ignores_claude_agents_dir) nor the root
|
|
44
|
+
# .mcp.json (it uses .marim/mcp.json; see mcp/config.py). The playwright agents
|
|
45
|
+
# + MCP server ship as the examples/playwright plugin, the source of truth.
|
|
46
|
+
.claude/
|
|
47
|
+
.mcp.json
|
|
48
|
+
# Stray Playwright seed scaffolded at the repo root by `playwright init-agents`.
|
|
49
|
+
# The e2e workflow's real seed lives at tests/seed.spec.ts (still trackable);
|
|
50
|
+
# only the misplaced root copy is ignored.
|
|
51
|
+
/seed.spec.ts
|
|
52
|
+
|
|
53
|
+
# Playwright e2e workspace scaffolded by `playwright init-agents` (the planner's
|
|
54
|
+
# specs/plan.md output dir). Scaffold, not marim source — the workflow itself
|
|
55
|
+
# lives in the examples/playwright plugin. Ignored wholesale.
|
|
56
|
+
/specs/
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to marim-harness are documented here.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and the project adheres to [Semantic Versioning](https://semver.org/) —
|
|
7
|
+
pre-1.0, minor versions may contain breaking changes.
|
|
8
|
+
|
|
9
|
+
## [Unreleased]
|
|
10
|
+
|
|
11
|
+
Everything so far — `0.1.0` will be the first tagged release. Highlights of
|
|
12
|
+
what exists today:
|
|
13
|
+
|
|
14
|
+
- **Interactive TUI** (Textual): streaming responses, tool-call cards, live
|
|
15
|
+
token counter, inline approval / ask-user / plan panels, sub-agents screen,
|
|
16
|
+
settings, model picker, themes.
|
|
17
|
+
- **Headless mode**: one-shot prompts with `text`, `json`, or `stream-json`
|
|
18
|
+
output; `marim serve` HTTP daemon (REST + WebSocket) in the `[serve]` extra.
|
|
19
|
+
- **Providers**: OpenRouter (default), any local OpenAI-compatible server
|
|
20
|
+
(Ollama, LM Studio), Google Gemini, and a `claude-cli` provider that
|
|
21
|
+
delegates turns to Claude Code on a Claude subscription.
|
|
22
|
+
- **Permission modes** (`auto` / `ask` / `plan`), a configurable shell command
|
|
23
|
+
policy, and workspace-confined file tools.
|
|
24
|
+
- **Sessions**: per-workspace persistence, resume, compaction with observation
|
|
25
|
+
masking, checkpoints and `/rewind` backed by git snapshots.
|
|
26
|
+
- **Sub-agents**: parallel spawns with granted tool reach, model tiers
|
|
27
|
+
(`cheap`/`med`/`high`), nesting with a depth ceiling, detached fan-out with
|
|
28
|
+
live cards, and an optional `claude -p` backend.
|
|
29
|
+
- **Dynamic workflows**: a gated `run_workflow` tool executing model-authored
|
|
30
|
+
scripts in a pydantic-monty sandbox (`[workflows]` extra).
|
|
31
|
+
- **Integrations**: MCP servers (global / project / plugin scope), LSP
|
|
32
|
+
navigation + diagnostics via pluggable providers (Python, TypeScript, C++,
|
|
33
|
+
Java bundled), Gitea/GitHub forge tools via the `tea` CLI, lifecycle hooks
|
|
34
|
+
(Claude-Code-compatible), plugins, skills, and persistent memory.
|
|
35
|
+
- **Embeddable**: `HarnessBuilder` composes the same agent loop as a library
|
|
36
|
+
with explicit config and no env reads (see `docs/embedding.md` and
|
|
37
|
+
`docs/sdk/`).
|
|
38
|
+
- **Extras**: advisor model, thinking levels, desktop notifications, image
|
|
39
|
+
input, background jobs with autonomous wake, session scratchpad.
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## What this is
|
|
6
|
+
|
|
7
|
+
`marim-harness` is a terminal coding agent built on [Pydantic AI](https://ai.pydantic.dev/)
|
|
8
|
+
and [Textual](https://textual.textualize.io/). It reads/searches/edits files and runs
|
|
9
|
+
commands in a workspace, with an interactive TUI and a headless one-shot mode. The
|
|
10
|
+
console scripts are `marim` and `marim-harness` (both → `marim_harness.__main__:main`).
|
|
11
|
+
|
|
12
|
+
## Commands
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
uv sync # install deps (creates .venv)
|
|
16
|
+
uv run pytest # full test suite (coverage is on by default via pyproject)
|
|
17
|
+
uv run pytest tests/test_agent.py # one file
|
|
18
|
+
uv run pytest tests/test_agent.py::test_name # one test
|
|
19
|
+
uv run pytest --no-cov tests/test_x.py # skip coverage for a fast single run
|
|
20
|
+
uv run ruff check src tests # lint
|
|
21
|
+
uv run ruff check --fix src tests
|
|
22
|
+
uv run pyright # type-check (standard mode, src only)
|
|
23
|
+
uv run marim serve --port 8642 # HTTP daemon (REST + WebSocket); needs the [serve] extra
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
CI (`.gitea/workflows/ci.yml`) runs ruff → pyright → pytest on Python 3.10, 3.12,
|
|
27
|
+
and 3.14 (plus a `uv build` packaging check on the 3.12 leg). Match that order
|
|
28
|
+
locally before claiming work is done. `requires-python` is `>=3.10`, so avoid
|
|
29
|
+
3.11+ only syntax.
|
|
30
|
+
|
|
31
|
+
Set `MARIM_DEBUG=1` for DEBUG logging. Provider config lives in env vars / `.env`
|
|
32
|
+
(see `.env.example`): `MARIM_PROVIDER` (`openrouter`|`local`|`google`|`claude-cli`), `MARIM_MODEL`,
|
|
33
|
+
`OPENROUTER_API_KEY`, etc. Default provider is OpenRouter, default model
|
|
34
|
+
`anthropic/claude-sonnet-4-6`. `claude-cli` delegates each turn to the `claude` CLI on a
|
|
35
|
+
Claude subscription — marim acts as a launcher (Claude runs its own tools/loop), so marim's
|
|
36
|
+
own tools/approval/LSP/MCP do not apply in that provider. Claude's own Agent/Task
|
|
37
|
+
sub-agents, however, are demuxed out of the stream (`subagents/cli_demux.py`) and
|
|
38
|
+
rendered as first-class cards in the sub-agents screen, for both the main-loop
|
|
39
|
+
provider and `backend: claude-cli` spawns. Interrupted `claude-cli` spawns
|
|
40
|
+
resume via the CLI's own `--resume` (the session id is checkpointed in the
|
|
41
|
+
spawn's sidecar meta).
|
|
42
|
+
|
|
43
|
+
## Architecture
|
|
44
|
+
|
|
45
|
+
The dependency flow is **`__main__` → `interfaces/cli/router` → `default_cmd` →
|
|
46
|
+
`runtime/bootstrap.py`'s `build_harness` → `Harness`**. The two front-ends (TUI and
|
|
47
|
+
headless) both go through `build_harness`, so they wire up models, sessions, MCP,
|
|
48
|
+
hooks, and LSP identically — keep new wiring there, not duplicated per interface.
|
|
49
|
+
|
|
50
|
+
The turn-execution engine lives in the **`runtime/`** package: `harness.py`
|
|
51
|
+
(`Harness`, `build_collaborators`, `build_services`), `controller.py`
|
|
52
|
+
(`TurnController`, the approval/persist loop), `context.py` (per-turn context
|
|
53
|
+
helpers), `deps.py`, `permissions.py` (`Mode`), `errors.py`, `instructions.py`,
|
|
54
|
+
`builder.py`, and `bootstrap.py`. Imports target submodules directly (`from
|
|
55
|
+
.deps import Deps`); the package root deliberately re-exports nothing, keeping
|
|
56
|
+
the deps/services cycle below from leaking through `__init__` at import time.
|
|
57
|
+
|
|
58
|
+
`HarnessBuilder` (`builder.py`) is the embedding front door — explicit model,
|
|
59
|
+
explicit tool/session/sub-agent composition, no `MARIM_*` env reads; see
|
|
60
|
+
`docs/embedding.md`. `bootstrap.build_harness` is the CLI preset built on top
|
|
61
|
+
of that same builder (env config, workspace scanning, TUI/headless wiring).
|
|
62
|
+
New construction wiring (a tool group, a config knob) goes in the builder;
|
|
63
|
+
env/discovery reading stays in bootstrap, so the two paths cannot drift.
|
|
64
|
+
|
|
65
|
+
### The core turn loop (`runtime/harness.py`)
|
|
66
|
+
|
|
67
|
+
`Harness` owns the Pydantic AI `Agent` and drives one user turn to completion.
|
|
68
|
+
`Harness.run_turn` → `_run_with_approval` is the heart of the system. Key invariants
|
|
69
|
+
encoded there (read the docstrings before touching):
|
|
70
|
+
|
|
71
|
+
- **Approval rounds.** The agent's `output_type` is `[str, DeferredToolRequests]`.
|
|
72
|
+
Gated tools (`write_file`, `edit_file`, `bash`) defer; `_run_with_approval` loops,
|
|
73
|
+
resolving each deferred batch via `resolve_approvals` against the current `Mode`
|
|
74
|
+
(`auto`/`ask`/`plan`), then continues the run with the results.
|
|
75
|
+
- **Resumability.** A persisted history must never end with a `ToolCallPart` lacking
|
|
76
|
+
its `ToolReturnPart` — every provider rejects that on the next request.
|
|
77
|
+
`_repair_unanswered_tool_calls` self-heals such histories; an aborted turn is
|
|
78
|
+
flushed via `_flush_resumable` (with a tight deadline so Ctrl-C stays snappy).
|
|
79
|
+
The dirty history held during an approval round is deliberately **not** persisted —
|
|
80
|
+
`resumable` is the rollback baseline and is refreshed only after a clean persist.
|
|
81
|
+
- **Prompt assembly.** `_assemble_prompt` prepends per-turn context (task checklist,
|
|
82
|
+
finished-job digests, the prior turn's actionable error note, SessionStart /
|
|
83
|
+
UserPromptSubmit hook output) and wraps the injected prefix in a `<turn-context>`
|
|
84
|
+
envelope so a resumed session can recover just what the user typed
|
|
85
|
+
(`strip_turn_context`). The system prompt is kept stable to preserve prompt caching.
|
|
86
|
+
- **Error notes.** `_actionable_error_note` surfaces only failures the *model* can act
|
|
87
|
+
on (4xx client errors, usage limits, malformed responses) and stays silent on infra
|
|
88
|
+
(429/5xx), cancels, and render bugs. Full provider payloads spill to
|
|
89
|
+
`.marim/last-provider-error.json`.
|
|
90
|
+
|
|
91
|
+
### Construction & the deps/services cycle
|
|
92
|
+
|
|
93
|
+
`build_collaborators` (in `runtime/harness.py`) builds the whole collaborator graph
|
|
94
|
+
(agent, MCP, LSP, session, checkpoints, hooks, subagents) in dependency order. There
|
|
95
|
+
is one unavoidable late binding: `Deps` and `HarnessServices` form a reference cycle — `TurnHooks` and the
|
|
96
|
+
sub-agent runners hold `deps`, while tools reach back through `ctx.deps.services`.
|
|
97
|
+
`build_services` performs that single binding. `HarnessConfig` bundles all optional
|
|
98
|
+
knobs; `Harness.__init__` still accepts legacy `**kwargs` as a shorthand for
|
|
99
|
+
building one (pass `config=` *or* kwargs, not both — mixing raises `TypeError`).
|
|
100
|
+
|
|
101
|
+
`Deps` (`runtime/deps.py`) is the `RunContext` payload threaded through every tool. All
|
|
102
|
+
UI-facing collaboration is **optional callbacks** that headless leaves as `None`
|
|
103
|
+
(each reader guards with `is None`). The TUI wires them in one place via
|
|
104
|
+
`Harness.bind_ui` — don't poke `harness.deps`/`harness.session` field-by-field from
|
|
105
|
+
the interface layer.
|
|
106
|
+
|
|
107
|
+
### Tools (`tools/`)
|
|
108
|
+
|
|
109
|
+
Tool implementations are module-level functions in `tools/provider.py` so they can be
|
|
110
|
+
registered two ways from one source of truth: onto the main agent (gated tools behind
|
|
111
|
+
`requires_approval=True`) and onto sub-agents (registered *plain* — reach is decided
|
|
112
|
+
up front by which names are granted, never by mid-run prompting). `spawn_agent`
|
|
113
|
+
is granted to a sub-agent only when it could still nest within the depth ceiling
|
|
114
|
+
(`depth + 1 < SUBAGENT_MAX_DEPTH`, default 3) — see `SubagentRunner.build`; at
|
|
115
|
+
the leaf depth the tool is absent, so nesting is bounded, not forbidden. Nested
|
|
116
|
+
spawns render in the sub-agents screen as an indented tree (a child card streams
|
|
117
|
+
into its parent's transcript pane). Tool docstrings are the model-facing tool
|
|
118
|
+
descriptions — they are part of the product; write them with that in mind.
|
|
119
|
+
`names.py` is the leaf module holding tool-name sets (`GATED_TOOLS`, `LSP_TOOLS`, etc.)
|
|
120
|
+
to avoid import cycles.
|
|
121
|
+
|
|
122
|
+
### Supporting subsystems (one concern each)
|
|
123
|
+
|
|
124
|
+
- `session/` — `SessionStore` (persists to `$XDG_DATA_HOME/marim-harness/sessions`),
|
|
125
|
+
`SessionManager`, `SessionController` (compaction/autoname), `CheckpointManager`
|
|
126
|
+
(rewind via `GitSnapshotter`, honoring `.gitignore`).
|
|
127
|
+
- `mcp/` — Model Context Protocol server config + lifecycle; servers can be granted
|
|
128
|
+
selectively to sub-agents. Project-local `.marim/mcp.json` servers launch code on
|
|
129
|
+
connect, so they load only when the project is trusted (the same
|
|
130
|
+
`MARIM_TRUST_PROJECT_HOOKS` gate as project hooks); global/plugin servers always load.
|
|
131
|
+
- `lsp/` — multilspy-backed language servers, now assembled from **LSP providers**
|
|
132
|
+
(`provider.py`: `LspProvider` + `LspRegistry`) rather than a hard-coded set. Four
|
|
133
|
+
bundled language plugins (`lsp/bundled/{python,typescript,cpp,java}`) ship in-tree
|
|
134
|
+
and always load; third-party plugins add languages via an `lsp` manifest block
|
|
135
|
+
(declarative `command`/`args` only) under the same `MARIM_TRUST_PROJECT_HOOKS` gate
|
|
136
|
+
as MCP. `backend:`/named-`diagnostics:` keys are a bundled-only seam to in-tree tuned
|
|
137
|
+
code (`basedpyright.py`, ruff/pyright via `checks.py`). Declarative servers launch
|
|
138
|
+
through `GenericStdioServer` (`generic.py`). Two switches still gate the whole thing:
|
|
139
|
+
`lsp_enabled` (manager + diagnostics-on-edit) and `lsp_tools_enabled` (the six nav
|
|
140
|
+
tools). marim never downloads server binaries — it probes PATH and surfaces the
|
|
141
|
+
provider's install hint.
|
|
142
|
+
- `forge/` — Gitea/GitHub integration via a `ForgeBackend` seam. `TeaBackend`
|
|
143
|
+
shells out to the `tea` CLI (`--output json`); five forge-agnostic tools
|
|
144
|
+
(`tools/forge_tools.py`) list/view PRs, check CI, and open/check out PRs, with
|
|
145
|
+
create/checkout gated for approval. Attached at build time only when
|
|
146
|
+
`MARIM_FORGE` is on (default) and a backend is available (`tea` on PATH + a
|
|
147
|
+
configured login). A `gh` backend is a future drop-in behind the same protocol.
|
|
148
|
+
- `hooks/` — Claude-Code-compatible lifecycle hook engine (session/prompt/tool/
|
|
149
|
+
compaction events). Observe-only except SessionStart/UserPromptSubmit (inject
|
|
150
|
+
context) and PreCompact (may block a *manual* /compact via exit 2 or
|
|
151
|
+
`{"decision":"block"}`; block verdicts on auto compaction are logged and
|
|
152
|
+
ignored). Project-local hooks run only when trusted
|
|
153
|
+
(`MARIM_TRUST_PROJECT_HOOKS`).
|
|
154
|
+
- `plugins/` — bundles skills + sub-agents + hooks + MCP + `AGENTS.md`; hooks/MCP load
|
|
155
|
+
only for *trusted* plugins. Namespaced `plugin:item`. See `docs/plugins.md`.
|
|
156
|
+
- `workspace/` — fs primitives, memory (`remember`/`recall`), skills, sub-agent specs,
|
|
157
|
+
git worktrees, snapshots, and the session scratchpad (a per-session /tmp dir for
|
|
158
|
+
intermediate files: advertised in the prompt, reachable by the file tools as an
|
|
159
|
+
extra guard root, auto-approved in ask mode, gated by `MARIM_SCRATCHPAD`). (The
|
|
160
|
+
root-level `compaction.py` builds the summarizer/titler aux agents and the
|
|
161
|
+
token-budget compaction helpers.)
|
|
162
|
+
- `subagents/` — `runner.py` (`SubagentRunner`: spawn-lifecycle coordinator),
|
|
163
|
+
`run_driver.py` (model-loop retry/overflow/contention recovery),
|
|
164
|
+
`cli_spawn.py` (`claude -p` execute/resume orchestration), `masking.py`
|
|
165
|
+
(per-spawn context masking of stale tool observations), and `cli_backend.py`
|
|
166
|
+
(the optional `claude -p` CLI backend it delegates to). Re-exported as
|
|
167
|
+
`marim_harness.subagents.SubagentRunner`. Native spawns pick a model by **tier** (`cheap`/`med`/`high`, in `subagents/tiers.py`): resolved from the spawner's `tier=` override → the spec's `tier:` frontmatter → tool reach (read-only→cheap, mutating→high), mapped to `MARIM_SUBAGENT_TIER_*`; unset tiers inherit the main model and a `model=` slug stays a bounded escape hatch.
|
|
168
|
+
- `workflows/` — dynamic workflows: the gated `run_workflow` tool executes a
|
|
169
|
+
model-authored Python script in a pydantic-monty sandbox (`engine.py`);
|
|
170
|
+
`agent()`/`log()` host functions delegate to `SubagentRunner.run` through
|
|
171
|
+
the `services.run_workflow` seam. Schema validation of agent() reports is
|
|
172
|
+
engine-level (`schema.py`, jsonschema). Never cancel the Monty VM task —
|
|
173
|
+
aborts flow through host functions (see engine.py's module docstring).
|
|
174
|
+
Optional extra `[workflows]`; `MARIM_WORKFLOWS` gates it.
|
|
175
|
+
- `advisor.py` (root) — the advisor: an `advisor()` tool on the main agent
|
|
176
|
+
forwards the full transcript to a separately-configured model
|
|
177
|
+
(`MARIM_ADVISOR_MODEL`, any provider) and returns strategic guidance.
|
|
178
|
+
Live seam is `services.advise` (a pydantic-ai `prepare` hook omits the tool
|
|
179
|
+
when it's `None`, so `/advisor <model>`/`/advisor off` toggle without a
|
|
180
|
+
rebuild — at the cost of one prompt-cache break per toggle). Session
|
|
181
|
+
persistence mirrors `store.model` (`"off"` sentinel = explicitly disabled);
|
|
182
|
+
per-turn call cap `MARIM_ADVISOR_MAX_USES` rides on `Deps`. Main loop only
|
|
183
|
+
(sub-agents have tiering); the tool doesn't exist under the claude-cli
|
|
184
|
+
main-loop provider (marim's tools don't apply there), but a claude-cli
|
|
185
|
+
*advisor* model works via the `aux_model_for` clone.
|
|
186
|
+
- `thinking.py` (root) — thinking level (reasoning effort): one ordered
|
|
187
|
+
vocabulary (`off/minimal/low/medium/high/xhigh`) and three pure helpers —
|
|
188
|
+
`parse_thinking_level` (env/CLI/`/think` coercion), `settings_for` (fold a
|
|
189
|
+
level into `ModelSettings.thinking`; `off`/unset OMITS the key, byte-identical
|
|
190
|
+
to pre-thinking behavior), and `resolve_thinking` (sub-agent precedence:
|
|
191
|
+
spawn override → spec `thinking:`/`effort:` → inherited session level). The
|
|
192
|
+
main loop applies it per turn in `TurnController._turn_model_settings`; the
|
|
193
|
+
level persists on `SessionStore.thinking` and lives on `Harness.thinking_level_id`
|
|
194
|
+
(read lazily by the controller closure and the sub-agent runner, so `/think`
|
|
195
|
+
switches without a rebuild). Seeded by `MARIM_THINKING` / `--think`; TUI
|
|
196
|
+
`/think` command + Settings row. Under the `claude-cli` main provider it's a
|
|
197
|
+
documented no-op (marim's `ModelSettings` don't reach Claude Code). Detection
|
|
198
|
+
(`catalog.supports_thinking`) is best-effort UI annotation only — it never
|
|
199
|
+
blocks a level.
|
|
200
|
+
- `interfaces/tui/` — Textual app, widgets, `styles.tcss`, streaming render;
|
|
201
|
+
`interactions/` — inline approval/ask-user/plan-card panels (mounted above the
|
|
202
|
+
status bar, not modals, so the transcript stays scrollable) sharing an
|
|
203
|
+
`InteractionPanel` base; `subagents/` — the sub-agents screen: master list,
|
|
204
|
+
full-bleed view, inline card, persistent transcript pane, pure stats.
|
|
205
|
+
`interfaces/cli/` — router + per-command modules (lazily imported so
|
|
206
|
+
`config`/`models` don't pay for `pydantic_ai`).
|
|
207
|
+
|
|
208
|
+
## Conventions
|
|
209
|
+
|
|
210
|
+
- Use `uv` for everything (`uv run …`, `uv sync`). Don't invoke `pip` or a bare
|
|
211
|
+
`python`/`pytest`.
|
|
212
|
+
- Ruff line length is 100; lint set is `E,F,I,UP,B,SIM,C901` (import sorting
|
|
213
|
+
enforced; pyupgrade, bugbear, and flake8-simplify also on).
|
|
214
|
+
- Cyclomatic complexity is capped at 10 (`C901`, mccabe). CI rejects any function
|
|
215
|
+
above it. When a function trips the ceiling, extract cohesive branch-clusters into
|
|
216
|
+
named helpers (or a small state value-object where locals mutate across the region)
|
|
217
|
+
— do not add a blanket `# noqa: C901`. Note: this bounds *branch count*, not length;
|
|
218
|
+
a long, straight-line, well-commented function is fine.
|
|
219
|
+
- Keep pure decision/parse helpers (command policy, snapshot diffing, arg coercion,
|
|
220
|
+
path-guard resolution, and the extracted module-level helpers inside the effectful
|
|
221
|
+
modules) side-effect-free and unit-tested directly. The effectful I/O itself lives in
|
|
222
|
+
`tools/impl/` (`fs.py` writes, `shell.py` spawns, `fetch.py` opens sockets) — that is
|
|
223
|
+
the real I/O *core*, not a pure layer; it is exercised directly against a tmp
|
|
224
|
+
workspace. Above it, the tool layer (`fs_tools.py`, `edit_tools.py`, `net_tools.py`)
|
|
225
|
+
is thin `ctx.deps`-unwrapping wiring. Follow that three-way split when adding behavior.
|
|
226
|
+
- The codebase favors long, explanatory comments on *why* a non-obvious invariant
|
|
227
|
+
holds (especially around resumability and the deps/services cycle). Preserve them
|
|
228
|
+
when editing nearby code.
|
|
229
|
+
- Follow `coding-guidelines.md` for code design principles: control complexity,
|
|
230
|
+
prefer straight-line flow, model the domain when it pays off, encapsulate
|
|
231
|
+
collections with behavior, limit deep navigation, name for clarity, optimize for
|
|
232
|
+
cohesion, treat large state as a smell, and encapsulate behavior over data.
|
|
233
|
+
It's guidance, not dogma — break a rule when the tradeoff is clear and
|
|
234
|
+
document why.
|