Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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