Commit Graph
1052 Commits
Author SHA1 Message Date
Dark-Alex-17 fdfe4ba023 refactor!: drop the .install remote migration hint
'remote' is no longer special-cased anywhere; the token falls through
to the unified .install dispatch like any other value.
2026-08-24 11:15:13 -06:00
Dark-Alex-17 8f02bf1c33 refactor!: drop the --install-from tombstone entirely
The flag no longer exists in any form; --install <GIT_URL|OWNER/REPO>
is the only spelling.
2026-08-24 11:15:13 -06:00
Dark-Alex-17 80b082423c fix: address code review findings on the bundle lifecycle
The user-origin marker on replaced mcp.json entries is now sticky:
re-records and cross-bundle transfers only upgrade replaced to
transferred when the prior record proves bundle origin, so updating a
bundle can no longer make uninstall delete a key the user had before the
bundle replaced it. Canonical source URLs lowercase only the host, since
self-hosted forges treat repository paths as case-sensitive and
collapsing distinct repos misdirects updates and uninstalls. git clone
invocations pass '--' before the URL so a crafted source cannot be
parsed as a git flag. Lifecycle flags (--install, --install-builtins,
--update-bundle, --uninstall) and their companions now conflict
explicitly instead of first-match dispatch silently dropping actions.
--install-from returns as a hidden tombstone that errors with the
replacement instead of feeding the flag to the LLM as prompt text.
--list-bundles dispatches before config load so a pure read no longer
boots MCP servers. write_file_atomic fsyncs before the rename so a crash
cannot persist a truncated store. REPL: .uninstall accepts --yes,
.install rejects trailing tokens after a category, and .install remote
gets a migration hint. Plus polish: host validation rejects '#' and '?',
renamed_to no longer serializes null, derived names get a debug assert
against the validator, completions share DEFAULT_GIT_HOST, README
mentions skills.
2026-08-24 11:15:13 -06:00
Dark-Alex-17 4324d551d6 fix: reserve category names, confirm fork-name collisions, report secrets on uninstall
Bundle names that collide with an asset category (agents, roles, skills,
macros, functions, mcp_config) are now owner-qualified at install time,
whether derived from the repo or declared by a manifest, so no bundle can
shadow a category by name. A manifest name that collides with a bundle
from a different source now prompts for confirmation interactively (a
fork or typo-squat is the likely cause); declining aborts before anything
is written, and non-interactive runs keep the deterministic
owner-qualification. Uninstall summaries now list the vault secrets the
bundle's MCP servers reference, noting they are installed by the bundle
but not removed. Also removes the dead ResolvedBundleName.migrated_from
field.
2026-08-24 11:15:13 -06:00
Dark-Alex-17 1136b1385b docs: removed extra fluff on bundles from the main README 2026-08-24 11:15:13 -06:00
Dark-Alex-17 84b90bfe26 style: remove em-dashes from comments and the uninstall selector 2026-08-24 11:15:13 -06:00
Dark-Alex-17 53ccbda97c feat: expand owner/repo shorthand for --install with a --git-host flag
--install someuser/repo expands to https://github.com/someuser/repo;
--git-host overrides the default host and forces source interpretation
even when the value matches an installed bundle name. Two or more path
segments are accepted so nested GitLab-style groups work, and #ref
pinning applies to shorthand values. --uninstall resolves owner/repo
against recorded sources: a single match uninstalls, multiple matches
prompt an interactive selection showing each bundle's source, and
non-interactive runs bail instead of guessing.
2026-08-24 11:15:13 -06:00
Dark-Alex-17 2d1bf372d8 style: strip narration comments from bundle provenance code
Function docs that restated behavior already evident from names,
signatures, and code are removed; only comments carrying invariants
the code cannot express remain.
2026-08-24 11:15:13 -06:00
Dark-Alex-17 4987d850f9 feat!: remove the deprecated --install-from flag and .install remote form
--install <git-url|name> is the single entry point for remote installs
and updates; the unified .install dispatch likewise replaces
.install remote. Flag completion for .install now applies to the
unified form.
2026-08-24 11:15:13 -06:00
Dark-Alex-17 9541a094d8 fix: make bundle provenance portable to Windows
Provenance records stored OS-native path separators, making
installed-bundles.yaml non-portable; slug derivation treated a Windows
drive letter as an scp host and swallowed the whole path into one
sanitized segment. Store paths are now always forward-slashed and
backslashes normalize before URL parsing. Test fixture repos commit a
'* -text' .gitattributes so clone-side autocrlf cannot rewrite content
assertions.
2026-08-24 11:15:13 -06:00
Dark-Alex-17 89df8ec1ca docs: document bundle lifecycle and manifest for sharing configurations 2026-08-24 11:15:13 -06:00
Dark-Alex-17 bca85a4017 feat: rename install flags and unify .install dispatch
--install now takes a git URL or an installed bundle name: categories
are redirected to the new --install-builtins, installed names become
implicit updates, and source-shaped values install remotely. The old
--install-from keeps its exact behavior as a hidden deprecated alias.
The REPL's .install gains the same unified dispatch while keeping
.install <category> and .install remote <url> back-compat.
2026-08-24 11:15:12 -06:00
Dark-Alex-17 0e5d85f2ff feat: add --uninstall and .uninstall for installed bundles 2026-08-24 11:15:12 -06:00
Dark-Alex-17 0a806da8d2 feat: add --update-bundle with provenance-aware conflict handling
Updates re-clone a bundle's recorded source (honoring a recorded commit
pin unless a #<ref> override moves it), silently refresh files the bundle
owns that the user never modified, and fall back to the normal conflict
prompts for modified or unowned files. Files the remote no longer ships
are offered for deletion (kept by default non-interactively, staying
owned). The record is refreshed with the new commit, version, and
metadata, and stamped with an updated_at timestamp on success.
2026-08-24 11:15:12 -06:00
Dark-Alex-17 2790a823b0 feat: add --list-bundles and .list bundles with drift detection 2026-08-24 11:15:12 -06:00
Dark-Alex-17 88acf2362f feat: record bundle provenance when installing from remote repos 2026-08-24 11:15:12 -06:00
Dark-Alex-17 bfcc762ec9 feat: add bundle provenance store 2026-08-24 11:15:12 -06:00
Dark-Alex-17 b21699b749 feat: parse bundle manifests and capture resolved SHAs for remote installs 2026-08-24 11:15:12 -06:00
Dark-Alex-17 5f23e2403f fix: user__ask should have been renamed to user__select in graph agent user interaction invocations 2026-08-21 14:49:27 -06:00
Dark-Alex-17 2af6fe64d4 Merge branch 'feat/comment-discipline' 2026-08-21 14:02:55 -06:00
Dark-Alex-17 da640f3dcd feat: created a new comment-discipline skill for the built in sisyphus suite 2026-08-21 14:02:39 -06:00
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