coding-tools 0.3.0

Declarative, agent-friendly CLI tools behind one 'ct' command: search, view, verifiable edits, and framed command tests.
Documentation
{
  "name": "ct-search",
  "description": "Recursively find files by name, type, size, and content from a chosen root, replacing find|xargs|grep pipelines. An entry matches only when all supplied predicates hold. A search can also be posed as a pass/fail test: --question frames it, --expect sets an expectation over the match count, and --emit prints a templated verdict. The exit status follows the verdict = --expect applied to the count: 0 SUCCESS, 1 ERROR, 2 usage/runtime error; the default expectation 'any' makes this 0 if anything matched and 1 if not. Pattern arguments use substring->glob->regex promotion: text with no metacharacters is a literal substring; glob metacharacters (* ? [ ]) that are not a valid regex are treated as a glob; otherwise the pattern is used as a regex. --mode literal|glob|regex pins the interpretation (promotion off) for every pattern in the invocation. --grep accepts payload schemes: file:PATH reads the pattern verbatim from a file (literal by default), text:VALUE escapes the prefix; a multi-line pattern matches as a line-anchored literal BLOCK (K lines match K consecutive source lines byte-for-byte; each occurrence counts at its start line; under --detail a block with no match reports its nearest miss to stderr). Invoke as `ct search ...` or `ct-search ...`.",
  "input_schema": {
    "type": "object",
    "properties": {
      "base": {
        "type": "string",
        "description": "Search root, relative or absolute, independent of the current working directory.",
        "default": "."
      },
      "name": {
        "type": "string",
        "description": "File-name pattern. '|'-separated alternatives, each substring->glob->regex promoted and anchored to the whole name (e.g. '*.java|*.kt')."
      },
      "type": {
        "type": "array",
        "items": {
          "type": "string",
          "enum": [
            "f",
            "d",
            "l"
          ]
        },
        "description": "Restrict to entry kinds: f=regular file, d=directory, l=symlink. May be repeated or comma-joined."
      },
      "grep": {
        "type": "string",
        "description": "Content pattern, substring->glob->regex promoted and searched unanchored against file contents. Implies regular files. Accepts file:PATH / text:VALUE payloads; a multi-line payload matches as a line-anchored literal block."
      },
      "mode": {
        "type": "string",
        "enum": [
          "literal",
          "glob",
          "regex"
        ],
        "description": "Pin how patterns are interpreted; promotion off for every pattern in the invocation. Use literal for verbatim code anchors."
      },
      "size": {
        "type": "string",
        "description": "Size predicate [+|-]N[k|m|g]: +N larger than, -N smaller than, N at least N. Applies to regular files."
      },
      "hidden": {
        "type": "boolean",
        "description": "Include dot-entries (names starting with '.'). Default: skipped."
      },
      "follow": {
        "type": "boolean",
        "description": "Follow symlinks while traversing."
      },
      "limit": {
        "type": "integer",
        "description": "Stop after this many matches."
      },
      "question": {
        "type": "string",
        "description": "Question this search answers, framing it as a test; printed as a '== ... ==' banner unless quiet."
      },
      "expect": {
        "type": "string",
        "description": "Verdict expectation over the match count; default 'any'. One of: any (>=1), none (==0), N (>=N), =N (==N), +N (>N), -N (<N). 'none' inverts a search into a negative assertion that passes when nothing matches."
      },
      "emit": {
        "type": "string",
        "description": "Template written to stdout after the search (alias: emit-stdout). Tokens: {RESULT} {QUESTION} {COUNT} {LINES} {BASE} {MATCHES}."
      },
      "emit-stderr": {
        "type": "string",
        "description": "Template written to stderr after the search. Same tokens as emit."
      },
      "list": {
        "type": "boolean",
        "description": "Output mode: print one matching path per line. This is the default mode."
      },
      "summary": {
        "type": "boolean",
        "description": "Output mode: print counts only. Mutually exclusive with the other output modes."
      },
      "detail": {
        "type": "boolean",
        "description": "Output mode: print matches plus, for --grep, each hit as path:line:text. Mutually exclusive with the other output modes."
      },
      "quiet": {
        "type": "boolean",
        "description": "Output mode: print no per-match output and no --question banner; report via exit status (and --emit, which still fires). Mutually exclusive with the other output modes."
      },
      "timeout": {
        "type": "number",
        "description": "Abort with exit 2 (and a one-line message) if the search exceeds SECS seconds (fractional allowed)."
      },
      "heartbeat": {
        "type": "number",
        "description": "Print a liveness pulse every SECS seconds (fractional allowed) while the run is in progress."
      },
      "heartbeat-emit": {
        "type": "string",
        "description": "Heartbeat line template. Tokens: {ELAPSED} (whole seconds so far) {TOOL}. Default: \"[{ELAPSED}s]\"."
      },
      "heartbeat-to": {
        "type": "string",
        "enum": [
          "stderr",
          "stdout"
        ],
        "description": "Stream heartbeat pulses are written to. Default: stderr."
      }
    },
    "required": []
  }
}