dashclaw 1.8.0 → 1.8.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 +642 -1
- package/dashclaw.js +316 -8
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Full reference for the DashClaw SDK (Node.js). For Python, see the [Python SDK docs](../sdk-python/README.md).
|
|
4
4
|
|
|
5
|
-
Install, configure, and instrument your AI agents with
|
|
5
|
+
Install, configure, and instrument your AI agents with 95+ methods across 21+ categories including action recording, behavior guard, context management, session handoffs, security scanning, agent messaging, agent pairing, identity binding, organization management, webhooks, policy testing, compliance, task routing, and more.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -239,6 +239,54 @@ Stream actions live to the dashboard as they happen.
|
|
|
239
239
|
|
|
240
240
|
---
|
|
241
241
|
|
|
242
|
+
## Real-Time Events
|
|
243
|
+
|
|
244
|
+
Subscribe to server-sent events (SSE) for instant push notifications. Eliminates polling for approvals, policy changes, and task assignments.
|
|
245
|
+
|
|
246
|
+
### claw.events()
|
|
247
|
+
|
|
248
|
+
Open a persistent SSE connection. Returns a chainable handle with `.on(event, callback)` and `.close()`.
|
|
249
|
+
|
|
250
|
+
**Supported events:** `action.created`, `action.updated`, `message.created`, `policy.updated`, `task.assigned`, `task.completed`
|
|
251
|
+
|
|
252
|
+
```javascript
|
|
253
|
+
const stream = claw.events();
|
|
254
|
+
|
|
255
|
+
stream
|
|
256
|
+
.on('action.created', (data) => console.log('New action:', data.action_id))
|
|
257
|
+
.on('action.updated', (data) => {
|
|
258
|
+
if (data.status === 'running') console.log('Approved:', data.action_id);
|
|
259
|
+
})
|
|
260
|
+
.on('policy.updated', (data) => console.log('Policy changed:', data.change_type))
|
|
261
|
+
.on('task.assigned', (data) => console.log('Task routed:', data.task?.title))
|
|
262
|
+
.on('task.completed', (data) => console.log('Task done:', data.task?.task_id))
|
|
263
|
+
.on('error', (err) => console.error('Stream error:', err));
|
|
264
|
+
|
|
265
|
+
// When done:
|
|
266
|
+
stream.close();
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### claw.waitForApproval(actionId, { useEvents: true })
|
|
270
|
+
|
|
271
|
+
SSE-powered approval waiting — resolves instantly when the operator approves/denies instead of polling every 5 seconds.
|
|
272
|
+
|
|
273
|
+
```javascript
|
|
274
|
+
// SSE mode (instant, recommended)
|
|
275
|
+
const { action } = await claw.waitForApproval('act_abc', { useEvents: true });
|
|
276
|
+
|
|
277
|
+
// Polling mode (default, backward-compatible)
|
|
278
|
+
const { action } = await claw.waitForApproval('act_abc');
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
| Parameter | Type | Default | Description |
|
|
282
|
+
|-----------|------|---------|-------------|
|
|
283
|
+
| actionId | string | — | Action ID to watch |
|
|
284
|
+
| options.timeout | number | 300000 | Max wait time (ms) |
|
|
285
|
+
| options.interval | number | 5000 | Poll interval (polling mode only) |
|
|
286
|
+
| options.useEvents | boolean | false | Use SSE instead of polling |
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
242
290
|
## Token & Cost Analytics
|
|
243
291
|
|
|
244
292
|
Track token usage and estimated costs for every action. DashClaw automatically aggregates these into "Cost per Goal" metrics.
|
|
@@ -412,6 +460,20 @@ Retrieve recent guard evaluation decisions for audit and review.
|
|
|
412
460
|
|
|
413
461
|
Push data from your agent directly to the DashClaw dashboard. All methods auto-attach the agent's agentId.
|
|
414
462
|
|
|
463
|
+
### claw.reportTokenUsage(usage)
|
|
464
|
+
Report a token usage snapshot for this agent.
|
|
465
|
+
|
|
466
|
+
**Parameters:**
|
|
467
|
+
| Parameter | Type | Required | Description |
|
|
468
|
+
|-----------|------|----------|-------------|
|
|
469
|
+
| tokens_in | number | Yes | Input tokens consumed |
|
|
470
|
+
| tokens_out | number | Yes | Output tokens generated |
|
|
471
|
+
| context_used | number | No | Context window tokens used |
|
|
472
|
+
| context_max | number | No | Context window max capacity |
|
|
473
|
+
| model | string | No | Model name |
|
|
474
|
+
|
|
475
|
+
**Returns:** `Promise<{snapshot: Object}>`
|
|
476
|
+
|
|
415
477
|
### claw.recordDecision(entry)
|
|
416
478
|
Record a decision for the learning database. Track what your agent decides and why.
|
|
417
479
|
|
|
@@ -543,6 +605,47 @@ Report active connections/integrations for this agent.
|
|
|
543
605
|
|
|
544
606
|
**Returns:** `Promise<{ connections: Object[], created: number }>`
|
|
545
607
|
|
|
608
|
+
### claw.createCalendarEvent(event)
|
|
609
|
+
Create a calendar event.
|
|
610
|
+
|
|
611
|
+
**Parameters:**
|
|
612
|
+
| Parameter | Type | Required | Description |
|
|
613
|
+
|-----------|------|----------|-------------|
|
|
614
|
+
| summary | string | Yes | Event title/summary |
|
|
615
|
+
| start_time | string | Yes | Start time (ISO string) |
|
|
616
|
+
| end_time | string | No | End time (ISO string) |
|
|
617
|
+
| location | string | No | Event location |
|
|
618
|
+
| description | string | No | Event description |
|
|
619
|
+
|
|
620
|
+
**Returns:** `Promise<{event: Object}>`
|
|
621
|
+
|
|
622
|
+
### claw.recordIdea(idea)
|
|
623
|
+
Record an idea or inspiration for later review.
|
|
624
|
+
|
|
625
|
+
**Parameters:**
|
|
626
|
+
| Parameter | Type | Required | Description |
|
|
627
|
+
|-----------|------|----------|-------------|
|
|
628
|
+
| title | string | Yes | Idea title |
|
|
629
|
+
| description | string | No | Detailed description |
|
|
630
|
+
| category | string | No | Category |
|
|
631
|
+
| score | number | No | Priority/quality score 0-100 |
|
|
632
|
+
| status | string | No | "pending", "in_progress", "shipped", "rejected" |
|
|
633
|
+
| source | string | No | Where this idea came from |
|
|
634
|
+
|
|
635
|
+
**Returns:** `Promise<{idea: Object}>`
|
|
636
|
+
|
|
637
|
+
### claw.reportMemoryHealth(report)
|
|
638
|
+
Report a memory health snapshot with entities and topics.
|
|
639
|
+
|
|
640
|
+
**Parameters:**
|
|
641
|
+
| Parameter | Type | Required | Description |
|
|
642
|
+
|-----------|------|----------|-------------|
|
|
643
|
+
| health | Object | Yes | Health metrics (must include `score` 0-100) |
|
|
644
|
+
| entities | Object[] | No | Key entities found in memory |
|
|
645
|
+
| topics | Object[] | No | Topics/themes found in memory |
|
|
646
|
+
|
|
647
|
+
**Returns:** `Promise<{snapshot: Object, entities_count: number, topics_count: number}>`
|
|
648
|
+
|
|
546
649
|
---
|
|
547
650
|
|
|
548
651
|
## Session Handoffs
|
|
@@ -573,6 +676,20 @@ Get handoffs for this agent with optional date and limit filters.
|
|
|
573
676
|
|
|
574
677
|
**Returns:** `Promise<{handoffs: Object[], total: number}>`
|
|
575
678
|
|
|
679
|
+
### claw.getLatestHandoff()
|
|
680
|
+
Get the most recent handoff for this agent. Useful for resuming context at the start of a new session.
|
|
681
|
+
|
|
682
|
+
**Returns:** `Promise<{handoff: Object|null}>`
|
|
683
|
+
|
|
684
|
+
**Example:**
|
|
685
|
+
```javascript
|
|
686
|
+
const { handoff } = await claw.getLatestHandoff();
|
|
687
|
+
if (handoff) {
|
|
688
|
+
console.log('Last session:', handoff.summary);
|
|
689
|
+
console.log('Next priorities:', handoff.next_priorities);
|
|
690
|
+
}
|
|
691
|
+
```
|
|
692
|
+
|
|
576
693
|
---
|
|
577
694
|
|
|
578
695
|
## Context Manager
|
|
@@ -603,9 +720,63 @@ Create a context thread for tracking a topic across multiple entries.
|
|
|
603
720
|
|
|
604
721
|
**Returns:** `Promise<{thread: Object, thread_id: string}>`
|
|
605
722
|
|
|
723
|
+
### claw.getKeyPoints(filters?)
|
|
724
|
+
Get key points with optional filters.
|
|
725
|
+
|
|
726
|
+
**Parameters:**
|
|
727
|
+
| Parameter | Type | Required | Description |
|
|
728
|
+
|-----------|------|----------|-------------|
|
|
729
|
+
| category | string | No | Filter by category: decision, task, insight, question, general |
|
|
730
|
+
| session_date | string | No | Filter by date (YYYY-MM-DD) |
|
|
731
|
+
| limit | number | No | Max results |
|
|
732
|
+
|
|
733
|
+
**Returns:** `Promise<{points: Object[], total: number}>`
|
|
734
|
+
|
|
606
735
|
### claw.addThreadEntry(threadId, content, entryType?)
|
|
607
736
|
Add an entry to an existing thread.
|
|
608
737
|
|
|
738
|
+
**Parameters:**
|
|
739
|
+
| Parameter | Type | Required | Description |
|
|
740
|
+
|-----------|------|----------|-------------|
|
|
741
|
+
| threadId | string | Yes | The thread ID |
|
|
742
|
+
| content | string | Yes | Entry content |
|
|
743
|
+
| entryType | string | No | Entry type (default: "note") |
|
|
744
|
+
|
|
745
|
+
**Returns:** `Promise<{entry: Object, entry_id: string}>`
|
|
746
|
+
|
|
747
|
+
### claw.closeThread(threadId, summary?)
|
|
748
|
+
Close a context thread with an optional final summary.
|
|
749
|
+
|
|
750
|
+
**Parameters:**
|
|
751
|
+
| Parameter | Type | Required | Description |
|
|
752
|
+
|-----------|------|----------|-------------|
|
|
753
|
+
| threadId | string | Yes | The thread ID to close |
|
|
754
|
+
| summary | string | No | Final summary for the thread |
|
|
755
|
+
|
|
756
|
+
**Returns:** `Promise<{thread: Object}>`
|
|
757
|
+
|
|
758
|
+
### claw.getThreads(filters?)
|
|
759
|
+
Get context threads with optional filters.
|
|
760
|
+
|
|
761
|
+
**Parameters:**
|
|
762
|
+
| Parameter | Type | Required | Description |
|
|
763
|
+
|-----------|------|----------|-------------|
|
|
764
|
+
| status | string | No | Filter by status: active, closed |
|
|
765
|
+
| limit | number | No | Max results |
|
|
766
|
+
|
|
767
|
+
**Returns:** `Promise<{threads: Object[], total: number}>`
|
|
768
|
+
|
|
769
|
+
### claw.getContextSummary()
|
|
770
|
+
Get a combined context summary containing today's key points and all active threads. Convenience method that calls `getKeyPoints()` and `getThreads()` in parallel.
|
|
771
|
+
|
|
772
|
+
**Returns:** `Promise<{points: Object[], threads: Object[]}>`
|
|
773
|
+
|
|
774
|
+
**Example:**
|
|
775
|
+
```javascript
|
|
776
|
+
const { points, threads } = await claw.getContextSummary();
|
|
777
|
+
console.log(`${points.length} key points today, ${threads.length} active threads`);
|
|
778
|
+
```
|
|
779
|
+
|
|
609
780
|
---
|
|
610
781
|
|
|
611
782
|
## Automation Snippets
|
|
@@ -702,6 +873,144 @@ await claw.deleteSnippet('sn_abc123');
|
|
|
702
873
|
|
|
703
874
|
---
|
|
704
875
|
|
|
876
|
+
## User Preferences
|
|
877
|
+
|
|
878
|
+
Track user observations, learned preferences, mood/energy, and approach effectiveness across sessions.
|
|
879
|
+
|
|
880
|
+
### claw.logObservation(obs)
|
|
881
|
+
Log a user observation (what you noticed about the user's behavior or preferences).
|
|
882
|
+
|
|
883
|
+
**Parameters:**
|
|
884
|
+
| Parameter | Type | Required | Description |
|
|
885
|
+
|-----------|------|----------|-------------|
|
|
886
|
+
| observation | string | Yes | The observation text |
|
|
887
|
+
| category | string | No | Category tag |
|
|
888
|
+
| importance | number | No | Importance 1-10 |
|
|
889
|
+
|
|
890
|
+
**Returns:** `Promise<{observation: Object, observation_id: string}>`
|
|
891
|
+
|
|
892
|
+
**Example:**
|
|
893
|
+
```javascript
|
|
894
|
+
await claw.logObservation({
|
|
895
|
+
observation: 'User prefers concise responses over detailed explanations',
|
|
896
|
+
category: 'communication',
|
|
897
|
+
importance: 8,
|
|
898
|
+
});
|
|
899
|
+
```
|
|
900
|
+
|
|
901
|
+
### claw.setPreference(pref)
|
|
902
|
+
Set a learned user preference. Use this to record patterns you detect about how the user likes to work.
|
|
903
|
+
|
|
904
|
+
**Parameters:**
|
|
905
|
+
| Parameter | Type | Required | Description |
|
|
906
|
+
|-----------|------|----------|-------------|
|
|
907
|
+
| preference | string | Yes | The preference description |
|
|
908
|
+
| category | string | No | Category tag |
|
|
909
|
+
| confidence | number | No | Confidence 0-100 |
|
|
910
|
+
|
|
911
|
+
**Returns:** `Promise<{preference: Object, preference_id: string}>`
|
|
912
|
+
|
|
913
|
+
### claw.logMood(entry)
|
|
914
|
+
Log user mood/energy for a session. Helps track patterns in productivity and satisfaction.
|
|
915
|
+
|
|
916
|
+
**Parameters:**
|
|
917
|
+
| Parameter | Type | Required | Description |
|
|
918
|
+
|-----------|------|----------|-------------|
|
|
919
|
+
| mood | string | Yes | Mood description (e.g., "focused", "frustrated") |
|
|
920
|
+
| energy | string | No | Energy level (e.g., "high", "low") |
|
|
921
|
+
| notes | string | No | Additional notes |
|
|
922
|
+
|
|
923
|
+
**Returns:** `Promise<{mood: Object, mood_id: string}>`
|
|
924
|
+
|
|
925
|
+
### claw.trackApproach(entry)
|
|
926
|
+
Track an approach and whether it succeeded or failed. Builds a knowledge base of what works.
|
|
927
|
+
|
|
928
|
+
**Parameters:**
|
|
929
|
+
| Parameter | Type | Required | Description |
|
|
930
|
+
|-----------|------|----------|-------------|
|
|
931
|
+
| approach | string | Yes | The approach description |
|
|
932
|
+
| context | string | No | Context for when to use this approach |
|
|
933
|
+
| success | boolean | No | true = worked, false = failed, undefined = just recording |
|
|
934
|
+
|
|
935
|
+
**Returns:** `Promise<{approach: Object, approach_id: string}>`
|
|
936
|
+
|
|
937
|
+
### claw.getPreferenceSummary()
|
|
938
|
+
Get a summary of all user preference data including observations, preferences, moods, and approaches.
|
|
939
|
+
|
|
940
|
+
**Returns:** `Promise<{summary: Object}>`
|
|
941
|
+
|
|
942
|
+
### claw.getApproaches(filters?)
|
|
943
|
+
Get tracked approaches with success/fail counts.
|
|
944
|
+
|
|
945
|
+
**Parameters:**
|
|
946
|
+
| Parameter | Type | Required | Description |
|
|
947
|
+
|-----------|------|----------|-------------|
|
|
948
|
+
| limit | number | No | Max results |
|
|
949
|
+
|
|
950
|
+
**Returns:** `Promise<{approaches: Object[], total: number}>`
|
|
951
|
+
|
|
952
|
+
---
|
|
953
|
+
|
|
954
|
+
## Daily Digest
|
|
955
|
+
|
|
956
|
+
### claw.getDailyDigest(date?)
|
|
957
|
+
Get a daily activity digest aggregated from all data sources (actions, decisions, handoffs, context, etc.).
|
|
958
|
+
|
|
959
|
+
**Parameters:**
|
|
960
|
+
| Parameter | Type | Required | Description |
|
|
961
|
+
|-----------|------|----------|-------------|
|
|
962
|
+
| date | string | No | Date string YYYY-MM-DD (defaults to today) |
|
|
963
|
+
|
|
964
|
+
**Returns:** `Promise<{date: string, digest: Object, summary: Object}>`
|
|
965
|
+
|
|
966
|
+
**Example:**
|
|
967
|
+
```javascript
|
|
968
|
+
const { digest, summary } = await claw.getDailyDigest('2025-01-15');
|
|
969
|
+
console.log(`Actions: ${summary.actions_count}, Decisions: ${summary.decisions_count}`);
|
|
970
|
+
```
|
|
971
|
+
|
|
972
|
+
---
|
|
973
|
+
|
|
974
|
+
## Security Scanning
|
|
975
|
+
|
|
976
|
+
Scan text for sensitive data before sending it anywhere. The scanner detects API keys, tokens, PII, and other secrets.
|
|
977
|
+
|
|
978
|
+
### claw.scanContent(text, destination?)
|
|
979
|
+
Scan text for sensitive data. Returns findings and redacted text. Does NOT store the original content.
|
|
980
|
+
|
|
981
|
+
**Parameters:**
|
|
982
|
+
| Parameter | Type | Required | Description |
|
|
983
|
+
|-----------|------|----------|-------------|
|
|
984
|
+
| text | string | Yes | Text to scan |
|
|
985
|
+
| destination | string | No | Where this text is headed (for context) |
|
|
986
|
+
|
|
987
|
+
**Returns:** `Promise<{clean: boolean, findings_count: number, findings: Object[], redacted_text: string}>`
|
|
988
|
+
|
|
989
|
+
**Example:**
|
|
990
|
+
```javascript
|
|
991
|
+
const result = await claw.scanContent(
|
|
992
|
+
'Deploy with key sk-abc123xyz to production',
|
|
993
|
+
'slack'
|
|
994
|
+
);
|
|
995
|
+
if (!result.clean) {
|
|
996
|
+
console.log(`Found ${result.findings_count} issues`);
|
|
997
|
+
console.log('Safe version:', result.redacted_text);
|
|
998
|
+
}
|
|
999
|
+
```
|
|
1000
|
+
|
|
1001
|
+
### claw.reportSecurityFinding(text, destination?)
|
|
1002
|
+
Scan text and store finding metadata for audit trails. The original content is never stored, only the finding metadata.
|
|
1003
|
+
|
|
1004
|
+
**Parameters:**
|
|
1005
|
+
| Parameter | Type | Required | Description |
|
|
1006
|
+
|-----------|------|----------|-------------|
|
|
1007
|
+
| text | string | Yes | Text to scan |
|
|
1008
|
+
| destination | string | No | Where this text is headed |
|
|
1009
|
+
|
|
1010
|
+
**Returns:** `Promise<{clean: boolean, findings_count: number, findings: Object[], redacted_text: string}>`
|
|
1011
|
+
|
|
1012
|
+
---
|
|
1013
|
+
|
|
705
1014
|
## Agent Messaging
|
|
706
1015
|
|
|
707
1016
|
### claw.sendMessage(params)
|
|
@@ -720,9 +1029,298 @@ Send a message to another agent or broadcast.
|
|
|
720
1029
|
|
|
721
1030
|
**Returns:** `Promise<{message: Object, message_id: string}>`
|
|
722
1031
|
|
|
1032
|
+
### claw.getInbox(params?)
|
|
1033
|
+
Get inbox messages for this agent.
|
|
1034
|
+
|
|
1035
|
+
**Parameters:**
|
|
1036
|
+
| Parameter | Type | Required | Description |
|
|
1037
|
+
|-----------|------|----------|-------------|
|
|
1038
|
+
| type | string | No | Filter by message type |
|
|
1039
|
+
| unread | boolean | No | Only unread messages |
|
|
1040
|
+
| threadId | string | No | Filter by thread |
|
|
1041
|
+
| limit | number | No | Max messages to return (default: 50) |
|
|
1042
|
+
|
|
1043
|
+
**Returns:** `Promise<{messages: Object[], total: number, unread_count: number}>`
|
|
1044
|
+
|
|
1045
|
+
### claw.markRead(messageIds)
|
|
1046
|
+
Mark messages as read.
|
|
1047
|
+
|
|
1048
|
+
**Parameters:**
|
|
1049
|
+
| Parameter | Type | Required | Description |
|
|
1050
|
+
|-----------|------|----------|-------------|
|
|
1051
|
+
| messageIds | string[] | Yes | Array of message IDs to mark read |
|
|
1052
|
+
|
|
1053
|
+
**Returns:** `Promise<{updated: number}>`
|
|
1054
|
+
|
|
1055
|
+
### claw.archiveMessages(messageIds)
|
|
1056
|
+
Archive messages.
|
|
1057
|
+
|
|
1058
|
+
**Parameters:**
|
|
1059
|
+
| Parameter | Type | Required | Description |
|
|
1060
|
+
|-----------|------|----------|-------------|
|
|
1061
|
+
| messageIds | string[] | Yes | Array of message IDs to archive |
|
|
1062
|
+
|
|
1063
|
+
**Returns:** `Promise<{updated: number}>`
|
|
1064
|
+
|
|
1065
|
+
### claw.broadcast(params)
|
|
1066
|
+
Broadcast a message to all agents in the organization.
|
|
1067
|
+
|
|
1068
|
+
**Parameters:**
|
|
1069
|
+
| Parameter | Type | Required | Description |
|
|
1070
|
+
|-----------|------|----------|-------------|
|
|
1071
|
+
| type | string | No | Message type (default: "info") |
|
|
1072
|
+
| subject | string | No | Subject line |
|
|
1073
|
+
| body | string | Yes | Message body |
|
|
1074
|
+
| threadId | string | No | Thread ID |
|
|
1075
|
+
|
|
1076
|
+
**Returns:** `Promise<{message: Object, message_id: string}>`
|
|
1077
|
+
|
|
1078
|
+
### claw.createMessageThread(params)
|
|
1079
|
+
Create a new message thread for multi-turn conversations between agents.
|
|
1080
|
+
|
|
1081
|
+
**Parameters:**
|
|
1082
|
+
| Parameter | Type | Required | Description |
|
|
1083
|
+
|-----------|------|----------|-------------|
|
|
1084
|
+
| name | string | Yes | Thread name |
|
|
1085
|
+
| participants | string[] | No | Agent IDs (null = open to all) |
|
|
1086
|
+
|
|
1087
|
+
**Returns:** `Promise<{thread: Object, thread_id: string}>`
|
|
1088
|
+
|
|
1089
|
+
### claw.getMessageThreads(params?)
|
|
1090
|
+
List message threads.
|
|
1091
|
+
|
|
1092
|
+
**Parameters:**
|
|
1093
|
+
| Parameter | Type | Required | Description |
|
|
1094
|
+
|-----------|------|----------|-------------|
|
|
1095
|
+
| status | string | No | Filter by status: open, resolved, archived |
|
|
1096
|
+
| limit | number | No | Max threads to return (default: 20) |
|
|
1097
|
+
|
|
1098
|
+
**Returns:** `Promise<{threads: Object[], total: number}>`
|
|
1099
|
+
|
|
1100
|
+
### claw.resolveMessageThread(threadId, summary?)
|
|
1101
|
+
Resolve (close) a message thread with an optional summary.
|
|
1102
|
+
|
|
1103
|
+
**Parameters:**
|
|
1104
|
+
| Parameter | Type | Required | Description |
|
|
1105
|
+
|-----------|------|----------|-------------|
|
|
1106
|
+
| threadId | string | Yes | Thread ID to resolve |
|
|
1107
|
+
| summary | string | No | Resolution summary |
|
|
1108
|
+
|
|
1109
|
+
**Returns:** `Promise<{thread: Object}>`
|
|
1110
|
+
|
|
723
1111
|
### claw.saveSharedDoc(params)
|
|
724
1112
|
Create or update a shared workspace document. Upserts by name.
|
|
725
1113
|
|
|
1114
|
+
**Parameters:**
|
|
1115
|
+
| Parameter | Type | Required | Description |
|
|
1116
|
+
|-----------|------|----------|-------------|
|
|
1117
|
+
| name | string | Yes | Document name (unique per org) |
|
|
1118
|
+
| content | string | Yes | Document content |
|
|
1119
|
+
|
|
1120
|
+
**Returns:** `Promise<{doc: Object, doc_id: string}>`
|
|
1121
|
+
|
|
1122
|
+
---
|
|
1123
|
+
|
|
1124
|
+
## Agent Pairing
|
|
1125
|
+
|
|
1126
|
+
Pair agents with user accounts via public key registration and approval flow.
|
|
1127
|
+
|
|
1128
|
+
### claw.createPairing(options)
|
|
1129
|
+
Create an agent pairing request. Returns a link the user can click to approve the pairing.
|
|
1130
|
+
|
|
1131
|
+
**Parameters:**
|
|
1132
|
+
| Parameter | Type | Required | Description |
|
|
1133
|
+
|-----------|------|----------|-------------|
|
|
1134
|
+
| publicKeyPem | string | Yes | PEM public key (SPKI format) to register for this agent |
|
|
1135
|
+
| algorithm | string | No | Signing algorithm (default: "RSASSA-PKCS1-v1_5") |
|
|
1136
|
+
| agentName | string | No | Agent name override |
|
|
1137
|
+
|
|
1138
|
+
**Returns:** `Promise<{pairing: Object, pairing_url: string}>`
|
|
1139
|
+
|
|
1140
|
+
### claw.createPairingFromPrivateJwk(privateJwk, options?)
|
|
1141
|
+
Convenience method that derives the public PEM from a private JWK and creates a pairing request.
|
|
1142
|
+
|
|
1143
|
+
**Parameters:**
|
|
1144
|
+
| Parameter | Type | Required | Description |
|
|
1145
|
+
|-----------|------|----------|-------------|
|
|
1146
|
+
| privateJwk | Object | Yes | Private key in JWK format |
|
|
1147
|
+
| options.agentName | string | No | Agent name override |
|
|
1148
|
+
|
|
1149
|
+
**Returns:** `Promise<{pairing: Object, pairing_url: string}>`
|
|
1150
|
+
|
|
1151
|
+
### claw.waitForPairing(pairingId, options?)
|
|
1152
|
+
Poll a pairing request until it is approved or expired.
|
|
1153
|
+
|
|
1154
|
+
**Parameters:**
|
|
1155
|
+
| Parameter | Type | Required | Description |
|
|
1156
|
+
|-----------|------|----------|-------------|
|
|
1157
|
+
| pairingId | string | Yes | The pairing ID to poll |
|
|
1158
|
+
| options.timeout | number | No | Max wait time in ms (default: 300000 / 5 min) |
|
|
1159
|
+
| options.interval | number | No | Poll interval in ms (default: 2000) |
|
|
1160
|
+
|
|
1161
|
+
**Returns:** `Promise<Object>` (the approved pairing object)
|
|
1162
|
+
|
|
1163
|
+
**Throws:** `Error` if pairing expires or times out.
|
|
1164
|
+
|
|
1165
|
+
**Example:**
|
|
1166
|
+
```javascript
|
|
1167
|
+
const { pairing, pairing_url } = await claw.createPairing({
|
|
1168
|
+
publicKeyPem: myPublicKeyPem,
|
|
1169
|
+
});
|
|
1170
|
+
console.log('Approve pairing at:', pairing_url);
|
|
1171
|
+
|
|
1172
|
+
const approved = await claw.waitForPairing(pairing.id);
|
|
1173
|
+
console.log('Pairing approved!', approved.status);
|
|
1174
|
+
```
|
|
1175
|
+
|
|
1176
|
+
---
|
|
1177
|
+
|
|
1178
|
+
## Identity Binding
|
|
1179
|
+
|
|
1180
|
+
Register and manage agent public keys for cryptographic identity verification.
|
|
1181
|
+
|
|
1182
|
+
### claw.registerIdentity(identity)
|
|
1183
|
+
Register or update an agent's public key for identity verification. Requires admin API key.
|
|
1184
|
+
|
|
1185
|
+
**Parameters:**
|
|
1186
|
+
| Parameter | Type | Required | Description |
|
|
1187
|
+
|-----------|------|----------|-------------|
|
|
1188
|
+
| agent_id | string | Yes | Agent ID to register |
|
|
1189
|
+
| public_key | string | Yes | PEM public key (SPKI format) |
|
|
1190
|
+
| algorithm | string | No | Signing algorithm (default: "RSASSA-PKCS1-v1_5") |
|
|
1191
|
+
|
|
1192
|
+
**Returns:** `Promise<{identity: Object}>`
|
|
1193
|
+
|
|
1194
|
+
### claw.getIdentities()
|
|
1195
|
+
List all registered agent identities for this organization.
|
|
1196
|
+
|
|
1197
|
+
**Returns:** `Promise<{identities: Object[]}>`
|
|
1198
|
+
|
|
1199
|
+
---
|
|
1200
|
+
|
|
1201
|
+
## Organization Management
|
|
1202
|
+
|
|
1203
|
+
Manage organizations and API keys. All methods require admin API key.
|
|
1204
|
+
|
|
1205
|
+
### claw.getOrg()
|
|
1206
|
+
Get the current organization's details.
|
|
1207
|
+
|
|
1208
|
+
**Returns:** `Promise<{organizations: Object[]}>`
|
|
1209
|
+
|
|
1210
|
+
### claw.createOrg(org)
|
|
1211
|
+
Create a new organization with an initial admin API key.
|
|
1212
|
+
|
|
1213
|
+
**Parameters:**
|
|
1214
|
+
| Parameter | Type | Required | Description |
|
|
1215
|
+
|-----------|------|----------|-------------|
|
|
1216
|
+
| name | string | Yes | Organization name |
|
|
1217
|
+
| slug | string | Yes | URL-safe slug (lowercase alphanumeric + hyphens) |
|
|
1218
|
+
|
|
1219
|
+
**Returns:** `Promise<{organization: Object, api_key: Object}>`
|
|
1220
|
+
|
|
1221
|
+
### claw.getOrgById(orgId)
|
|
1222
|
+
Get organization details by ID.
|
|
1223
|
+
|
|
1224
|
+
**Parameters:**
|
|
1225
|
+
| Parameter | Type | Required | Description |
|
|
1226
|
+
|-----------|------|----------|-------------|
|
|
1227
|
+
| orgId | string | Yes | Organization ID |
|
|
1228
|
+
|
|
1229
|
+
**Returns:** `Promise<{organization: Object}>`
|
|
1230
|
+
|
|
1231
|
+
### claw.updateOrg(orgId, updates)
|
|
1232
|
+
Update organization details.
|
|
1233
|
+
|
|
1234
|
+
**Parameters:**
|
|
1235
|
+
| Parameter | Type | Required | Description |
|
|
1236
|
+
|-----------|------|----------|-------------|
|
|
1237
|
+
| orgId | string | Yes | Organization ID |
|
|
1238
|
+
| updates | Object | Yes | Fields to update (name, slug) |
|
|
1239
|
+
|
|
1240
|
+
**Returns:** `Promise<{organization: Object}>`
|
|
1241
|
+
|
|
1242
|
+
### claw.getOrgKeys(orgId)
|
|
1243
|
+
List API keys for an organization.
|
|
1244
|
+
|
|
1245
|
+
**Parameters:**
|
|
1246
|
+
| Parameter | Type | Required | Description |
|
|
1247
|
+
|-----------|------|----------|-------------|
|
|
1248
|
+
| orgId | string | Yes | Organization ID |
|
|
1249
|
+
|
|
1250
|
+
**Returns:** `Promise<{keys: Object[]}>`
|
|
1251
|
+
|
|
1252
|
+
---
|
|
1253
|
+
|
|
1254
|
+
## Activity Logs
|
|
1255
|
+
|
|
1256
|
+
### claw.getActivityLogs(filters?)
|
|
1257
|
+
Get activity/audit logs for the organization.
|
|
1258
|
+
|
|
1259
|
+
**Parameters:**
|
|
1260
|
+
| Parameter | Type | Required | Description |
|
|
1261
|
+
|-----------|------|----------|-------------|
|
|
1262
|
+
| action | string | No | Filter by action type |
|
|
1263
|
+
| actor_id | string | No | Filter by actor |
|
|
1264
|
+
| resource_type | string | No | Filter by resource type |
|
|
1265
|
+
| before | string | No | Before timestamp (ISO string) |
|
|
1266
|
+
| after | string | No | After timestamp (ISO string) |
|
|
1267
|
+
| limit | number | No | Max results (default: 50, max: 200) |
|
|
1268
|
+
| offset | number | No | Pagination offset |
|
|
1269
|
+
|
|
1270
|
+
**Returns:** `Promise<{logs: Object[], stats: Object, pagination: Object}>`
|
|
1271
|
+
|
|
1272
|
+
---
|
|
1273
|
+
|
|
1274
|
+
## Webhooks
|
|
1275
|
+
|
|
1276
|
+
Subscribe to DashClaw events and receive real-time notifications.
|
|
1277
|
+
|
|
1278
|
+
### claw.getWebhooks()
|
|
1279
|
+
List all webhooks for this organization.
|
|
1280
|
+
|
|
1281
|
+
**Returns:** `Promise<{webhooks: Object[]}>`
|
|
1282
|
+
|
|
1283
|
+
### claw.createWebhook(webhook)
|
|
1284
|
+
Create a new webhook subscription.
|
|
1285
|
+
|
|
1286
|
+
**Parameters:**
|
|
1287
|
+
| Parameter | Type | Required | Description |
|
|
1288
|
+
|-----------|------|----------|-------------|
|
|
1289
|
+
| url | string | Yes | Webhook endpoint URL |
|
|
1290
|
+
| events | string[] | No | Event types to subscribe to |
|
|
1291
|
+
|
|
1292
|
+
**Returns:** `Promise<{webhook: Object}>`
|
|
1293
|
+
|
|
1294
|
+
### claw.deleteWebhook(webhookId)
|
|
1295
|
+
Delete a webhook.
|
|
1296
|
+
|
|
1297
|
+
**Parameters:**
|
|
1298
|
+
| Parameter | Type | Required | Description |
|
|
1299
|
+
|-----------|------|----------|-------------|
|
|
1300
|
+
| webhookId | string | Yes | Webhook ID |
|
|
1301
|
+
|
|
1302
|
+
**Returns:** `Promise<{deleted: boolean}>`
|
|
1303
|
+
|
|
1304
|
+
### claw.testWebhook(webhookId)
|
|
1305
|
+
Send a test event to a webhook to verify connectivity.
|
|
1306
|
+
|
|
1307
|
+
**Parameters:**
|
|
1308
|
+
| Parameter | Type | Required | Description |
|
|
1309
|
+
|-----------|------|----------|-------------|
|
|
1310
|
+
| webhookId | string | Yes | Webhook ID |
|
|
1311
|
+
|
|
1312
|
+
**Returns:** `Promise<{delivery: Object}>`
|
|
1313
|
+
|
|
1314
|
+
### claw.getWebhookDeliveries(webhookId)
|
|
1315
|
+
Get delivery history for a webhook.
|
|
1316
|
+
|
|
1317
|
+
**Parameters:**
|
|
1318
|
+
| Parameter | Type | Required | Description |
|
|
1319
|
+
|-----------|------|----------|-------------|
|
|
1320
|
+
| webhookId | string | Yes | Webhook ID |
|
|
1321
|
+
|
|
1322
|
+
**Returns:** `Promise<{deliveries: Object[]}>`
|
|
1323
|
+
|
|
726
1324
|
---
|
|
727
1325
|
|
|
728
1326
|
## Bulk Sync
|
|
@@ -959,6 +1557,49 @@ Get routing system health status and diagnostics.
|
|
|
959
1557
|
|
|
960
1558
|
---
|
|
961
1559
|
|
|
1560
|
+
## Agent Schedules
|
|
1561
|
+
|
|
1562
|
+
Define recurring tasks and cron-based schedules for agents.
|
|
1563
|
+
|
|
1564
|
+
### claw.listAgentSchedules(filters?)
|
|
1565
|
+
List agent schedules, optionally filtered by agent.
|
|
1566
|
+
|
|
1567
|
+
```javascript
|
|
1568
|
+
const { schedules } = await claw.listAgentSchedules({ agent_id: 'forge' });
|
|
1569
|
+
```
|
|
1570
|
+
|
|
1571
|
+
**Parameters:**
|
|
1572
|
+
| Parameter | Type | Required | Description |
|
|
1573
|
+
|-----------|------|----------|-------------|
|
|
1574
|
+
| filters.agent_id | string | No | Filter by agent ID |
|
|
1575
|
+
|
|
1576
|
+
**Returns:** `Promise<{ schedules: Object[] }>`
|
|
1577
|
+
|
|
1578
|
+
### claw.createAgentSchedule(schedule)
|
|
1579
|
+
Create a new agent schedule entry.
|
|
1580
|
+
|
|
1581
|
+
```javascript
|
|
1582
|
+
const { schedule } = await claw.createAgentSchedule({
|
|
1583
|
+
agent_id: 'forge',
|
|
1584
|
+
name: 'Build projects',
|
|
1585
|
+
cron_expression: '0 */6 * * *',
|
|
1586
|
+
description: 'Check for pending builds every 6 hours'
|
|
1587
|
+
});
|
|
1588
|
+
```
|
|
1589
|
+
|
|
1590
|
+
**Parameters:**
|
|
1591
|
+
| Parameter | Type | Required | Description |
|
|
1592
|
+
|-----------|------|----------|-------------|
|
|
1593
|
+
| schedule.agent_id | string | Yes | Agent this schedule belongs to |
|
|
1594
|
+
| schedule.name | string | Yes | Schedule name |
|
|
1595
|
+
| schedule.cron_expression | string | Yes | Cron expression (e.g. `0 */6 * * *`) |
|
|
1596
|
+
| schedule.description | string | No | Human-readable description |
|
|
1597
|
+
| schedule.enabled | boolean | No | Whether schedule is active (default: true) |
|
|
1598
|
+
|
|
1599
|
+
**Returns:** `Promise<{ schedule: Object }>`
|
|
1600
|
+
|
|
1601
|
+
---
|
|
1602
|
+
|
|
962
1603
|
## Error Handling
|
|
963
1604
|
|
|
964
1605
|
All SDK methods throw on non-2xx responses. Errors include `status` (HTTP code) and `details` (when available).
|
package/dashclaw.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Full-featured agent toolkit for the DashClaw platform.
|
|
4
4
|
* Zero-dependency ESM SDK — requires Node 18+ (native fetch).
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* 96+ methods across 22+ categories:
|
|
7
7
|
* - Action Recording (7)
|
|
8
8
|
* - Loops & Assumptions (7)
|
|
9
9
|
* - Signals (1)
|
|
@@ -16,10 +16,16 @@
|
|
|
16
16
|
* - Security Scanning (2)
|
|
17
17
|
* - Agent Messaging (9)
|
|
18
18
|
* - Behavior Guard (2)
|
|
19
|
+
* - Agent Pairing (3)
|
|
20
|
+
* - Identity Binding (2)
|
|
21
|
+
* - Organization Management (5)
|
|
22
|
+
* - Activity Logs (1)
|
|
23
|
+
* - Webhooks (5)
|
|
19
24
|
* - Bulk Sync (1)
|
|
20
25
|
* - Policy Testing (3)
|
|
21
26
|
* - Compliance Engine (5)
|
|
22
27
|
* - Task Routing (10)
|
|
28
|
+
* - Real-Time Events (1)
|
|
23
29
|
*/
|
|
24
30
|
|
|
25
31
|
class DashClaw {
|
|
@@ -65,6 +71,9 @@ class DashClaw {
|
|
|
65
71
|
}
|
|
66
72
|
|
|
67
73
|
this.baseUrl = baseUrl.replace(/\/$/, '');
|
|
74
|
+
if (!this.baseUrl.startsWith('https://') && !this.baseUrl.includes('localhost') && !this.baseUrl.includes('127.0.0.1')) {
|
|
75
|
+
console.warn('[DashClaw] WARNING: baseUrl does not use HTTPS. API keys will be sent in plaintext. Use HTTPS in production.');
|
|
76
|
+
}
|
|
68
77
|
this.apiKey = apiKey;
|
|
69
78
|
this.agentId = agentId;
|
|
70
79
|
this.agentName = agentName || null;
|
|
@@ -464,32 +473,172 @@ class DashClaw {
|
|
|
464
473
|
|
|
465
474
|
/**
|
|
466
475
|
* Poll for human approval of a pending action.
|
|
467
|
-
* @param {string} actionId
|
|
476
|
+
* @param {string} actionId
|
|
468
477
|
* @param {Object} [options]
|
|
469
478
|
* @param {number} [options.timeout=300000] - Max wait time (5 min)
|
|
470
479
|
* @param {number} [options.interval=5000] - Poll interval
|
|
480
|
+
* @param {boolean} [options.useEvents=false] - Use SSE stream instead of polling
|
|
471
481
|
*/
|
|
472
|
-
async waitForApproval(actionId, { timeout = 300000, interval = 5000 } = {}) {
|
|
482
|
+
async waitForApproval(actionId, { timeout = 300000, interval = 5000, useEvents = false } = {}) {
|
|
483
|
+
if (!useEvents) {
|
|
484
|
+
return this._waitForApprovalPolling(actionId, timeout, interval);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
return new Promise((resolve, reject) => {
|
|
488
|
+
const stream = this.events();
|
|
489
|
+
const timeoutId = setTimeout(() => {
|
|
490
|
+
stream.close();
|
|
491
|
+
reject(new Error(`Timed out waiting for approval of action ${actionId}`));
|
|
492
|
+
}, timeout);
|
|
493
|
+
|
|
494
|
+
stream.on('action.updated', (data) => {
|
|
495
|
+
if (data.action_id !== actionId) return;
|
|
496
|
+
if (data.status === 'running') {
|
|
497
|
+
clearTimeout(timeoutId);
|
|
498
|
+
stream.close();
|
|
499
|
+
resolve({ action: data, action_id: actionId });
|
|
500
|
+
} else if (data.status === 'failed' || data.status === 'cancelled') {
|
|
501
|
+
clearTimeout(timeoutId);
|
|
502
|
+
stream.close();
|
|
503
|
+
reject(new ApprovalDeniedError(data.error_message || 'Operator denied the action.'));
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
stream.on('error', (err) => {
|
|
508
|
+
clearTimeout(timeoutId);
|
|
509
|
+
stream.close();
|
|
510
|
+
reject(err);
|
|
511
|
+
});
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/** @private Polling-based waitForApproval implementation. */
|
|
516
|
+
async _waitForApprovalPolling(actionId, timeout, interval) {
|
|
473
517
|
const startTime = Date.now();
|
|
474
|
-
|
|
518
|
+
|
|
475
519
|
while (Date.now() - startTime < timeout) {
|
|
476
520
|
const { action } = await this.getAction(actionId);
|
|
477
|
-
|
|
521
|
+
|
|
478
522
|
if (action.status === 'running') {
|
|
479
523
|
console.log(`[DashClaw] Action ${actionId} approved by operator.`);
|
|
480
524
|
return { action, action_id: actionId };
|
|
481
525
|
}
|
|
482
|
-
|
|
526
|
+
|
|
483
527
|
if (action.status === 'failed' || action.status === 'cancelled') {
|
|
484
528
|
throw new ApprovalDeniedError(action.error_message || 'Operator denied the action.');
|
|
485
529
|
}
|
|
486
|
-
|
|
530
|
+
|
|
487
531
|
await new Promise(r => setTimeout(r, interval));
|
|
488
532
|
}
|
|
489
|
-
|
|
533
|
+
|
|
490
534
|
throw new Error(`[DashClaw] Timed out waiting for approval of action ${actionId}`);
|
|
491
535
|
}
|
|
492
536
|
|
|
537
|
+
// ══════════════════════════════════════════════
|
|
538
|
+
// Real-Time Events (1 method)
|
|
539
|
+
// ══════════════════════════════════════════════
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Subscribe to real-time SSE events from the DashClaw server.
|
|
543
|
+
* Uses fetch-based SSE parsing for Node 18+ compatibility (no native EventSource required).
|
|
544
|
+
*
|
|
545
|
+
* @returns {{ on(eventType: string, callback: Function): this, close(): void, _promise: Promise<void> }}
|
|
546
|
+
*
|
|
547
|
+
* @example
|
|
548
|
+
* const stream = client.events();
|
|
549
|
+
* stream
|
|
550
|
+
* .on('action.created', (data) => console.log('New action:', data))
|
|
551
|
+
* .on('action.updated', (data) => console.log('Action updated:', data))
|
|
552
|
+
* .on('policy.updated', (data) => console.log('Policy changed:', data))
|
|
553
|
+
* .on('task.assigned', (data) => console.log('Task assigned:', data))
|
|
554
|
+
* .on('task.completed', (data) => console.log('Task done:', data))
|
|
555
|
+
* .on('error', (err) => console.error('Stream error:', err));
|
|
556
|
+
*
|
|
557
|
+
* // Later:
|
|
558
|
+
* stream.close();
|
|
559
|
+
*/
|
|
560
|
+
events() {
|
|
561
|
+
const url = `${this.baseUrl}/api/stream`;
|
|
562
|
+
const apiKey = this.apiKey;
|
|
563
|
+
|
|
564
|
+
const handlers = new Map();
|
|
565
|
+
let closed = false;
|
|
566
|
+
let controller = null;
|
|
567
|
+
|
|
568
|
+
const connect = async () => {
|
|
569
|
+
controller = new AbortController();
|
|
570
|
+
const res = await fetch(url, {
|
|
571
|
+
headers: { 'x-api-key': apiKey },
|
|
572
|
+
signal: controller.signal,
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
if (!res.ok) {
|
|
576
|
+
throw new Error(`SSE connection failed: ${res.status} ${res.statusText}`);
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
const reader = res.body.getReader();
|
|
580
|
+
const decoder = new TextDecoder();
|
|
581
|
+
let buffer = '';
|
|
582
|
+
|
|
583
|
+
while (!closed) {
|
|
584
|
+
const { done, value } = await reader.read();
|
|
585
|
+
if (done) break;
|
|
586
|
+
buffer += decoder.decode(value, { stream: true });
|
|
587
|
+
|
|
588
|
+
// Parse SSE frames from buffer
|
|
589
|
+
const lines = buffer.split('\n');
|
|
590
|
+
buffer = lines.pop(); // Keep incomplete line in buffer
|
|
591
|
+
|
|
592
|
+
let currentEvent = null;
|
|
593
|
+
let currentData = '';
|
|
594
|
+
|
|
595
|
+
for (const line of lines) {
|
|
596
|
+
if (line.startsWith('event: ')) {
|
|
597
|
+
currentEvent = line.slice(7).trim();
|
|
598
|
+
} else if (line.startsWith('data: ')) {
|
|
599
|
+
currentData += line.slice(6);
|
|
600
|
+
} else if (line === '' && currentEvent) {
|
|
601
|
+
// End of SSE frame — dispatch
|
|
602
|
+
const eventHandlers = handlers.get(currentEvent) || [];
|
|
603
|
+
if (eventHandlers.length > 0 && currentData) {
|
|
604
|
+
try {
|
|
605
|
+
const parsed = JSON.parse(currentData);
|
|
606
|
+
for (const cb of eventHandlers) {
|
|
607
|
+
try { cb(parsed); } catch { /* ignore handler errors */ }
|
|
608
|
+
}
|
|
609
|
+
} catch { /* ignore parse errors */ }
|
|
610
|
+
}
|
|
611
|
+
currentEvent = null;
|
|
612
|
+
currentData = '';
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
const connectionPromise = connect().catch((err) => {
|
|
619
|
+
if (closed) return; // Abort is expected on close
|
|
620
|
+
const errorHandlers = handlers.get('error') || [];
|
|
621
|
+
for (const cb of errorHandlers) {
|
|
622
|
+
try { cb(err); } catch { /* ignore */ }
|
|
623
|
+
}
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
const handle = {
|
|
627
|
+
on(eventType, callback) {
|
|
628
|
+
if (!handlers.has(eventType)) handlers.set(eventType, []);
|
|
629
|
+
handlers.get(eventType).push(callback);
|
|
630
|
+
return handle;
|
|
631
|
+
},
|
|
632
|
+
close() {
|
|
633
|
+
closed = true;
|
|
634
|
+
if (controller) controller.abort();
|
|
635
|
+
},
|
|
636
|
+
_promise: connectionPromise,
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
return handle;
|
|
640
|
+
}
|
|
641
|
+
|
|
493
642
|
/**
|
|
494
643
|
* Update the outcome of an existing action.
|
|
495
644
|
* @param {string} actionId - The action_id to update
|
|
@@ -1747,6 +1896,165 @@ class DashClaw {
|
|
|
1747
1896
|
return this._request('/api/routing/health', 'GET');
|
|
1748
1897
|
}
|
|
1749
1898
|
|
|
1899
|
+
// ══════════════════════════════════════════════════════════
|
|
1900
|
+
// Agent Pairing (3 methods)
|
|
1901
|
+
// ══════════════════════════════════════════════════════════
|
|
1902
|
+
|
|
1903
|
+
// createPairing, createPairingFromPrivateJwk, waitForPairing
|
|
1904
|
+
// (defined near the top of the class)
|
|
1905
|
+
|
|
1906
|
+
// ══════════════════════════════════════════════════════════
|
|
1907
|
+
// Identity Binding (2 methods)
|
|
1908
|
+
// ══════════════════════════════════════════════════════════
|
|
1909
|
+
|
|
1910
|
+
/**
|
|
1911
|
+
* Register or update an agent's public key for identity verification.
|
|
1912
|
+
* Requires admin API key.
|
|
1913
|
+
* @param {Object} identity
|
|
1914
|
+
* @param {string} identity.agent_id - Agent ID to register
|
|
1915
|
+
* @param {string} identity.public_key - PEM public key (SPKI format)
|
|
1916
|
+
* @param {string} [identity.algorithm='RSASSA-PKCS1-v1_5'] - Signing algorithm
|
|
1917
|
+
* @returns {Promise<{identity: Object}>}
|
|
1918
|
+
*/
|
|
1919
|
+
async registerIdentity(identity) {
|
|
1920
|
+
return this._request('/api/identities', 'POST', identity);
|
|
1921
|
+
}
|
|
1922
|
+
|
|
1923
|
+
/**
|
|
1924
|
+
* List all registered agent identities for this org.
|
|
1925
|
+
* @returns {Promise<{identities: Object[]}>}
|
|
1926
|
+
*/
|
|
1927
|
+
async getIdentities() {
|
|
1928
|
+
return this._request('/api/identities', 'GET');
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1931
|
+
// ══════════════════════════════════════════════════════════
|
|
1932
|
+
// Organization Management (5 methods)
|
|
1933
|
+
// ══════════════════════════════════════════════════════════
|
|
1934
|
+
|
|
1935
|
+
/**
|
|
1936
|
+
* Get the current organization's details. Requires admin API key.
|
|
1937
|
+
* @returns {Promise<{organizations: Object[]}>}
|
|
1938
|
+
*/
|
|
1939
|
+
async getOrg() {
|
|
1940
|
+
return this._request('/api/orgs', 'GET');
|
|
1941
|
+
}
|
|
1942
|
+
|
|
1943
|
+
/**
|
|
1944
|
+
* Create a new organization with an initial admin API key. Requires admin API key.
|
|
1945
|
+
* @param {Object} org
|
|
1946
|
+
* @param {string} org.name - Organization name
|
|
1947
|
+
* @param {string} org.slug - URL-safe slug (lowercase alphanumeric + hyphens)
|
|
1948
|
+
* @returns {Promise<{organization: Object, api_key: Object}>}
|
|
1949
|
+
*/
|
|
1950
|
+
async createOrg(org) {
|
|
1951
|
+
return this._request('/api/orgs', 'POST', org);
|
|
1952
|
+
}
|
|
1953
|
+
|
|
1954
|
+
/**
|
|
1955
|
+
* Get organization details by ID. Requires admin API key.
|
|
1956
|
+
* @param {string} orgId - Organization ID
|
|
1957
|
+
* @returns {Promise<{organization: Object}>}
|
|
1958
|
+
*/
|
|
1959
|
+
async getOrgById(orgId) {
|
|
1960
|
+
return this._request(`/api/orgs/${encodeURIComponent(orgId)}`, 'GET');
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1963
|
+
/**
|
|
1964
|
+
* Update organization details. Requires admin API key.
|
|
1965
|
+
* @param {string} orgId - Organization ID
|
|
1966
|
+
* @param {Object} updates - Fields to update (name, slug)
|
|
1967
|
+
* @returns {Promise<{organization: Object}>}
|
|
1968
|
+
*/
|
|
1969
|
+
async updateOrg(orgId, updates) {
|
|
1970
|
+
return this._request(`/api/orgs/${encodeURIComponent(orgId)}`, 'PATCH', updates);
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1973
|
+
/**
|
|
1974
|
+
* List API keys for an organization. Requires admin API key.
|
|
1975
|
+
* @param {string} orgId - Organization ID
|
|
1976
|
+
* @returns {Promise<{keys: Object[]}>}
|
|
1977
|
+
*/
|
|
1978
|
+
async getOrgKeys(orgId) {
|
|
1979
|
+
return this._request(`/api/orgs/${encodeURIComponent(orgId)}/keys`, 'GET');
|
|
1980
|
+
}
|
|
1981
|
+
|
|
1982
|
+
// ══════════════════════════════════════════════════════════
|
|
1983
|
+
// Activity Logs (1 method)
|
|
1984
|
+
// ══════════════════════════════════════════════════════════
|
|
1985
|
+
|
|
1986
|
+
/**
|
|
1987
|
+
* Get activity/audit logs for the organization.
|
|
1988
|
+
* @param {Object} [filters]
|
|
1989
|
+
* @param {string} [filters.action] - Filter by action type
|
|
1990
|
+
* @param {string} [filters.actor_id] - Filter by actor
|
|
1991
|
+
* @param {string} [filters.resource_type] - Filter by resource type
|
|
1992
|
+
* @param {string} [filters.before] - Before timestamp (ISO string)
|
|
1993
|
+
* @param {string} [filters.after] - After timestamp (ISO string)
|
|
1994
|
+
* @param {number} [filters.limit=50] - Max results (max 200)
|
|
1995
|
+
* @param {number} [filters.offset=0] - Pagination offset
|
|
1996
|
+
* @returns {Promise<{logs: Object[], stats: Object, pagination: Object}>}
|
|
1997
|
+
*/
|
|
1998
|
+
async getActivityLogs(filters = {}) {
|
|
1999
|
+
const params = new URLSearchParams();
|
|
2000
|
+
for (const [key, value] of Object.entries(filters)) {
|
|
2001
|
+
if (value !== undefined && value !== null && value !== '') {
|
|
2002
|
+
params.set(key, String(value));
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
return this._request(`/api/activity?${params}`, 'GET');
|
|
2006
|
+
}
|
|
2007
|
+
|
|
2008
|
+
// ══════════════════════════════════════════════════════════
|
|
2009
|
+
// Webhooks (5 methods)
|
|
2010
|
+
// ══════════════════════════════════════════════════════════
|
|
2011
|
+
|
|
2012
|
+
/**
|
|
2013
|
+
* List all webhooks for this org.
|
|
2014
|
+
* @returns {Promise<{webhooks: Object[]}>}
|
|
2015
|
+
*/
|
|
2016
|
+
async getWebhooks() {
|
|
2017
|
+
return this._request('/api/webhooks', 'GET');
|
|
2018
|
+
}
|
|
2019
|
+
|
|
2020
|
+
/**
|
|
2021
|
+
* Create a new webhook subscription.
|
|
2022
|
+
* @param {Object} webhook
|
|
2023
|
+
* @param {string} webhook.url - Webhook endpoint URL
|
|
2024
|
+
* @param {string[]} [webhook.events] - Event types to subscribe to
|
|
2025
|
+
* @returns {Promise<{webhook: Object}>}
|
|
2026
|
+
*/
|
|
2027
|
+
async createWebhook(webhook) {
|
|
2028
|
+
return this._request('/api/webhooks', 'POST', webhook);
|
|
2029
|
+
}
|
|
2030
|
+
|
|
2031
|
+
/**
|
|
2032
|
+
* Delete a webhook.
|
|
2033
|
+
* @param {string} webhookId - Webhook ID
|
|
2034
|
+
* @returns {Promise<{deleted: boolean}>}
|
|
2035
|
+
*/
|
|
2036
|
+
async deleteWebhook(webhookId) {
|
|
2037
|
+
return this._request(`/api/webhooks?id=${encodeURIComponent(webhookId)}`, 'DELETE');
|
|
2038
|
+
}
|
|
2039
|
+
|
|
2040
|
+
/**
|
|
2041
|
+
* Send a test event to a webhook.
|
|
2042
|
+
* @param {string} webhookId - Webhook ID
|
|
2043
|
+
* @returns {Promise<{delivery: Object}>}
|
|
2044
|
+
*/
|
|
2045
|
+
async testWebhook(webhookId) {
|
|
2046
|
+
return this._request(`/api/webhooks/${encodeURIComponent(webhookId)}/test`, 'POST');
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
/**
|
|
2050
|
+
* Get delivery history for a webhook.
|
|
2051
|
+
* @param {string} webhookId - Webhook ID
|
|
2052
|
+
* @returns {Promise<{deliveries: Object[]}>}
|
|
2053
|
+
*/
|
|
2054
|
+
async getWebhookDeliveries(webhookId) {
|
|
2055
|
+
return this._request(`/api/webhooks/${encodeURIComponent(webhookId)}/deliveries`, 'GET');
|
|
2056
|
+
}
|
|
2057
|
+
|
|
1750
2058
|
// ─── Bulk Sync ────────────────────────────────────────────
|
|
1751
2059
|
|
|
1752
2060
|
/**
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dashclaw",
|
|
3
|
-
"version": "1.8.
|
|
4
|
-
"description": "Full-featured agent toolkit for the DashClaw platform.
|
|
3
|
+
"version": "1.8.1",
|
|
4
|
+
"description": "Full-featured agent toolkit for the DashClaw platform. 95+ methods across 21+ categories for action recording, context management, session handoffs, security scanning, behavior guard, compliance, task routing, identity binding, organization management, webhooks, bulk sync, and more.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|