1081 Commits
Author SHA1 Message Date
Dark-Alex-17 79ec2d87c7 fix: support tab completions for graph-based agents with variables as well as standard agents 2026-08-21 12:47:38 -06:00
Dark-Alex-17 faf9dd581f feat: created a dedicated git_command tool to tighten tool calling permissions in the git-master skill 2026-08-21 12:33:28 -06:00
Dark-Alex-17 873deef7c7 feat: Added a new security review step to the code writing quality gates 2026-08-21 12:30:53 -06:00
Alex Clarke f518c8a6fc Merge pull request #16 from Dark-Alex-17/feat/macros-as-commands
feat: macros as first-class custom commands
2026-08-21 12:29:24 -06:00
Dark-Alex-17 aea5f3d615 test: updated embedded macro tests to expect descriptions for all built-in macros 2026-08-21 12:22:48 -06:00
Dark-Alex-17 bda37d9f38 docs: Added a description to the built-in generate-commit-message macro 2026-08-21 12:15:31 -06:00
Dark-Alex-17 96e5390621 test: use collision-proof temp dirs in macro_policy tests
The with_macro_dirs fixture derived its temp-dir name from a wall-clock
nanosecond timestamp, so parallel tests starting in the same clock tick
shared a directory and saw each other's macro files (flaky on CI
runners with coarse tick granularity). A process id + atomic counter
makes the name unique by construction.
2026-08-21 12:03:11 -06:00
Dark-Alex-17 b43acac8ee fix: surface macro parse errors on top-level invocation
An invalid installed macro invoked as a top-level command fell through
to the generic unknown-command error, while .macro <name> reported the
parse/validation failure. Both paths now surface the reason.
2026-08-21 11:55:14 -06:00
Dark-Alex-17 03687c8981 feat: addressed review comments 2026-08-21 11:55:14 -06:00
Dark-Alex-17 95dd31e24b docs: cleaned up docs 2026-08-21 11:55:14 -06:00
Dark-Alex-17 e1b5562888 refactor: render .list agents and .list skills as comfy-tables
Long agent/skill descriptions wrapped badly in the bullet-list format.
Extract a shared asset_table helper (UTF8_FULL + dynamic arrangement,
same style as the markdown renderer and .list macros) and use it for
the agents, skills, and macros listings. The skills loaded marker
keeps its color; comfy-table's custom_styling feature accounts for
ANSI sequences in column widths.
2026-08-21 11:55:14 -06:00
Dark-Alex-17 fba040c668 fix: render .list macros as a comfy-table instead of fixed-width columns
Hand-rolled {:<24} padding broke alignment as soon as a macro name
exceeded the column width. Reuse the comfy-table UTF8_FULL preset with
dynamic content arrangement, matching the markdown renderer's tables.
2026-08-21 11:55:13 -06:00
Dark-Alex-17 f61a8f7afd style: updated styles across macro implementation 2026-08-21 11:55:13 -06:00
Dark-Alex-17 91328ca7e1 docs: document macros as first-class custom commands
Covers top-level .name invocation, the new description/isolated macro
fields (with the non-isolation persistence, fail-fast, nested-macro, and
.exit caveats), workspace .coyote/macros/ + --no-workspace-macros,
enabled_macros scoping at global/role/agent/session levels, and
.macro enable|disable across the README and every example config.
graph.example.yaml gains a note that enabled_macros is ignored in graph
configs.

CHANGELOG intentionally untouched: it is generated by commitizen at
release time from the conventional commit subjects.

Implements plans/custom-commands-design.md §8.
2026-08-21 11:55:13 -06:00
Dark-Alex-17 125360033d docs(plans): record implementation-verified correction from T6
no_workspace_mcp (and therefore no_workspace_macros, per the exact-mirror
ruling) is CLI-flag-only: AppConfig field exists but there is no
Config-struct key and no env arm, so a config.yaml entry is non-functional.
Pre-existing issue: config.example.yaml:140 documents the dead
no_workspace_mcp key — recorded as follow-up, out of scope.
2026-08-21 11:55:13 -06:00
Dark-Alex-17 4323d4823c feat: add --no-workspace-macros opt-out for workspace macro loading
Mirrors --no-workspace-mcp exactly: a CLI-only flag backed by an
AppConfig field (default false) that disables .coyote/macros in both
the resolved macro policy and Macro::load's workspace-then-global
preference, so the two always agree (custom-commands design §5).
2026-08-21 11:55:13 -06:00
Dark-Alex-17 5478c5a239 feat: execute non-isolated macros on the live REPL context
Make the macro isolated field live (design §3, §9 step 5):
isolated: false now runs the interpolated steps via run_repl_command
on the live RequestContext — session-recorded, conversation-visible,
with mutating steps persisting by design — while isolated: true keeps
the forked execution byte-for-byte unchanged.

