Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ jobs:
run: dotnet restore SharpClawCode.sln
- name: Build
run: dotnet build SharpClawCode.sln --no-restore --configuration Release
- name: Build examples
run: |
dotnet build examples/WebApiAgent/WebApiAgent.csproj --no-restore --configuration Release
dotnet build examples/MinimalConsoleAgent/MinimalConsoleAgent.csproj --no-restore --configuration Release
dotnet build examples/WorkerServiceHost/WorkerServiceHost.csproj --no-restore --configuration Release
dotnet build examples/McpToolAgent/McpToolAgent.csproj --no-restore --configuration Release
- name: Test
run: dotnet test SharpClawCode.sln --no-build --configuration Release --collect:"XPlat Code Coverage" --results-directory ./coverage
- name: Upload coverage
Expand Down
6 changes: 5 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.5" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="10.0.5" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.5" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.14.0" />
<PackageVersion Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="8.14.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageVersion Include="Anthropic" Version="12.11.0" />
<PackageVersion Include="Microsoft.Extensions.AI" Version="10.4.1" />
<PackageVersion Include="Microsoft.Extensions.AI.OpenAI" Version="10.4.1" />
<PackageVersion Include="ModelContextProtocol" Version="1.2.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" />
<PackageVersion Include="Microsoft.Data.Sqlite" Version="10.0.0" />
<PackageVersion Include="Spectre.Console" Version="0.55.0" />
<PackageVersion Include="System.CommandLine" Version="2.0.5" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.4" />
</ItemGroup>
</Project>
</Project>
62 changes: 57 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ SharpClaw Code is a C# and .NET-native coding agent runtime for teams building A

It combines durable sessions, permission-aware tool execution, provider abstraction, structured telemetry, and an automation-friendly command-line surface in a runtime shaped for real .NET systems: explicit, testable, and operationally legible.

The repository now ships both a terminal-first agent runtime and an embeddable host SDK through `SharpClaw.Code`, which makes it viable for standalone CLIs, local editor backends, and tenant-aware embedded services.

## What It Is

SharpClaw Code is an open-source runtime for building and operating coding-agent experiences in the .NET ecosystem.
Expand Down Expand Up @@ -65,6 +67,21 @@ dotnet run --project src/SharpClaw.Code.Cli -- prompt "Summarize this workspace"
dotnet run --project src/SharpClaw.Code.Cli -- doctor
dotnet run --project src/SharpClaw.Code.Cli -- status

# Refresh and query the workspace knowledge index
dotnet run --project src/SharpClaw.Code.Cli -- index refresh
dotnet run --project src/SharpClaw.Code.Cli -- index query WidgetService

# Save and inspect durable memory
dotnet run --project src/SharpClaw.Code.Cli -- memory save --scope project "Keep prompts concise"
dotnet run --project src/SharpClaw.Code.Cli -- memory list --scope project

# Inspect metering summaries and details
dotnet run --project src/SharpClaw.Code.Cli -- usage summary
dotnet run --project src/SharpClaw.Code.Cli -- usage detail --limit 25

# Manage packaged tool bundles
dotnet run --project src/SharpClaw.Code.Cli -- tool-packages list

