gitclaw 0.3.0

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 (58) hide show
  1. package/README.md +440 -0
  2. package/dist/agents.d.ts +8 -0
  3. package/dist/agents.js +82 -0
  4. package/dist/audit.d.ts +27 -0
  5. package/dist/audit.js +55 -0
  6. package/dist/compliance.d.ts +30 -0
  7. package/dist/compliance.js +108 -0
  8. package/dist/config.d.ts +11 -0
  9. package/dist/config.js +43 -0
  10. package/dist/examples.d.ts +6 -0
  11. package/dist/examples.js +40 -0
  12. package/dist/exports.d.ts +13 -0
  13. package/dist/exports.js +6 -0
  14. package/dist/hooks.d.ts +24 -0
  15. package/dist/hooks.js +108 -0
  16. package/dist/index.d.ts +2 -0
  17. package/dist/index.js +542 -0
  18. package/dist/knowledge.d.ts +17 -0
  19. package/dist/knowledge.js +55 -0
  20. package/dist/loader.d.ts +64 -0
  21. package/dist/loader.js +222 -0
  22. package/dist/sandbox.d.ts +28 -0
  23. package/dist/sandbox.js +54 -0
  24. package/dist/sdk-hooks.d.ts +8 -0
  25. package/dist/sdk-hooks.js +31 -0
  26. package/dist/sdk-types.d.ts +127 -0
  27. package/dist/sdk-types.js +1 -0
  28. package/dist/sdk.d.ts +6 -0
  29. package/dist/sdk.js +444 -0
  30. package/dist/session.d.ts +15 -0
  31. package/dist/session.js +127 -0
  32. package/dist/skills.d.ts +18 -0
  33. package/dist/skills.js +104 -0
  34. package/dist/tool-loader.d.ts +3 -0
  35. package/dist/tool-loader.js +138 -0
  36. package/dist/tools/cli.d.ts +3 -0
  37. package/dist/tools/cli.js +86 -0
  38. package/dist/tools/index.d.ts +13 -0
  39. package/dist/tools/index.js +29 -0
  40. package/dist/tools/memory.d.ts +3 -0
  41. package/dist/tools/memory.js +128 -0
  42. package/dist/tools/read.d.ts +3 -0
  43. package/dist/tools/read.js +46 -0
  44. package/dist/tools/sandbox-cli.d.ts +4 -0
  45. package/dist/tools/sandbox-cli.js +48 -0
  46. package/dist/tools/sandbox-memory.d.ts +4 -0
  47. package/dist/tools/sandbox-memory.js +117 -0
  48. package/dist/tools/sandbox-read.d.ts +4 -0
  49. package/dist/tools/sandbox-read.js +25 -0
  50. package/dist/tools/sandbox-write.d.ts +4 -0
  51. package/dist/tools/sandbox-write.js +26 -0
  52. package/dist/tools/shared.d.ts +38 -0
  53. package/dist/tools/shared.js +69 -0
  54. package/dist/tools/write.d.ts +3 -0
  55. package/dist/tools/write.js +28 -0
  56. package/dist/workflows.d.ts +8 -0
  57. package/dist/workflows.js +81 -0
  58. package/package.json +57 -0
