From 369213498dbd6c1fdf833c73e6d4293d0c60fafe Mon Sep 17 00:00:00 2001 From: Nivesh353 Date: Fri, 12 Jun 2026 11:22:22 +0530 Subject: [PATCH] refactor: rename gitclaw adapter/format to gitagent --- README.md | 2 +- docs.md | 2 +- paper/open-gap.md | 10 ++++---- paper/open-gap.tex | 8 +++---- paper/tables/fidelity-matrix.csv | 2 +- src/adapters/{gitclaw.ts => gitagent.ts} | 26 ++++++++++---------- src/adapters/index.ts | 2 +- src/commands/export.ts | 10 ++++---- src/commands/run.ts | 10 ++++---- src/runners/{gitclaw.ts => gitagent.ts} | 30 ++++++++++++------------ 10 files changed, 51 insertions(+), 51 deletions(-) rename src/adapters/{gitclaw.ts => gitagent.ts} (90%) rename src/runners/{gitclaw.ts => gitagent.ts} (74%) diff --git a/README.md b/README.md index e914558..82c8bd7 100644 --- a/README.md +++ b/README.md @@ -370,7 +370,7 @@ Adapters are used by both `export` and `run`. Available adapters: | `copilot` | GitHub Copilot instructions (export only) | | `codex` | OpenAI Codex CLI instructions (export only) | | `kiro` | Kiro agent format (export only) | -| `gitclaw` | GitClaw agent format | +| `gitagent` | Gitagent agent format | ```bash # Export to system prompt diff --git a/docs.md b/docs.md index 2cb14a6..7c3824b 100644 --- a/docs.md +++ b/docs.md @@ -636,7 +636,7 @@ opengap run [options] Either `--repo` or `--dir` is required. -`--workspace` lets an agent definition live separately from the repository it operates on. It is honored by adapters that can safely set the spawned process working directory directly, including `claude`, `openai`, `crewai`, `openclaw`, and `nanobot`. Adapters that generate an isolated runtime workspace, such as `opencode`, `gemini`, and `gitclaw`, continue to run from that prepared workspace to avoid overwriting files such as `AGENTS.md`, `GEMINI.md`, or `agent.yaml` in the target repository. +`--workspace` lets an agent definition live separately from the repository it operates on. It is honored by adapters that can safely set the spawned process working directory directly, including `claude`, `openai`, `crewai`, `openclaw`, and `nanobot`. Adapters that generate an isolated runtime workspace, such as `opencode`, `gemini`, and `gitagent`, continue to run from that prepared workspace to avoid overwriting files such as `AGENTS.md`, `GEMINI.md`, or `agent.yaml` in the target repository. **Available adapters:** diff --git a/paper/open-gap.md b/paper/open-gap.md index d3cf8e7..2fa1fd6 100644 --- a/paper/open-gap.md +++ b/paper/open-gap.md @@ -13,7 +13,7 @@ OpenGAP Working Group AI agents are being deployed into regulated, high-stakes environments faster than the tooling to govern them has matured. Today, an agent's *identity* lives in a Python class, its *policy* lives in a dashboard, its *memory* lives in a vector store, its *audit trail* lives nowhere in particular, and its *version* is whatever commit someone happens to deploy. This paper argues that the right unit of an agent is not a process, not a model, not a config file, and not a dashboard, but a **git repository** — and presents the **GitAgentProtocol (OpenGAP)**, an open standard that makes that abstraction concrete. -Under OpenGAP, an agent is fully described by files in a directory: identity (`SOUL.md`), hard constraints (`RULES.md`), segregation-of-duties (`DUTIES.md`), skills, tools, knowledge, memory, hooks, sub-agents, and regulatory-compliance artifacts. A single canonical definition deterministically exports to **15 execution environments** (Claude Code, OpenAI Agents SDK, CrewAI, Cursor, Gemini CLI, Codex, OpenCode, Kiro, Lyzr, OpenClaw, Nanobot, GitHub Copilot, GitHub Models, GitClaw, system-prompt) with a documented **fidelity profile** per target. **Fourteen lifecycle patterns** — which we show decompose into four meta-patterns: *structural guarantees*, *lifecycle operations*, *collaboration primitives*, and *runtime hooks* — emerge naturally from the git substrate. Compliance is a first-class spec element, mapped onto FINRA 3110/4511/2210, SEC Reg BI/Reg S-P/17a-4, Federal Reserve SR 11-7, and CFPB Circular 2022-03, and enforced through `pre_tool_use` hooks with `fail_open: false` semantics. We prove a simple **structural SOD theorem**: any segregation-of-duties conflict declared in `DUTIES.md` is unbypassable by the agent itself, provided branch-protection rules are active and the agent has no force-push rights. +Under OpenGAP, an agent is fully described by files in a directory: identity (`SOUL.md`), hard constraints (`RULES.md`), segregation-of-duties (`DUTIES.md`), skills, tools, knowledge, memory, hooks, sub-agents, and regulatory-compliance artifacts. A single canonical definition deterministically exports to **15 execution environments** (Claude Code, OpenAI Agents SDK, CrewAI, Cursor, Gemini CLI, Codex, OpenCode, Kiro, Lyzr, OpenClaw, Nanobot, GitHub Copilot, GitHub Models, Gitagent, system-prompt) with a documented **fidelity profile** per target. **Fourteen lifecycle patterns** — which we show decompose into four meta-patterns: *structural guarantees*, *lifecycle operations*, *collaboration primitives*, and *runtime hooks* — emerge naturally from the git substrate. Compliance is a first-class spec element, mapped onto FINRA 3110/4511/2210, SEC Reg BI/Reg S-P/17a-4, Federal Reserve SR 11-7, and CFPB Circular 2022-03, and enforced through `pre_tool_use` hooks with `fail_open: false` semantics. We prove a simple **structural SOD theorem**: any segregation-of-duties conflict declared in `DUTIES.md` is unbypassable by the agent itself, provided branch-protection rules are active and the agent has no force-push rights. Spec v0.4 adds three concrete extensions to this surface: portable `mcp_servers` declarations that export to each runtime's native MCP configuration, a `financial_governance` block with spending caps and approval thresholds for payment-capable agents, and an accepted RFC for an optional Ed25519 cryptographic-identity layer. @@ -313,7 +313,7 @@ Fifteen targets currently ship: | `nanobot` | ✓ | ✓ | Nanobot CLI | Nanobot config | | `copilot` | ✓ | – | GitHub Copilot | `.github/copilot-*` | | `github` | ✓ | ✓ | GitHub Models | GitHub Actions workflow | -| `gitclaw` | ✓ | ✓ | GitClaw | GitClaw workspace | +| `gitagent` | ✓ | ✓ | Gitagent | Gitagent workspace | | `system-prompt` | ✓ | – | any LLM | Concatenated text | ### 5.4 Fidelity profile @@ -663,7 +663,7 @@ As of May 2026, the reference repository `open-gitagent/opengap` has: - **Three spec features shipped from community RFCs/PRs** in v0.4: portable `mcp_servers`, the `financial_governance` block, and the accepted cryptographic-identity RFC - **Provenance-signed** releases on npm as `@open-gitagent/opengap` v0.4.0 (the unscoped root `opengap` is blocked by npm's package-similarity policy, so the scoped name is canonical) - **CI on Node 18 / 20 / 22** building and validating the bundled example agents on every push -- **Cross-community pollination**: GAP agents appear in registries that predate it (the Lyzr registry) and in new registries that postdate it (GitClaw, the OpenClaw ecosystem) +- **Cross-community pollination**: GAP agents appear in registries that predate it (the Lyzr registry) and in new registries that postdate it (Gitagent, the OpenClaw ecosystem) External adapter and spec contributions are the strongest signal that the protocol is perceived as a **neutral substrate**, not a vendor product. No single contributor has standing to force a breaking change in favor of their framework. @@ -841,7 +841,7 @@ The OpenGAP working group thanks contributors to the reference implementation an | `nanobot` | F | F | P | F | F | P | P | ⊥ | ⊥ | | `copilot` | F | F | P | P | P | ⊥ | ⊥ | ⊥ | ⊥ | | `github` | F | F | P | P | F | ⊥ | ⊥ | ⊥ | P | -| `gitclaw` | F | F | F | F | F | F | F | F | F | +| `gitagent` | F | F | F | F | F | F | F | F | F | | `system-prompt` | F | F | P | P | ⊥ | ⊥ | ⊥ | ⊥ | ⊥ | **Legend:** **F** = fully preserved · **P** = partially preserved (text present, semantics dropped) · **⊥** = not representable in the target format. Columns correspond to $I$=identity, $R$=rules, $D$=duties, $S$=skills, $T$=tools, $H$=hooks, $Me$=memory, $A$=sub-agents, $C$=compliance. @@ -887,7 +887,7 @@ A CLI or library is **GAP-conformant at level $k$** iff: - **Level 2 (export):** for at least one target $t$, it produces an output artifact whose fidelity profile matches the specification's published profile for $t$. - **Level 3 (run):** for at least one target $t$, it launches the target runtime in a way that honors $(R, D, H)$ when those elements are present. -The reference implementation `opengap` is Level 3-conformant on Claude Code, OpenCode, Gemini, CrewAI, OpenAI, Lyzr, OpenClaw, Nanobot, GitHub, and GitClaw. +The reference implementation `opengap` is Level 3-conformant on Claude Code, OpenCode, Gemini, CrewAI, OpenAI, Lyzr, OpenClaw, Nanobot, GitHub, and Gitagent. --- diff --git a/paper/open-gap.tex b/paper/open-gap.tex index a1f45fd..9fc42df 100644 --- a/paper/open-gap.tex +++ b/paper/open-gap.tex @@ -77,7 +77,7 @@ From this single source of truth, the reference CLI (\texttt{opengap}) deterministically exports the same agent into fifteen different execution environments, including Claude Code, OpenAI Agents SDK, CrewAI, Cursor, Gemini CLI, Codex, OpenCode, Kiro, Lyzr, -OpenClaw, Nanobot, GitHub Copilot, GitHub Models, GitClaw, and a plain system-prompt +OpenClaw, Nanobot, GitHub Copilot, GitHub Models, Gitagent, and a plain system-prompt target. We describe the repository-as-agent abstraction, the adapter model underlying this portability, fourteen architectural patterns that emerge when agents are defined git-natively (human-in-the-loop learning, agent versioning, branch-based deployment, @@ -414,7 +414,7 @@ \subsection{Adapter inventory} \texttt{nanobot} & \checkmark & \checkmark & Nanobot CLI & Nanobot config \\ \texttt{copilot} & \checkmark & - & GitHub Copilot & \texttt{.github/copilot-*} \\ \texttt{github} & \checkmark & \checkmark & GitHub Models & GitHub Actions workflow \\ -\texttt{gitclaw} & \checkmark & \checkmark & GitClaw & GitClaw workspace \\ +\texttt{gitagent} & \checkmark & \checkmark & Gitagent & Gitagent workspace \\ \texttt{system-prompt} & \checkmark & - & any LLM & Concatenated text \\ \bottomrule \end{tabular} @@ -457,7 +457,7 @@ \subsection{Fidelity profile} \end{tabular} \caption{Abbreviated fidelity profile. \textbf{F} = fully preserved, \textbf{P} = partially (text only, semantics dropped), \textbf{-} = not representable. Rows for -\texttt{copilot}, \texttt{github}, \texttt{gitclaw} omitted for space; see +\texttt{copilot}, \texttt{github}, \texttt{gitagent} omitted for space; see Appendix~\ref{app:fidelity}.} \label{tab:fidelity} \end{table} @@ -1044,7 +1044,7 @@ \section{Full Fidelity Matrix}\label{app:fidelity} \texttt{nanobot} & F & F & P & F & F & P & P & - & - \\ \texttt{copilot} & F & F & P & P & P & - & - & - & - \\ \texttt{github} & F & F & P & P & F & - & - & - & P \\ -\texttt{gitclaw} & F & F & F & F & F & F & F & F & F \\ +\texttt{gitagent} & F & F & F & F & F & F & F & F & F \\ \texttt{system-prompt} & F & F & P & P & - & - & - & - & - \\ \bottomrule \end{tabular} diff --git a/paper/tables/fidelity-matrix.csv b/paper/tables/fidelity-matrix.csv index 6320d2d..f30b364 100644 --- a/paper/tables/fidelity-matrix.csv +++ b/paper/tables/fidelity-matrix.csv @@ -12,5 +12,5 @@ openclaw,F,F,P,F,F,P,F,F,F nanobot,F,F,P,F,F,P,P,-,- copilot,F,F,P,P,P,-,-,-,- github,F,F,P,P,F,-,-,-,P -gitclaw,F,F,F,F,F,F,F,F,F +gitagent,F,F,F,F,F,F,F,F,F system-prompt,F,F,P,P,-,-,-,-,- diff --git a/src/adapters/gitclaw.ts b/src/adapters/gitagent.ts similarity index 90% rename from src/adapters/gitclaw.ts rename to src/adapters/gitagent.ts index 7ebe63b..c0f1a87 100644 --- a/src/adapters/gitclaw.ts +++ b/src/adapters/gitagent.ts @@ -5,9 +5,9 @@ import { loadAgentManifest, loadFileIfExists } from '../utils/loader.js'; import { loadAllSkills } from '../utils/skill-loader.js'; /** - * Export a gitagent to gitclaw format. + * Export a gitagent to gitagent format. * - * Gitclaw uses the same git-native directory structure but with differences: + * Gitagent uses the same git-native directory structure but with differences: * - agent.yaml model format: "provider:model-id" (colon, not slash) * - knowledge/index.yaml uses "entries" (not "documents") * - tools are a flat string array of built-in names in agent.yaml @@ -16,7 +16,7 @@ import { loadAllSkills } from '../utils/skill-loader.js'; * Most files (SOUL.md, RULES.md, DUTIES.md, skills/, hooks/) pass through * unchanged. The adapter transforms agent.yaml and knowledge/index.yaml. */ -export interface GitclawExport { +export interface GitagentExport { agentYaml: string; soulMd: string | null; rulesMd: string | null; @@ -27,7 +27,7 @@ export interface GitclawExport { hooks: string | null; } -export function exportToGitclaw(dir: string): GitclawExport { +export function exportToGitagent(dir: string): GitagentExport { const agentDir = resolve(dir); const manifest = loadAgentManifest(agentDir); @@ -43,8 +43,8 @@ export function exportToGitclaw(dir: string): GitclawExport { return { agentYaml, soulMd, rulesMd, dutiesMd, knowledgeIndex, skills, tools, hooks }; } -export function exportToGitclawString(dir: string): string { - const exp = exportToGitclaw(dir); +export function exportToGitagentString(dir: string): string { + const exp = exportToGitagent(dir); const parts: string[] = []; parts.push('# === agent.yaml ==='); @@ -102,14 +102,14 @@ function buildAgentYaml( if (manifest.author) gc.author = manifest.author; if (manifest.license) gc.license = manifest.license; - // Model: convert to gitclaw "provider:model-id" format + // Model: convert to gitagent "provider:model-id" format if (manifest.model) { const model: Record = {}; if (manifest.model.preferred) { - model.preferred = toGitclawModel(manifest.model.preferred); + model.preferred = toGitagentModel(manifest.model.preferred); } if (manifest.model.fallback) { - model.fallback = manifest.model.fallback.map(toGitclawModel); + model.fallback = manifest.model.fallback.map(toGitagentModel); } if (manifest.model.constraints) { model.constraints = manifest.model.constraints; @@ -152,11 +152,11 @@ function buildAgentYaml( } /** - * Convert gitagent model name to gitclaw "provider:model-id" format. + * Convert gitagent model name to gitagent "provider:model-id" format. * gitagent: "claude-sonnet-4-5" or "anthropic/claude-sonnet-4-5" - * gitclaw: "anthropic:claude-sonnet-4-5" + * gitagent: "anthropic:claude-sonnet-4-5" */ -function toGitclawModel(model: string): string { +function toGitagentModel(model: string): string { // Already in provider:model format if (model.includes(':') && !model.includes('://')) return model; @@ -191,7 +191,7 @@ function collectToolNames(agentDir: string): string[] { } /** - * Convert gitagent knowledge/index.yaml (documents) to gitclaw format (entries). + * Convert gitagent knowledge/index.yaml (documents) to gitagent format (entries). */ function buildKnowledgeIndex(agentDir: string): string | null { const indexPath = join(agentDir, 'knowledge', 'index.yaml'); diff --git a/src/adapters/index.ts b/src/adapters/index.ts index ba52490..1c9606f 100644 --- a/src/adapters/index.ts +++ b/src/adapters/index.ts @@ -10,4 +10,4 @@ export { exportToCursorString, exportToCursor } from './cursor.js'; export { exportToGeminiString, exportToGemini } from './gemini.js'; export { exportToCodexString, exportToCodex } from './codex.js'; export { exportToKiroString, exportToKiro } from './kiro.js'; -export { exportToGitclawString, exportToGitclaw } from './gitclaw.js'; +export { exportToGitagentString, exportToGitagent } from './gitagent.js'; diff --git a/src/commands/export.ts b/src/commands/export.ts index fdfe4af..21f7946 100644 --- a/src/commands/export.ts +++ b/src/commands/export.ts @@ -14,7 +14,7 @@ import { exportToGeminiString, exportToCodexString, exportToKiroString, - exportToGitclawString, + exportToGitagentString, } from '../adapters/index.js'; import { exportToLyzrString } from '../adapters/lyzr.js'; import { exportToGitHubString } from '../adapters/github.js'; @@ -27,7 +27,7 @@ interface ExportOptions { export const exportCommand = new Command('export') .description('Export agent to other formats') - .requiredOption('-f, --format ', 'Export format (system-prompt, claude-code, openai, crewai, openclaw, nanobot, lyzr, github, copilot, opencode, cursor, gemini, codex, kiro, gitclaw)') + .requiredOption('-f, --format ', 'Export format (system-prompt, claude-code, openai, crewai, openclaw, nanobot, lyzr, github, copilot, opencode, cursor, gemini, codex, kiro, gitagent)') .option('-d, --dir ', 'Agent directory', '.') .option('-o, --output ', 'Output file path') .action(async (options: ExportOptions) => { @@ -82,12 +82,12 @@ export const exportCommand = new Command('export') case 'kiro': result = exportToKiroString(dir); break; - case 'gitclaw': - result = exportToGitclawString(dir); + case 'gitagent': + result = exportToGitagentString(dir); break; default: error(`Unknown format: ${options.format}`); - info('Supported formats: system-prompt, claude-code, openai, crewai, openclaw, nanobot, lyzr, github, copilot, opencode, cursor, gemini, codex, kiro, gitclaw'); + info('Supported formats: system-prompt, claude-code, openai, crewai, openclaw, nanobot, lyzr, github, copilot, opencode, cursor, gemini, codex, kiro, gitagent'); process.exit(1); } diff --git a/src/commands/run.ts b/src/commands/run.ts index 733f017..295f7f2 100644 --- a/src/commands/run.ts +++ b/src/commands/run.ts @@ -14,7 +14,7 @@ import { runWithGitHub } from '../runners/github.js'; import { runWithGit } from '../runners/git.js'; import { runWithOpenCode } from '../runners/opencode.js'; import { runWithGemini } from '../runners/gemini.js'; -import { runWithGitclaw } from '../runners/gitclaw.js'; +import { runWithGitagent } from '../runners/gitagent.js'; interface RunOptions { repo?: string; @@ -30,7 +30,7 @@ interface RunOptions { export const runCommand = new Command('run') .description('Run an agent from a git repository or local directory') .option('-r, --repo ', 'Git repository URL') - .option('-a, --adapter ', 'Adapter: claude, openai, crewai, openclaw, nanobot, lyzr, github, opencode, gemini, gitclaw, git, prompt', 'claude') + .option('-a, --adapter ', 'Adapter: claude, openai, crewai, openclaw, nanobot, lyzr, github, opencode, gemini, gitagent, git, prompt', 'claude') .option('-b, --branch ', 'Git branch/tag to clone', 'main') .option('--refresh', 'Force re-clone (pull latest)', false) .option('--no-cache', 'Clone to temp dir, delete on exit') @@ -126,8 +126,8 @@ export const runCommand = new Command('run') case 'gemini': runWithGemini(agentDir, manifest, { prompt: options.prompt, workspace: options.workspace }); break; - case 'gitclaw': - runWithGitclaw(agentDir, manifest, { prompt: options.prompt, workspace: options.workspace }); + case 'gitagent': + runWithGitagent(agentDir, manifest, { prompt: options.prompt, workspace: options.workspace }); break; case 'git': if (!options.repo) { @@ -148,7 +148,7 @@ export const runCommand = new Command('run') break; default: error(`Unknown adapter: ${options.adapter}`); - info('Supported adapters: claude, openai, crewai, openclaw, nanobot, lyzr, github, opencode, gemini, gitclaw, git, prompt'); + info('Supported adapters: claude, openai, crewai, openclaw, nanobot, lyzr, github, opencode, gemini, gitagent, git, prompt'); process.exit(1); } } catch (e) { diff --git a/src/runners/gitclaw.ts b/src/runners/gitagent.ts similarity index 74% rename from src/runners/gitclaw.ts rename to src/runners/gitagent.ts index f50e067..180cf10 100644 --- a/src/runners/gitclaw.ts +++ b/src/runners/gitagent.ts @@ -3,35 +3,35 @@ import { join } from 'node:path'; import { tmpdir } from 'node:os'; import { spawnSync } from 'node:child_process'; import { randomBytes } from 'node:crypto'; -import { exportToGitclaw } from '../adapters/gitclaw.js'; +import { exportToGitagent } from '../adapters/gitagent.js'; import { AgentManifest } from '../utils/loader.js'; import { error, info } from '../utils/format.js'; -export interface GitclawRunOptions { +export interface GitagentRunOptions { prompt?: string; workspace?: string; } /** - * Run a gitagent agent using the gitclaw SDK. + * Run a gitagent agent using the gitagent SDK. * - * Creates a temporary workspace with the full gitclaw directory structure: + * Creates a temporary workspace with the full gitagent directory structure: * - agent.yaml (provider:model format) * - SOUL.md, RULES.md, DUTIES.md * - skills/, tools/, hooks/, knowledge/ * - * Then launches `gitclaw` CLI in that workspace. - * Supports both interactive mode (no prompt) and single-shot mode (`gitclaw run -p`). + * Then launches `gitagent` CLI in that workspace. + * Supports both interactive mode (no prompt) and single-shot mode (`gitagent run -p`). */ -export function runWithGitclaw(agentDir: string, manifest: AgentManifest, options: GitclawRunOptions = {}): void { +export function runWithGitagent(agentDir: string, manifest: AgentManifest, options: GitagentRunOptions = {}): void { if (options.workspace) { - info('--workspace is not applied to gitclaw because it reads agent.yaml and related files from the prepared temporary workspace.'); + info('--workspace is not applied to gitagent because it reads agent.yaml and related files from the prepared temporary workspace.'); } - const exp = exportToGitclaw(agentDir); + const exp = exportToGitagent(agentDir); // Create a temporary workspace - const workspaceDir = join(tmpdir(), `gitagent-gitclaw-${randomBytes(4).toString('hex')}`); + const workspaceDir = join(tmpdir(), `gitagent-ws-${randomBytes(4).toString('hex')}`); mkdirSync(workspaceDir, { recursive: true }); // Write agent.yaml @@ -78,19 +78,19 @@ export function runWithGitclaw(agentDir: string, manifest: AgentManifest, option info(` Model: ${manifest.model.preferred}`); } - // Build gitclaw CLI args + // Build gitagent CLI args const args: string[] = []; if (options.prompt) { args.push('run', '-p', options.prompt); } - info(`Launching gitclaw agent "${manifest.name}"...`); + info(`Launching gitagent agent "${manifest.name}"...`); if (!options.prompt) { info('Starting interactive mode. Type your messages to chat.'); } - const result = spawnSync('gitclaw', args, { + const result = spawnSync('gitagent', args, { stdio: 'inherit', cwd: workspaceDir, env: { ...process.env }, @@ -100,8 +100,8 @@ export function runWithGitclaw(agentDir: string, manifest: AgentManifest, option try { rmSync(workspaceDir, { recursive: true, force: true }); } catch { /* ignore */ } if (result.error) { - error(`Failed to launch gitclaw: ${result.error.message}`); - info('Make sure gitclaw is installed: npm install -g gitclaw'); + error(`Failed to launch gitagent: ${result.error.message}`); + info('Make sure gitagent is installed: npm i @open-gitagent/opengap'); process.exitCode = 1; return; }