@aryaminus/controlkeel-opencode 0.2.18 → 0.2.19
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.
- package/.opencode/skills/agent-integration/SKILL.md +49 -0
- package/.opencode/skills/agent-integration/agents/openai.yaml +11 -0
- package/.opencode/skills/agent-integration/references/target-matrix.md +21 -0
- package/.opencode/skills/benchmark-operator/SKILL.md +33 -0
- package/.opencode/skills/benchmark-operator/agents/openai.yaml +12 -0
- package/.opencode/skills/benchmark-operator/references/benchmark-playbook.md +6 -0
- package/.opencode/skills/cloudflare-agent/SKILL.md +366 -0
- package/.opencode/skills/cloudflare-agent/references/cloudflare-integration.md +226 -0
- package/.opencode/skills/compliance-audit/SKILL.md +34 -0
- package/.opencode/skills/compliance-audit/agents/openai.yaml +12 -0
- package/.opencode/skills/compliance-audit/references/control-matrix.md +51 -0
- package/.opencode/skills/controlkeel-governance/SKILL.md +89 -0
- package/.opencode/skills/controlkeel-governance/agents/openai.yaml +12 -0
- package/.opencode/skills/controlkeel-governance/references/workflow.md +28 -0
- package/.opencode/skills/cost-optimization/SKILL.md +36 -0
- package/.opencode/skills/cost-optimization/agents/openai.yaml +12 -0
- package/.opencode/skills/cost-optimization/references/budget-playbook.md +18 -0
- package/.opencode/skills/domain-audit/SKILL.md +41 -0
- package/.opencode/skills/domain-audit/agents/openai.yaml +12 -0
- package/.opencode/skills/domain-audit/references/domain-review-matrix.md +71 -0
- package/.opencode/skills/policy-training/SKILL.md +35 -0
- package/.opencode/skills/policy-training/agents/openai.yaml +12 -0
- package/.opencode/skills/policy-training/references/promotion-rules.md +6 -0
- package/.opencode/skills/proof-memory/SKILL.md +39 -0
- package/.opencode/skills/proof-memory/agents/openai.yaml +11 -0
- package/.opencode/skills/proof-memory/references/proof-workflow.md +6 -0
- package/.opencode/skills/security-review/SKILL.md +34 -0
- package/.opencode/skills/security-review/agents/openai.yaml +12 -0
- package/.opencode/skills/security-review/references/review-checklist.md +69 -0
- package/.opencode/skills/ship-readiness/SKILL.md +35 -0
- package/.opencode/skills/ship-readiness/agents/openai.yaml +12 -0
- package/.opencode/skills/ship-readiness/references/release-checklist.md +8 -0
- package/package.json +1 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-integration
|
|
3
|
+
description: "Attach ControlKeel to agents, verify MCP connectivity, confirm native skills availability, and choose the right distribution target for each client."
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
compatibility:
|
|
6
|
+
- codex
|
|
7
|
+
- claude-standalone
|
|
8
|
+
- claude-plugin
|
|
9
|
+
- copilot-plugin
|
|
10
|
+
- github-repo
|
|
11
|
+
- open-standard
|
|
12
|
+
disable-model-invocation: true
|
|
13
|
+
metadata:
|
|
14
|
+
author: controlkeel
|
|
15
|
+
version: "2.0"
|
|
16
|
+
category: integration
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Agent Integration Skill
|
|
20
|
+
|
|
21
|
+
Use this skill when the task is attaching or distributing ControlKeel across agents.
|
|
22
|
+
|
|
23
|
+
## Workflow
|
|
24
|
+
|
|
25
|
+
1. Identify whether the target is native-skill capable, plugin-capable, or MCP-only.
|
|
26
|
+
2. Prefer native install where supported, with CK MCP as the transport for governance tools.
|
|
27
|
+
3. Export plugin bundles when the user wants a shareable package.
|
|
28
|
+
4. For MCP-only tools, generate the instruction bundle and installation guidance.
|
|
29
|
+
5. For Conductor, prefer the Claude Code install path because Conductor documents support for `.mcp.json`, `CLAUDE.md`, and `.claude/commands`.
|
|
30
|
+
|
|
31
|
+
## Cursor (Rules, Skills, Agents, Hooks, Plugins)
|
|
32
|
+
|
|
33
|
+
Cursor’s **Settings → Rules, Skills, Subagents** (and related **Commands**, **Hooks**, **Plugins**) align to repo files ControlKeel already generates on `controlkeel attach cursor`:
|
|
34
|
+
|
|
35
|
+
| Cursor concept | CK attach output | Notes |
|
|
36
|
+
| --- | --- | --- |
|
|
37
|
+
| **Rules** | `.cursor/rules/controlkeel.mdc` | Always-on governance instructions for the agent. |
|
|
38
|
+
| **Skills** | `.cursor/skills/*` plus `.agents/skills/*` | Native Cursor skills tree plus open-standard AgentSkills for import tools. |
|
|
39
|
+
| **Commands** | `.cursor/commands/*.md` | Slash-style review / plan / annotate / last flows. |
|
|
40
|
+
| **Agents / Subagents** | `.cursor/agents/*.md`, `.cursor/background-agents/*.md` | Governor-style prompts and background workflow guidance; hooks include `subagentStart`. |
|
|
41
|
+
| **Hooks** | `.cursor/hooks.json`, `.cursor/hooks/*.sh` | Shell / write / MCP / session / stop gates calling `controlkeel validate` when available. |
|
|
42
|
+
| **MCP** | `.cursor/mcp.json` | Stdio MCP; use `${workspaceFolder}` for command paths and `CK_PROJECT_ROOT`. |
|
|
43
|
+
| **Plugins** | `.cursor-plugin/` | Distributable bundle (`plugin.json`, mirrored assets, `hooks/hooks.json`, `mcpServers`) for **Plugins → Install** / marketplace-style flows. |
|
|
44
|
+
|
|
45
|
+
**Install path:** `controlkeel attach cursor` in the governed repo root, then enable the ControlKeel MCP server in Cursor and (if desired) install the generated `.cursor-plugin` from the repo or a release export.
|
|
46
|
+
|
|
47
|
+
## Additional resources
|
|
48
|
+
|
|
49
|
+
- [Target matrix](references/target-matrix.md)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "Agent Integration"
|
|
3
|
+
short_description: "Attach and distribute ControlKeel across native and MCP-only agent clients."
|
|
4
|
+
brand_color: "#0891b2"
|
|
5
|
+
policy:
|
|
6
|
+
allow_implicit_invocation: false
|
|
7
|
+
dependencies:
|
|
8
|
+
tools:
|
|
9
|
+
- type: "mcp"
|
|
10
|
+
value: "controlkeel"
|
|
11
|
+
description: "ControlKeel MCP server"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Target Matrix
|
|
2
|
+
|
|
3
|
+
## Native-first
|
|
4
|
+
|
|
5
|
+
- Codex: `.agents/skills`, `.codex/agents`
|
|
6
|
+
- Claude Code: `.claude/skills`, `.claude/agents`, plugins
|
|
7
|
+
- Copilot / VS Code: `.github/skills`, `.github/agents`, plugins
|
|
8
|
+
- Cursor: `.cursor/skills`, `.cursor/agents`, `.cursor/rules`, `.cursor/hooks.json`, `.cursor/mcp.json`, `.cursor-plugin/`
|
|
9
|
+
- Conductor compatibility: use Claude Code repo-local surfaces (`.mcp.json`, `CLAUDE.md`, `.claude/commands`)
|
|
10
|
+
|
|
11
|
+
## MCP-only fallback
|
|
12
|
+
|
|
13
|
+
- Windsurf
|
|
14
|
+
- Kiro
|
|
15
|
+
- Amp
|
|
16
|
+
- OpenCode
|
|
17
|
+
- Gemini CLI
|
|
18
|
+
- Continue
|
|
19
|
+
- Aider
|
|
20
|
+
|
|
21
|
+
All MCP-only tools should still receive CK instruction snippets so the model knows how and when to call CK tools.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: benchmark-operator
|
|
3
|
+
description: "Run, inspect, import, and export ControlKeel benchmark suites and multi-subject matrices. Use this when comparing governed and external agents or validating policy changes."
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
compatibility:
|
|
6
|
+
- codex
|
|
7
|
+
- claude-standalone
|
|
8
|
+
- claude-plugin
|
|
9
|
+
- copilot-plugin
|
|
10
|
+
- github-repo
|
|
11
|
+
- open-standard
|
|
12
|
+
disable-model-invocation: true
|
|
13
|
+
metadata:
|
|
14
|
+
author: controlkeel
|
|
15
|
+
version: "2.0"
|
|
16
|
+
category: benchmark
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Benchmark Operator Skill
|
|
20
|
+
|
|
21
|
+
Use this skill when the task is benchmark orchestration instead of normal governed delivery work.
|
|
22
|
+
|
|
23
|
+
## Workflow
|
|
24
|
+
|
|
25
|
+
1. Select the suite and subjects.
|
|
26
|
+
2. Run the suite or import manual outputs.
|
|
27
|
+
3. Review catch rate, block rate, expected-rule hit rate, latency, and overhead.
|
|
28
|
+
4. Export the run if you need external analysis.
|
|
29
|
+
|
|
30
|
+
## Additional resources
|
|
31
|
+
|
|
32
|
+
- [Benchmark operator playbook](references/benchmark-playbook.md)
|
|
33
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "Benchmark Operator"
|
|
3
|
+
short_description: "Operate CK benchmark suites and multi-agent matrices."
|
|
4
|
+
brand_color: "#065f46"
|
|
5
|
+
policy:
|
|
6
|
+
allow_implicit_invocation: false
|
|
7
|
+
dependencies:
|
|
8
|
+
tools:
|
|
9
|
+
- type: "mcp"
|
|
10
|
+
value: "controlkeel"
|
|
11
|
+
description: "ControlKeel MCP server"
|
|
12
|
+
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Benchmark Operator Playbook
|
|
2
|
+
|
|
3
|
+
- Public suites are for comparable external reporting and normal operator use.
|
|
4
|
+
- Held-out suites should stay internal and only feed policy training and promotion gates.
|
|
5
|
+
- Benchmark runs must not be confused with governed sessions or ship metrics.
|
|
6
|
+
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cloudflare-agent
|
|
3
|
+
description: "Enable ControlKeel governance for Cloudflare Agents with policy gates, budget enforcement, PII detection, and secure execution."
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
compatibility:
|
|
6
|
+
- cloudflare-workers-runtime
|
|
7
|
+
- open-standard
|
|
8
|
+
disable-model-invocation: true
|
|
9
|
+
metadata:
|
|
10
|
+
author: controlkeel
|
|
11
|
+
version: "1.0"
|
|
12
|
+
category: integration
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Cloudflare Agent Governance
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
|
|
19
|
+
This skill enables ControlKeel to govern Cloudflare Agents by providing policy gates, budget enforcement, audit logging, and secure execution capabilities.
|
|
20
|
+
|
|
21
|
+
## When to Use
|
|
22
|
+
|
|
23
|
+
Use this skill when:
|
|
24
|
+
- Building Cloudflare Agents that need governance guardrails
|
|
25
|
+
- Enforcing budget/spend limits on Workers AI or external providers
|
|
26
|
+
- Auditing agent actions for compliance
|
|
27
|
+
- Running shell commands in sandboxed environments within CF Agents
|
|
28
|
+
- Integrating PII detection and security scanning
|
|
29
|
+
|
|
30
|
+
## Prerequisites
|
|
31
|
+
|
|
32
|
+
- Cloudflare Workers project with Agents SDK installed
|
|
33
|
+
- ControlKeel MCP connected to the agent
|
|
34
|
+
- For shell tools: ExecutionSandbox adapter (local/docker/e2b)
|
|
35
|
+
|
|
36
|
+
## Integration Pattern
|
|
37
|
+
|
|
38
|
+
### 1. Connect CK to Cloudflare Agent via MCP
|
|
39
|
+
|
|
40
|
+
The agent exposes governance tools via MCP:
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { McpAgent } from "agents/mcp";
|
|
44
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
45
|
+
|
|
46
|
+
export class GovernedAgent extends McpAgent {
|
|
47
|
+
server = new McpServer({
|
|
48
|
+
name: "controlkeel-governance",
|
|
49
|
+
version: "1.0.0"
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
async init() {
|
|
53
|
+
// Register CK governance tools
|
|
54
|
+
this.server.tool(
|
|
55
|
+
"ck_validate",
|
|
56
|
+
"Validate an action against governance policies",
|
|
57
|
+
{ prompt: z.string(), context: z.record(z.string(), z.any()).optional() },
|
|
58
|
+
async ({ prompt, context }) => {
|
|
59
|
+
// Call CK governance endpoint
|
|
60
|
+
return await this.callCKGovernance(prompt, context);
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
this.server.tool(
|
|
65
|
+
"ck_budget_check",
|
|
66
|
+
"Check remaining budget for AI spend",
|
|
67
|
+
{ scope: z.enum(["task", "session", "daily"]).optional() },
|
|
68
|
+
async ({ scope }) => {
|
|
69
|
+
// Query CK budget state
|
|
70
|
+
return await this.callCKBudget(scope || "task");
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async callCKGovernance(prompt: string, context?: Record<string, any>) {
|
|
76
|
+
const response = await this.env.CK_GOVERNANCE.fetch("/validate", {
|
|
77
|
+
method: "POST",
|
|
78
|
+
body: JSON.stringify({ prompt, context })
|
|
79
|
+
});
|
|
80
|
+
return response.json();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 2. Policy Gate Pattern
|
|
86
|
+
|
|
87
|
+
Validate before execution:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
export class GovernedAgent extends Agent {
|
|
91
|
+
@callable()
|
|
92
|
+
async executeWithGovernance(command: string, args: string[]) {
|
|
93
|
+
// Pre-execution policy check
|
|
94
|
+
const validation = await this.validateWithCK({
|
|
95
|
+
action: "execute_command",
|
|
96
|
+
payload: { command, args }
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
if (validation.decision === "denied") {
|
|
100
|
+
return { error: "Policy violation", reason: validation.reason };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Execute if approved
|
|
104
|
+
const result = await this.executeCommand(command, args);
|
|
105
|
+
|
|
106
|
+
// Post-execution audit
|
|
107
|
+
await this.auditWithCK({
|
|
108
|
+
action: "command_executed",
|
|
109
|
+
payload: { command, args, result },
|
|
110
|
+
validation_id: validation.id
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 3. Budget Enforcement
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
export class BudgetedAgent extends Agent {
|
|
122
|
+
@callable()
|
|
123
|
+
async callAIWithBudget(model: string, messages: any[]) {
|
|
124
|
+
// Check budget before AI call
|
|
125
|
+
const budget = await this.ckBudgetCheck("task");
|
|
126
|
+
|
|
127
|
+
if (!budget.has_remaining) {
|
|
128
|
+
return { error: "Budget exhausted", remaining: 0 };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Make AI call
|
|
132
|
+
const response = await this.callAI(model, messages);
|
|
133
|
+
|
|
134
|
+
// Deduct from budget
|
|
135
|
+
await this.ckBudgetDeduct({
|
|
136
|
+
amount: response.usage_tokens,
|
|
137
|
+
scope: "task"
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
return response;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 4. Shell Execution (via CK ExecutionSandbox)
|
|
146
|
+
|
|
147
|
+
For agents that need shell access:
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
export class ShellEnabledAgent extends Agent {
|
|
151
|
+
@callable()
|
|
152
|
+
async shell(command: string, cwd?: string) {
|
|
153
|
+
// Validate shell command
|
|
154
|
+
const validation = await this.validateWithCK({
|
|
155
|
+
action: "shell_execution",
|
|
156
|
+
payload: { command, cwd }
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
if (validation.decision === "denied") {
|
|
160
|
+
throw new Error(`Shell denied: ${validation.reason}`);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Execute via CK sandbox (local/docker/e2b)
|
|
164
|
+
const result = await this.env.CK_SANDBOX.fetch("/execute", {
|
|
165
|
+
method: "POST",
|
|
166
|
+
body: JSON.stringify({
|
|
167
|
+
command,
|
|
168
|
+
cwd: cwd || this.state.cwd || "/workspace",
|
|
169
|
+
sandbox: "local" // or docker, e2b
|
|
170
|
+
})
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
return result.json();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### 5. File System via R2
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
export class FileEnabledAgent extends Agent {
|
|
182
|
+
@callable()
|
|
183
|
+
async readFile(path: string) {
|
|
184
|
+
const object = await this.env.AGENT_BUCKET.get(path);
|
|
185
|
+
if (!object) throw new Error(`File not found: ${path}`);
|
|
186
|
+
return await object.text();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
@callable()
|
|
190
|
+
async writeFile(path: string, content: string) {
|
|
191
|
+
await this.env.AGENT_BUCKET.put(path, content);
|
|
192
|
+
return { success: true, path };
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
@callable()
|
|
196
|
+
async listFiles(prefix: string) {
|
|
197
|
+
const objects = await this.env.AGENT_BUCKET.list({ prefix });
|
|
198
|
+
return objects.objects.map(o => o.key);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 6. SQLite via D1
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
export class DBEnabledAgent extends Agent {
|
|
207
|
+
@callable()
|
|
208
|
+
async query(sql: string, params?: any[]) {
|
|
209
|
+
const stmt = await this.env.DB.prepare(sql);
|
|
210
|
+
return params ? stmt.bind(...params).all() : stmt.all();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
@callable()
|
|
214
|
+
async initSchema() {
|
|
215
|
+
await this.env.DB.exec(`
|
|
216
|
+
CREATE TABLE IF NOT EXISTS agent_state (
|
|
217
|
+
key TEXT PRIMARY KEY,
|
|
218
|
+
value TEXT,
|
|
219
|
+
updated_at INTEGER
|
|
220
|
+
);
|
|
221
|
+
`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Tools Reference
|
|
227
|
+
|
|
228
|
+
### MCP Tools (serve to agents)
|
|
229
|
+
|
|
230
|
+
| Tool | Description | Parameters |
|
|
231
|
+
|------|-------------|------------|
|
|
232
|
+
| `ck_validate` | Validate action against policies | `prompt`, `context` |
|
|
233
|
+
| `ck_budget_check` | Check remaining budget | `scope` |
|
|
234
|
+
| `ck_budget_deduct` | Deduct from budget | `amount`, `scope` |
|
|
235
|
+
| `ck_finding` | Log a finding | `severity`, `message`, `payload` |
|
|
236
|
+
| `ck_context` | Get governance context | - |
|
|
237
|
+
| `ck_delegate` | Delegate to sub-agent | `agent`, `task` |
|
|
238
|
+
|
|
239
|
+
### CK to Agent Tools
|
|
240
|
+
|
|
241
|
+
| Tool | Description |
|
|
242
|
+
|------|-------------|
|
|
243
|
+
| `ck_shell` | Execute shell command (sandboxed) |
|
|
244
|
+
| `ck_read` | Read file from agent workspace |
|
|
245
|
+
| `ck_write` | Write file to agent workspace |
|
|
246
|
+
| `ck_ai` | Call AI with budget tracking |
|
|
247
|
+
|
|
248
|
+
## Environment Variables
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
# CK Governance endpoint (Durable Object or external)
|
|
252
|
+
CK_GOVERNANCE=do://agent-governance
|
|
253
|
+
|
|
254
|
+
# CK Sandbox endpoint
|
|
255
|
+
CK_SANDBOX=do://agent-sandbox
|
|
256
|
+
|
|
257
|
+
# Agent bucket (R2)
|
|
258
|
+
AGENT_BUCKET=agent-workspace
|
|
259
|
+
|
|
260
|
+
# Agent database (D1)
|
|
261
|
+
DB=agent-db
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Example: Complete Governed Agent
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
import { Agent, callable } from "agents";
|
|
268
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
269
|
+
|
|
270
|
+
type Env = {
|
|
271
|
+
CK_GOVERNANCE: DurableObjectNamespace;
|
|
272
|
+
AGENT_BUCKET: R2Bucket;
|
|
273
|
+
DB: D1Database;
|
|
274
|
+
AI: Ai;
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
export class GovernedCFAgent extends Agent<Env, { cwd: string }> {
|
|
278
|
+
initialState = { cwd: "/workspace" };
|
|
279
|
+
|
|
280
|
+
async onStart() {
|
|
281
|
+
await this.initDB();
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
async initDB() {
|
|
285
|
+
await this.env.DB.exec(`
|
|
286
|
+
CREATE TABLE IF NOT EXISTS logs (
|
|
287
|
+
id INTEGER PRIMARY KEY,
|
|
288
|
+
action TEXT,
|
|
289
|
+
payload TEXT,
|
|
290
|
+
timestamp INTEGER
|
|
291
|
+
);
|
|
292
|
+
`);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
@callable()
|
|
296
|
+
async executeCommand(cmd: string, args: string[]) {
|
|
297
|
+
// 1. Validate
|
|
298
|
+
const validation = await this.validateAction("execute", { cmd, args });
|
|
299
|
+
if (validation.denied) {
|
|
300
|
+
await this.log("validation_denied", { cmd, reason: validation.reason });
|
|
301
|
+
return { error: validation.reason };
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// 2. Execute
|
|
305
|
+
const result = await this.runCommand(cmd, args);
|
|
306
|
+
|
|
307
|
+
// 3. Audit
|
|
308
|
+
await this.log("executed", { cmd, args, exitCode: result.exitCode });
|
|
309
|
+
|
|
310
|
+
return result;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
@callable()
|
|
314
|
+
async readFile(path: string) {
|
|
315
|
+
const fullPath = `${this.state.cwd}/${path}`;
|
|
316
|
+
const obj = await this.env.AGENT_BUCKET.get(fullPath);
|
|
317
|
+
return obj?.text() || null;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
@callable()
|
|
321
|
+
async writeFile(path: string, content: string) {
|
|
322
|
+
const fullPath = `${this.state.cwd}/${path}`;
|
|
323
|
+
await this.env.AGENT_BUCKET.put(fullPath, content);
|
|
324
|
+
await this.log("file_written", { path: fullPath });
|
|
325
|
+
return { success: true };
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
private async validateAction(action: string, payload: any) {
|
|
329
|
+
const stub = this.env.CK_GOVERNANCE.get(this.env.CK_GOVERNANCE.idFromName("default"));
|
|
330
|
+
return await stub.validate({ action, payload, context: this.state });
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
private async log(action: string, payload: any) {
|
|
334
|
+
await this.env.DB.prepare(
|
|
335
|
+
"INSERT INTO logs (action, payload, timestamp) VALUES (?, ?, ?)"
|
|
336
|
+
).bind(action, JSON.stringify(payload), Date.now()).run();
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
private async runCommand(cmd: string, args: string[]): Promise<{ output: string; exitCode: number }> {
|
|
340
|
+
// Execute via CK sandbox or direct
|
|
341
|
+
const fullCommand = [cmd, ...args].join(" ");
|
|
342
|
+
return { output: `Executed: ${fullCommand}`, exitCode: 0 };
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Security Considerations
|
|
348
|
+
|
|
349
|
+
1. **Shell commands** - Always validate via CK policy gates before execution
|
|
350
|
+
2. **File access** - Restrict to workspace directory, validate paths
|
|
351
|
+
3. **AI budget** - Set per-task and daily limits
|
|
352
|
+
4. **Audit logging** - Log all governance decisions and actions
|
|
353
|
+
5. **PII scanning** - Use CK PIIDetector on prompts/responses
|
|
354
|
+
|
|
355
|
+
## Deployment
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
# Deploy to Cloudflare Workers
|
|
359
|
+
wrangler deploy
|
|
360
|
+
|
|
361
|
+
# Bind required resources
|
|
362
|
+
# - D1 database for agent state
|
|
363
|
+
# - R2 bucket for file workspace
|
|
364
|
+
# - Durable Object for governance
|
|
365
|
+
# - Workers AI or external provider
|
|
366
|
+
```
|