package/README.md ADDED
@@ -0,0 +1,440 @@
1
+ <p align="center">
2
+ <img src="https://img.shields.io/npm/v/gitclaw?style=flat-square&color=blue" alt="npm version" />
3
+ <img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen?style=flat-square" alt="node version" />
4
+ <img src="https://img.shields.io/github/license/open-gitagent/gitclaw?style=flat-square" alt="license" />
5
+ <img src="https://img.shields.io/badge/TypeScript-5.7-blue?style=flat-square&logo=typescript&logoColor=white" alt="typescript" />
6
+ </p>
7
+
8
+ <h1 align="center">Gitclaw</h1>
9
+
10
+ <p align="center">
11
+ <strong>A universal git-native AI agent framework.</strong><br/>
12
+ Your agent lives inside a git repo — identity, rules, memory, tools, and skills are all version-controlled files.
13
+ </p>
14
+
15
+ <p align="center">
16
+ <a href="#quick-start">Quick Start</a> &bull;
17
+ <a href="#sdk">SDK</a> &bull;
18
+ <a href="#architecture">Architecture</a> &bull;
19
+ <a href="#tools">Tools</a> &bull;
20
+ <a href="#hooks">Hooks</a> &bull;
21
+ <a href="#skills">Skills</a>
22
+ </p>
23
+
24
+ ---
25
+
26
+ ## Why Gitclaw?
27
+
28
+ Most agent frameworks treat configuration as code scattered across your application. Gitclaw flips this — **your agent IS a git repository**:
29
+
30
+ - **`agent.yaml`** — model, tools, runtime config
31
+ - **`SOUL.md`** — personality and identity
32
+ - **`RULES.md`** — behavioral constraints
33
+ - **`memory/`** — git-committed memory with full history
34
+ - **`tools/`** — declarative YAML tool definitions
35
+ - **`skills/`** — composable skill modules
36
+ - **`hooks/`** — lifecycle hooks (script or programmatic)
37
+
38
+ Fork an agent. Branch a personality. `git log` your agent's memory. Diff its rules. This is **agents as repos**.
39
+
40
+ ## Quick Start
41
+
42
+ ### CLI
43
+
44
+ ```bash
45
+ npm install -g gitclaw
46
+
47
+ # Set your API key
48
+ export OPENAI_API_KEY="sk-..."
49
+ # or: export ANTHROPIC_API_KEY="sk-ant-..."
50
+
51
+ # Point gitclaw at any directory — it handles everything
52
+ gitclaw --dir ~/my-project
53
+ ```
54
+
55
+ That's it. Gitclaw auto-scaffolds everything on first run:
56
+ - `git init` if not already a repo
57
+ - Creates `agent.yaml`, `SOUL.md`, `memory/MEMORY.md`
58
+ - Commits the scaffold
59
+ - Drops you into the REPL
60
+
61
+ ```
62
+ ? Repository path (. for current dir): ~/my-project
63
+ Initializing git repository...
64
+ Created agent.yaml (model: openai:gpt-4o-mini)
65
+ my-project v0.1.0
66
+ Model: openai:gpt-4o-mini
67
+ Tools: cli, read, write, memory
68
+ → List all files and explain the project
69
+ ```
70
+
71
+ Or run without `--dir` and it will ask you interactively:
72
+
73
+ ```bash
74
+ gitclaw
75
+ ```
76
+
77
+ Single-shot mode:
78
+
79
+ ```bash
80
+ gitclaw --dir ~/my-project -p "Create a hello world script"
81
+ ```
82
+
83
+ ### SDK
84
+
85
+ ```bash
86
+ npm install gitclaw
87
+ ```
88
+
89
+ ```typescript
90
+ import { query, tool } from "gitclaw";
91
+
92
+ // Simple query
93
+ for await (const msg of query({
94
+ prompt: "List all TypeScript files and summarize them",
95
+ dir: "./my-agent",
96
+ model: "openai:gpt-4o-mini",
97
+ })) {
98
+ if (msg.type === "delta") process.stdout.write(msg.content);
99
+ if (msg.type === "assistant") console.log("\n\nDone.");
100
+ }
101
+ ```
102
+
103
+ ## SDK
104
+
105
+ The SDK provides a programmatic interface to Gitclaw agents. It mirrors the [Claude Agent SDK](https://github.com/anthropics/claude-code-sdk) pattern but runs **in-process** — no subprocesses, no IPC.
106
+
107
+ ### `query(options): Query`
108
+
109
+ Returns an `AsyncGenerator<GCMessage>` that streams agent events.
110
+
111
+ ```typescript
112
+ import { query } from "gitclaw";
113
+
114
+ for await (const msg of query({
115
+ prompt: "Refactor the auth module",
116
+ dir: "/path/to/agent",
117
+ model: "anthropic:claude-sonnet-4-5-20250929",
118
+ })) {
119
+ switch (msg.type) {
120
+ case "delta": // streaming text chunk
121
+ process.stdout.write(msg.content);
122
+ break;
123
+ case "assistant": // complete response
124
+ console.log(`\nTokens: ${msg.usage?.totalTokens}`);
125
+ break;
126
+ case "tool_use": // tool invocation
127
+ console.log(`Tool: ${msg.toolName}(${JSON.stringify(msg.args)})`);
128
+ break;
129
+ case "tool_result": // tool output
130
+ console.log(`Result: ${msg.content}`);
131
+ break;
132
+ case "system": // lifecycle events & errors
133
+ console.log(`[${msg.subtype}] ${msg.content}`);
134
+ break;
135
+ }
136
+ }
137
+ ```
138
+
139
+ ### `tool(name, description, schema, handler): GCToolDefinition`
140
+
141
+ Define custom tools the agent can call:
142
+
143
+ ```typescript
144
+ import { query, tool } from "gitclaw";
145
+
146
+ const search = tool(
147
+ "search_docs",
148
+ "Search the documentation",
149
+ {
150
+ properties: {
151
+ query: { type: "string", description: "Search query" },
152
+ limit: { type: "number", description: "Max results" },
153
+ },
154
+ required: ["query"],
155
+ },
156
+ async (args) => {
157
+ const results = await mySearchEngine(args.query, args.limit ?? 10);
158
+ return { text: JSON.stringify(results), details: { count: results.length } };
159
+ },
160
+ );
161
+
162
+ for await (const msg of query({
163
+ prompt: "Find docs about authentication",
164
+ tools: [search],
165
+ })) {
166
+ // agent can now call search_docs
167
+ }
168
+ ```
169
+
170
+ ### Hooks
171
+
172
+ Programmatic lifecycle hooks for gating, logging, and control:
173
+
174
+ ```typescript
175
+ for await (const msg of query({
176
+ prompt: "Deploy the service",
177
+ hooks: {
178
+ preToolUse: async (ctx) => {
179
+ // Block dangerous operations
180
+ if (ctx.toolName === "cli" && ctx.args.command?.includes("rm -rf"))
181
+ return { action: "block", reason: "Destructive command blocked" };
182
+
183
+ // Modify arguments
184
+ if (ctx.toolName === "write" && !ctx.args.path.startsWith("/safe/"))
185
+ return { action: "modify", args: { ...ctx.args, path: `/safe/${ctx.args.path}` } };
186
+
187
+ return { action: "allow" };
188
+ },
189
+ onError: async (ctx) => {
190
+ console.error(`Agent error: ${ctx.error}`);
191
+ },
192
+ },
193
+ })) {
194
+ // ...
195
+ }
196
+ ```
197
+
198
+ ### QueryOptions Reference
199
+
200
+ | Option | Type | Description |
201
+ |---|---|---|
202
+ | `prompt` | `string \| AsyncIterable` | User prompt or multi-turn stream |
203
+ | `dir` | `string` | Agent directory (default: `cwd`) |
204
+ | `model` | `string` | `"provider:model-id"` |
205
+ | `env` | `string` | Environment config (`config/<env>.yaml`) |
206
+ | `systemPrompt` | `string` | Override discovered system prompt |
207
+ | `systemPromptSuffix` | `string` | Append to discovered system prompt |
208
+ | `tools` | `GCToolDefinition[]` | Additional tools |
209
+ | `replaceBuiltinTools` | `boolean` | Skip cli/read/write/memory |
210
+ | `allowedTools` | `string[]` | Tool name allowlist |
211
+ | `disallowedTools` | `string[]` | Tool name denylist |
212
+ | `hooks` | `GCHooks` | Programmatic lifecycle hooks |
213
+ | `maxTurns` | `number` | Max agent turns |
214
+ | `abortController` | `AbortController` | Cancellation signal |
215
+ | `constraints` | `object` | `temperature`, `maxTokens`, `topP`, `topK` |
216
+
217
+ ### Message Types
218
+
219
+ | Type | Description | Key Fields |
220
+ |---|---|---|
221
+ | `delta` | Streaming text/thinking chunk | `deltaType`, `content` |
222
+ | `assistant` | Complete LLM response | `content`, `model`, `usage`, `stopReason` |
223
+ | `tool_use` | Tool invocation | `toolName`, `args`, `toolCallId` |
224
+ | `tool_result` | Tool output | `content`, `isError`, `toolCallId` |
225
+ | `system` | Lifecycle events | `subtype`, `content`, `metadata` |
226
+ | `user` | User message (multi-turn) | `content` |
227
+
228
+ ## Architecture
229
+
230
+ ```
231
+ my-agent/
232
+ ├── agent.yaml # Model, tools, runtime config
233
+ ├── SOUL.md # Agent identity & personality
234
+ ├── RULES.md # Behavioral rules & constraints
235
+ ├── DUTIES.md # Role-specific responsibilities
236
+ ├── memory/
237
+ │ └── MEMORY.md # Git-committed agent memory
238
+ ├── tools/
239
+ │ └── *.yaml # Declarative tool definitions
240
+ ├── skills/
241
+ │ └── <name>/
242
+ │ ├── SKILL.md # Skill instructions (YAML frontmatter)
243
+ │ └── scripts/ # Skill scripts
244
+ ├── workflows/
245
+ │ └── *.yaml|*.md # Multi-step workflow definitions
246
+ ├── agents/
247
+ │ └── <name>/ # Sub-agent definitions
248
+ ├── hooks/
249
+ │ └── hooks.yaml # Lifecycle hook scripts
250
+ ├── knowledge/
251
+ │ └── index.yaml # Knowledge base entries
252
+ ├── config/
253
+ │ ├── default.yaml # Default environment config
254
+ │ └── <env>.yaml # Environment overrides
255
+ ├── examples/
256
+ │ └── *.md # Few-shot examples
257
+ └── compliance/
258
+ └── *.yaml # Compliance & audit config
259
+ ```
260
+
261
+ ### Agent Manifest (`agent.yaml`)
262
+
263
+ ```yaml
264
+ spec_version: "0.1.0"
265
+ name: my-agent
266
+ version: 1.0.0
267
+ description: An agent that does things
268
+
269
+ model:
270
+ preferred: "anthropic:claude-sonnet-4-5-20250929"
271
+ fallback: ["openai:gpt-4o"]
272
+ constraints:
273
+ temperature: 0.7
274
+ max_tokens: 4096
275
+
276
+ tools: [cli, read, write, memory]
277
+
278
+ runtime:
279
+ max_turns: 50
280
+ timeout: 120
281
+
282
+ # Optional
283
+ extends: "https://github.com/org/base-agent.git"
284
+ skills: [code-review, deploy]
285
+ delegation:
286
+ mode: auto
287
+ compliance:
288
+ risk_level: medium
289
+ human_in_the_loop: true
290
+ ```
291
+
292
+ ## Tools
293
+
294
+ ### Built-in Tools
295
+
296
+ | Tool | Description |
297
+ |---|---|
298
+ | `cli` | Execute shell commands |
299
+ | `read` | Read files with pagination |
300
+ | `write` | Write/create files |
301
+ | `memory` | Load/save git-committed memory |
302
+
303
+ ### Declarative Tools
304
+
305
+ Define tools as YAML in `tools/`:
306
+
307
+ ```yaml
308
+ # tools/search.yaml
309
+ name: search
310
+ description: Search the codebase
311
+ input_schema:
312
+ properties:
313
+ query:
314
+ type: string
315
+ description: Search query
316
+ path:
317
+ type: string
318
+ description: Directory to search
319
+ required: [query]
320
+ implementation:
321
+ script: search.sh
322
+ runtime: sh
323
+ ```
324
+
325
+ The script receives args as JSON on stdin and returns output on stdout.
326
+
327
+ ## Hooks
328
+
329
+ Script-based hooks in `hooks/hooks.yaml`:
330
+
331
+ ```yaml
332
+ hooks:
333
+ on_session_start:
334
+ - script: validate-env.sh
335
+ description: Check environment is ready
336
+ pre_tool_use:
337
+ - script: audit-tools.sh
338
+ description: Log and gate tool usage
339
+ post_response:
340
+ - script: notify.sh
341
+ on_error:
342
+ - script: alert.sh
343
+ ```
344
+
345
+ Hook scripts receive context as JSON on stdin and return:
346
+
347
+ ```json
348
+ { "action": "allow" }
349
+ { "action": "block", "reason": "Not permitted" }
350
+ { "action": "modify", "args": { "modified": "args" } }
351
+ ```
352
+
353
+ ## Skills
354
+
355
+ Skills are composable instruction modules in `skills/<name>/`:
356
+
357
+ ```
358
+ skills/
359
+ code-review/
360
+ SKILL.md
361
+ scripts/
362
+ lint.sh
363
+ ```
364
+
365
+ ```markdown
366
+ ---
367
+ name: code-review
368
+ description: Review code for quality and security
369
+ ---
370
+
371
+ # Code Review
372
+
373
+ When reviewing code:
374
+ 1. Check for security vulnerabilities
375
+ 2. Verify error handling
376
+ 3. Run the lint script for style checks
377
+ ```
378
+
379
+ Invoke via CLI: `/skill:code-review Review the auth module`
380
+
381
+ ## Multi-Model Support
382
+
383
+ Gitclaw works with any LLM provider supported by [pi-ai](https://github.com/nicepkg/pi-ai):
384
+
385
+ ```yaml
386
+ # agent.yaml
387
+ model:
388
+ preferred: "anthropic:claude-sonnet-4-5-20250929"
389
+ fallback:
390
+ - "openai:gpt-4o"
391
+ - "google:gemini-2.0-flash"
392
+ ```
393
+
394
+ Supported providers: `anthropic`, `openai`, `google`, `xai`, `groq`, `mistral`, and more.
395
+
396
+ ## Inheritance & Composition
397
+
398
+ Agents can extend base agents:
399
+
400
+ ```yaml
401
+ # agent.yaml
402
+ extends: "https://github.com/org/base-agent.git"
403
+
404
+ # Dependencies
405
+ dependencies:
406
+ - name: shared-tools
407
+ source: "https://github.com/org/shared-tools.git"
408
+ version: main
409
+ mount: tools
410
+
411
+ # Sub-agents
412
+ delegation:
413
+ mode: auto
414
+ ```
415
+
416
+ ## Compliance & Audit
417
+
418
+ Built-in compliance validation and audit logging:
419
+
420
+ ```yaml
421
+ # agent.yaml
422
+ compliance:
423
+ risk_level: high
424
+ human_in_the_loop: true
425
+ data_classification: confidential
426
+ regulatory_frameworks: [SOC2, GDPR]
427
+ recordkeeping:
428
+ audit_logging: true
429
+ retention_days: 90
430
+ ```
431
+
432
+ Audit logs are written to `.gitagent/audit.jsonl` with full tool invocation traces.
433
+
434
+ ## Contributing
435
+
436
+ Contributions are welcome! Please open an issue or submit a pull request.
437
+
438
+ ## License
439
+
440
+ MIT
@@ -0,0 +1,8 @@
1
+ export interface SubAgentMetadata {
2
+ name: string;
3
+ description: string;
4
+ type: "directory" | "file";
5
+ path: string;
6
+ }
7
+ export declare function discoverSubAgents(agentDir: string): Promise<SubAgentMetadata[]>;
8
+ export declare function formatSubAgentsForPrompt(agents: SubAgentMetadata[]): string;
package/dist/agents.js ADDED
@@ -0,0 +1,82 @@
1
+ import { readFile, readdir, stat } from "fs/promises";
2
+ import { join } from "path";
3
+ import yaml from "js-yaml";
4
+ function parseFrontmatter(content) {
5
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
6
+ if (!match) {
7
+ return { frontmatter: {}, body: content };
8
+ }
9
+ const frontmatter = yaml.load(match[1]);
10
+ return { frontmatter, body: match[2] };
11
+ }
12
+ export async function discoverSubAgents(agentDir) {
13
+ const agentsDir = join(agentDir, "agents");
14
+ try {
15
+ const s = await stat(agentsDir);
16
+ if (!s.isDirectory())
17
+ return [];
18
+ }
19
+ catch {
20
+ return [];
21
+ }
22
+ const entries = await readdir(agentsDir, { withFileTypes: true });
23
+ const agents = [];
24
+ for (const entry of entries) {
25
+ const entryPath = join(agentsDir, entry.name);
26
+ if (entry.isDirectory()) {
27
+ // Directory form: agents/<name>/agent.yaml
28
+ const agentYamlPath = join(entryPath, "agent.yaml");
29
+ try {
30
+ const raw = await readFile(agentYamlPath, "utf-8");
31
+ const data = yaml.load(raw);
32
+ if (data?.name && data?.description) {
33
+ agents.push({
34
+ name: data.name,
35
+ description: data.description,
36
+ type: "directory",
37
+ path: `agents/${entry.name}`,
38
+ });
39
+ }
40
+ }
41
+ catch {
42
+ // Skip directories without valid agent.yaml
43
+ }
44
+ }
45
+ else if (entry.name.endsWith(".md") && entry.isFile()) {
46
+ // File form: agents/<name>.md
47
+ try {
48
+ const raw = await readFile(entryPath, "utf-8");
49
+ const { frontmatter } = parseFrontmatter(raw);
50
+ const name = frontmatter.name || entry.name.replace(/\.md$/, "");
51
+ const description = frontmatter.description || "";
52
+ if (description) {
53
+ agents.push({
54
+ name,
55
+ description,
56
+ type: "file",
57
+ path: `agents/${entry.name}`,
58
+ });
59
+ }
60
+ }
61
+ catch {
62
+ // Skip unreadable files
63
+ }
64
+ }
65
+ }
66
+ return agents.sort((a, b) => a.name.localeCompare(b.name));
67
+ }
68
+ export function formatSubAgentsForPrompt(agents) {
69
+ if (agents.length === 0)
70
+ return "";
71
+ const entries = agents
72
+ .map((a) => `<agent>\n<name>${a.name}</name>\n<description>${a.description}</description>\n<type>${a.type}</type>\n<path>${a.path}</path>\n</agent>`)
73
+ .join("\n");
74
+ return `# Sub-Agents
75
+
76
+ <available_agents>
77
+ ${entries}
78
+ </available_agents>
79
+
80
+ To delegate to a sub-agent, use the \`cli\` tool to run: \`gitclaw --dir ${"{agent_path}"} -p "task description"\`
81
+ For file-based agents, use the \`read\` tool to load their instructions.`;
82
+ }
@@ -0,0 +1,27 @@
1
+ export interface AuditEntry {
2
+ timestamp: string;
3
+ session_id: string;
4
+ event: string;
5
+ tool?: string;
6
+ args?: Record<string, any>;
7
+ result?: string;
8
+ error?: string;
9
+ [key: string]: any;
10
+ }
11
+ export declare class AuditLogger {
12
+ private logPath;
13
+ private sessionId;
14
+ private enabled;
15
+ constructor(gitagentDir: string, sessionId: string, enabled: boolean);
16
+ log(event: string, data?: Partial<AuditEntry>): Promise<void>;
17
+ logToolUse(tool: string, args: Record<string, any>): Promise<void>;
18
+ logToolResult(tool: string, result: string): Promise<void>;
19
+ logResponse(): Promise<void>;
20
+ logError(error: string): Promise<void>;
21
+ logSessionStart(): Promise<void>;
22
+ logSessionEnd(): Promise<void>;
23
+ }
24
+ /**
25
+ * Check if audit logging is enabled via compliance config.
26
+ */
27
+ export declare function isAuditEnabled(compliance?: Record<string, any>): boolean;
package/dist/audit.js ADDED
@@ -0,0 +1,55 @@
1
+ import { appendFile, mkdir } from "fs/promises";
2
+ import { join, dirname } from "path";
3
+ export class AuditLogger {
4
+ logPath;
5
+ sessionId;
6
+ enabled;
7
+ constructor(gitagentDir, sessionId, enabled) {
8
+ this.logPath = join(gitagentDir, "audit.jsonl");
9
+ this.sessionId = sessionId;
10
+ this.enabled = enabled;
11
+ }
12
+ async log(event, data = {}) {
13
+ if (!this.enabled)
14
+ return;
15
+ const entry = {
16
+ timestamp: new Date().toISOString(),
17
+ session_id: this.sessionId,
18
+ event,
19
+ ...data,
20
+ };
21
+ try {
22
+ await mkdir(dirname(this.logPath), { recursive: true });
23
+ await appendFile(this.logPath, JSON.stringify(entry) + "\n", "utf-8");
24
+ }
25
+ catch {
26
+ // Audit logging failures are non-fatal
27
+ }
28
+ }
29
+ async logToolUse(tool, args) {
30
+ await this.log("tool_use", { tool, args });
31
+ }
32
+ async logToolResult(tool, result) {
33
+ await this.log("tool_result", { tool, result: result.slice(0, 1000) });
34
+ }
35
+ async logResponse() {
36
+ await this.log("response");
37
+ }
38
+ async logError(error) {
39
+ await this.log("error", { error });
40
+ }
41
+ async logSessionStart() {
42
+ await this.log("session_start");
43
+ }
44
+ async logSessionEnd() {
45
+ await this.log("session_end");
46
+ }
47
+ }
48
+ /**
49
+ * Check if audit logging is enabled via compliance config.
50
+ */
51
+ export function isAuditEnabled(compliance) {
52
+ if (!compliance)
53
+ return false;
54
+ return compliance.recordkeeping?.audit_logging === true;
55
+ }
@@ -0,0 +1,30 @@
1
+ import type { AgentManifest } from "./loader.js";
2
+ export interface ComplianceConfig {
3
+ risk_level?: "low" | "medium" | "high" | "critical";
4
+ human_in_the_loop?: boolean;
5
+ data_classification?: string;
6
+ regulatory_frameworks?: string[];
7
+ recordkeeping?: {
8
+ audit_logging?: boolean;
9
+ retention_days?: number;
10
+ };
11
+ review?: {
12
+ required_approvers?: number;
13
+ auto_review?: boolean;
14
+ };
15
+ [key: string]: any;
16
+ }
17
+ export interface ComplianceWarning {
18
+ rule: string;
19
+ message: string;
20
+ severity: "error" | "warning";
21
+ }
22
+ /**
23
+ * Validate compliance section of agent manifest against spec rules.
24
+ */
25
+ export declare function validateCompliance(manifest: AgentManifest): ComplianceWarning[];
26
+ /**
27
+ * Load compliance directory files and format summary for system prompt.
28
+ */
29
+ export declare function loadComplianceContext(agentDir: string): Promise<string>;
30
+ export declare function formatComplianceWarnings(warnings: ComplianceWarning[]): string;