karta-runtime 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. karta_runtime-0.1.0/PKG-INFO +396 -0
  2. karta_runtime-0.1.0/README.md +347 -0
  3. karta_runtime-0.1.0/pyproject.toml +116 -0
  4. karta_runtime-0.1.0/src/karta/__init__.py +48 -0
  5. karta_runtime-0.1.0/src/karta/__main__.py +4 -0
  6. karta_runtime-0.1.0/src/karta/active_releases.py +129 -0
  7. karta_runtime-0.1.0/src/karta/agent.py +59 -0
  8. karta_runtime-0.1.0/src/karta/app.py +672 -0
  9. karta_runtime-0.1.0/src/karta/billing/__init__.py +13 -0
  10. karta_runtime-0.1.0/src/karta/billing/usage_emitter.py +416 -0
  11. karta_runtime-0.1.0/src/karta/builder.py +223 -0
  12. karta_runtime-0.1.0/src/karta/byok.py +206 -0
  13. karta_runtime-0.1.0/src/karta/cache.py +257 -0
  14. karta_runtime-0.1.0/src/karta/cli.py +609 -0
  15. karta_runtime-0.1.0/src/karta/cli_renderer.py +173 -0
  16. karta_runtime-0.1.0/src/karta/consumer/__init__.py +7 -0
  17. karta_runtime-0.1.0/src/karta/consumer/challenge.py +116 -0
  18. karta_runtime-0.1.0/src/karta/consumer/embed.py +310 -0
  19. karta_runtime-0.1.0/src/karta/consumer/event_log.py +80 -0
  20. karta_runtime-0.1.0/src/karta/consumer/events.py +34 -0
  21. karta_runtime-0.1.0/src/karta/consumer/managed_agents.py +66 -0
  22. karta_runtime-0.1.0/src/karta/consumer/openai_chat.py +97 -0
  23. karta_runtime-0.1.0/src/karta/consumer/openai_responses.py +116 -0
  24. karta_runtime-0.1.0/src/karta/consumer/project_origins.py +98 -0
  25. karta_runtime-0.1.0/src/karta/consumer/session_token.py +78 -0
  26. karta_runtime-0.1.0/src/karta/control_plane.py +140 -0
  27. karta_runtime-0.1.0/src/karta/durable/__init__.py +22 -0
  28. karta_runtime-0.1.0/src/karta/durable/local.py +34 -0
  29. karta_runtime-0.1.0/src/karta/durable/port.py +19 -0
  30. karta_runtime-0.1.0/src/karta/durable/s3.py +64 -0
  31. karta_runtime-0.1.0/src/karta/events.py +21 -0
  32. karta_runtime-0.1.0/src/karta/execution/__init__.py +22 -0
  33. karta_runtime-0.1.0/src/karta/execution/fake.py +78 -0
  34. karta_runtime-0.1.0/src/karta/execution/local.py +96 -0
  35. karta_runtime-0.1.0/src/karta/execution/port.py +85 -0
  36. karta_runtime-0.1.0/src/karta/gateway/__init__.py +15 -0
  37. karta_runtime-0.1.0/src/karta/gateway/base.py +29 -0
  38. karta_runtime-0.1.0/src/karta/gateway/events.py +73 -0
  39. karta_runtime-0.1.0/src/karta/gateway/http.py +80 -0
  40. karta_runtime-0.1.0/src/karta/gateway/local.py +151 -0
  41. karta_runtime-0.1.0/src/karta/gateway/registry.py +65 -0
  42. karta_runtime-0.1.0/src/karta/harness/__init__.py +4 -0
  43. karta_runtime-0.1.0/src/karta/harness/base.py +142 -0
  44. karta_runtime-0.1.0/src/karta/harness/claude.py +974 -0
  45. karta_runtime-0.1.0/src/karta/harness/claude_message_mapper.py +418 -0
  46. karta_runtime-0.1.0/src/karta/harness/factory.py +37 -0
  47. karta_runtime-0.1.0/src/karta/harness/opencode.py +592 -0
  48. karta_runtime-0.1.0/src/karta/harness/utils.py +45 -0
  49. karta_runtime-0.1.0/src/karta/hub.py +126 -0
  50. karta_runtime-0.1.0/src/karta/instance.py +729 -0
  51. karta_runtime-0.1.0/src/karta/model_settings.py +134 -0
  52. karta_runtime-0.1.0/src/karta/observability/__init__.py +156 -0
  53. karta_runtime-0.1.0/src/karta/observability/_noop.py +75 -0
  54. karta_runtime-0.1.0/src/karta/observability/_otel.py +81 -0
  55. karta_runtime-0.1.0/src/karta/observability/logging_setup.py +96 -0
  56. karta_runtime-0.1.0/src/karta/observability/metrics.py +74 -0
  57. karta_runtime-0.1.0/src/karta/observability/secret_redaction.py +96 -0
  58. karta_runtime-0.1.0/src/karta/participant.py +55 -0
  59. karta_runtime-0.1.0/src/karta/persistence/__init__.py +46 -0
  60. karta_runtime-0.1.0/src/karta/persistence/gc.py +164 -0
  61. karta_runtime-0.1.0/src/karta/persistence/local_backend.py +128 -0
  62. karta_runtime-0.1.0/src/karta/persistence/manifest.py +225 -0
  63. karta_runtime-0.1.0/src/karta/persistence/profile.py +156 -0
  64. karta_runtime-0.1.0/src/karta/persistence/reconcile.py +76 -0
  65. karta_runtime-0.1.0/src/karta/persistence/s3_backend.py +131 -0
  66. karta_runtime-0.1.0/src/karta/persistence/store.py +297 -0
  67. karta_runtime-0.1.0/src/karta/persistence/text_merge.py +70 -0
  68. karta_runtime-0.1.0/src/karta/policies.py +29 -0
  69. karta_runtime-0.1.0/src/karta/project_runtime.py +201 -0
  70. karta_runtime-0.1.0/src/karta/registry.py +137 -0
  71. karta_runtime-0.1.0/src/karta/release_artifacts.py +70 -0
  72. karta_runtime-0.1.0/src/karta/releases.py +478 -0
  73. karta_runtime-0.1.0/src/karta/response.py +150 -0
  74. karta_runtime-0.1.0/src/karta/runtime/__init__.py +3 -0
  75. karta_runtime-0.1.0/src/karta/runtime/turn_accumulator.py +146 -0
  76. karta_runtime-0.1.0/src/karta/secrets_bootstrap.py +88 -0
  77. karta_runtime-0.1.0/src/karta/server/__init__.py +3 -0
  78. karta_runtime-0.1.0/src/karta/server/agentcore.py +393 -0
  79. karta_runtime-0.1.0/src/karta/server/agentcore_client.py +481 -0
  80. karta_runtime-0.1.0/src/karta/server/agentcore_project_runtime.py +210 -0
  81. karta_runtime-0.1.0/src/karta/server/agentcore_router.py +118 -0
  82. karta_runtime-0.1.0/src/karta/server/agentcore_serve.py +116 -0
  83. karta_runtime-0.1.0/src/karta/server/auth.py +625 -0
  84. karta_runtime-0.1.0/src/karta/server/credential_guard.py +51 -0
  85. karta_runtime-0.1.0/src/karta/server/fastapi_app.py +2454 -0
  86. karta_runtime-0.1.0/src/karta/server/instance_routes.py +199 -0
  87. karta_runtime-0.1.0/src/karta/server/serve_surfaces.py +231 -0
  88. karta_runtime-0.1.0/src/karta/server/session_store.py +220 -0
  89. karta_runtime-0.1.0/src/karta/server/sse.py +10 -0
  90. karta_runtime-0.1.0/src/karta/session.py +161 -0
  91. karta_runtime-0.1.0/src/karta/vault/__init__.py +21 -0
  92. karta_runtime-0.1.0/src/karta/vault/agentcore.py +33 -0
  93. karta_runtime-0.1.0/src/karta/vault/local.py +43 -0
  94. karta_runtime-0.1.0/src/karta/vault/port.py +28 -0
  95. karta_runtime-0.1.0/src/karta/workspace.py +489 -0