# Emit machine-readable output
dotnet run --project src/SharpClaw.Code.Cli -- --output-format json doctor
```
Expand All @@ -73,6 +90,8 @@ Built-in REPL slash commands include `/help`, `/status`, `/doctor`, `/session`,

Parity-oriented commands now include:

- `index` / `/index`
- `memory` / `/memory`
- `models` / `/models`
- `usage` / `/usage`
- `cost` / `/cost`
Expand Down Expand Up @@ -101,12 +120,16 @@ Primary workflow modes:
| Durable sessions | Persist conversation state, turn history, checkpoints, and recovery metadata for longer-running agent work |
| Permission-aware tools | Route file, shell, and plugin-backed actions through explicit policy and approval decisions |
| Provider abstraction | Run against Anthropic and OpenAI-compatible backends through a typed runtime surface |
| Local runtime catalog | Surface Ollama, llama.cpp, and other OpenAI-compatible profiles with health, model discovery, and embedding defaults |
| MCP support | Register, supervise, and integrate MCP servers with explicit lifecycle state |
| Plugins and skills | Extend the runtime with trusted plugin manifests and discoverable workspace skills |
| Workspace knowledge | Build a durable local index for lexical, symbol, and semantic workspace search |
| Cross-session memory | Persist project and user memory so later sessions can recall repo-specific guidance and user preferences |
| Structured telemetry | Emit runtime events and usage signals that support diagnostics, replay, and automation |
| Enterprise host controls | Add tenant-aware storage, authenticated approvals, admin APIs, and usage metering for embedded deployments |
| JSON-friendly CLI | Use the same runtime through human-readable terminal flows or machine-readable command output |
| Spec workflow mode | Turn prompts into structured requirements, technical design, and task documents for feature proposals |
| Embedded local server | Expose prompt, session, status, doctor, and share endpoints for editor or automation clients |
| Embedded SDK + server | Host the runtime via `SharpClaw.Code` or expose prompt, session, admin, and SSE endpoints for editor or automation clients |
| Config + agent catalog | Layer user/workspace JSONC config with typed agent defaults, tool allowlists, and runtime hooks |
| Session sharing | Create self-hosted share links and durable sanitized share snapshots under `.sharpclaw/` |
| Diagnostics context | Surface configured diagnostics sources into prompt context, status, and machine-readable output |
Expand All @@ -123,6 +146,7 @@ Primary workflow modes:

| Area | Project(s) |
|---|---|
| Embeddable SDK | `SharpClaw.Code` |
| CLI and command handlers | `SharpClaw.Code.Cli`, `SharpClaw.Code.Commands` |
| Core contracts | `SharpClaw.Code.Protocol` |
| Runtime orchestration | `SharpClaw.Code.Runtime` |
Expand All @@ -135,12 +159,27 @@ Primary workflow modes:

For dependency boundaries and project responsibilities, see [docs/architecture.md](docs/architecture.md) and [AGENTS.md](AGENTS.md).

## Example Hosts

The solution includes embeddable host samples under `examples/`:

- `MinimalConsoleAgent` for direct SDK prompt execution
- `WebApiAgent` for an HTTP-hosted runtime surface
- `WorkerServiceHost` for lifecycle-managed background hosting
- `McpToolAgent` for MCP-aware host composition

## Testing

```bash
# Run all tests
dotnet test SharpClawCode.sln

# Build example hosts as part of local validation
dotnet build examples/WebApiAgent/WebApiAgent.csproj
dotnet build examples/MinimalConsoleAgent/MinimalConsoleAgent.csproj
dotnet build examples/WorkerServiceHost/WorkerServiceHost.csproj
dotnet build examples/McpToolAgent/McpToolAgent.csproj

# Run a single test by name
dotnet test SharpClawCode.sln --filter "FullyQualifiedName~YourTestName"

Expand All @@ -167,8 +206,12 @@ dotnet test SharpClawCode.sln --filter "FullyQualifiedName~ParityScenarioTests"
| `--primary-mode <mode>` | Workflow bias for prompts: `build`, `plan`, or `spec` |
| `--session <id>` | Reuse a specific SharpClaw session id for prompt execution |
| `--agent <id>` | Select the active agent for prompt execution |
| `--host-id <id>` | Stable embedded-host identifier for metering, admin, and event envelopes |
| `--tenant-id <id>` | Tenant identifier used by host-aware storage, approvals, and metering |
| `--storage-root <path>` | External root for host-managed durable runtime state |
| `--session-store fileSystem\|sqlite` | Select the embedded session/event storage backend |

Subcommands include `prompt`, `repl`, `doctor`, `status`, `session`, `models`, `usage`, `cost`, `stats`, `connect`, `hooks`, `skills`, `agents`, `todo`, `share`, `unshare`, `compact`, `serve`, `commands`, `mcp`, `plugins`, `acp`, `bridge`, and `version`.
Subcommands include `prompt`, `repl`, `doctor`, `status`, `session`, `index`, `memory`, `models`, `usage`, `cost`, `stats`, `connect`, `hooks`, `skills`, `agents`, `todo`, `share`, `unshare`, `compact`, `serve`, `commands`, `mcp`, `plugins`, `tool-packages`, `acp`, `bridge`, and `version`.