- Add macro_non_isolated companion field beside macro_flag; both
  fork-propagation sites mirror it verbatim.
- RAII MacroModeGuard wraps the whole &mut RequestContext (DerefMut
  passthrough) and restores flag+mode on every exit path, including a
  failing step; steps remain fail-fast.
- Reject nested macro invocation when the current mode is non-isolated
  ("nested macros not allowed in non-isolated mode"); an isolated
  macro's step may still run a non-isolated macro inline on its fork.
- use_agent now suppresses the agent's default session only for
  isolated macros; a non-isolated .agent step engages it as if typed.
2026-08-21 11:55:13 -06:00
Dark-Alex-17 e94bd450cd feat: surface macros as first-class custom commands in the REPL
Implements the invocation and management surfaces from
plans/custom-commands-design.md §4 and §6:

- Top-level dispatch: an enabled macro <name> now runs as ".<name> [args]"
  from the command catch-all; runtime-disabled macros point at
  ".macro enable <name>", locked macros name the owning config, and
  unknown commands keep the existing error verbatim
- .macro enable|disable <name>: runtime toggles over the in-memory
  global-level enabled_macros list (disable with no list materializes
  all-active-minus-name); toggles error when a role/agent/session
  allowlist owns the field
- .set enabled_macros <csv|null> with workspace-then-global existence
  validation; .set key completion gains enabled_macros and the
  previously missing enabled_skills
- Dynamic completion: enabled macros (with descriptions) join built-ins
  on ".<TAB>" without touching the static command registry;
  ".macro <TAB>" lists invocable macros (incl. built-in-shadowed ones)
  plus the enable/disable subcommands; second-arg completion offers
  toggle-eligible names
- .list macros: enriched table (name, source, isolated, state,
  description) covering every resolver state incl. missing and
  shadowed rows; .help gains a custom-commands section
- Session info/render and sysinfo display enabled_macros; Macro::load
  resolves workspace-then-global; enable/disable rejected as macro
  names in the creator
2026-08-21 11:55:13 -06:00
Dark-Alex-17 e8ddb61518 feat: add lazy macro resolver with two-dir discovery and per-macro states
Adds src/config/macro_policy.rs: MacroPolicy::effective computes the
visible macro set on demand from the discovered definition files, the
four-level enabled_macros allowlists, and the built-in command names.

- Discovery scans workspace (.coyote/macros/) then global macros dirs on
  every resolution; workspace shadows global by name, and the shadowed
  global entry is retained and flagged so both stay listable (plan
  custom-commands-design.md §5). Workspace scanning is gated on a bool
  parameter so the future --no-workspace-macros flag wires in one line.
- Allowlist precedence is session > agent > role > global, first Some
  wins, no merging; None falls through, an empty list is an explicit
  zero, all-None enables everything (mirrors SkillPolicy).
- Per-macro states per plan §6: enabled, disabled (runtime, global-level
  exclusions only), locked (role/agent/session exclusions, recording the
  owning level), missing (unknown allowlist names warn instead of
  bailing — deliberate divergence from skills), shadowed (built-in name
  collisions), and invalid (parse failures and the reserved names
  enable/disable). Invalid beats allowlist exclusion beats shadowing.
- Adds enabled_macros() accessors on Role, Session, and Agent alongside
  their enabled_skills() counterparts, plus paths::workspace_macros_dir.