@@ -0,0 +1,396 @@
1
+ Metadata-Version: 2.3
2
+ Name: karta-runtime
3
+ Version: 0.1.0
4
+ Summary: Karta agent runtime: harness adapters, dev serve, and the platform serve layer
5
+ License: MIT
6
+ Keywords: agents,ai,framework,orchestration
7
+ Author: Karta
8
+ Author-email: team@karta.sh
9
+ Requires-Python: >=3.9,<4.0
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Framework :: FastAPI
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Provides-Extra: dev-reload
21
+ Provides-Extra: gitmerge
22
+ Provides-Extra: otel
23
+ Provides-Extra: postgres
24
+ Provides-Extra: s3
25
+ Requires-Dist: anyio (>=4.8.0,<5.0.0)
26
+ Requires-Dist: boto3 (>=1.35.92,<2.0.0) ; extra == "s3"
27
+ Requires-Dist: claude-agent-sdk (>=0.2.82,<0.3.0) ; python_version >= "3.10"
28
+ Requires-Dist: fastapi (>=0.115.6,<0.116.0)
29
+ Requires-Dist: httpx (>=0.28.1,<0.29.0)
30
+ Requires-Dist: opentelemetry-api (>=1.27.0,<2.0.0) ; extra == "otel"
31
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http (>=1.27.0,<2.0.0) ; extra == "otel"
32
+ Requires-Dist: opentelemetry-instrumentation-asgi (>=0.48b0,<0.49) ; extra == "otel"
33
+ Requires-Dist: opentelemetry-instrumentation-fastapi (>=0.48b0,<0.49) ; extra == "otel"
34
+ Requires-Dist: opentelemetry-instrumentation-httpx (>=0.48b0,<0.49) ; extra == "otel"
35
+ Requires-Dist: opentelemetry-sdk (>=1.27.0,<2.0.0) ; extra == "otel"
36
+ Requires-Dist: psycopg[binary] (>=3.2.3,<4.0.0) ; extra == "postgres"
37
+ Requires-Dist: pydantic (>=2.10.4,<3.0.0)
38
+ Requires-Dist: pygit2 (>=1.18.0,<2.0.0) ; (python_version >= "3.11") and (extra == "gitmerge")
39
+ Requires-Dist: python-frontmatter (>=1.1.0,<2.0.0)
40
+ Requires-Dist: rich (>=13.0.0,<16.0.0)
41
+ Requires-Dist: typer (>=0.21.0,<0.22.0)
42
+ Requires-Dist: uvicorn[standard] (>=0.32.1,<0.40.0)
43
+ Requires-Dist: watchfiles (>=1.0.0,<2.0.0) ; extra == "dev-reload"
44
+ Project-URL: Documentation, https://docs.karta.sh
45
+ Project-URL: Homepage, https://karta.sh
46
+ Project-URL: Repository, https://github.com/karta-sh/karta
47
+ Description-Content-Type: text/markdown
48
+
49
+ <div align="center">
50
+ <h1>karta-runtime</h1>
51
+ <p><strong>The Karta runtime: harness adapters, sessions, and the consumer session API on agent harnesses like Claude Code and OpenCode</strong></p>
52
+ </div>
53
+
54
+ <div align="center">
55
+
56
+ [![GitHub License](https://img.shields.io/github/license/karta/karta?logo=github)](https://github.com/karta/karta/blob/main/LICENSE)
57
+ [![PyPI Version](https://img.shields.io/pypi/v/karta-runtime?logo=pypi&color=blue)](https://pypi.org/project/karta-runtime/)
58
+ [![Python Version](https://img.shields.io/badge/Python-3.9--3.12-blue?logo=python)](https://www.python.org/)
59
+ [![GitHub issues](https://img.shields.io/github/issues/karta/karta)](https://github.com/karta/karta/issues)
60
+
61
+ </div>
62
+
63
+ > **Looking for the `karta` command?** The public CLI is
64
+ > [`@karta.sh/cli`](../../sdks/typescript-cli/) (`npm install -g @karta.sh/cli`).
65
+ > This package is `karta-runtime` - the internal engine that CLI bootstraps
66
+ > for `karta dev`, and the data plane the platform serves (RFC 0013,
67
+ > [docs/rfcs/0013-unified-cli.md](../../docs/rfcs/0013-unified-cli.md)). Its
68
+ > own CLI verbs are internal (see [CLI](#cli-internal)); use it directly as a
69
+ > Python SDK/library, exactly as documented below.
70
+
71
+ ## Why Karta
72
+
73
+ Agent frameworks like [LangGraph](https://github.com/langchain-ai/langgraph), [CrewAI](https://github.com/crewAIInc/crewAI), [AutoGen](https://github.com/microsoft/autogen), and the [OpenAI Agents SDK](https://github.com/openai/openai-agents-python) build agents from scratch — defining their own tool systems, context management, memory, and execution loops.
74
+
75
+ **Karta takes the opposite approach.** Agent harnesses like [Claude Code](https://docs.anthropic.com/en/docs/claude-code) and [OpenCode](https://opencode.ai) already solved the hard problems — tools, MCP servers, context management, memory, skills, and agentic execution. They're battle-tested, deeply integrated with real development workflows, and improving fast.
76
+
77
+ Karta builds **on top** of these harnesses in two tiers: a **thin core** that delegates all agent execution and conversation persistence to the harness, plus a **platform layer** that adds the multi-tenant SaaS machinery production applications need. Together they provide **multi-user sessions**, **multi-agent routing**, **participant-aware messaging**, **cross-instance communication**, **HTTP deployment**, **multi-tenancy with durable tenant isolation**, **BYOK key management**, **usage metering**, **policy enforcement**, and **lifecycle hooks** — without reinventing agent capabilities from scratch.
78
+
79
+ ```
80
+ ┌──────────────────────────────────────────────────────────┐
81
+ │ Other frameworks │ Karta │
82
+ │ │ │
83
+ │ Build agents from scratch │ Build ON existing harnesses │
84
+ │ Own tool system │ Harness tools (MCP, etc.) │
85
+ │ Own memory/context │ Harness memory/context │
86
+ │ Own execution loop │ Harness execution loop │
87
+ │ + Multi-agent orchestr. │ + Multi-user sessions │
88
+ │ │ + Multi-agent routing │
89
+ │ │ + Gateway & fan-out │
90
+ │ │ + Multi-tenancy │
91
+ │ │ + HTTP API & CLI │
92
+ │ │ + Hooks & policies │
93
+ └──────────────────────────────────────────────────────────┘
94
+ ```
95
+
96
+ ## What Karta provides
97
+
98
+ | Feature | Description |
99
+ |---------|-------------|
100
+ | **Multi-agent routing** | Discover and route to specialist agents defined in your harness's native format |
101
+ | **Multi-user sessions** | Route conversations by metadata (customer ID, channel, etc.) with automatic persistence |
102
+ | **Participant model** | Multiple humans and AI agents in the same session with message attribution |
103
+ | **Gateway & fan-out** | Unified event ingestion with fan-out delivery to all session participants |
104
+ | **Cross-instance messaging** | Agents on different Karta instances communicate via gateway HTTP POST |
105
+ | **Multi-tenancy** | Workspace-per-user isolation with `KartaHub` orchestrator |
106
+ | **Session persistence** | SQLite (default), PostgreSQL, or S3 backends |
107
+ | **Lifecycle hooks** | Events on `message.received`, `message.completed`, `agent.handoff`, `session.created` |
108
+ | **Policy enforcement** | Validate messages against configurable policies (length limits, message counts, keyword gates) |
109
+ | **HTTP API** | Production-ready FastAPI server with REST endpoints and SSE streaming |
110
+ | **Internal CLI** | `karta-runtime dev/dev-serve/serve` - streaming terminal REPL and the local/self-host serve planes (the public CLI is `@karta.sh/cli`) |
111
+ | **Typed streaming** | Structured events: `text`, `tool_use`, `reasoning`, `step_start`, `step_finish`, `error`, `input_required` |
112
+
113
+ ## Install
114
+
115
+ ```bash
116
+ pip install karta-runtime
117
+ ```
118
+
119
+ With optional backends:
120
+
121
+ ```bash
122
+ pip install karta-runtime[postgres] # PostgreSQL sessions
123
+ pip install karta-runtime[s3] # S3 sessions
124
+ ```
125
+
126
+ You also need a coding agent harness installed:
127
+
128
+ - **Claude Code**: `npm install -g @anthropic-ai/claude-code` ([docs](https://docs.anthropic.com/en/docs/claude-code))
129
+ - **OpenCode**: `curl -fsSL https://opencode.ai/install | bash` ([docs](https://opencode.ai))
130
+
131
+ ## Quickstart
132
+
133
+ ### Zero-config hello world
134
+
135
+ ```python
136
+ from karta import Karta
137
+
138
+ app = Karta()
139
+ response = app.send_sync("Hello!")
140
+ print(response.text)
141
+ ```
142
+
143
+ Karta auto-detects your harness from the project directory (`.claude/` → Claude Code, `.opencode/` → OpenCode).
144
+
145
+ ### Multi-turn sessions
146
+
147
+ ```python
148
+ from karta import Karta
149
+
150
+ app = Karta()
151
+
152
+ session = app.session(metadata={"customer_id": "abc123"})
153
+ response = session.send_sync("I need help with my order")
154
+ response = session.send_sync("Order #12345")
155
+
156
+ # Resume later by looking up the session
157
+ session = app.session(metadata={"customer_id": "abc123"})
158
+ response = session.send_sync("Any updates?")
159
+ ```
160
+
161
+ ### Multi-agent routing
162
+
163
+ Define specialist agents in your harness's native format (`.claude/agents/*.md` or `.opencode/agents/*.md`), then route:
164
+
165
+ ```python
166
+ from karta import Karta
167
+
168
+ app = Karta()
169
+
170
+ # Route to a specific agent
171
+ response = app.send_sync("Audit my billing", agent="billing-specialist")
172
+
173
+ # Agent handoff within a session
174
+ session = app.session(metadata={"customer_id": "abc123"})
175
+ session.send_sync("I need help with my order") # → default agent
176
+ session.current_agent = app.agents["billing"] # handoff
177
+ session.send_sync("Check invoice #789") # → billing agent
178
+ ```
179
+
180
+ ### Multi-participant sessions
181
+
182
+ ```python
183
+ from karta import Karta, HumanAgent
184
+
185
+ app = Karta()
186
+ session = app.session()
187
+
188
+ alice = HumanAgent(name="alice", display_name="Alice Chen")
189
+ bob = HumanAgent(name="bob", display_name="Bob Park")
190
+
191
+ # Messages are attributed to the sending participant
192
+ session.send_sync("I need help with deployment", participant=alice)
193
+ session.send_sync("I can help — what's the error?", participant=bob)
194
+ ```
195
+
196
+ ### Streaming
197
+
198
+ ```python
199
+ import asyncio
200
+ from karta import Karta
201
+
202
+ async def main():
203
+ app = Karta()
204
+ async for event in app.stream("Explain quicksort"):
205
+ if event.type == "text":
206
+ print(event.text, end="", flush=True)
207
+
208
+ asyncio.run(main())
209
+ ```
210
+
211
+ ### HTTP API
212
+
213
+ ```python
214
+ from karta import Karta
215
+ from karta.server import create_fastapi_app
216
+ import uvicorn
217
+
218
+ app = Karta()
219
+ fastapi_app = create_fastapi_app(app)
220
+ uvicorn.run(fastapi_app, host="0.0.0.0", port=8000)
221
+ ```
222
+
223
+ This exposes:
224
+
225
+ - `POST /v1/send` — send a message, get a response
226
+ - `POST /v1/stream` — send a message, get SSE stream
227
+ - `POST /v1/sessions` — create a session
228
+ - `GET /v1/sessions` — list/lookup sessions
229
+ - `POST /v1/sessions/{id}/messages` — send within a session
230
+ - `POST /v1/sessions/{id}/input/respond` — respond to approval prompts
231
+ - `POST /v1/gateway/submit` — submit a gateway event
232
+ - `POST /v1/gateway/deliver` — deliver to a local participant
233
+ - `GET /healthz` — health check
234
+
235
+ ### Multi-tenancy
236
+
237
+ ```python
238
+ from karta import KartaHub
239
+
240
+ hub = KartaHub("/path/to/karta-root")
241
+
242
+ # Each tenant/user gets an isolated workspace
243
+ session = hub.session("acme", "alice", metadata={"topic": "billing"})
244
+ response = session.send_sync("Help with invoice")
245
+ ```
246
+
247
+ ### Lifecycle hooks
248
+
249
+ ```python
250
+ app = Karta()
251
+
252
+ @app.on("message.completed")
253
+ async def log_response(event):
254
+ print(f"Session {event.session.id}: {event.message.text}")
255
+
256
+ @app.on("agent.handoff")
257
+ async def track_handoff(event):
258
+ print(f"Handoff: {event.payload['from']} → {event.payload['to']}")
259
+ ```
260
+
261
+ ### CLI (internal)
262
+
263
+ The customer-facing CLI is `@karta.sh/cli`; this package's verbs are internal
264
+ (local platform dev, self-host):
265
+
266
+ ```bash
267
+ karta-runtime dev <path> # Hot-reload REPL against a folder
268
+ karta-runtime dev-serve <path> # Serve a folder behind the consumer session API
269
+ # (what the unified CLI's `karta dev` spawns)
270
+ karta-runtime serve # The platform serve plane (self-host / dev-infra)
271
+ ```
272
+
273
+ This package installs no `karta` script at all - that name belongs to
274
+ the unified CLI (`npm install -g @karta.sh/cli`). It was dropped rather
275
+ than shimmed: karta-python never shipped to PyPI, so there is no
276
+ installed base to point anywhere.
277
+
278
+ ## Architecture
279
+
280
+ ```
281
+ External Clients / Other Karta Instances
282
+
283
+ ┌─────────▼──────────┐
284
+ │ Gateway │ event ingestion, fan-out delivery
285
+ │ Local · HTTP │ cross-instance messaging
286
+ └─────────┬──────────┘
287
+
288
+ ┌─────────▼──────────┐
289
+ │ Client Layer │ HTTP API · CLI · Python SDK
290
+ └─────────┬──────────┘
291
+
292
+ ┌─────────▼──────────┐
293
+ │ Multi-Tenancy │ KartaHub → WorkspaceManager
294
+ └─────────┬──────────┘
295
+
296
+ ┌─────────▼──────────┐
297
+ │ Karta Core │ sessions, agents, policies,
298
+ │ │ hooks, participants
299
+ └─────────┬──────────┘
300
+
301
+ ┌─────────▼──────────┐
302
+ │ Harness Layer │ Claude Code (SDK) or
303
+ │ │ OpenCode (CLI subprocess)
304
+ └─────────┬──────────┘
305
+
306
+ ┌─────────▼──────────┐
307
+ │ Coding Agent │ tools, MCP, context,
308
+ │ │ memory, skills
309
+ └──────────────────────┘
310
+ ```
311
+
312
+ ### Design principles
313
+
314
+ - **Convention over configuration** — follows your harness's folder conventions
315
+ - **Progressive disclosure** — start with 3 lines, add features as you need them
316
+ - **Harness-native** — agents are defined in `.claude/agents/*.md` or `.opencode/agents/*.md`, not reinvented
317
+ - **Zero abstraction tax** — examples from harness docs work as-is inside Karta
318
+
319
+ ## Progressive examples
320
+
321
+ The [`examples/`](examples/) directory walks through increasing levels of complexity:
322
+
323
+ | Level | Directory | What it demonstrates |
324
+ |-------|-----------|---------------------|
325
+ | 0 | `level-0-zero-config/` | No config needed — just `app.send()` |
326
+ | 1 | `level-1-project-context/` | Project context with `AGENTS.md` / `.opencode` |
327
+ | 1 | `level-1-project-context-claude-code/` | Same, using Claude Code |
328
+ | 2 | `level-2-custom-agent/` | Single agent with a custom skill |
329
+ | 2 | `level-2-custom-agent-claude-code/` | Same, using Claude Code |
330
+ | 3 | `level-3-multiple-agents/` | Multi-agent routing |
331
+ | 4 | `level-4-multi-turn-sessions/` | Session persistence and metadata lookup |
332
+ | 5 | `level-5-hooks-policies/` | Lifecycle hooks and policy enforcement |
333
+
334
+ ## Configuration
335
+
336
+ Karta uses your harness's native agent definitions as the source of truth. Optional Karta-specific settings go in `karta.jsonc`:
337
+
338
+ ```jsonc
339
+ {
340
+ "cli": {
341
+ "hidden_event_types": ["system"],
342
+ "input_required_policy": "prompt"
343
+ },
344
+ "harness": {
345
+ "claude": {
346
+ "idle_timeout_seconds": 600,
347
+ "permission_intercept": false
348
+ }
349
+ }
350
+ }
351
+ ```
352
+
353
+ See [`examples/configurations/`](examples/configurations/) for copy-ready templates.
354
+
355
+ ## Supported harnesses
356
+
357
+ | Harness | Adapter | Detection |
358
+ |---------|---------|-----------|
359
+ | Claude Code | `ClaudeAdapter` (via Claude SDK) | `.claude/` directory or `CLAUDE.md` |
360
+ | OpenCode | `OpenCodeAdapter` (via `opencode run`) | `.opencode/` directory |
361
+
362
+ Adding a new harness means implementing one `HarnessAdapter` class.
363
+
364
+ ## Documentation
365
+
366
+ Design documents and implementation specs live in [`dev/`](dev/):
367
+
368
+ - [Architecture](dev/ARCHITECTURE.md) — system architecture reference
369
+ - [Design document](dev/2026-02-12-karta-design-doc.md) — architecture and design philosophy
370
+ - [Implementation spec](dev/2026-02-13-karta-implementation-spec.md) — detailed implementation reference
371
+ - [CLI spec](dev/2026-02-13-karta-cli.md) — CLI commands and options
372
+ - [HTTP API spec](dev/2026-02-13-karta-http-api.md) — REST endpoint reference
373
+ - [Gateway implementation plan](dev/2026-02-14-gateway-implementation-plan.md) — gateway system design
374
+ - [Multi-tenancy architecture](dev/2026-02-14-multi-tenancy-architecture.md) — workspace isolation deep dive
375
+ - [Phase status](dev/phase-status.md) — implementation progress tracking
376
+
377
+ ## Development
378
+
379
+ ```bash
380
+ # Install dependencies
381
+ poetry install --all-extras
382
+
383
+ # Run tests
384
+ poetry run pytest
385
+
386
+ # Lint
387
+ poetry run ruff check src/ tests/
388
+
389
+ # Type check
390
+ poetry run mypy src/karta/
391
+ ```
392
+
393
+ ## License
394
+
395
+ This project is licensed under the MIT License — see the [LICENSE](LICENSE) file for details.
396
+