Commit Graph
1056 Commits
Author SHA1 Message Date
Dark-Alex-17 cb025b7fff feat: add background job runner, job__* handlers, and start gates
Detached tokio::process runner with a frozen JobEnvSnapshot (env-derived
bin dirs, vault-interpolated agent envs, COYOTE_TOOL_TIMEOUT resolved at
start), process_group(0) with pgid-guarded SIGTERM/SIGKILL escalation,
capture-only ring-buffer telemetry, and LLM_OUTPUT read after wait().
MCP jobs snapshot a single-entry McpRuntime holding only the validated
server and render through the same free fn as the foreground path.

job__start enforces its gates synchronously before any spawn:
jobs_enabled, the backgroundable whitelist with directionality teaching
errors, the per-request declared-names stash captured in
before_chat_completion, then capacity (lazy supervisor get-or-init in
plain sessions). job__check/list read the shared JobState cell without
consuming; job__collect blocks with the escalation early-out and applies
a tail-biased char-boundary cap plus optional tail_lines; job__cancel
kills the group with a 5s grace.

Job declarations are injected iff jobs are enabled at agent init, the
plain-session function-init sites, and the exit_agent rebuild; job__ is
carved out of enabled_tools filtering and excluded from
concrete_tool_names so REPL toggles cannot grant or revoke it.
2026-08-25 17:36:17 -06:00
Dark-Alex-17 fcc3756634 fix(function): floor tool-output truncation cut to a UTF-8 char boundary
When max_chars landed inside a multi-byte UTF-8 character of the
serialized output, s.get(..max_chars) returned None and the code fell
back to the FULL untruncated string while still prepending the
truncation marker — the "truncated" output actually grew. The cut is
now floored to the previous char boundary so the prefix is always a
valid, genuinely truncated slice.
2026-08-25 17:36:11 -06:00
Dark-Alex-17 257b06bbd4 fix(supervisor): make agent__check a pure status probe that never consumes the handle
agent__check on a finished agent delegated to agent__collect, which
returned the full (unbounded) result and consumed the handle. That
contradicted the tool's own docs and broke the check-then-collect
pattern: a second collect on the same id failed.

check now reports { status: finished } with a pointer to
agent__collect and leaves the handle registered; collect is the single
retrieval verb. The tool description and prompt table are updated to
stop promising that check returns the result.
2026-08-25 17:36:11 -06:00
Dark-Alex-17 7cf88c030f fix(supervisor): surface finished-but-uncollected tasks in turn-end guardrail
The turn-end guardrail only counted still-running agents, so an agent
that finished before the turn ended was invisible: its uncollected
result was silently dropped. Jobs were never counted at all.

The guardrail now enumerates every registered task (running and
finished, agents and jobs) via Supervisor::list_tasks and renders a
kind-aware prompt with two sections: still-running tasks to reclaim,
and completed-but-uncollected tasks with the exact collect command.

At the force-terminate cap, finished-but-uncollected handles are
explicitly discarded with a warning naming the lost ids, so the
guardrail cannot loop forever on handles nobody will collect.
2026-08-25 17:36:11 -06:00
Dark-Alex-17 a9df9a4dd5 docs(plan): reconcile whitelist row 1 with the grep-class carve-out row
T3 implementation followed the specific fs_*/ast_grep 'NO in v1' row;
row 1's 'ALL external command tools' over-claimed. No design change.
2026-08-25 17:35:47 -06:00
Dark-Alex-17 7f3f95d89d feat: generalize supervisor registry to TaskHandle enum with job scaffolding, kill discipline, and max_concurrent_jobs config
Implements T1 of plans/background-jobs-design.md (§6, R7/R8/R9):

- Supervisor.handles is now HashMap<String, TaskHandle> where
  TaskHandle = Agent(AgentHandle) | Job(JobHandle); agent-facing
  accessors (active_count, effective_active_count, is_finished, take,
  inbox, abort_signal_for, list_agents) match only Agent variants,
  preserving all existing external behavior byte-for-byte.
- New JobHandle/JobState/JobStatus/JobResult types with pgid-guarded
  process-group kill discipline: Drop and cancel_all/cancel_recursive
  kill the group only while state.pgid is still set (pid-reuse guard),
  via libc::killpg on unix and JoinHandle::abort elsewhere.
- Per-kind job capacity: Supervisor carries max_concurrent_jobs
  (builder-set, default 0); job registration rejects at capacity.
