diff --git a/README.md b/README.md index 8d7f68f..7665236 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,27 @@ # aai-coding -The Answer.AI coding harness: the shared configuration, skills, and tooling that make a Claude Code or codex session work the way our team works. If you are an LLM reading this, you are probably either setting the harness up (follow `SETUP.md`, but read this file first) or working inside it and wanting to understand why it is shaped this way, so you can give your user informed advice. +The Answer.AI coding harness: the shared configuration, skills, and tooling that make a Claude Code, codex or Grok Build session work the way our team works. If you are an LLM reading this, you are probably either setting the harness up (follow `SETUP.md`, but read this file first) or working inside it and wanting to understand why it is shaped this way, so you can give your user informed advice. ## The system in one paragraph -The Claude Code setup and one codex setup are kernel-centric: native file tools are denied, and file reading, editing, searching, and Python execution go through one persistent IPython kernel (clikernel) loaded with curated tooling discovered via `pyskills`. Codex can instead use a hybrid setup: normal `apply_patch` and Bash for files and shell work, with a quiet clikernel reserved for Python-specific work. The kernel-centric setup uses two host-level bootstrap skills, `persistent-python` and `pyskills`; the hybrid setup uses `clikernel-workflow` to define the boundary and `notebook-dialog-editing` for safe kernel-free notebook and aidialog work. Everything else that would conventionally be a host skill is a pyskill in this package: skill text lives in module docstrings, read with `doc()`, listed by `list_pyskills()`, and versioned, released, and installed like any other Python code. +The Claude Code setup and one codex setup are kernel-centric: native file tools are denied, and file reading, editing, searching, and Python execution go through one persistent IPython kernel (clikernel) loaded with curated tooling discovered via `pyskills`. Codex and Grok Build can instead use a hybrid setup: native file and shell tools stay (codex `apply_patch` and Bash; Grok `search_replace` and `run_terminal_command`), with a quiet clikernel reserved for Python-specific work. Grok Build is hybrid-only. The kernel-centric setup uses two host-level bootstrap skills, `persistent-python` and `pyskills`; the hybrid setup uses `clikernel-workflow` to define the boundary and `notebook-dialog-editing` for safe kernel-free notebook and aidialog work. Everything else that would conventionally be a host skill is a pyskill in this package: skill text lives in module docstrings, read with `doc()`, listed by `list_pyskills()`, and versioned, released, and installed like any other Python code. ## What is in here - `aai_coding/` - the pyskills. `coding_patterns` (style, testing judgment, and team policy; part of the kernel startup doc round), `write_prose` (anti-slop rules for narrative prose), `write_docs` (the voiceless register for docstrings, READMEs, and PRs), `harness_docs` (how to find official harness docs via llms.txt), and `harness` (not a skill: the `aai-hook` CLI that implements both harnesses' hooks). -- `skills/` - the harness-level SKILL.md sources, symlinked into `~/.claude/skills` or `~/.codex/skills`. `persistent-python` and `pyskills` bootstrap the kernel-centric setup; `clikernel` and `notebook-dialog-editing` support the hybrid codex setup. +- `skills/` - the harness-level SKILL.md sources, symlinked into `~/.claude/skills`, `~/.codex/skills`, or `~/.grok/skills`. `persistent-python` and `pyskills` bootstrap the kernel-centric setup; `clikernel` and `notebook-dialog-editing` support the hybrid codex and Grok Build setups. - `plugins/safecmd/` - a Claude Code plugin that auto-approves allowlisted Bash commands via the `safecmd` package, so the deny-heavy permission setup stays livable. -- `prompts/` - shared prompt text. `core.md` holds harness-neutral behavioral rules: codex reads it natively via a `~/.codex/AGENTS.md` symlink, and Claude Code can append it. `sysp.md` is a full replacement for Claude Code's default system prompt, tuned against the default's consultant and action biases; install it as a `~/.claude/sysp` symlink and launch with `claude --system-prompt-file ~/.claude/sysp --append-system-prompt-file /prompts/core.md` (replacement drops the default prompt's prose but tool schemas survive; the dynamic environment block and scratchpad path are the known losses). +- `prompts/` - shared prompt text. `core.md` holds harness-neutral behavioral rules: codex reads it natively via a `~/.codex/AGENTS.md` symlink, Grok Build via a `~/.grok/AGENTS.md` symlink, and Claude Code can append it. `sysp.md` is a full replacement for Claude Code's default system prompt, tuned against the default's consultant and action biases; install it as a `~/.claude/sysp` symlink and launch with `claude --system-prompt-file ~/.claude/sysp --append-system-prompt-file /prompts/core.md` (replacement drops the default prompt's prose but tool schemas survive; the dynamic environment block and scratchpad path are the known losses). - `SETUP.md` - the setup runbook, written as a prompt for an LLM session rather than an installer script. ## Design decisions, and why -- **Task skills are pyskills.** In a kernel-centric harness the native skill list stops being the discovery surface; `list_pyskills()` is. Docstrings-as-skill-text means nothing depends on the harness's skill machinery. It also lets skill text live beside its executable companions in one module. The hybrid codex workflow remains a host skill because it tells codex when to cross into the kernel at all. +- **Task skills are pyskills.** In a kernel-centric harness the native skill list stops being the discovery surface; `list_pyskills()` is. Docstrings-as-skill-text means nothing depends on the harness's skill machinery. It also lets skill text live beside its executable companions in one module. The hybrid codex workflow remains a host skill because it tells codex or Grok Build when to cross into the kernel at all. - **Hooks are a CLI.** Every hook body is a subcommand of `aai-hook` (`aai_coding/harness.py`): versioned, unit-tested Python instead of shell one-liners scattered through settings files. Harness configs only register command names. -- **Everything installs by symlink.** Like the workspace's editable installs, config points into the checkout, so `git pull` updates every machine and there is no copy to drift. The only exceptions are settings files that must be merged (Claude Code's `settings.json`, codex's `config.toml`), which is why setup is a runbook and not a script: merging into someone's existing configuration takes judgment and conversation, which an LLM has and an installer does not. -- **Per-harness differences are data, not templates.** Where Claude Code and codex genuinely differ, a module carries both facts (a `dict` keyed by harness, or two adjacent bullets); nothing is rendered or generated. +- **Everything installs by symlink.** Like the workspace's editable installs, config points into the checkout, so `git pull` updates every machine and there is no copy to drift. The only exceptions are settings files that must be merged (Claude Code's `settings.json`, codex's `config.toml`, Grok Build's `config.toml`), which is why setup is a runbook and not a script: merging into someone's existing configuration takes judgment and conversation, which an LLM has and an installer does not. +- **Per-harness differences are data, not templates.** Where Claude Code, codex, and Grok Build genuinely differ, a module carries both facts (a `dict` keyed by harness, or two adjacent bullets); nothing is rendered or generated. - **Team-agreeable versus personal.** This repo holds only what any team member would nod at. Personal preferences (model choice, sounds people disagree about, individual workflow like release management) belong in each person's own CLAUDE.md, settings, and local skills, and the runbook is explicit about which is which. ## Using and changing it -Day to day there is nothing to operate. Kernel-centric sessions bootstrap through `persistent-python`; hybrid codex sessions use `clikernel-workflow` for Python, `notebook-dialog-editing` for notebooks and aidialog dialogs, and the native tools otherwise. Both discover Python tooling through the pyskills catalog and read it with `doc()` or `pyskills-doc`. To change a skill, edit its source in this checkout and let the team pick it up by pulling; releases go through the standard fastship flow (`ship-release`), with the version in `aai_coding/__init__.py` bumped after each release. +Day to day there is nothing to operate. Kernel-centric sessions bootstrap through `persistent-python`; hybrid codex and Grok Build sessions use `clikernel-workflow` for Python, `notebook-dialog-editing` for notebooks and aidialog dialogs, and the native tools otherwise. Both discover Python tooling through the pyskills catalog and read it with `doc()` or `pyskills-doc`. To change a skill, edit its source in this checkout and let the team pick it up by pulling; releases go through the standard fastship flow (`ship-release`), with the version in `aai_coding/__init__.py` bumped after each release. diff --git a/SETUP.md b/SETUP.md index 66eb88a..dc21b56 100644 --- a/SETUP.md +++ b/SETUP.md @@ -2,18 +2,18 @@ This file is a runbook for an LLM session, not a script. If you are a person: open Claude Code or codex, `cd` anywhere in the aai-ws workspace, and say "follow aai-coding/SETUP.md". If you are the session: first read `README.md` in this repo in full, since the steps below change your user's configuration and the README's design context is what lets you merge, recommend, and answer questions in an informed way. Then work through the steps in order. Each step states an outcome to reach, a check, and what to settle with the user first. Make no change beyond the stated outcomes without asking. Where the user's existing configuration overlaps, merge and never replace: show them each conflict and agree a resolution. -Assumptions: macOS, the aai-ws uv workspace cloned and synced (this repo is a member, so its `aai-hook` CLI and pyskills are already installed), and at least one harness (Claude Code or codex) installed and signed in. Ask which harnesses to set up before starting, and use absolute paths for this repo and the workspace venv throughout. +Assumptions: macOS, the aai-ws uv workspace cloned and synced (this repo is a member, so its `aai-hook` CLI and pyskills are already installed), and at least one harness (Claude Code, codex, or Grok Build) installed and signed in. Ask which harnesses to set up before starting, and use absolute paths for this repo and the workspace venv throughout. -Codex has two supported modes. This choice applies only to codex; Claude Code remains kernel-centric. Settle which codex mode the user wants before changing its configuration: +Codex has two supported modes. This choice applies only to codex; Claude Code remains kernel-centric; Grok Build is hybrid-only. Settle which codex mode the user wants before changing its configuration: 1. **Kernel-centric:** do file, shell, and Python work through clikernel, complete the llmdojo bootstrap, and discover tools through pyskills. This is the existing Answer.AI harness workflow and most closely matches the Claude Code setup. -2. **Hybrid:** use codex's `apply_patch` and Bash tools normally, and use `clikernel-mcp --quiet` only for Python-specific work. This keeps persistent Python state and pyskills without replacing codex's native file and shell workflow. +2. **Hybrid:** use the native file and shell tools normally (codex: `apply_patch` and Bash; Grok Build: `search_replace` and `run_terminal_command`), and use `clikernel-mcp --quiet` only for Python-specific work. This keeps persistent Python state and pyskills without replacing the native file and shell workflow. ## 1. Kernel server Outcome: the clikernel MCP server is registered. Claude Code: a user-scope server named `clikernel` running `/bin/clikernel-mcp`. Kernel-centric codex: a `[mcp_servers.clikernel]` block in `~/.codex/config.toml` with `command` set to that binary, `startup_timeout_sec = 30`, `tool_timeout_sec = 3600`, and `approval_mode = "approve"` for its `execute`, `connect`, `restart`, and `interrupt` tools. -Hybrid codex: use the following exact working configuration, changing the `command` path if the workspace is elsewhere: +Hybrid (codex or Grok Build): use the following exact working configuration in `~/.codex/config.toml` or `~/.grok/config.toml`, changing the `command` path if the workspace is elsewhere: ```toml [mcp_servers.clikernel] @@ -77,7 +77,7 @@ Check: the file still parses as JSON after editing. ## 5. Skills, safecmd, and prompts -Outcome: symlinks from `~/.claude/skills/persistent-python` and `~/.claude/skills/pyskills` to `/skills/`. Kernel-centric codex gets the same two skill symlinks. Hybrid codex instead gets `~/.codex/skills/clikernel` pointing to `/skills/clikernel` and `~/.codex/skills/notebook-dialog-editing` pointing to `/skills/notebook-dialog-editing`; the latter teaches Codex to inspect and edit notebooks and aidialog dialogs safely through the shell CLIs without using a kernel. Remove the other mode's codex skill symlinks when switching, since they intentionally prescribe conflicting tool-use policies. Also link `~/.claude/skills/safecmd` to `/plugins/safecmd` and `~/.codex/AGENTS.md` to `/prompts/core.md`. +Outcome: symlinks from `~/.claude/skills/persistent-python` and `~/.claude/skills/pyskills` to `/skills/`. Kernel-centric codex gets the same two skill symlinks. Hybrid (codex or Grok Build) instead gets `clikernel` and `notebook-dialog-editing` under `~/.codex/skills/` or `~/.grok/skills/`, pointing at `/skills/`; the latter teaches the harness to inspect and edit notebooks and aidialog dialogs safely through the shell CLIs without using a kernel. Remove the other mode's skill symlinks when switching, since they intentionally prescribe conflicting tool-use policies. Also link `~/.claude/skills/safecmd` to `/plugins/safecmd` and `~/.codex/AGENTS.md` or `~/.grok/AGENTS.md` to `/prompts/core.md`. safecmd auto-approves allowlisted Bash commands. The `safecmd` package is a workspace member, so it is already installed; its allowlist lives at `~/.config/safecmd/config.ini` and the defaults are fine to start. @@ -93,10 +93,10 @@ The user might find it useful to hear a quiet tone when the harness finishes or ## 7. Restart and verify wiring -Both harnesses read configuration at startup: ask the user to restart each, accepting codex's hook trust prompt when hooks changed. Then verify a kernel round trip by running `1+1` through clikernel. In the hybrid codex mode, the reply should contain just the result rather than the startup text. +All three harnesses read configuration at startup: ask the user to restart each, accepting codex's hook trust prompt when hooks changed. Then verify a kernel round trip by running `1+1` through clikernel. In hybrid mode, the reply should contain just the result rather than the startup text. ## 8. Acceptance In a fresh Claude Code or kernel-centric codex session in any workspace Python project: the bootstrap notice fires; invoking `persistent-python` then running `dojo_start()` completes a clean round; `list_pyskills()` shows the `aai_coding.*` rows; `doc(aai_coding.coding_patterns)` renders. -In a fresh hybrid codex session: `clikernel-workflow` and `notebook-dialog-editing` appear in the available skills; ordinary local text edits use `apply_patch`; notebook and aidialog work can use the shell CLIs without starting a kernel; shell work uses Bash; and clikernel retains Python state across two execution calls. Inside clikernel, `list_pyskills()` shows the `aai_coding.*` rows and `doc(aai_coding.coding_patterns)` renders. When a check fails, fix that step's wiring before moving on, and tell the user what was wrong. +In a fresh hybrid session (codex or Grok Build): `clikernel-workflow` and `notebook-dialog-editing` appear in the available skills; ordinary local text edits use `apply_patch` (Grok: `search_replace`); notebook and aidialog work can use the shell CLIs without starting a kernel; shell work uses Bash (Grok: `run_terminal_command`); and clikernel retains Python state across two execution calls. Inside clikernel, `list_pyskills()` shows the `aai_coding.*` rows and `doc(aai_coding.coding_patterns)` renders. When a check fails, fix that step's wiring before moving on, and tell the user what was wrong. diff --git a/aai_coding/harness.py b/aai_coding/harness.py index cb46fe6..7fcef9c 100644 --- a/aai_coding/harness.py +++ b/aai_coding/harness.py @@ -1,4 +1,4 @@ -"""Hook implementations for the team harness, installed as the `aai-hook` CLI. Each subcommand is registered in a harness's hook config (Claude Code settings.json or codex hooks.json) and reads the hook event's JSON payload from stdin. See SETUP.md for the wiring.""" +"""Hook implementations for the team harness, installed as the `aai-hook` CLI. Each subcommand is registered in a harness's hook config (Claude Code settings.json, codex and Grok Build hooks.json) and reads the hook event's JSON payload from stdin. See SETUP.md for the wiring.""" import json, os, re, sys from datetime import datetime from pathlib import Path diff --git a/aai_coding/harness_docs.py b/aai_coding/harness_docs.py index 8fd2f6b..244f53e 100644 --- a/aai_coding/harness_docs.py +++ b/aai_coding/harness_docs.py @@ -1,20 +1,23 @@ -r'''Official docs for the tool you are running in (Claude Code or codex): read before answering questions about its behaviour, config, or features. +r'''Official docs for the tool you are running in (Claude Code, codex, or Grok Build): read before answering questions about its behaviour, config, or features. # Harness Docs 1. Work in `clikernel`, with the `exhash` pyskill loaded. Open the docs index in one step, never displaying the raw text: `toc = open_doc(llms_txt())`. 2. Find the page with `toc.links('')`: a few `[n] Title: description` rows are the whole display. Pick the row whose title matches the question. For codex the index is the whole OpenAI developers hub (the codex-scoped llms.txt their docs link to is a 404), so narrow to Codex first: `toc.search('^## Codex')` lists one `Codex — ` row per page with its address token, then `toc.at('').links('')` gives that page's followable row. A bare `toc.links('')` over the hub matches other OpenAI products too. + For Grok Build the published llms.txt is a concatenated dump of the xAI docs hub, not a page index. Narrow immediately: `toc.search('Grok Build')` or `toc.links('build')`. Never display the whole file. The CLI also ships the user guide at `~/.grok/docs/user-guide/`; `grok inspect` and `grok --help` are the local contracts. 3. Open it with `page = toc.open(n)`: fetched, parsed, and `base`-recorded in one step. No URL is copied at any point. Never fetch `llms-full.txt`. Pick the right page from the index instead. 4. Display `page` bare and read the listing: every row ends with the section's size, so the whole-or-sections decision reads straight off it. At most 30,000 characters in total: display the whole `page.text`. A short page read whole gives an overview sections cannot. Larger: do not display it. `page.search('')` shows `token title (count) [size] preview` rows; retrieve matching sections with `at('')`, or `paths(2)` when structure itself is the question. Never display an arbitrary slice. The choice is the whole page or selected sections, nothing between. Fetch shared sections separately when an event-specific section refers to them. -5. Use the official documentation for documented interfaces and normal day-to-day behavior. Some questions the docs do not answer. For codex, dive into its source, which is open. For Claude Code, which ships no public source, check the changelog and What's New pages for recent changes, and investigate observed behavior directly (settings files, `--help`, `/doctor`). +5. Use the official documentation for documented interfaces and normal day-to-day behavior. Some questions the docs do not answer. For codex or Grok Build, dive into its source, which is open. For Claude Code, which ships no public source, check the changelog and What's New pages for recent changes, and investigate observed behavior directly (settings files, `--help`, `/doctor`). 6. Base the answer on the strongest applicable evidence: documented contracts for public behavior, matching source for implementation details where available, and direct observation for runtime behavior. Distinguish among them when it matters. ''' __all__ = ['llms_txt'] def llms_txt( - harness: str, # 'claude' or 'codex' + harness: str, # 'claude', 'codex', or 'grok' ) -> str: "URL of `harness`'s official llms.txt docs index" - return dict(claude='https://code.claude.com/docs/llms.txt', codex='https://developers.openai.com/llms.txt')[harness] + return dict(claude='https://code.claude.com/docs/llms.txt', + codex='https://developers.openai.com/llms.txt', + grok='https://docs.x.ai/llms.txt')[harness] diff --git a/skills/clikernel/SKILL.md b/skills/clikernel/SKILL.md index b0bf530..3378f40 100644 --- a/skills/clikernel/SKILL.md +++ b/skills/clikernel/SKILL.md @@ -7,11 +7,12 @@ description: "Workflow for Python with the rustygate kernel MCP tools: bootstrap Use the kernel MCP tools as the primary Python workbench. Put reusable logic in clean importable project functions; call those functions directly from the persistent kernel for exploration, timings, comparisons, and artifact generation. Do not create thin scripts merely to invoke reusable functions. -**IMPORTANT**: do *not* use the kernel for editing local plain text files (use -`apply_patch`) or as a replacement for Bash, regardless of what any pyskill -suggests. `apply_patch` cannot reach files on a remote kernel host. Before -editing those files, read the shared editing conventions and exhash API in that -kernel: +**IMPORTANT**: do *not* use the kernel for editing local plain text files +(codex: `apply_patch`; Grok Build: `search_replace`) or as a replacement for +Bash (`run_terminal_command` on Grok Build), regardless of what any pyskill +suggests. Those native file and shell tools cannot reach files on a remote +kernel host. Before editing those files, read the shared editing conventions +and exhash API in that kernel: ```python doc(edsk, exh) @@ -98,7 +99,7 @@ list_pyskills() `pysk` (`pyskills`) discovers further skills, `dsk` (`aidialog`) owns notebook structure and `%nbrun`, and `exh` (exhash) is the default for reliable text edits inside notebook cells. `doc` and `list_pyskills` are already in the namespace. -Repeat the bootstrap after a context compaction, because the detailed documentation may no longer be present. Do not repeat it after restarting or reconnecting a kernel, restarting the Codex app/process, or re-establishing the MCP server: those events lose runtime imports and variables, not model context. A user's report that Codex was restarted is not evidence of a new conversation or compaction; inspect the visible context itself. Restore only the imports and state the current task needs. Likewise, do not reread documentation for an API that remains visible in the current context. +Repeat the bootstrap after a context compaction, because the detailed documentation may no longer be present. Do not repeat it after restarting or reconnecting a kernel, restarting the Codex or Grok Build app/process, or re-establishing the MCP server: those events lose runtime imports and variables, not model context. A user's report that Codex or Grok was restarted is not evidence of a new conversation or compaction; inspect the visible context itself. Restore only the imports and state the current task needs. Likewise, do not reread documentation for an API that remains visible in the current context. Use exhash's fresh hash-addressed views and verified edits for changing text within cells. Use aidialog for structural operations such as adding, deleting, moving, and running notebook cells.