- 37 tests: state matrix, pairwise precedence, explicit-zero pinned at
  every level, workspace shadowing, reserved names, builtin collisions,
  missing rows, invalid YAML, and env-gated discovery (#[serial]).
2026-08-21 11:55:13 -06:00
Dark-Alex-17 f39381aa9d feat: add enabled_macros config field at global, role, agent, and session levels
Mirrors the enabled_skills plumbing per plans/custom-commands-design.md §5:
- global: Config + AppConfig structs, from_config copy, and the
  COYOTE_ENABLED_MACROS env-override arm (csv_to_vec parsing)
- role: frontmatter via parse_string_or_array (list or csv string),
  plus the export() mirror so Role::save round-trips the field
- agent (non-graph): plain serde on AgentConfig; graph.yaml silently
  ignores the key (pinned by test, no field on Graph by design)
- session: plain serde with csv-or-vec deserializer

Empty list/string deserializes to Some([]) (explicit zero), distinct
from absent/null (None) — pinned by tests at every level, including
the env arm (serial-fenced against the from_config tests, which read
the process env via load_envs).
2026-08-21 11:55:13 -06:00
Dark-Alex-17 e8b55bba15 feat: add description and isolated fields to Macro struct
description (optional, default None) will surface in listings and
completion; isolated (default true) preserves today's forked-context
execution behavior exactly. Both fields use plain serde defaults so
every existing macro YAML deserializes unchanged, and unknown fields
in newer files remain tolerated by older binaries.

Adds Serialize to Macro/MacroVariable (None description skipped) and
back-compat, round-trip, and embedded-asset deserialization tests.

Per plans/custom-commands-design.md §3 / §9 step 1.
2026-08-21 11:55:13 -06:00
Dark-Alex-17 9863c7a5f3 docs(plans): add macros-as-custom-commands design (gate-approved)
Design doc for macros as first-class custom commands: top-level .name
invocation, description/isolated fields, enabled_macros scoping,
workspace-local macros, completion integration.

Gatekeeper: sealed (3 findings fixed). Oracle plan-review: approved.
2026-08-21 11:55:13 -06:00
Dark-Alex-17 f44722df04 lint: Removed accidental session file
CI / All (ubuntu-latest) (push) Failing after 32s
CI / All (macos-latest) (push) Canceled after 0s
CI / All (windows-latest) (push) Canceled after 0s
2026-08-19 12:59:50 -06:00
Dark-Alex-17 3eaae0e652 feat: Dynamically detect RAG embedding model dimension for any given model 2026-08-18 19:57:11 -06:00
Dark-Alex-17 b12829db39 fix: drain crossterm characters in zellij in kitty contexts to prevent DA1 responses from entering prompt 2026-08-18 15:30:07 -06:00
Dark-Alex-17 dffaf6b9db fix: drain tty input when displaying inquire prompts to prevent unintentional escapes 2026-08-18 15:10:30 -06:00
Dark-Alex-17 a9a4ccca88 fix: breaking iwe MCP server changes with newest version 2026-08-18 11:29:36 -06:00
Dark-Alex-17 7cb7d66575 fix: improved handling of non service-specific secrets using sbx custom-secrets
CI / All (ubuntu-latest) (push) Failing after 30s
CI / All (macos-latest) (push) Canceled after 0s
CI / All (windows-latest) (push) Canceled after 0s
2026-08-17 18:01:21 -06:00
Dark-Alex-17 400b50fbd0 feat: Support auto confirmation for gatekeeper agents 2026-08-17 15:48:36 -06:00
Dark-Alex-17 7eeff2a226 fix: include tool output to LLM_OUTPUT in errors as well as stderr 2026-08-17 11:38:21 -06:00
Dark-Alex-17 374e8c0bf7 fix: prevent tmp-overwriting
CI / All (ubuntu-latest) (push) Failing after 29s
CI / All (macos-latest) (push) Canceled after 0s
CI / All (windows-latest) (push) Canceled after 0s
2026-08-15 19:35:12 -06:00
Dark-Alex-17 ede87df960 fix: Corrected a rare edge case on how tool files are generated during parallel executions 2026-08-15 18:41:13 -06:00
Dark-Alex-17 95a8c3df44 fix: cosmetic fix after improved bash tool handling 2026-08-15 17:31:32 -06:00
Dark-Alex-17 f57bd21ee4 fix: Improved subagent escalation handling 2026-08-14 16:53:37 -06:00
Dark-Alex-17 e1b6e3f8c6 fix: latent parsing bugs in fs_patch and argc 2026-08-14 16:12:41 -06:00
Dark-Alex-17 644d899f78 fix: Prevent infinite hangs in coder agent and implement timeouts for LLM API calls and interactive tools 2026-08-14 15:22:25 -06:00
Dark-Alex-17 2596194417 feat: retry LLM API calls once after 401 by force-refreshing the OAuth token
The Client trait's default chat_completions, chat_completions_streaming,
and embeddings methods now classify failures via ApiStatusError: on a
401 with a cached OAuth token, the token is distrusted (identity-aware
marker) and the call retried exactly once — the retry's prepare step
sees the marker and force-refreshes. Streaming retries only while the
SSE handler has received no content, preventing duplicate rendering.
A second 401 propagates the original error; other retry errors
propagate as-is. API-key clients never retry. No backoff by design:
cost is bounded to one refresh + one retry per failing request.
2026-08-14 13:17:56 -06:00
Dark-Alex-17 684f19250a feat: identity-aware rejected-token marker for LLM OAuth cache
distrust_access_token compare-and-invalidates the in-memory entry only
when the cached token equals the rejected one, so a concurrent refresh
is never clobbered. is_valid_access_token and both expiry checks in
prepare_oauth_access_token treat marked tokens as expired, forcing a
refresh of provider-rejected tokens that are still locally unexpired.
The marker is cleared after every completed refresh, including ones
that return the same token.
2026-08-14 13:07:51 -06:00
Dark-Alex-17 f3d59ade11 feat: typed ApiStatusError carrying HTTP status through LLM client errors
catch_error and sse_stream now bail with ApiStatusError{status, message}
instead of bare anyhow strings, preserving every existing Display output
byte-for-byte. Enables structural status classification (e.g. 401
detection) via downcast through anyhow context chains.
2026-08-14 13:01:08 -06:00
Dark-Alex-17 e1604c58ea feat: per-request OAuth token injection with mid-session refresh for HTTP MCP servers
Replace the spawn-time static Authorization header for OAuth-managed HTTP
MCP servers with McpOAuthClient, a custom implementation of rmcp's
StreamableHttpClient trait that resolves the bearer token on every
request via load_or_refresh_mcp_token. Tokens that expire mid-session
now refresh transparently instead of failing tool calls until restart.

On a 401 for an injected token, the wrapper force-refreshes (identity-
aware: a still-unexpired copy of the rejected token is not trusted) and
retries exactly once, matching Claude Code / official SDK semantics.
Both *_with_max_sse_event_size trait methods are overridden to preserve
the inner client's SSE size enforcement, and the inner reqwest client
mirrors rmcp's default (pool_max_idle_per_host(0), no redirects).

SSE, stdio, and static-header HTTP paths are unchanged; startup
warning semantics (McpAuthRequired reasons) are preserved. Verified
live: mid-session backdated token refreshed transparently during an
active atlassian session.
2026-08-14 12:33:46 -06:00
Dark-Alex-17 dcacb3a962 chore: upgrade rmcp 1.8.0 -> 3.1.2
Compile-clean upgrade verified: zero source changes needed, full test
suite green, clippy clean. Coyote's rmcp API surface (14 items) dodges
all 2.0/3.0 breaking changes; the "Auth required" error string matched
by is_auth_required_error is intact in 3.1.2.
2026-08-14 11:10:45 -06:00
Dark-Alex-17 d791098e51 feat: reason-specific warnings for MCP servers that fail OAuth at startup
Distinguish why an OAuth MCP server was not started: never authenticated
(no stored credentials), stored token expired and refresh failed, or the
server rejected a token that looked valid. McpTokenStatus replaces the
Option<String> return of load_or_refresh_mcp_token, and McpAuthRequired
carries the reason across the error boundary via anyhow context.
2026-08-14 11:07:56 -06:00
Dark-Alex-17 d31110cd67 fix: allow nested italics inside bold spans in markdown renderer
CI / All (ubuntu-latest) (push) Failing after 29s
CI / All (macos-latest) (push) Has been cancelled
CI / All (windows-latest) (push) Has been cancelled
2026-08-13 16:18:50 -06:00
Dark-Alex-17 0f35e03a85 fix: properly handle OAuth refreshes
CI / All (ubuntu-latest) (push) Failing after 29s
CI / All (macos-latest) (push) Has been cancelled
CI / All (windows-latest) (push) Has been cancelled
2026-08-13 16:00:42 -06:00
Dark-Alex-17 c2b0c120d7 chore: Added grok4.6 to models.yaml
CI / All (ubuntu-latest) (push) Failing after 29s
CI / All (macos-latest) (push) Has been cancelled
CI / All (windows-latest) (push) Has been cancelled
2026-08-13 14:20:35 -06:00
Dark-Alex-17 65c9be36b2 fix: correct newline removal from fs_write and fs_patch 2026-08-13 14:18:45 -06:00
Dark-Alex-17 2658ca776e feat: Installed duckdb into the coyote image
CI / All (ubuntu-latest) (push) Failing after 29s
CI / All (macos-latest) (push) Has been cancelled
CI / All (windows-latest) (push) Has been cancelled
2026-08-12 19:29:26 -06:00
Dark-Alex-17 f8682102a0 docs: Added duckdb prerequisite
CI / All (ubuntu-latest) (push) Failing after 29s
CI / All (macos-latest) (push) Has been cancelled
CI / All (windows-latest) (push) Has been cancelled
2026-08-12 19:07:31 -06:00
Dark-Alex-17 3fa0f5c428 feat: Support managing MCP servers from the CLI directly
CI / All (ubuntu-latest) (push) Failing after 29s
CI / All (macos-latest) (push) Has been cancelled
CI / All (windows-latest) (push) Has been cancelled
2026-08-12 17:55:33 -06:00
Dark-Alex-17 68135b97d1 feat: append new built-in rag__query function to RAG contexts to allow further querying by LLMs
CI / All (ubuntu-latest) (push) Failing after 29s
CI / All (macos-latest) (push) Has been cancelled
CI / All (windows-latest) (push) Has been cancelled
2026-08-12 16:25:50 -06:00