dashclaw 1.0.0 → 1.2.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 (3) hide show
  1. package/README.md +4 -1
  2. package/dashclaw.js +53 -2
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -20,9 +20,12 @@ const claw = new DashClaw({
20
20
  apiKey: process.env.DASHCLAW_API_KEY,
21
21
  agentId: 'my-agent',
22
22
  agentName: 'My Agent',
23
+ // Optional: Cryptographic Identity Binding
24
+ // Supports CryptoKey object or plain JWK object
25
+ // privateKey: JSON.parse(process.env.AGENT_PRIVATE_KEY)
23
26
  });
24
27
 
25
- // Record an action
28
+ // Record an action (automatically signed if privateKey is provided)
26
29
  const { action_id } = await claw.createAction({
27
30
  action_type: 'deploy',
28
31
  declared_goal: 'Deploy auth service to production',
package/dashclaw.js CHANGED
@@ -29,8 +29,9 @@ class DashClaw {
29
29
  * @param {string} [options.swarmId] - Swarm/group identifier if part of a multi-agent system
30
30
  * @param {string} [options.guardMode='off'] - Auto guard check before createAction: 'off' | 'warn' | 'enforce'
31
31
  * @param {Function} [options.guardCallback] - Called with guard decision object when guardMode is active
32
+ * @param {CryptoKey} [options.privateKey] - Web Crypto API Private Key for signing actions
32
33
  */
33
- constructor({ baseUrl, apiKey, agentId, agentName, swarmId, guardMode, guardCallback }) {
34
+ constructor({ baseUrl, apiKey, agentId, agentName, swarmId, guardMode, guardCallback, privateKey }) {
34
35
  if (!baseUrl) throw new Error('baseUrl is required');
35
36
  if (!apiKey) throw new Error('apiKey is required');
36
37
  if (!agentId) throw new Error('agentId is required');
@@ -47,6 +48,29 @@ class DashClaw {
47
48
  this.swarmId = swarmId || null;
48
49
  this.guardMode = guardMode || 'off';
49
50
  this.guardCallback = guardCallback || null;
51
+ this.privateKey = privateKey || null;
52
+
53
+ // Auto-import JWK if passed as plain object
54
+ if (this.privateKey && typeof this.privateKey === 'object' && this.privateKey.kty) {
55
+ this._pendingKeyImport = this._importJwk(this.privateKey);
56
+ }
57
+ }
58
+
59
+ async _importJwk(jwk) {
60
+ try {
61
+ const cryptoSubtle = globalThis.crypto?.subtle || (await import('node:crypto')).webcrypto.subtle;
62
+ this.privateKey = await cryptoSubtle.importKey(
63
+ "jwk",
64
+ jwk,
65
+ { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" },
66
+ false,
67
+ ["sign"]
68
+ );
69
+ delete this._pendingKeyImport;
70
+ } catch (err) {
71
+ console.warn(`[DashClaw] Failed to auto-import privateKey JWK: ${err.message}`);
72
+ this.privateKey = null;
73
+ }
50
74
  }
51
75
 
52
76
  async _request(path, method, body) {
@@ -140,11 +164,38 @@ class DashClaw {
140
164
  */
141
165
  async createAction(action) {
142
166
  await this._guardCheck(action);
143
- return this._request('/api/actions', 'POST', {
167
+ if (this._pendingKeyImport) await this._pendingKeyImport;
168
+
169
+ const payload = {
144
170
  agent_id: this.agentId,
145
171
  agent_name: this.agentName,
146
172
  swarm_id: this.swarmId,
147
173
  ...action
174
+ };
175
+
176
+ let signature = null;
177
+ if (this.privateKey) {
178
+ try {
179
+ const encoder = new TextEncoder();
180
+ const data = encoder.encode(JSON.stringify(payload));
181
+ // Use global crypto or fallback to node:crypto
182
+ const cryptoSubtle = globalThis.crypto?.subtle || (await import('node:crypto')).webcrypto.subtle;
183
+
184
+ const sigBuffer = await cryptoSubtle.sign(
185
+ { name: "RSASSA-PKCS1-v1_5" },
186
+ this.privateKey,
187
+ data
188
+ );
189
+ // Base64 encode signature
190
+ signature = btoa(String.fromCharCode(...new Uint8Array(sigBuffer)));
191
+ } catch (err) {
192
+ throw new Error(`Failed to sign action: ${err.message}`);
193
+ }
194
+ }
195
+
196
+ return this._request('/api/actions', 'POST', {
197
+ ...payload,
198
+ _signature: signature
148
199
  });
149
200
  }
150
201
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dashclaw",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "Full-featured agent toolkit for the DashClaw platform. 57 methods for action recording, context management, session handoffs, security scanning, behavior guard, bulk sync, and more.",
5
5
  "type": "module",
6
6
  "main": "./index.cjs",