dashclaw 2.1.5 → 2.2.1

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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # DashClaw SDK (v2.1.2)
1
+ # DashClaw SDK (v2.2.0)
2
2
 
3
3
  **Minimal governance runtime for AI agents.**
4
4
 
@@ -25,7 +25,7 @@ DashClaw v2 is designed around a single 4-step loop.
25
25
  import { DashClaw } from 'dashclaw';
26
26
 
27
27
  const claw = new DashClaw({
28
- baseUrl: 'https://dashclaw.io',
28
+ baseUrl: process.env.DASHCLAW_BASE_URL,
29
29
  apiKey: process.env.DASHCLAW_API_KEY,
30
30
  agentId: 'my-agent'
31
31
  });
@@ -45,11 +45,12 @@ await claw.updateOutcome(action_id, { status: 'completed' });
45
45
 
46
46
  ### Python
47
47
  ```python
48
+ import os
48
49
  from dashclaw import DashClaw
49
50
 
50
51
  claw = DashClaw(
51
- base_url="https://dashclaw.io",
52
- api_key="your_api_key",
52
+ base_url=os.environ["DASHCLAW_BASE_URL"],
53
+ api_key=os.environ["DASHCLAW_API_KEY"],
53
54
  agent_id="my-agent"
54
55
  )
55
56
 
@@ -69,38 +70,40 @@ claw.update_outcome(action_id, status="completed")
69
70
 
70
71
  ---
71
72
 
72
- ## SDK Surface Area (v2.1.2)
73
+ ## SDK Surface Area (v2.1.5)
73
74
 
74
- The v2.1.2 SDK is optimized for stability and zero-overhead governance:
75
+ The v2.1.5 SDK is optimized for stability and zero-overhead governance:
75
76
 
76
77
  ### Core Runtime
77
- - `guard(context)` Policy evaluation ("Can I do X?")
78
- - `createAction(action)` Lifecycle tracking ("I am doing X")
79
- - `updateOutcome(id, outcome)` Result recording ("X finished with Y")
80
- - `recordAssumption(assumption)` Integrity tracking ("I believe Z while doing X")
81
- - `waitForApproval(id)` Polling helper for human-in-the-loop approvals
78
+ - `guard(context)` -- Policy evaluation ("Can I do X?")
79
+ - `createAction(action)` -- Lifecycle tracking ("I am doing X")
80
+ - `updateOutcome(id, outcome)` -- Result recording ("X finished with Y")
81
+ - `recordAssumption(assumption)` -- Integrity tracking ("I believe Z while doing X")
82
+ - `waitForApproval(id)` -- Polling helper for human-in-the-loop approvals
83
+ - `approveAction(id, decision, reasoning?)` -- Submit approval decisions from code
84
+ - `getPendingApprovals()` -- List actions awaiting human review
82
85
 
83
86
  ### Decision Integrity
84
- - `registerOpenLoop(actionId, type, desc)` Register unresolved dependencies.
85
- - `resolveOpenLoop(loopId, status, res)` Resolve pending loops.
86
- - `getSignals()` Get current risk signals across all agents.
87
+ - `registerOpenLoop(actionId, type, desc)` -- Register unresolved dependencies.
88
+ - `resolveOpenLoop(loopId, status, res)` -- Resolve pending loops.
89
+ - `getSignals()` -- Get current risk signals across all agents.
87
90
 
88
91
  ### Swarm & Connectivity
89
- - `heartbeat(status, metadata)` Report agent presence and health.
90
- - `reportConnections(connections)` Report active provider connections.
92
+ - `heartbeat(status, metadata)` -- Report agent presence and health.
93
+ - `reportConnections(connections)` -- Report active provider connections.
91
94
 
92
95
  ### Learning & Optimization
93
- - `getLearningVelocity()` Track agent improvement rate.
94
- - `getLearningCurves()` Measure efficiency gains per action type.
95
- - `renderPrompt(context)` Fetch rendered prompt templates from DashClaw.
96
+ - `getLearningVelocity()` -- Track agent improvement rate.
97
+ - `getLearningCurves()` -- Measure efficiency gains per action type.
98
+ - `renderPrompt(context)` -- Fetch rendered prompt templates from DashClaw.
96
99
 
97
100
  ### Compliance & Audit
98
- - `createScorer(name, type, config)` Define automated evaluations.
99
- - `createScoringProfile(profile)` Weighted quality scoring.
100
- - `mapCompliance(framework)` Map behavior to regulatory controls.
101
- - `getProofReport(format)` Generate audit-ready evidence exports.
102
- - `getActivityLogs(filters)` Query the immutable audit trail.
103
- - `createWebhook(url, events)` Real-time event exfiltration.
101
+ - `createScorer(name, type, config)` -- Define automated evaluations.
102
+ - `createScoringProfile(profile)` -- Weighted quality scoring.
103
+ - `mapCompliance(framework)` -- Map behavior to regulatory controls.
104
+ - `getProofReport(format)` -- Generate audit-ready evidence exports.
105
+ - `getActivityLogs(filters)` -- Query the immutable audit trail.
106
+ - `createWebhook(url, events)` -- Real-time event exfiltration.
104
107
 
105
108
  ---
106
109
 
@@ -108,8 +111,38 @@ The v2.1.2 SDK is optimized for stability and zero-overhead governance:
108
111
 
109
112
  DashClaw uses standard HTTP status codes and custom error classes:
110
113
 
111
- - `GuardBlockedError` Thrown when `claw.guard()` returns a `block` decision.
112
- - `ApprovalDeniedError` Thrown when an operator denies an action during `waitForApproval()`.
114
+ - `GuardBlockedError` -- Thrown when `claw.guard()` returns a `block` decision.
115
+ - `ApprovalDeniedError` -- Thrown when an operator denies an action during `waitForApproval()`.
116
+
117
+ ---
118
+
119
+ ## CLI Approval Channel
120
+
121
+ Install the DashClaw CLI to approve agent actions from the terminal:
122
+
123
+ ```bash
124
+ npm install -g @dashclaw/cli
125
+ ```
126
+
127
+ ```bash
128
+ dashclaw approvals # interactive approval inbox
129
+ dashclaw approve <actionId> # approve a specific action
130
+ dashclaw deny <actionId> # deny a specific action
131
+ ```
132
+
133
+ When an agent calls `waitForApproval()`, it prints the action ID and replay link to stdout. Approve from any terminal or the dashboard, and the agent unblocks instantly.
134
+
135
+ ## Claude Code Hooks
136
+
137
+ Govern Claude Code tool calls without any SDK instrumentation. Copy two files from the `hooks/` directory in the repo into your `.claude/hooks/` folder:
138
+
139
+ ```bash
140
+ # In your project directory
141
+ cp path/to/DashClaw/hooks/dashclaw_pretool.py .claude/hooks/
142
+ cp path/to/DashClaw/hooks/dashclaw_posttool.py .claude/hooks/
143
+ ```
144
+
145
+ Then merge the hooks block from `hooks/settings.json` into your `.claude/settings.json`. Set `DASHCLAW_BASE_URL`, `DASHCLAW_API_KEY`, and optionally `DASHCLAW_HOOK_MODE=enforce`.
113
146
 
114
147
  ---
115
148
 
package/dashclaw.js CHANGED
@@ -57,6 +57,10 @@ class DashClaw {
57
57
  const data = await res.json();
58
58
 
59
59
  if (!res.ok) {
60
+ if (res.status === 403 && data.decision && data.decision.decision === 'block') {
61
+ throw new GuardBlockedError(data.decision);
62
+ }
63
+
60
64
  // Prioritize reason (from governance blocks) over generic error field
61
65
  const errorMessage = data.reason || data.error || `Request failed with status ${res.status}`;
62
66
  const err = new Error(errorMessage);
@@ -101,6 +105,36 @@ class DashClaw {
101
105
  });
102
106
  }
103
107
 
108
+ /**
109
+ * GET /api/actions/:id — Fetch a single action by ID.
110
+ */
111
+ async getAction(actionId) {
112
+ return this._request(`/api/actions/${actionId}`, 'GET');
113
+ }
114
+
115
+ /**
116
+ * GET /api/actions?status=pending_approval — List actions awaiting approval.
117
+ */
118
+ async getPendingApprovals(limit = 20, offset = 0) {
119
+ return this._request('/api/actions', 'GET', null, {
120
+ status: 'pending_approval',
121
+ limit,
122
+ offset,
123
+ });
124
+ }
125
+
126
+ /**
127
+ * POST /api/actions/:id/approve — Approve or deny an action.
128
+ * @param {string} actionId
129
+ * @param {'allow'|'deny'} decision
130
+ * @param {string} [reasoning]
131
+ */
132
+ async approveAction(actionId, decision, reasoning) {
133
+ const body = { decision };
134
+ if (reasoning) body.reasoning = reasoning;
135
+ return this._request(`/api/actions/${actionId}/approve`, 'POST', body);
136
+ }
137
+
104
138
  /**
105
139
  * POST /api/assumptions — "I believe Z is true while doing X."
106
140
  */
@@ -114,9 +148,40 @@ class DashClaw {
114
148
  async waitForApproval(actionId, { timeout = 300000, interval = 5000 } = {}) {
115
149
  const startTime = Date.now();
116
150
  let wasPending = false;
151
+ let printedBlock = false;
117
152
 
118
153
  while (Date.now() - startTime < timeout) {
119
154
  const { action } = await this._request(`/api/actions/${actionId}`, 'GET');
155
+
156
+ // Print structured approval block on first fetch
157
+ if (!printedBlock) {
158
+ printedBlock = true;
159
+ try {
160
+ const actionType = action.action_type || 'unknown';
161
+ const riskScore = action.risk_score != null ? String(action.risk_score) : '-';
162
+ const goal = action.declared_goal || '-';
163
+ const agent = action.agent_id || this.agentId;
164
+ const replayUrl = `${this.baseUrl}/replay/${actionId}`;
165
+
166
+ const lines = [
167
+ '\u2554\u2550\u2550 DashClaw Approval Required \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557',
168
+ ` Action ID: ${actionId}`,
169
+ ` Agent: ${agent}`,
170
+ ` Action: ${actionType}`,
171
+ ' Policy: require_approval',
172
+ ` Risk Score: ${riskScore}`,
173
+ ` Goal: ${goal}`,
174
+ '',
175
+ ` Replay: ${replayUrl}`,
176
+ '',
177
+ ' Waiting for approval... (Ctrl+C to abort)',
178
+ '\u255a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255d',
179
+ ];
180
+ process.stdout.write('\n' + lines.join('\n') + '\n\n');
181
+ } catch (_) {
182
+ // Rendering failure must not prevent the wait from proceeding
183
+ }
184
+ }
120
185
 
121
186
  if (action.status === 'pending_approval') {
122
187
  wasPending = true;
@@ -1,14 +1,14 @@
1
1
  /**
2
- * DashClaw SDK: CommonJS compatibility wrapper.
3
- * For ESM: import { DashClaw } from 'dashclaw'
4
- * For CJS: const { DashClaw } = require('dashclaw')
2
+ * DashClaw SDK v1 (Legacy): CommonJS compatibility wrapper.
3
+ * For ESM: import { DashClaw } from 'dashclaw/legacy'
4
+ * For CJS: const { DashClaw } = require('dashclaw/legacy')
5
5
  */
6
6
 
7
7
  let _module;
8
8
 
9
9
  async function loadModule() {
10
10
  if (!_module) {
11
- _module = await import('./dashclaw.js');
11
+ _module = await import('./dashclaw-v1.js');
12
12
  }
13
13
  return _module;
14
14
  }
package/package.json CHANGED
@@ -1,49 +1,49 @@
1
- {
2
- "name": "dashclaw",
3
- "version": "2.1.5",
4
- "description": "Minimal governance runtime for AI agents. Intercept, govern, and verify agent actions.",
5
- "type": "module",
6
- "publishConfig": {
7
- "access": "public"
8
- },
9
- "main": "./index.cjs",
10
- "module": "./dashclaw.js",
11
- "exports": {
12
- ".": {
13
- "import": "./dashclaw.js",
14
- "require": "./index.cjs"
15
- },
16
- "./legacy": {
17
- "import": "./legacy/dashclaw-v1.js",
18
- "require": "./legacy/index-v1.cjs"
19
- }
20
- },
21
- "files": [
22
- "dashclaw.js",
23
- "index.cjs",
24
- "LICENSE",
25
- "README.md",
26
- "legacy/"
27
- ],
28
- "keywords": [
29
- "ai-agent",
30
- "decision-infrastructure",
31
- "agent-governance",
32
- "guardrails",
33
- "dashclaw"
34
- ],
35
- "author": "DashClaw",
36
- "license": "MIT",
37
- "repository": {
38
- "type": "git",
39
- "url": "git+https://github.com/ucsandman/DashClaw.git",
40
- "directory": "sdk"
41
- },
42
- "engines": {
43
- "node": ">=18.0.0"
44
- },
45
- "dependencies": {},
46
- "devDependencies": {},
47
- "scripts": {},
48
- "sideEffects": false
49
- }
1
+ {
2
+ "name": "dashclaw",
3
+ "version": "2.2.1",
4
+ "description": "Minimal governance runtime for AI agents. Intercept, govern, and verify agent actions.",
5
+ "type": "module",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "main": "./index.cjs",
10
+ "module": "./dashclaw.js",
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dashclaw.js",
14
+ "require": "./index.cjs"
15
+ },
16
+ "./legacy": {
17
+ "import": "./legacy/dashclaw-v1.js",
18
+ "require": "./legacy/index-v1.cjs"
19
+ }
20
+ },
21
+ "files": [
22
+ "dashclaw.js",
23
+ "index.cjs",
24
+ "LICENSE",
25
+ "README.md",
26
+ "legacy/"
27
+ ],
28
+ "keywords": [
29
+ "ai-agent",
30
+ "decision-infrastructure",
31
+ "agent-governance",
32
+ "guardrails",
33
+ "dashclaw"
34
+ ],
35
+ "author": "DashClaw",
36
+ "license": "MIT",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "git+https://github.com/ucsandman/DashClaw.git",
40
+ "directory": "sdk"
41
+ },
42
+ "engines": {
43
+ "node": ">=18.0.0"
44
+ },
45
+ "dependencies": {},
46
+ "devDependencies": {},
47
+ "scripts": {},
48
+ "sideEffects": false
49
+ }