## Documentation Map

Expand Down Expand Up @@ -205,9 +248,9 @@ Key runtime configuration sections:
|---|---|
| `SharpClaw:Providers:Catalog` | Default provider, model aliases |
| `SharpClaw:Providers:Anthropic` | Anthropic API key, base URL, default model |
| `SharpClaw:Providers:OpenAiCompatible` | OpenAI-compatible API key, base URL, default model |
| `SharpClaw:Providers:OpenAiCompatible` | OpenAI-compatible base settings plus local runtime profiles, auth mode, and default embedding model |
| `SharpClaw:Web` | Web search provider name, endpoint template, user agent |
| `SharpClaw:Telemetry` | Runtime event ring buffer capacity |
| `SharpClaw:Telemetry` | Runtime event ring buffer capacity plus webhook event export behavior |

Key `sharpclaw.jsonc` capabilities:

Expand All @@ -226,8 +269,13 @@ All options are validated at startup via `IValidateOptions` implementations.
- The shared tooling layer is permission-aware across the runtime.
- The current runtime includes multi-turn provider-backed tool execution, session-backed prompt replay, and durable conversation history.
- Agent-driven tool calls flow through the same approval and allowlist enforcement path used by direct tool execution, including caller-aware interactive approval behavior.
- Workspace indexing, symbol search, and durable memory are available through both CLI commands and built-in tools.
- ACP now carries editor context, approval round-trips, model catalog queries, workspace search/index actions, and memory actions, which is enough for a real VS Code client over a single transport.
- OpenAI-compatible local runtime profiles can surface Ollama, llama.cpp, and similar endpoints with profile-aware auth and model discovery.
- Embedded hosts can opt into trusted-header or OIDC-backed approval identity, tenant-aware usage metering, webhook/SSE event streaming, and admin APIs for provider catalog, index status, search, memory inspection, and tool package management.
- The CLI mirrors those enterprise surfaces with `usage summary`, `usage detail`, and `tool-packages` commands while preserving the existing workspace-local `usage`, `cost`, and `stats` flows.
- Operational commands support stable JSON output via `--output-format json`, which makes them suitable for scripts, editors, and automation.
- The embedded server exposes local JSON and SSE endpoints for prompts, sessions, sharing, status, and doctor flows.
- The embedded server exposes local JSON and SSE endpoints for prompts, sessions, admin control, metering, and event streaming.

## Contributing

Expand All @@ -238,6 +286,10 @@ Before opening a PR:
```bash
dotnet build SharpClawCode.sln
dotnet test SharpClawCode.sln
dotnet build examples/WebApiAgent/WebApiAgent.csproj
dotnet build examples/MinimalConsoleAgent/MinimalConsoleAgent.csproj
dotnet build examples/WorkerServiceHost/WorkerServiceHost.csproj
dotnet build examples/McpToolAgent/McpToolAgent.csproj
```