- Cross-kind teaching errors at the four agent-lookup miss sites
  (agent__check/collect/cancel/send_message) when the id is a
  registered job or job_-prefixed; genuinely-unknown ids keep their
  existing messages.
- Supervisor init condition is now can_spawn_agents || jobs_enabled in
  use_agent and both child-agent spawn paths, with agent capacity 0 in
  jobs-only contexts; use_agent cancels the old supervisor recursively
  before replacing it.
- max_concurrent_jobs config plumbing: global Config field, AgentConfig
  override + accessor, all four AppConfig touch points including the
  COYOTE_MAX_CONCURRENT_JOBS env override; shared
  effective_max_concurrent_jobs/jobs_enabled predicates
  (agent override -> global -> default 5; 0 disables).
- Stage dependency-free RingBuf (64 KiB default) in src/function/jobs.rs
  for the upcoming job output pump.
- New sanctioned dependency: libc 0.2 under cfg(unix).
2026-08-25 15:17:57 -06:00
Dark-Alex-17 bfc3b7bfea test: pin current tool-eval, guardrail, and truncation behavior ahead of background-jobs work
T0 characterization safety net per plans/background-jobs-design.md §9.3: 43 tests
pinning handle_collect/check/cancel/spawn, the pending-agents guardrail (incl.
ForceTerminate + counter resets), eval_tool_calls partition/re-sort/soft-fail/
loop-alert/truncation, truncate_if_needed's UTF-8 boundary edge, ToolCall::eval
prefix routing, merge_tool_results shape, and cancel_recursive recursion.

Known-buggy behaviors deliberately pinned for visible later diffs: handle_check
consumes finished handles, guardrail ignores finished-but-uncollected agents,
mid-char truncation returns the full string with marker prepended.

Not covered (findings): empty-after-dedup bail is unreachable from non-empty
input; run_child_agent needs a mock LLM client (none exists) — manual case;
over-threshold summarization pinned via deterministic unknown-model failure.
2026-08-25 13:55:15 -06:00
Dark-Alex-17 240eaa081a docs: add background jobs + push notifications design doc
Gatekeeper-SEALED + Oracle-APPROVED v1.8 (2026-08-24 gates; 2026-08-25
accuracy refresh against the MCP resources/prompts merge).
2026-08-25 13:27:49 -06:00
Dark-Alex-17andSisyphus c7384b7a9b feat: run an advisory observability pass after implementation in sisyphus
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-25 13:19:10 -06:00
Dark-Alex-17andSisyphus ed9778c07b feat: add an observability-review skill for post-implementation monitoring analysis
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-25 13:19:09 -06:00
Dark-Alex-17andSisyphus 5a32219178 feat: check under- and over-logging in the code review gate
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-25 13:19:09 -06:00
Dark-Alex-17andSisyphus 9e652f7801 feat: calibrate logging registers in the code-writing agents
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-25 13:19:09 -06:00
Dark-Alex-17andSisyphus fcff426ae5 feat: add a logging-discipline skill for calibrating log output to repo conventions
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-25 13:17:33 -06:00
Dark-Alex-17 cb0802c2d0 fix: fix grep "binary" errors when searching UTF-8 files with unicode characters like some of the Coyote source 2026-08-25 13:06:16 -06:00
Dark-Alex-17 d7524b8de7 Merge branch 'main' of github.com:Dark-Alex-17/coyote 2026-08-25 12:13:44 -06:00
Alex Clarke aa14e66c35 Merge pull request #18 from Dark-Alex-17/feat/mcp-resources-prompts
CI / All (ubuntu-latest) (push) Failing after 29s
CI / All (macos-latest) (push) Canceled after 0s
CI / All (windows-latest) (push) Canceled after 0s
feat: MCP server resources and prompts support
2026-08-25 12:13:31 -06:00
Dark-Alex-17 3c9f443bce feat(cli)!: rename --prompt to --temp-role
Completes the .prompt/.temp-role split: --prompt set an ad-hoc system
role, which is what .temp-role now means everywhere. The --prompt name
is left unbound so a future one-shot MCP prompt flag can take it with
properly designed non-interactive semantics. use_prompt follows the
rename as use_temp_role.

BREAKING CHANGE: invocations using --prompt <text> must switch to
--temp-role <text>; clap rejects the old flag loudly.
2026-08-25 12:04:45 -06:00
Dark-Alex-17 e55120dac6 fix(bundles): harden the install pipeline for cross-platform correctness
Windows review findings on the bundle provenance code:

- clones now pin core.autocrlf=false and core.eol=lf so recorded sha256
  values reflect repository bytes, not the machine's git config (autocrlf
  on Windows previously made every text file a false conflict on update),
  plus core.longpaths=true for deep bundle trees
- is_safe_relative_path additionally rejects NTFS alternate data stream
  colons, reserved device names (con, nul, COM1..), and trailing dots or
  spaces; such names never come from a valid checkout and previously
  desynced or failed on Windows
- file ownership dedupe compares paths case-insensitively on Windows and
  macOS where case variants denote one physical file (uninstalling one
  bundle could previously delete another bundle's file)
- a failed git clone no longer leaks its partial tree in the temp dir,
  and temp cleanup failures are logged instead of swallowed
- recording a bundle file outside the config dir (asset dir override)
  now warns instead of silently producing an undeletable record
2026-08-25 11:37:41 -06:00
Dark-Alex-17 b67f1ef854 refactor: pulled out some imports to clean up the MCP render module a bit 2026-08-25 11:37:41 -06:00
Dark-Alex-17 b38562a961 fix(mcp): harden the spill path for cross-platform correctness
Windows review findings: reserved device names (con, nul, COM1..) and
trailing dots in server names break or desync directory creation, so
sanitize_server now escapes reserved stems, strips trailing dots, and
caps length at 64 chars. Spill writes go through a temp file + rename
so a visible file is always complete (closes a cross-process partial
read race), and eviction protection compares content-hashed file names
instead of full paths. Also drops a duplicated cfg attribute.
2026-08-25 11:37:41 -06:00
Dark-Alex-17 40846de37a test(bundles): skip uninstall ambiguity test when stdout is a TTY
The non-interactive bail under test only triggers without a TTY; from a
terminal the code correctly opens the interactive selector instead, so
the test hung or failed depending on input. Same guard as the three
sibling non-interactive tests.
2026-08-25 11:37:41 -06:00
Dark-Alex-17 a5a3eed6d8 fix(repl): offer prompts in .list tab completion and rename its listing helpers
MCP prompts are live, server-owned catalog entries, not managed assets;
list_prompt_assets/prompt_asset_rows implied otherwise and are now
list_mcp_prompts/mcp_prompt_rows. The .list completer was also missing
the prompts kind that the usage string and unknown-kind error advertise.
2026-08-25 11:37:41 -06:00
Dark-Alex-17 ad9ff3bea8 style: revised a few stylistic choices after I changed my mind 2026-08-25 11:37:41 -06:00
Dark-Alex-17 5177d95ee0 feat: complete --filter and --force on the first .install argument
The unified install parser accepts flags in any position, so the
first-argument completion list now offers all four flags instead of
only --git-host and --help.
2026-08-25 11:37:41 -06:00
Dark-Alex-17 9bc37e226b docs: removed design doc from commit 2026-08-25 11:37:41 -06:00
Dark-Alex-17 a4b55d9e42 fix(mcp): gate unix-only spill permission APIs for windows builds 2026-08-25 11:37:41 -06:00
Dark-Alex-17 c8b00b20bc docs: document MCP resources and prompts support
Update the README's MCP feature entry to cover the full capability trio
(tools, resources, prompts): the capability-gated mcp_read/mcp_prompt
meta-tools, bounded results and blob spilling, and the .prompt REPL
command with staged tab-completion and .list prompts.

Per plans/mcp-resources-prompts-design.md section 10.T9.
2026-08-25 11:37:41 -06:00
Dark-Alex-17 eb37f8bb46 feat(mcp): bound tool-result passthrough and surface resource audience annotations
Route CallToolResult content through the render.rs content policy per
plans/mcp-resources-prompts-design.md §6 (T8): oversized text sliced at
TEXT_MAX_BYTES_CLAMP with a self-explaining truncation note, image/audio/
embedded blob content spilled (or inlined when UTF-8-clean) instead of
shipping base64 into model context, and structuredContent subject to the
same ceiling. Clamp server-controlled uri/mime metadata strings to the new
METADATA_MAX_BYTES bound in both the read and tool-result paths, sanitize
the terminal rendering of MCP dispatch errors while keeping raw text in
the tool_call_error payload, and surface resource audience annotations in
both mcp_search results and mcp_read metadata via the catalog.
2026-08-25 11:37:41 -06:00
Dark-Alex-17 6fade71e8c feat(mcp): add mcp_prompt meta-tool and harden prompt display rendering
Emit an mcp_prompt_<server> declaration for servers advertising the
prompts capability, execute prompts via McpRuntime::prompt on both tool
dispatch chains, and return the flattened prompt text as the tool
result. Sanitize server-controlled prompt names, descriptions, and
argument names before terminal rendering, and attribute the .prompt
argument inquire label to its server and prompt.

Per plans/mcp-resources-prompts-design.md §5.2 (T7).
2026-08-25 11:37:41 -06:00
Dark-Alex-17 61a3cfb662 feat(repl): add .prompt command with live staged tab-completion
Implements plans/mcp-resources-prompts-design.md §5.1/§5.4 (T6):

- .prompt <server> <name> [key=value ...] fetches an MCP prompt and
  submits the result as chat input via Input::from_str + ask(), never
  through REPL line parsing; GetPromptResult messages are flattened
  into one user-role block with unconditional [user]/[assistant] labels
- missing required prompt arguments are collected interactively
- .list prompts renders server/name/description/args via the unified
  catalog (CatalogItem gains an arguments field), degrading per server
- staged live tab-completion: enabled+running+prompts-capable servers
  (no RPC), then live prompt names, then key= argument suggestions with
  (required) markers; 2s timeout per RPC, all errors degrade to silent
  empty suggestions, ctx read guard dropped before blocking
- the enabled-server alias expansion is factored into a shared helper
  used by both tool-scope rebuild and completion
- BREAKING: the former .prompt <text> temp-role builtin is renamed to
  .temp-role <text> (behavior preserved); .prompt now belongs to MCP
  prompts, and a user macro named prompt or temp-role is shadowed
2026-08-25 11:37:41 -06:00
Dark-Alex-17 67819784b7 feat(mcp): add mcp_read meta-tool for resource reads
Implements plans/mcp-resources-prompts-design.md section 4.3 (T4):
mcp_read_<server> declaration and handler wired to render.rs, RFC 6570
Level-1-only URI template expansion, defensive ResourceContents parsing,
per-item text paging with pattern filtering, blob spill metadata, an
overall 204800-byte multi-content ceiling, dispatch wiring on both
eval chains, and a render_text paging-stall guard.
2026-08-25 11:37:41 -06:00
Dark-Alex-17 437512fd6d feat(mcp): gate meta-function emission on advertised server capabilities
Per-server McpServerFeatures (tools fail-open, resources/prompts
fail-closed) now drive which meta-functions are declared, with
gated_meta_function_prefixes as the single gating seam; read/prompt
declarations land together with their handlers. The server-enablement
sentinel keys on the always-emitted search name so resources-only
servers survive role filtering.

Implements plans/mcp-resources-prompts-design.md §4.4/D7 (T5).
2026-08-25 11:37:41 -06:00
Dark-Alex-17 ef88b6a2c8 feat(mcp): add render.rs content policy (text paging, pattern filter, blob spill)
Single content-policy module for MCP resource and tool content, per
plans/mcp-resources-prompts-design.md §4.5 (T3):

- render_text: UTF-8-boundary-safe paging with clamped max_bytes and
  grep-style fancy-regex line filtering (2 lines of context, 1-based
  line-number prefixes, merged hunks); offsets walk the filtered stream.
- render_blob/render_blob_at: streaming base64 decode with a 50 MiB
  ceiling, UTF-8 sniff, sha256-named 0600 spill files under a sanitized
  server dir with a fixed mime->ext allowlist, and best-effort
  oldest-first eviction bounding the spill tree at 512 MiB.

Not yet wired to call sites; module carries #![allow(dead_code)] until
the read/prompt surfaces land.
2026-08-25 11:37:41 -06:00
Dark-Alex-17 d68f4ecaeb feat(mcp): extend the server catalog to resources, templates, and prompts
Implements the unified catalog from plans/mcp-resources-prompts-design.md §4.2 (T2): CatalogItem gains kind/uri/mime_type/size keyed as {kind}:{id}; catalog_items() lists per kind gated by advertised capabilities with warn-and-degrade; mcp_search results carry kind; mcp_describe gains an optional kind param (default tool); write-only registry ServerCatalog removed.
2026-08-25 11:37:41 -06:00
Dark-Alex-17 01ada1da18 refactor(mcp): centralize meta-function prefix predicates and fix list_tools pagination
Implements T1 of plans/mcp-resources-prompts-design.md (§4.1, §4.6):

- Replace list_tools(None) with cursor-following list_all_tools() at the
  three call sites (start_server catalog build, catalog_items, describe)
  so paginating servers no longer silently lose tools past page one.
- Add MCP_READ/MCP_PROMPT prefix constants (declared nowhere yet; wired
  in T4/T7) plus centralized helpers MCP_META_FUNCTION_PREFIXES,
  is_mcp_meta_function, and mcp_meta_function_names.
- Mechanically replace every hand-rolled 3-prefix starts_with triple
  (partition in eval_tool_calls, 3 exclusion triples in
  select_enabled_functions, 3 inclusion triples + per-server name
  construction in select_enabled_mcp_servers) with the helpers,
  preserving the existing lax starts_with matching semantics and the
  mcp_invoke_* enablement sentinel (sentinel moves to search in T5).
- Behavior-neutral: dispatch chains keep their 3 arms, emission stays
  at exactly 3 meta-functions per server, existing tests unmodified.
- Add unit tests: helper classification, prefix-soundness property,
  lax-matching pin, ordered candidate-name construction.
2026-08-25 11:37:41 -06:00
Dark-Alex-17 7caa24d090 docs(plans): add MCP resources & prompts design (v1.3, gate-approved)
Gatekeeper: SEALED. Oracle: APPROVE-WITH-CHANGES (B1-B3 folded in).
Phases: unified catalog + mcp_read w/ render.rs content policy;
.prompt REPL + staged live tab-completion + mcp_prompt meta-tool;
CallToolResult bounding; capability gating via McpRuntime::server_features.
2026-08-25 11:37:41 -06:00
Dark-Alex-17 0e941fb360 feat: complete --filter and --force on the first .install argument
The unified install parser accepts flags in any position, so the
first-argument completion list now offers all four flags instead of
only --git-host and --help.
2026-08-25 10:02:50 -06:00
Dark-Alex-17andSisyphus b972c12559 docs: extend the mattpocock/skills credit to the grilling adaptation
CI / All (ubuntu-latest) (push) Failing after 33s
CI / All (macos-latest) (push) Canceled after 0s
CI / All (windows-latest) (push) Canceled after 0s
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-24 15:12:37 -06:00
Dark-Alex-17andSisyphus f8cab9b439 feat: run design interviews as grilling frontier rounds across the planning agents
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-24 15:12:37 -06:00
Dark-Alex-17andSisyphus 45333db5c2 feat: add a grilling skill for frontier-round design interviews
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-24 15:12:37 -06:00
Dark-Alex-17andSisyphus 7748b953f0 docs: extend the mattpocock/skills credit to the codebase-design adaptations
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-24 15:07:50 -06:00
Dark-Alex-17andSisyphus 720591d24a feat: add an on-demand architecture-reviewer agent for deepening scans
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-24 15:07:50 -06:00
Dark-Alex-17andSisyphus dbb0c51b7e feat: add a codebase-design skill with the deep-module design vocabulary
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-24 15:07:50 -06:00
Dark-Alex-17andSisyphus 71cd50fe4d docs: credit mattpocock/skills for the diagnosing-bugs and smell-baseline adaptations
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-24 15:02:12 -06:00
Dark-Alex-17andSisyphus b5863dded0 feat: add a feedback-loop-first diagnosing-bugs skill to the coding suite
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-24 15:02:12 -06:00
Dark-Alex-17andSisyphus 03116d2f42 feat: add a Fowler code-smell baseline to the code-review skill
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-24 15:02:12 -06:00
Dark-Alex-17andSisyphus 9b23247815 feat: flag duplicate helpers in code reviews with a repo-wide DRY check
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-24 14:46:38 -06:00
Dark-Alex-17andSisyphus 3493b01e9a feat: add a transactional-integrity review skill to the code review gate
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-24 14:46:38 -06:00
Dark-Alex-17andSisyphus fd989c44d0 feat: add an operational-history prior-art lane to the code-reviewer agent
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-24 14:46:13 -06:00
Dark-Alex-17 e7307da6a9 feat: support name=value macro arguments with variable tab completion
Macro invocations (.name and .macro name) accept leading name=value
assignments before positional args: assignments set declared variables
directly so earlier variables can keep their defaults, remaining
positionals fill unassigned variables in declaration order, and the
free text after -- is never scanned for assignments. Identifier-shaped
keys that match no declared variable error with the declared list to
catch typos; non-identifier tokens containing = stay positional.
MacroVariable gains an optional description field, and tab completion
after a macro name offers name= candidates showing each variable's
description and default until the assignment prefix ends.
2026-08-24 14:20:21 -06:00