dashclaw 4.0.0 → 4.0.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/dashclaw.js +23 -20
- package/index.cjs +58 -29
- package/legacy/dashclaw-v1.js +16 -5
- package/package.json +1 -1
package/dashclaw.js
CHANGED
|
@@ -225,10 +225,18 @@ class DashClaw {
|
|
|
225
225
|
*/
|
|
226
226
|
async *_connectSSE(controller) {
|
|
227
227
|
const res = await fetch(`${this.baseUrl}/api/stream`, {
|
|
228
|
-
headers: {
|
|
228
|
+
headers: {
|
|
229
|
+
'x-api-key': this.apiKey,
|
|
230
|
+
...(this.authToken ? { 'Authorization': `Bearer ${this.authToken}` } : {}),
|
|
231
|
+
},
|
|
229
232
|
signal: controller.signal,
|
|
230
233
|
});
|
|
231
234
|
|
|
235
|
+
if (res.status === 403) {
|
|
236
|
+
let body = {};
|
|
237
|
+
try { body = await res.json(); } catch { /* ignore */ }
|
|
238
|
+
throw new GuardBlockedError(body.decision || { reason: 'SSE stream blocked by policy' });
|
|
239
|
+
}
|
|
232
240
|
if (!res.ok || !res.body) return;
|
|
233
241
|
|
|
234
242
|
const reader = res.body.getReader();
|
|
@@ -316,7 +324,7 @@ class DashClaw {
|
|
|
316
324
|
if (!controller.signal.aborted) controller.abort();
|
|
317
325
|
}
|
|
318
326
|
} catch (err) {
|
|
319
|
-
if (err instanceof ApprovalDeniedError || err.message?.includes('Timed out')) throw err;
|
|
327
|
+
if (err instanceof ApprovalDeniedError || err instanceof GuardBlockedError || err.message?.includes('Timed out')) throw err;
|
|
320
328
|
// SSE failed — fall through to polling
|
|
321
329
|
}
|
|
322
330
|
|
|
@@ -451,7 +459,7 @@ class DashClaw {
|
|
|
451
459
|
return this._request('/api/learning/lessons', 'GET', null, {
|
|
452
460
|
agent_id: this.agentId,
|
|
453
461
|
...(actionType && { action_type: actionType }),
|
|
454
|
-
...(limit && { limit }),
|
|
462
|
+
...(limit != null && { limit }),
|
|
455
463
|
});
|
|
456
464
|
}
|
|
457
465
|
|
|
@@ -540,6 +548,7 @@ class DashClaw {
|
|
|
540
548
|
* POST /api/scoring/score — score a single action against a profile
|
|
541
549
|
*/
|
|
542
550
|
async scoreWithProfile(profileId, action) {
|
|
551
|
+
if (Array.isArray(action)) throw new TypeError('scoreWithProfile expects a single action object; use batchScoreWithProfile for arrays');
|
|
543
552
|
return this._request('/api/scoring/score', 'POST', { profile_id: profileId, action });
|
|
544
553
|
}
|
|
545
554
|
|
|
@@ -547,6 +556,7 @@ class DashClaw {
|
|
|
547
556
|
* POST /api/scoring/score — batch score multiple actions against a profile
|
|
548
557
|
*/
|
|
549
558
|
async batchScoreWithProfile(profileId, actions) {
|
|
559
|
+
if (!Array.isArray(actions)) throw new TypeError('batchScoreWithProfile expects an array of actions');
|
|
550
560
|
return this._request('/api/scoring/score', 'POST', { profile_id: profileId, actions });
|
|
551
561
|
}
|
|
552
562
|
|
|
@@ -648,7 +658,7 @@ class DashClaw {
|
|
|
648
658
|
direction: 'inbox',
|
|
649
659
|
...(type && { type }),
|
|
650
660
|
...(unread != null && { unread }),
|
|
651
|
-
...(limit && { limit }),
|
|
661
|
+
...(limit != null && { limit }),
|
|
652
662
|
});
|
|
653
663
|
}
|
|
654
664
|
|
|
@@ -661,7 +671,7 @@ class DashClaw {
|
|
|
661
671
|
direction: 'sent',
|
|
662
672
|
...(type && { type }),
|
|
663
673
|
...(threadId && { thread_id: threadId }),
|
|
664
|
-
...(limit && { limit }),
|
|
674
|
+
...(limit != null && { limit }),
|
|
665
675
|
});
|
|
666
676
|
}
|
|
667
677
|
|
|
@@ -675,7 +685,7 @@ class DashClaw {
|
|
|
675
685
|
...(type && { type }),
|
|
676
686
|
...(unread != null && { unread }),
|
|
677
687
|
...(threadId && { thread_id: threadId }),
|
|
678
|
-
...(limit && { limit }),
|
|
688
|
+
...(limit != null && { limit }),
|
|
679
689
|
});
|
|
680
690
|
}
|
|
681
691
|
|
|
@@ -753,20 +763,6 @@ class DashClaw {
|
|
|
753
763
|
});
|
|
754
764
|
}
|
|
755
765
|
|
|
756
|
-
// ---------------------------------------------------------------------------
|
|
757
|
-
// Bulk Sync
|
|
758
|
-
// ---------------------------------------------------------------------------
|
|
759
|
-
|
|
760
|
-
/**
|
|
761
|
-
* POST /api/sync — Bulk state sync for periodic updates or bootstrap.
|
|
762
|
-
*/
|
|
763
|
-
async syncState(state) {
|
|
764
|
-
return this._request('/api/sync', 'POST', {
|
|
765
|
-
agent_id: this.agentId,
|
|
766
|
-
...state,
|
|
767
|
-
});
|
|
768
|
-
}
|
|
769
|
-
|
|
770
766
|
// ---------------------------------------------------------------------------
|
|
771
767
|
// Session Lifecycle
|
|
772
768
|
// ---------------------------------------------------------------------------
|
|
@@ -1131,6 +1127,13 @@ class DashClaw {
|
|
|
1131
1127
|
return this._request(`/api/capabilities/${capabilityId}`, 'PATCH', patch);
|
|
1132
1128
|
}
|
|
1133
1129
|
|
|
1130
|
+
/**
|
|
1131
|
+
* DELETE /api/capabilities/:id — Delete a capability.
|
|
1132
|
+
*/
|
|
1133
|
+
async deleteCapability(capabilityId) {
|
|
1134
|
+
return this._request(`/api/capabilities/${capabilityId}`, 'DELETE');
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1134
1137
|
/**
|
|
1135
1138
|
* POST /api/capabilities/:id/invoke — Invoke a governed capability.
|
|
1136
1139
|
*/
|
package/index.cjs
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* DashClaw SDK v2 (Stable Runtime API)
|
|
3
3
|
* CommonJS compatibility bridge.
|
|
4
|
-
*
|
|
4
|
+
*
|
|
5
5
|
* ESM: import { DashClaw } from 'dashclaw'
|
|
6
6
|
* CJS: const { DashClaw } = require('dashclaw')
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
const fs = require('fs');
|
|
10
|
-
const path = require('path');
|
|
11
|
-
|
|
12
9
|
// Minimal CommonJS shim for the v2 SDK
|
|
13
10
|
// We use a simplified bridge that forwards calls to the async ESM import
|
|
14
11
|
let _module;
|
|
@@ -20,6 +17,55 @@ async function loadModule() {
|
|
|
20
17
|
return _module;
|
|
21
18
|
}
|
|
22
19
|
|
|
20
|
+
// Lazy error class factory: constructs a placeholder class that delegates
|
|
21
|
+
// instanceof checks to the real ESM class once the module loads, matching
|
|
22
|
+
// the Symbol.hasInstance pattern from legacy/index-v1.cjs so that
|
|
23
|
+
// catch(e) { if (e instanceof ApprovalDeniedError) } works across the
|
|
24
|
+
// ESM/CJS boundary.
|
|
25
|
+
function makeLazyErrorClass(name) {
|
|
26
|
+
const Placeholder = class extends Error {
|
|
27
|
+
constructor(...args) {
|
|
28
|
+
super(...args);
|
|
29
|
+
this.name = name;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
Object.defineProperty(Placeholder, 'name', { value: name });
|
|
33
|
+
loadModule().then(m => {
|
|
34
|
+
if (m[name]) {
|
|
35
|
+
Object.defineProperty(Placeholder, Symbol.hasInstance, {
|
|
36
|
+
value: (instance) => instance && (instance.name === name || instance instanceof m[name])
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return Placeholder;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Recursive deferred proxy. Each property access records the access path and
|
|
44
|
+
// returns another callable proxy; invoking the leaf awaits the async ESM import,
|
|
45
|
+
// walks the path on the resolved instance, and calls the real method. This makes
|
|
46
|
+
// both flat methods (client.guard(...)) and nested namespaces
|
|
47
|
+
// (client.execution.capabilities.list(...)) work across the CJS bridge, where the
|
|
48
|
+
// ESM instance only exists after an async import.
|
|
49
|
+
function makeDeferred(target, path) {
|
|
50
|
+
return new Proxy(function () {}, {
|
|
51
|
+
get(_t, prop) {
|
|
52
|
+
if (prop === 'then' || typeof prop === 'symbol') return undefined;
|
|
53
|
+
return makeDeferred(target, path.concat(String(prop)));
|
|
54
|
+
},
|
|
55
|
+
apply(_t, _thisArg, args) {
|
|
56
|
+
return target._ready.then(() => {
|
|
57
|
+
let parent = target._instance;
|
|
58
|
+
for (let i = 0; i < path.length - 1; i++) parent = parent[path[i]];
|
|
59
|
+
const leaf = parent && parent[path[path.length - 1]];
|
|
60
|
+
if (typeof leaf !== 'function') {
|
|
61
|
+
throw new Error(`Method ${path.join('.')} does not exist on DashClaw v2`);
|
|
62
|
+
}
|
|
63
|
+
return leaf.apply(parent, args);
|
|
64
|
+
});
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
23
69
|
module.exports = {
|
|
24
70
|
// Sync wrapper that returns a proxy for the DashClaw class
|
|
25
71
|
DashClaw: class DashClawProxy {
|
|
@@ -32,15 +78,10 @@ module.exports = {
|
|
|
32
78
|
return new Proxy(this, {
|
|
33
79
|
get(target, prop) {
|
|
34
80
|
if (prop in target) return target[prop];
|
|
35
|
-
if (prop === 'then') return undefined;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (!target._instance[prop]) {
|
|
40
|
-
throw new Error(`Method ${String(prop)} does not exist on DashClaw v2`);
|
|
41
|
-
}
|
|
42
|
-
return target._instance[prop](...args);
|
|
43
|
-
};
|
|
81
|
+
if (prop === 'then' || typeof prop === 'symbol') return undefined;
|
|
82
|
+
// Defer to the async ESM instance; supports flat methods and
|
|
83
|
+
// nested namespaces (e.g. client.execution.capabilities.list(...)).
|
|
84
|
+
return makeDeferred(target, [String(prop)]);
|
|
44
85
|
}
|
|
45
86
|
});
|
|
46
87
|
}
|
|
@@ -51,20 +92,8 @@ module.exports = {
|
|
|
51
92
|
}
|
|
52
93
|
},
|
|
53
94
|
|
|
54
|
-
// Errors from v2
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
this.name = 'ApprovalDeniedError';
|
|
59
|
-
this.decision = decision;
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
|
|
63
|
-
GuardBlockedError: class GuardBlockedError extends Error {
|
|
64
|
-
constructor(decision) {
|
|
65
|
-
super(decision.reason || 'Action blocked by policy');
|
|
66
|
-
this.name = 'GuardBlockedError';
|
|
67
|
-
this.decision = decision;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
95
|
+
// Errors from v2 — lazy re-exports that resolve instanceof across the
|
|
96
|
+
// ESM/CJS boundary once the module has loaded.
|
|
97
|
+
ApprovalDeniedError: makeLazyErrorClass('ApprovalDeniedError'),
|
|
98
|
+
GuardBlockedError: makeLazyErrorClass('GuardBlockedError'),
|
|
70
99
|
};
|
package/legacy/dashclaw-v1.js
CHANGED
|
@@ -1419,6 +1419,7 @@ class DashClaw {
|
|
|
1419
1419
|
|
|
1420
1420
|
/**
|
|
1421
1421
|
* Capture a key point from the current session.
|
|
1422
|
+
* @deprecated The /api/context/points endpoint was retired in platform v4. This method always 404s.
|
|
1422
1423
|
* @param {Object} point
|
|
1423
1424
|
* @param {string} point.content - The key point content
|
|
1424
1425
|
* @param {string} [point.category] - One of: decision, task, insight, question, general
|
|
@@ -1427,6 +1428,7 @@ class DashClaw {
|
|
|
1427
1428
|
* @returns {Promise<{point: Object, point_id: string}>}
|
|
1428
1429
|
*/
|
|
1429
1430
|
async captureKeyPoint(point) {
|
|
1431
|
+
console.warn('[DashClaw] captureKeyPoint targets a retired endpoint (/api/context/points) and will 404. Upgrade to platform v4+.');
|
|
1430
1432
|
return this._request('/api/context/points', 'POST', {
|
|
1431
1433
|
agent_id: this.agentId,
|
|
1432
1434
|
...point
|
|
@@ -1435,6 +1437,7 @@ class DashClaw {
|
|
|
1435
1437
|
|
|
1436
1438
|
/**
|
|
1437
1439
|
* Get key points with optional filters.
|
|
1440
|
+
* @deprecated The /api/context/points endpoint was retired in platform v4. This method always 404s.
|
|
1438
1441
|
* @param {Object} [filters]
|
|
1439
1442
|
* @param {string} [filters.category] - Filter by category
|
|
1440
1443
|
* @param {string} [filters.session_date] - Filter by date
|
|
@@ -1442,6 +1445,7 @@ class DashClaw {
|
|
|
1442
1445
|
* @returns {Promise<{points: Object[], total: number}>}
|
|
1443
1446
|
*/
|
|
1444
1447
|
async getKeyPoints(filters = {}) {
|
|
1448
|
+
console.warn('[DashClaw] getKeyPoints targets a retired endpoint (/api/context/points) and will 404. Upgrade to platform v4+.');
|
|
1445
1449
|
const params = new URLSearchParams({ agent_id: this.agentId });
|
|
1446
1450
|
if (filters.category) params.set('category', filters.category);
|
|
1447
1451
|
if (filters.session_date) params.set('session_date', filters.session_date);
|
|
@@ -1451,12 +1455,14 @@ class DashClaw {
|
|
|
1451
1455
|
|
|
1452
1456
|
/**
|
|
1453
1457
|
* Create a context thread for tracking a topic across entries.
|
|
1458
|
+
* @deprecated The /api/context/threads endpoint was retired in platform v4. This method always 404s.
|
|
1454
1459
|
* @param {Object} thread
|
|
1455
1460
|
* @param {string} thread.name - Thread name (unique per agent per org)
|
|
1456
1461
|
* @param {string} [thread.summary] - Initial summary
|
|
1457
1462
|
* @returns {Promise<{thread: Object, thread_id: string}>}
|
|
1458
1463
|
*/
|
|
1459
1464
|
async createThread(thread) {
|
|
1465
|
+
console.warn('[DashClaw] createThread targets a retired endpoint (/api/context/threads) and will 404. Upgrade to platform v4+.');
|
|
1460
1466
|
return this._request('/api/context/threads', 'POST', {
|
|
1461
1467
|
agent_id: this.agentId,
|
|
1462
1468
|
...thread
|
|
@@ -1465,12 +1471,14 @@ class DashClaw {
|
|
|
1465
1471
|
|
|
1466
1472
|
/**
|
|
1467
1473
|
* Add an entry to an existing thread.
|
|
1474
|
+
* @deprecated The /api/context/threads endpoint was retired in platform v4. This method always 404s.
|
|
1468
1475
|
* @param {string} threadId - The thread ID
|
|
1469
1476
|
* @param {string} content - Entry content
|
|
1470
1477
|
* @param {string} [entryType] - Entry type (default: 'note')
|
|
1471
1478
|
* @returns {Promise<{entry: Object, entry_id: string}>}
|
|
1472
1479
|
*/
|
|
1473
1480
|
async addThreadEntry(threadId, content, entryType) {
|
|
1481
|
+
console.warn('[DashClaw] addThreadEntry targets a retired endpoint (/api/context/threads) and will 404. Upgrade to platform v4+.');
|
|
1474
1482
|
return this._request(`/api/context/threads/${threadId}/entries`, 'POST', {
|
|
1475
1483
|
content,
|
|
1476
1484
|
entry_type: entryType || 'note'
|
|
@@ -1479,11 +1487,13 @@ class DashClaw {
|
|
|
1479
1487
|
|
|
1480
1488
|
/**
|
|
1481
1489
|
* Close a thread with an optional summary.
|
|
1490
|
+
* @deprecated The /api/context/threads endpoint was retired in platform v4. This method always 404s.
|
|
1482
1491
|
* @param {string} threadId - The thread ID
|
|
1483
1492
|
* @param {string} [summary] - Final summary
|
|
1484
1493
|
* @returns {Promise<{thread: Object}>}
|
|
1485
1494
|
*/
|
|
1486
1495
|
async closeThread(threadId, summary) {
|
|
1496
|
+
console.warn('[DashClaw] closeThread targets a retired endpoint (/api/context/threads) and will 404. Upgrade to platform v4+.');
|
|
1487
1497
|
const body = { status: 'closed' };
|
|
1488
1498
|
if (summary) body.summary = summary;
|
|
1489
1499
|
return this._request(`/api/context/threads/${threadId}`, 'PATCH', body);
|
|
@@ -1491,12 +1501,14 @@ class DashClaw {
|
|
|
1491
1501
|
|
|
1492
1502
|
/**
|
|
1493
1503
|
* Get threads with optional filters.
|
|
1504
|
+
* @deprecated The /api/context/threads endpoint was retired in platform v4. This method always 404s.
|
|
1494
1505
|
* @param {Object} [filters]
|
|
1495
1506
|
* @param {string} [filters.status] - Filter by status (active, closed)
|
|
1496
1507
|
* @param {number} [filters.limit] - Max results
|
|
1497
1508
|
* @returns {Promise<{threads: Object[], total: number}>}
|
|
1498
1509
|
*/
|
|
1499
1510
|
async getThreads(filters = {}) {
|
|
1511
|
+
console.warn('[DashClaw] getThreads targets a retired endpoint (/api/context/threads) and will 404. Upgrade to platform v4+.');
|
|
1500
1512
|
const params = new URLSearchParams({ agent_id: this.agentId });
|
|
1501
1513
|
if (filters.status) params.set('status', filters.status);
|
|
1502
1514
|
if (filters.limit) params.set('limit', String(filters.limit));
|
|
@@ -1505,9 +1517,11 @@ class DashClaw {
|
|
|
1505
1517
|
|
|
1506
1518
|
/**
|
|
1507
1519
|
* Get a combined context summary: today's key points + active threads.
|
|
1520
|
+
* @deprecated The /api/context endpoints were retired in platform v4. This method always 404s.
|
|
1508
1521
|
* @returns {Promise<{points: Object[], threads: Object[]}>}
|
|
1509
1522
|
*/
|
|
1510
1523
|
async getContextSummary() {
|
|
1524
|
+
console.warn('[DashClaw] getContextSummary targets retired endpoints (/api/context/*) and will 404. Upgrade to platform v4+.');
|
|
1511
1525
|
const today = new Date().toISOString().split('T')[0];
|
|
1512
1526
|
const [pointsResult, threadsResult] = await Promise.all([
|
|
1513
1527
|
this.getKeyPoints({ session_date: today }),
|
|
@@ -1793,11 +1807,6 @@ class DashClaw {
|
|
|
1793
1807
|
return this._request(`/api/messages?${params}`, 'GET');
|
|
1794
1808
|
}
|
|
1795
1809
|
|
|
1796
|
-
/**
|
|
1797
|
-
* Mark messages as read.
|
|
1798
|
-
* @param {string[]} messageIds - Array of message IDs to mark read
|
|
1799
|
-
* @returns {Promise<{updated: number}>}
|
|
1800
|
-
*/
|
|
1801
1810
|
/**
|
|
1802
1811
|
* Get sent messages from this agent.
|
|
1803
1812
|
* @param {Object} [params]
|
|
@@ -2818,10 +2827,12 @@ class DashClaw {
|
|
|
2818
2827
|
}
|
|
2819
2828
|
|
|
2820
2829
|
async scoreWithProfile(profileId, action) {
|
|
2830
|
+
if (Array.isArray(action)) throw new TypeError('use batchScoreWithProfile for arrays');
|
|
2821
2831
|
return this._request('POST', '/api/scoring/score', { profile_id: profileId, action });
|
|
2822
2832
|
}
|
|
2823
2833
|
|
|
2824
2834
|
async batchScoreWithProfile(profileId, actions) {
|
|
2835
|
+
if (!Array.isArray(actions)) throw new TypeError('batchScoreWithProfile expects an array');
|
|
2825
2836
|
return this._request('POST', '/api/scoring/score', { profile_id: profileId, actions });
|
|
2826
2837
|
}
|
|
2827
2838
|
|