Commit Graph

2496 Commits

Author SHA1 Message Date
can1357 c3d83c2003 chore: bump version to 13.9.6 2026-03-08 03:41:22 +01:00
can1357 d4e3d5881c docs(coding-agent/prompts): clarified contextual pattern mode targeting behavior in ast-grep and ast-edit
- Clarified contextual pattern mode behavior in ast-grep and ast-edit documentation to explain that results target the selected node, not the outer wrapper.
- Enhanced TypeScript pattern examples to include class method matching syntax with `class $_ { method(...) }` wrapper pattern.
- Removed redundant class method examples that were superseded by improved documentation of contextual pattern mode.
2026-03-08 03:40:58 +01:00
can1357 72b036dcc0 refactor(coding-agent): simplified AST tool parameters and expanded documentation
- Renamed parameter names in ast-grep and ast-edit tools from `patterns`/`selector` to `pat`/`sel` for brevity across schema, implementation, and tests.
- Expanded ast-grep and ast-edit tool documentation with 12+ new usage guidelines, examples, and critical notes on pattern syntax, metavariable placement, and error handling.
- Updated CHANGELOG.md to document parameter renames and expanded tool guidance for AST pattern syntax and metavariable usage.
- Reformatted test assertions and type annotations across ast-edit and ast-grep test files for improved readability.
2026-03-08 03:08:38 +01:00
can1357 c3323160be feat(coding-agent): added glob parameter to grep tools for file filtering
- Added `glob` parameter to `ast_grep`, `ast_edit`, and `grep` tools for filtering files relative to `path`.
- Implemented `combineSearchGlobs()` utility to merge glob patterns from multiple sources instead of throwing errors.
- Changed `grep` tool to combine glob patterns when both `path` and `glob` parameters are provided.
- Updated tool documentation to recommend pairing `path`, `glob`, and `lang` for language-scoped search in mixed repositories.
- Added comprehensive test coverage for combined path and glob parameter handling across grep, ast_grep, and ast_edit tools.
2026-03-08 02:52:29 +01:00
can1357 069d27423d chore: bump version to 13.9.5 2026-03-08 01:45:46 +01:00
can1357 aac0156476 chore: bump version to 13.9.4 2026-03-08 00:06:35 +01:00
can1357 568592ff77 chore(coding-agent/tools): removed obsolete TypeScript error suppressions from Kagi search tests
- Removed three @ts-expect-error comments that are no longer needed for fetch.preconnect mocking.
- The test mocks now work without requiring type suppression.
2026-03-08 00:06:12 +01:00
can1357 c4946363ca feat(coding-agent): added Ollama capability detection and improved provider integrations
- Added automatic Ollama model capability detection via /api/show endpoint to discover reasoning and input modality support.
- Improved Kagi API error handling with structured error parsing for JSON and plain text response formats.
- Fixed Cerebras streaming compatibility by omitting stream_options.include_usage parameter.
- Simplified API key credential storage to always replace credentials instead of merging for non-minimax providers.
- Updated Kagi Search API key format from 'kagi_...' to 'KG_...' and clarified beta access requirement in provider description.
Fixes #326.
Fixes #321.
Fixes #298.
2026-03-08 00:00:59 +01:00
can1357 7d5a230e26 fix: lowercased tool names in argument parsing
Fixes #324.
2026-03-07 23:53:16 +01:00
Miroslav Drbal [ApoC] a2223cef60 fix: correct context window percentage and provider token mapping (#306)
The context fullness gauge was driven by output token count, causing
erratic jumps between turns (e.g. 84% -> 64%) with no compaction.

Status bar and estimateContextTokens now use calculatePromptTokens()
which returns input + cacheRead + cacheWrite — the actual input context
size. Previously both used a formula that included the final output token
count, which fluctuates with response length and is not part of the
context window for the current request.

isContextOverflow's usage-based fallback (z.ai silent overflow) was
also missing cacheWrite (cache_creation_input_tokens). Per Anthropic
docs the threshold is input + cache_read + cache_creation — all three.
Ref: https://platform.claude.com/docs/en/about-claude/pricing#long-context-pricing

google.ts and google-vertex.ts were double-counting cached tokens.
Gemini's promptTokenCount already includes cachedContentTokenCount, so
assigning input = promptTokenCount and cacheRead = cachedContentTokenCount
overcounted by cachedContentTokenCount on every cached request. Fixed
by subtracting first, matching the OpenAI convention:
  input = promptTokenCount - cachedContentTokenCount
  cacheRead = cachedContentTokenCount
  => input + cacheRead = promptTokenCount (total prompt, no double-count)
Ref: https://ai.google.dev/api/generate-content#v1beta.GenerateContentResponse.UsageMetadata

All other providers validated: amazon-bedrock (inputTokens is uncached
by API contract), openai-completions/responses/azure (already subtract
cached), kimi/gitlab-duo (delegate to correct implementations), cursor
(API exposes output tokens only — input stays 0 by design).

Co-authored-by: Miroslav Drbal <miroslav.drbal@gendigital.com>
2026-03-07 23:11:15 +01:00
can1357 f06fec1a2b chore: bump version to 13.9.3 2026-03-07 22:28:35 +01:00
Adrian Glapiński 5770987f6e fix(coding-agent): parse Exa MCP plain-text web_search payloads (#303)
* fix(coding-agent): parse Exa MCP plain-text web_search payloads

* fix(coding-agent): preserve embedded Title lines in Exa plain-text parsing

* fix(coding-agent): support CRLF in Exa plain-text MCP parsing
2026-03-07 22:17:38 +01:00
Joshua Christman 44f5f4e6cf Add PUPPETEER_PROXY and PUPPETEER_PROXY_IGNORE_CERT_ERRORS env vars (#323)
* Add PUPPETEER_PROXY and PUPPETEER_PROXY_IGNORE_CERT_ERRORS env vars

- PUPPETEER_PROXY: routes browser traffic through specified proxy
- PUPPETEER_PROXY_IGNORE_CERT_ERRORS: ignore HTTPS cert errors when set

Made-with: Cursor

* fix(browser): gate PUPPETEER_PROXY_IGNORE_CERT_ERRORS on explicit truthy parse

Previously any non-empty value (including 'false', '0') enabled
--ignore-certificate-errors, silently disabling TLS verification when
operators intended to keep it on. Now only 'true', '1', 'yes', 'on'
(case-insensitive) enable the flag.

Made-with: Cursor
2026-03-07 22:13:08 +01:00
can1357 5293eaff29 feat(ai): added credential disable tracking with auditability improvements
- Added `disabledCause` parameter to credential deletion methods to track reason credentials are disabled.
- Changed credential disabling mechanism from boolean `disabled` flag to `disabled_cause` text field for better auditability.
- Fixed credential purging to respect disabled credentials during email deduplication operations.
- Refactored `replaceAuthCredentialsForProvider()` to update matching credentials instead of deleting all, preserving credential history.
2026-03-06 16:05:04 +01:00
can1357 8f88e8c82e feat(ai): added incremental history for remote compact
- Added incremental history mode to OpenAI responses .
- Changed OpenAI Codex to exclusively use websockets v2 protocol with fatal error detection for automatic SSE fallback.
- Fixed Gemini model parsing to strip `-preview` suffix for consistent model identification across API calls.
- Improved websocket error handling to extract and report detailed error messages from error events.
- Removed deprecated BETA_RESPONSES_WEBSOCKETS constant and websocket v2 feature flag branching logic.
2026-03-06 15:45:24 +01:00
can1357 6364c627ae fix: missing thresholds. 2026-03-06 12:54:53 +01:00
can1357 8e3e0ebf9e feat: introduced Effort enum and ThinkingConfig for model-aware reasoning
- Introduced Effort enum and ThinkingConfig metadata for per-model reasoning capabilities with min/max effort levels.
- Migrated thinking level API from string-based ThinkingLevel to structured Effort enum across agent and AI packages.
- Added model-thinking module with effort mapping, policy application, and semantic versioning utilities for provider-specific thinking modes.
- Removed supportsXhigh() function and replaced effort clamping with model-aware validation using ThinkingConfig metadata.
- Expanded models.json with thinking configuration objects for 50+ models including Claude, Gemini, and OpenAI variants.
- Added Python analysis scripts for edit tool usage patterns and tool invocation stream processing.
2026-03-06 12:35:01 +01:00
can1357 b696842570 feat: added serviceTier option and providerPayload field to OpenAI providers
- Added serviceTier option to OpenAI providers for controlling processing priority and cost across agent, completions, responses, and codex APIs.
- Added providerPayload field to messages for transport-native history reconstruction in OpenAI Responses and Codex APIs.
- Added /fast slash command and serviceTier setting to coding-agent for toggling OpenAI priority mode with fast mode indicator.
- Added remote compaction support with encrypted reasoning preservation for OpenAI models in coding-agent.
- Removed usage caching layer across all providers and refactored UsageFetchContext to eliminate cache and now dependencies.
- Fixed OpenAI Codex streaming service_tier inclusion, provider retry logic with exponential backoff, and email-based credential deduplication.
2026-03-06 12:34:57 +01:00
HvC b93c6c0e12 Offer handoff as a compaction strategy (#305)
* idiomatic rust fixes

* idiomatic rust fixes

* display an image if we are fetching an image

* MIME type strictness

* codex nagging me

* codex nagging

* handoff instead of compaction as context filled strategy and surfacing

* handoff instead of compaction as context filled strategy and surfacing p2

* handoff instead of compaction as context filled strategy and surfacing p3

* handoff instead of compaction as context filled strategy and surfacing p4

* handoff instead of compaction as context filled strategy and surfacing p5

* handoff instead of compaction as context filled strategy and surfacing, fixes

* failing fetch test from the fetch tool updates

* handoff focus prompt skeleton

* handoff focus prompt skeleton p2

* fetch bugs

* further codex improvements

* further codex improvements

---------

Co-authored-by: Brit <lol@no.com>
2026-03-06 03:12:31 +01:00
ravshansbox 00bc379f42 feat(ai,coding-agent): add opencode-go and rename opencode to opencode-zen (#310)
* feat(ai,coding-agent): add opencode-go and rename opencode to opencode-zen

* fix(ai): remove unsupported opencode-zen free models
2026-03-06 03:12:11 +01:00
can1357 bbe984ed5f chore: bump version to 13.9.2 2026-03-05 02:03:54 +01:00
can1357 b278ae85d1 fix(coding-agent): corrected off-by-one range errors in hashline edits
- Added auto-correction logic for off-by-one range start errors in hashline edits.
- Added safety check to prevent false-positive auto-correction when position already includes boundary.
- Added test coverage for off-by-one range correction and duplicate leading line handling.
- Extracted turn-aborted-guidance prompt to external markdown file for better maintainability.
2026-03-05 02:03:37 +01:00
can1357 a55eebca6b fix(coding-agent): corrected provider selection case labels to use namespaced keys
- Corrected provider selection case labels from flat names to namespaced keys (webSearchProvider -> providers.webSearch, imageProvider -> providers.image).
- Expanded web search provider options to include brave, kimi, kagi, and synthetic providers.
2026-03-05 01:53:06 +01:00
can1357 2d90ed62f3 fix(ai): handle redacted thinking + rebuild export template
- Added RedactedThinkingContent type to support secure encrypted reasoning blocks in Anthropic messages.
- Updated message transformation logic to preserve signed thinking blocks and redacted thinking for latest assistant messages in Anthropic conversations.
- Added handling for redacted_thinking events in Anthropic stream processing with type, data, and index fields.
- Added comprehensive tests validating redacted thinking block preservation and Anthropic thinking immutability during message transformation.
2026-03-05 01:51:46 +01:00
can1357 ed65cf1f3e chore: bump version to 13.9.1 2026-03-05 01:33:51 +01:00
can1357 4bd495429f refactor: restructured thinking mode API from static constants to dynamic functions
- Removed static thinking mode constant exports (THINKING_LEVELS, ALL_THINKING_LEVELS, ALL_THINKING_MODES, THINKING_MODE_DESCRIPTIONS, THINKING_MODE_LABELS) in favor of dynamic function-based API.
- Renamed formatThinking() to getThinkingMetadata() with return type changed from string to structured ThinkingMetadata object containing value, label, and description.
- Renamed getAvailableThinkingLevel() to getAvailableThinkingLevels() and getAvailableThinkingEffort() to getAvailableThinkingEfforts() with added default parameters for runtime flexibility.
- Updated all consumer modules to use new function-based API instead of static constants, enabling dynamic thinking mode configuration.
2026-03-05 01:33:42 +01:00
can1357 1e6cff1700 chore: bump version to 13.9.0 2026-03-05 01:19:05 +01:00
can1357 66ae85017b feat(coding-agent): added configurable default line limit for read tool output
- Added `read.defaultLimit` setting to configure default line count for read tool output (default 300 lines).
- Added preset options (200, 300, 500, 1000, 5000 lines) for read default limit in settings UI.
- Updated read tool to distinguish between default and maximum limits per call in prompt documentation.
- Refactored read tool limit logic to use configurable default limit with bounds validation.
2026-03-05 01:18:34 +01:00
can1357 b5234bd97d refactor(coding-agent/patch): restructured variant and mode checks for clarity
- Separated model variant check from settings mode check for improved readability. Added numbered comments documenting the four-step fallback resolution order. Simplified conditional returns to reduce nesting depth.
2026-03-05 01:15:59 +01:00
can1357 5d2d76e16c fix(coding-agent): resolved provider session leaks during history branching
- Fixed provider session state not being cleared when branching or navigating tree history, preventing resource leaks with codex provider sessions.
- Added calls to `#closeCodexProviderSessionsForHistoryRewrite()` in branch and navigateTree methods to ensure proper cleanup.
- Added test coverage for provider session cleanup during history branching and tree navigation.
2026-03-05 01:14:12 +01:00
can1357 2419d09c33 refactor(coding-agent/tools): replaced fuzzy path matching with unique suffix resolution
- Removed complex fuzzy matching logic including Levenshtein distance calculation and similarity scoring in favor of a simpler glob-based suffix pattern approach. Replaced findReadPathSuggestions with findUniqueSuffixMatch that returns a path only when exactly one candidate matches, eliminating ambiguous suggestions. Removed legacy ttsr_trigger and ttsrTrigger fields from RuleFrontmatter interface.
2026-03-05 01:12:43 +01:00
can1357 586c18f293 feat(coding-agent/patch): map spark to use replace 2026-03-05 00:41:31 +01:00
can1357 5b60309ebc feat(coding-agent/discovery): added support for legacy thinking field in agent frontmatter
- Added fallback to parse the legacy 'thinking' field when 'thinkingLevel' is not provided. The 'thinkingLevel' field takes precedence when both are present. Added tests to verify backward compatibility and field precedence.
2026-03-05 00:37:02 +01:00
can1357 63e087368f refactor(coding-agent): added kebabToCamel and normalizeKeys utility
- Added kebabToCamel and normalizeKeys utility functions to convert kebab-case keys to camelCase recursively. Updated parseFrontmatter to normalize all parsed keys, ensuring consistent camelCase property access throughout the codebase. Updated all frontmatter key accesses to use camelCase notation (e.g., thinkingLevel, spdxId).
2026-03-05 00:25:13 +01:00
can1357 10242a445a refactor(ai): renamed reasoningEffort to reasoning across providers
- Updated option interfaces, param builders, and stream functions to use unified `reasoning` field.
- Added `resolveOpenAiReasoningEffort()` to centralize xhigh clamping logic.
- Replaced type casts with `castApi()` helper and fixed test option names.
- Updated coding-agent and benchmark references for consistency.
2026-03-05 00:25:12 +01:00
can1357 e1897ce013 refactor: migrated thinking configuration to centralized pi-ai module
- Extracted thinking module with ThinkingEffort, ThinkingLevel, and ThinkingMode types to centralize reasoning configuration across packages.
- Migrated ThinkingLevel type from pi-agent-core to pi-ai package with new validation functions parseThinkingLevel() and getAvailableThinkingLevel().
- Consolidated thinking level constants and descriptions into reusable exports (ALL_THINKING_LEVELS, THINKING_MODE_DESCRIPTIONS) for consistent UI display.
- Removed local thinking-effort-label utility and replaced formatThinkingEffortLabel() with centralized formatThinking() function from pi-ai.
- Refactored thinking mode handling to distinguish ThinkingSelector (user-facing with 'off' option) from ThinkingEffort (provider-level).
2026-03-05 00:03:40 +01:00
can1357 2e001bbf8d fix(coding-agent): fixed model selector to handle multiple roles on same model
- Added formatRoleThinkingModeLabel helper to display 'inherit' for default thinking mode, preventing badge ambiguity when multiple roles share the same model. Enhanced role menu labels to include role tags for clarity. Fixed model resolver to avoid substring matching that could incorrectly resolve exact model IDs to similar variants.
2026-03-04 23:21:10 +01:00
can1357 1427e93183 Merge pr-223: thinking suffix per-role overrides 2026-03-04 23:12:49 +01:00
can1357 b495ed5174 chore: bump version to 13.8.0 2026-03-04 23:00:59 +01:00
can1357 911928fc1c revert(coding-agent/discovery): reverted monorepo-friendly discovery for aux agents
- Removed ancestor directory walking logic from codex and opencode skill loading. Simplified project skills discovery to use single project directory instead of scanning up the filesystem tree. Fixed variable shadowing issues in gemini and github context file loading.
2026-03-04 22:58:55 +01:00
can1357 e79e6206d0 fix(coding-agent): limit context promotion to explicit targets
Fixes #282
2026-03-04 22:48:53 +01:00
can1357 e1cb3ef52a fix: collapse nanogpt :thinking model variants into base models
NanoGPT exposes per-thinking-level model IDs (e.g.
anthropic/claude-opus-4.6:thinking:low) as separate entries. These
pollute the model list and collide with parseModelString's thinking
level suffix stripping.

Filter out all :thinking and :thinking:level suffixed nanogpt models
during discovery. When a :thinking variant existed, mark the
corresponding base model as reasoning-capable. NanoGPT already supports
reasoning_effort via the OpenAI-compat path so no provider-side model
ID suffixing is needed.
2026-03-04 22:45:23 +01:00
can1357 631021aa67 feat(patch): added compact hashline diff preview for patch responses
- Added buildCompactHashlineDiffPreview() function to generate collapsed diff previews for tool responses.
- Enhanced EditTool response to include diff summary with added/removed line counts and compact preview.
- Added project-level discovery for .agent/ and .agents/ directories walking up to repository root.
- Implemented helper functions for truncating long diff runs (collapseFromStart, collapseFromEnd, collapseFromMiddle).
2026-03-04 22:39:39 +01:00
can1357 f59b1b9fbf docs(coding-agent/prompts): refined hashline prompt guidance for edit operations
- Clarified pos semantics for replace, prepend, and append operations with concise bullet format.
- Simplified lines parameter documentation to focus on practical usage patterns.
- Rewrote rules section to emphasize structural anchoring and when to use prepend/append versus range replace.
2026-03-04 22:39:39 +01:00
sundbp 16d7f9aec0 feat: monorepo-friendly discovery for AGENTS.md and skills (#293)
* feat: monorepo-friendly discovery for AGENTS.md and skills

Support hierarchical config discovery in monorepos by walking up from
cwd through ancestor directories, combining files from all levels
instead of only checking the immediate working directory.

AGENTS.md context files:
- Change dedup key from file.level to file.level + depth, so context
  files at different directory levels coexist instead of shadowing
- Root AGENTS.md and sub-project AGENTS.md are both included in the
  system prompt, ordered from least specific to most specific

Skills:
- Modify all 4 providers with project-level skill directories (native,
  claude, codex, opencode) to walk up from cwd through ancestors,
  scanning for skills at each level
- Skills at closer directories win on name conflicts via existing
  name-based dedup

Repo root boundary:
- Add findRepoRoot() utility that detects .git to identify repo root
- Add repoRoot field to LoadContext, computed once in loadCapability()
- All walk-up traversals (AGENTS.md, skills, nearest config dir) stop
  at the repo root, preventing discovery from leaking outside the repo
- When not in a git repo, falls back to walking to filesystem root

Files changed:
- capability/fs.ts: add findRepoRoot()
- capability/types.ts: add repoRoot to LoadContext
- capability/index.ts: compute repoRoot in loadCapability()
- capability/context-file.ts: depth-aware dedup key
- discovery/agents-md.ts: bound walk-up at repo root
- discovery/builtin.ts: getAncestorDirs stopAt param, skill walk-up
- discovery/claude.ts: skill walk-up with repo root bound
- discovery/codex.ts: skill walk-up with repo root bound
- discovery/opencode.ts: skill walk-up with repo root bound
- extensibility/skills.ts: add repoRoot to inline LoadContext

* feat(agents-provider): add project-level discovery with ancestor walk-up for all capability types

The agents provider (.agent/.agents directories) previously only loaded
capabilities from the user home directory (~/.agent/, ~/.agents/). This
meant project-level .agents/ directories in monorepo roots were not
discovered when sessions started from subdirectories.

Add getProjectPathCandidates() helper that walks from cwd up to repoRoot,
scanning both .agent/ and .agents/ at each ancestor level. Apply this to
all six capability types: skills, rules, prompts, commands, context files
(AGENTS.md), and system prompts (SYSTEM.md). This matches the ancestor
walk-up behavior already present in the builtin (.omp), claude, codex,
and opencode providers.

All loaders now parallelize project-level and user-level scans via
Promise.all. Project-level results appear closest-first so dedup at the
capability layer picks the nearest override.

* fix(discovery): remove hard cap of 20 on ancestor directory walking

All walk-up loops already terminate naturally at repoRoot or filesystem
root. The depth < 20 / .slice(0, 20) / MAX_DEPTH caps were redundant
safety guards that would silently stop discovery in deeply nested
projects.

Removed from: agents.ts, agents-md.ts, builtin.ts, claude.ts, codex.ts,
opencode.ts, and corresponding test files.

* fix(agents-provider): set depth on project-level ContextFile entries for correct dedup

loadContextFiles was creating project-level ContextFile entries without
a depth field. Since contextFileCapability.key uses
`project:${file.depth ?? 0}`, all ancestor-level AGENTS.md files
collapsed to the same key and only the first survived dedup.

Compute depth via calculateDepth(cwd, ancestorDir) where ancestorDir is
two levels up from the file path (past the .agent/.agents config dir).
This gives each ancestor level a distinct dedup key.

* fix(discovery): stop ancestor walk-up at $HOME when not in a git repo

When repoRoot is null (no .git found), walk-up loops traversed all the
way to filesystem root. This caused $HOME to be scanned as a project-
level directory and then again as user-level, producing duplicates.

All providers now use `ctx.repoRoot ?? ctx.home` as the stop boundary:
stop at repoRoot if in a repo, otherwise stop at home. Applied to
agents.ts, agents-md.ts, builtin.ts, claude.ts, codex.ts, and
opencode.ts.

* fix(context-files): clamp depth >= 0 in dedup key and fix provider depth computations

The dedup key `project:${file.depth}` used raw depth, which could be
negative when providers computed it from config subdirectories (e.g.
.claude/, .github/, .gemini/) rather than the ancestor directory. This
caused same-scope cwd-level files to get distinct keys like project:-1
and project:0, bypassing dedup and injecting conflicting instructions.

Two-layer fix:
1. Key function: clamp to Math.max(0, depth) so any file at or below
   cwd is treated as cwd-scope (depth 0). Defensive against future
   providers.
2. Providers: fix root cause in claude.ts, gemini.ts, github.ts to
   compute depth from the ancestor directory (parent of the config
   subdir), not the config subdir itself.

---------

Co-authored-by: Can Bölük <can1357@users.noreply.github.com>
2026-03-04 22:36:55 +01:00
Kevin Loftis cda7120591 Support :thinking suffix in modelRoles config values (#292)
parseModelString now extracts valid thinking level suffixes (e.g.,
"anthropic/claude-opus-4-6:high") instead of treating them as part of
the model ID. This enables per-role thinking levels in config:

  modelRoles:
    slow: anthropic/claude-opus-4-6:high
    default: anthropic/claude-opus-4-6:low
    smol: google/gemini-3-flash:medium

The thinking level is applied at startup, in SDK fallback resolution,
and during Ctrl+P role cycling. The original config string is preserved
on role cycle so the suffix round-trips correctly.
2026-03-04 22:36:10 +01:00
can1357 b31548dadb chore: bump version to 13.7.9 2026-03-04 20:09:13 +01:00
can1357 af1a71baa8 chore: bump version to 13.7.8 2026-03-04 20:01:10 +01:00
can1357 16b861d8cc fix(ai): add ZenMux to models.json gen and fix maxTokens extraction
- Fixed maxTokens extraction in zenmuxModelManagerOptions using max_completion_tokens
- Sort providers alphabetically in generated models.json output
2026-03-04 20:00:13 +01:00
HvC f70f1d2eab enable image rendering if the fetch tool gets one (#288)
* idiomatic rust fixes

* idiomatic rust fixes

* display an image if we are fetching an image

* MIME type strictness

* codex nagging me

* resize so we do not blow up the terminal we are in

* codex nagging

* codex nagging

* codex nagging

* codex nagging

* codex nagging

---------

Co-authored-by: Brit <lol@no.com>
2026-03-04 19:17:50 +01:00