## License
Expand Down
77 changes: 77 additions & 0 deletions SharpClawCode.sln
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpClaw.Code.Acp", "src\S
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpClaw.Code.Mcp.FixtureServer", "tests\SharpClaw.Code.Mcp.FixtureServer\SharpClaw.Code.Mcp.FixtureServer.csproj", "{7F55705B-1E53-4075-AB6F-3BA1BDD2CF85}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpClaw.Code", "src\SharpClaw.Code\SharpClaw.Code.csproj", "{8552440E-B169-4CD9-9B52-4BFFDDADF053}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{B36A84DF-456D-A817-6EDD-3EC3E7F6E11F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "McpToolAgent", "examples\McpToolAgent\McpToolAgent.csproj", "{97EC01C1-A53A-475B-9364-0BD79E9CE272}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApiAgent", "examples\WebApiAgent\WebApiAgent.csproj", "{963C636F-2096-45B1-8101-B8345967F197}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinimalConsoleAgent", "examples\MinimalConsoleAgent\MinimalConsoleAgent.csproj", "{7BA2E64A-B330-4783-9330-AEF46B91929A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkerServiceHost", "examples\WorkerServiceHost\WorkerServiceHost.csproj", "{2E8A9F4F-8161-4E49-9F04-533D972C11CB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -339,6 +351,66 @@ Global
{7F55705B-1E53-4075-AB6F-3BA1BDD2CF85}.Release|x64.Build.0 = Release|Any CPU
{7F55705B-1E53-4075-AB6F-3BA1BDD2CF85}.Release|x86.ActiveCfg = Release|Any CPU
{7F55705B-1E53-4075-AB6F-3BA1BDD2CF85}.Release|x86.Build.0 = Release|Any CPU
{8552440E-B169-4CD9-9B52-4BFFDDADF053}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8552440E-B169-4CD9-9B52-4BFFDDADF053}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8552440E-B169-4CD9-9B52-4BFFDDADF053}.Debug|x64.ActiveCfg = Debug|Any CPU
{8552440E-B169-4CD9-9B52-4BFFDDADF053}.Debug|x64.Build.0 = Debug|Any CPU
{8552440E-B169-4CD9-9B52-4BFFDDADF053}.Debug|x86.ActiveCfg = Debug|Any CPU
{8552440E-B169-4CD9-9B52-4BFFDDADF053}.Debug|x86.Build.0 = Debug|Any CPU
{8552440E-B169-4CD9-9B52-4BFFDDADF053}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8552440E-B169-4CD9-9B52-4BFFDDADF053}.Release|Any CPU.Build.0 = Release|Any CPU
{8552440E-B169-4CD9-9B52-4BFFDDADF053}.Release|x64.ActiveCfg = Release|Any CPU
{8552440E-B169-4CD9-9B52-4BFFDDADF053}.Release|x64.Build.0 = Release|Any CPU
{8552440E-B169-4CD9-9B52-4BFFDDADF053}.Release|x86.ActiveCfg = Release|Any CPU
{8552440E-B169-4CD9-9B52-4BFFDDADF053}.Release|x86.Build.0 = Release|Any CPU
{97EC01C1-A53A-475B-9364-0BD79E9CE272}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{97EC01C1-A53A-475B-9364-0BD79E9CE272}.Debug|Any CPU.Build.0 = Debug|Any CPU
{97EC01C1-A53A-475B-9364-0BD79E9CE272}.Debug|x64.ActiveCfg = Debug|Any CPU
{97EC01C1-A53A-475B-9364-0BD79E9CE272}.Debug|x64.Build.0 = Debug|Any CPU
{97EC01C1-A53A-475B-9364-0BD79E9CE272}.Debug|x86.ActiveCfg = Debug|Any CPU
{97EC01C1-A53A-475B-9364-0BD79E9CE272}.Debug|x86.Build.0 = Debug|Any CPU
{97EC01C1-A53A-475B-9364-0BD79E9CE272}.Release|Any CPU.ActiveCfg = Release|Any CPU
{97EC01C1-A53A-475B-9364-0BD79E9CE272}.Release|Any CPU.Build.0 = Release|Any CPU
{97EC01C1-A53A-475B-9364-0BD79E9CE272}.Release|x64.ActiveCfg = Release|Any CPU
{97EC01C1-A53A-475B-9364-0BD79E9CE272}.Release|x64.Build.0 = Release|Any CPU
{97EC01C1-A53A-475B-9364-0BD79E9CE272}.Release|x86.ActiveCfg = Release|Any CPU
{97EC01C1-A53A-475B-9364-0BD79E9CE272}.Release|x86.Build.0 = Release|Any CPU
{963C636F-2096-45B1-8101-B8345967F197}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{963C636F-2096-45B1-8101-B8345967F197}.Debug|Any CPU.Build.0 = Debug|Any CPU
{963C636F-2096-45B1-8101-B8345967F197}.Debug|x64.ActiveCfg = Debug|Any CPU
{963C636F-2096-45B1-8101-B8345967F197}.Debug|x64.Build.0 = Debug|Any CPU
{963C636F-2096-45B1-8101-B8345967F197}.Debug|x86.ActiveCfg = Debug|Any CPU
{963C636F-2096-45B1-8101-B8345967F197}.Debug|x86.Build.0 = Debug|Any CPU
{963C636F-2096-45B1-8101-B8345967F197}.Release|Any CPU.ActiveCfg = Release|Any CPU
{963C636F-2096-45B1-8101-B8345967F197}.Release|Any CPU.Build.0 = Release|Any CPU
{963C636F-2096-45B1-8101-B8345967F197}.Release|x64.ActiveCfg = Release|Any CPU
{963C636F-2096-45B1-8101-B8345967F197}.Release|x64.Build.0 = Release|Any CPU
{963C636F-2096-45B1-8101-B8345967F197}.Release|x86.ActiveCfg = Release|Any CPU
{963C636F-2096-45B1-8101-B8345967F197}.Release|x86.Build.0 = Release|Any CPU
{7BA2E64A-B330-4783-9330-AEF46B91929A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7BA2E64A-B330-4783-9330-AEF46B91929A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7BA2E64A-B330-4783-9330-AEF46B91929A}.Debug|x64.ActiveCfg = Debug|Any CPU
{7BA2E64A-B330-4783-9330-AEF46B91929A}.Debug|x64.Build.0 = Debug|Any CPU
{7BA2E64A-B330-4783-9330-AEF46B91929A}.Debug|x86.ActiveCfg = Debug|Any CPU
{7BA2E64A-B330-4783-9330-AEF46B91929A}.Debug|x86.Build.0 = Debug|Any CPU
{7BA2E64A-B330-4783-9330-AEF46B91929A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7BA2E64A-B330-4783-9330-AEF46B91929A}.Release|Any CPU.Build.0 = Release|Any CPU
{7BA2E64A-B330-4783-9330-AEF46B91929A}.Release|x64.ActiveCfg = Release|Any CPU
{7BA2E64A-B330-4783-9330-AEF46B91929A}.Release|x64.Build.0 = Release|Any CPU
{7BA2E64A-B330-4783-9330-AEF46B91929A}.Release|x86.ActiveCfg = Release|Any CPU
{7BA2E64A-B330-4783-9330-AEF46B91929A}.Release|x86.Build.0 = Release|Any CPU
{2E8A9F4F-8161-4E49-9F04-533D972C11CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E8A9F4F-8161-4E49-9F04-533D972C11CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E8A9F4F-8161-4E49-9F04-533D972C11CB}.Debug|x64.ActiveCfg = Debug|Any CPU
{2E8A9F4F-8161-4E49-9F04-533D972C11CB}.Debug|x64.Build.0 = Debug|Any CPU
{2E8A9F4F-8161-4E49-9F04-533D972C11CB}.Debug|x86.ActiveCfg = Debug|Any CPU
{2E8A9F4F-8161-4E49-9F04-533D972C11CB}.Debug|x86.Build.0 = Debug|Any CPU
{2E8A9F4F-8161-4E49-9F04-533D972C11CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2E8A9F4F-8161-4E49-9F04-533D972C11CB}.Release|Any CPU.Build.0 = Release|Any CPU
{2E8A9F4F-8161-4E49-9F04-533D972C11CB}.Release|x64.ActiveCfg = Release|Any CPU
{2E8A9F4F-8161-4E49-9F04-533D972C11CB}.Release|x64.Build.0 = Release|Any CPU
{2E8A9F4F-8161-4E49-9F04-533D972C11CB}.Release|x86.ActiveCfg = Release|Any CPU
{2E8A9F4F-8161-4E49-9F04-533D972C11CB}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -367,5 +439,10 @@ Global
{5F0ED186-7920-4A49-B0A3-75F84B4215B3} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
{0060F8FF-0714-4C01-936F-719D7E5F124D} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
{7F55705B-1E53-4075-AB6F-3BA1BDD2CF85} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
{8552440E-B169-4CD9-9B52-4BFFDDADF053} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
{97EC01C1-A53A-475B-9364-0BD79E9CE272} = {B36A84DF-456D-A817-6EDD-3EC3E7F6E11F}
{963C636F-2096-45B1-8101-B8345967F197} = {B36A84DF-456D-A817-6EDD-3EC3E7F6E11F}
{7BA2E64A-B330-4783-9330-AEF46B91929A} = {B36A84DF-456D-A817-6EDD-3EC3E7F6E11F}
{2E8A9F4F-8161-4E49-9F04-533D972C11CB} = {B36A84DF-456D-A817-6EDD-3EC3E7F6E11F}
EndGlobalSection
EndGlobal
Loading
Loading