@diskd-ai/sdk 5.1.2
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/LICENSE +190 -0
- package/README.md +1036 -0
- package/dist/agentHub/StreamProtocolFetcher.d.ts +55 -0
- package/dist/agentHub/StreamProtocolFetcher.d.ts.map +1 -0
- package/dist/agentHub/StreamProtocolFetcher.js +176 -0
- package/dist/agentHub/StreamProtocolFetcher.js.map +1 -0
- package/dist/agentHub/StreamProtocolHandler.d.ts +18 -0
- package/dist/agentHub/StreamProtocolHandler.d.ts.map +1 -0
- package/dist/agentHub/StreamProtocolHandler.js +63 -0
- package/dist/agentHub/StreamProtocolHandler.js.map +1 -0
- package/dist/agentHub/agentHub.d.ts +30 -0
- package/dist/agentHub/agentHub.d.ts.map +1 -0
- package/dist/agentHub/agentHub.js +200 -0
- package/dist/agentHub/agentHub.js.map +1 -0
- package/dist/agentHub/agentHubTypes.d.ts +110 -0
- package/dist/agentHub/agentHubTypes.d.ts.map +1 -0
- package/dist/agentHub/agentHubTypes.js +8 -0
- package/dist/agentHub/agentHubTypes.js.map +1 -0
- package/dist/agentHub/streamProtocolMap.d.ts +328 -0
- package/dist/agentHub/streamProtocolMap.d.ts.map +1 -0
- package/dist/agentHub/streamProtocolMap.js +8 -0
- package/dist/agentHub/streamProtocolMap.js.map +1 -0
- package/dist/auth/createApiKeyAuth.d.ts +11 -0
- package/dist/auth/createApiKeyAuth.d.ts.map +1 -0
- package/dist/auth/createApiKeyAuth.js +31 -0
- package/dist/auth/createApiKeyAuth.js.map +1 -0
- package/dist/auth/createAuth.d.ts +3 -0
- package/dist/auth/createAuth.d.ts.map +1 -0
- package/dist/auth/createAuth.js +128 -0
- package/dist/auth/createAuth.js.map +1 -0
- package/dist/auth/createAuthBrowser.d.ts +3 -0
- package/dist/auth/createAuthBrowser.d.ts.map +1 -0
- package/dist/auth/createAuthBrowser.js +104 -0
- package/dist/auth/createAuthBrowser.js.map +1 -0
- package/dist/auth/jwtClaims.d.ts +3 -0
- package/dist/auth/jwtClaims.d.ts.map +1 -0
- package/dist/auth/jwtClaims.js +23 -0
- package/dist/auth/jwtClaims.js.map +1 -0
- package/dist/auth/keyfile.d.ts +10 -0
- package/dist/auth/keyfile.d.ts.map +1 -0
- package/dist/auth/keyfile.js +28 -0
- package/dist/auth/keyfile.js.map +1 -0
- package/dist/auth/oidcDiscovery.d.ts +9 -0
- package/dist/auth/oidcDiscovery.d.ts.map +1 -0
- package/dist/auth/oidcDiscovery.js +27 -0
- package/dist/auth/oidcDiscovery.js.map +1 -0
- package/dist/auth/pkce.d.ts +4 -0
- package/dist/auth/pkce.d.ts.map +1 -0
- package/dist/auth/pkce.js +43 -0
- package/dist/auth/pkce.js.map +1 -0
- package/dist/auth/sessionStorage.d.ts +8 -0
- package/dist/auth/sessionStorage.d.ts.map +1 -0
- package/dist/auth/sessionStorage.js +8 -0
- package/dist/auth/sessionStorage.js.map +1 -0
- package/dist/auth/tokenRequests.d.ts +15 -0
- package/dist/auth/tokenRequests.d.ts.map +1 -0
- package/dist/auth/tokenRequests.js +89 -0
- package/dist/auth/tokenRequests.js.map +1 -0
- package/dist/auth/types.d.ts +35 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +2 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/auth/urlRuntime.d.ts +7 -0
- package/dist/auth/urlRuntime.d.ts.map +1 -0
- package/dist/auth/urlRuntime.js +17 -0
- package/dist/auth/urlRuntime.js.map +1 -0
- package/dist/browser/index.d.ts +8 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +3 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/calendar/calendar.d.ts +21 -0
- package/dist/calendar/calendar.d.ts.map +1 -0
- package/dist/calendar/calendar.js +105 -0
- package/dist/calendar/calendar.js.map +1 -0
- package/dist/calendar/calendarTypes.d.ts +191 -0
- package/dist/calendar/calendarTypes.d.ts.map +1 -0
- package/dist/calendar/calendarTypes.js +4 -0
- package/dist/calendar/calendarTypes.js.map +1 -0
- package/dist/contacts/contacts.d.ts +10 -0
- package/dist/contacts/contacts.d.ts.map +1 -0
- package/dist/contacts/contacts.js +86 -0
- package/dist/contacts/contacts.js.map +1 -0
- package/dist/contacts/contactsTypes.d.ts +81 -0
- package/dist/contacts/contactsTypes.d.ts.map +1 -0
- package/dist/contacts/contactsTypes.js +4 -0
- package/dist/contacts/contactsTypes.js.map +1 -0
- package/dist/drive/DriveRepository.d.ts +88 -0
- package/dist/drive/DriveRepository.d.ts.map +1 -0
- package/dist/drive/DriveRepository.js +156 -0
- package/dist/drive/DriveRepository.js.map +1 -0
- package/dist/drive/crontab.d.ts +7 -0
- package/dist/drive/crontab.d.ts.map +1 -0
- package/dist/drive/crontab.js +374 -0
- package/dist/drive/crontab.js.map +1 -0
- package/dist/drive/crontabTypes.d.ts +136 -0
- package/dist/drive/crontabTypes.d.ts.map +1 -0
- package/dist/drive/crontabTypes.js +2 -0
- package/dist/drive/crontabTypes.js.map +1 -0
- package/dist/drive/drive.d.ts +8 -0
- package/dist/drive/drive.d.ts.map +1 -0
- package/dist/drive/drive.js +711 -0
- package/dist/drive/drive.js.map +1 -0
- package/dist/drive/driveDb.d.ts +6 -0
- package/dist/drive/driveDb.d.ts.map +1 -0
- package/dist/drive/driveDb.js +220 -0
- package/dist/drive/driveDb.js.map +1 -0
- package/dist/drive/driveDbTypes.d.ts +138 -0
- package/dist/drive/driveDbTypes.d.ts.map +1 -0
- package/dist/drive/driveDbTypes.js +5 -0
- package/dist/drive/driveDbTypes.js.map +1 -0
- package/dist/drive/driveTypes.d.ts +322 -0
- package/dist/drive/driveTypes.d.ts.map +1 -0
- package/dist/drive/driveTypes.js +5 -0
- package/dist/drive/driveTypes.js.map +1 -0
- package/dist/drive/rpc.d.ts +14 -0
- package/dist/drive/rpc.d.ts.map +1 -0
- package/dist/drive/rpc.js +48 -0
- package/dist/drive/rpc.js.map +1 -0
- package/dist/drive/session.d.ts +7 -0
- package/dist/drive/session.d.ts.map +1 -0
- package/dist/drive/session.js +450 -0
- package/dist/drive/session.js.map +1 -0
- package/dist/drive/sessionBuilder.d.ts +33 -0
- package/dist/drive/sessionBuilder.d.ts.map +1 -0
- package/dist/drive/sessionBuilder.js +77 -0
- package/dist/drive/sessionBuilder.js.map +1 -0
- package/dist/drive/sessionObject.d.ts +57 -0
- package/dist/drive/sessionObject.d.ts.map +1 -0
- package/dist/drive/sessionObject.js +191 -0
- package/dist/drive/sessionObject.js.map +1 -0
- package/dist/drive/sessionTypes.d.ts +182 -0
- package/dist/drive/sessionTypes.d.ts.map +1 -0
- package/dist/drive/sessionTypes.js +2 -0
- package/dist/drive/sessionTypes.js.map +1 -0
- package/dist/drive/typeorm/DriveDriver.d.ts +27 -0
- package/dist/drive/typeorm/DriveDriver.d.ts.map +1 -0
- package/dist/drive/typeorm/DriveDriver.js +86 -0
- package/dist/drive/typeorm/DriveDriver.js.map +1 -0
- package/dist/drive/typeorm/DriveQueryRunner.d.ts +15 -0
- package/dist/drive/typeorm/DriveQueryRunner.d.ts.map +1 -0
- package/dist/drive/typeorm/DriveQueryRunner.js +76 -0
- package/dist/drive/typeorm/DriveQueryRunner.js.map +1 -0
- package/dist/drive/typeorm/createDriveDataSource.d.ts +3 -0
- package/dist/drive/typeorm/createDriveDataSource.d.ts.map +1 -0
- package/dist/drive/typeorm/createDriveDataSource.js +36 -0
- package/dist/drive/typeorm/createDriveDataSource.js.map +1 -0
- package/dist/drive/typeorm/datasourceTypes.d.ts +56 -0
- package/dist/drive/typeorm/datasourceTypes.d.ts.map +1 -0
- package/dist/drive/typeorm/datasourceTypes.js +5 -0
- package/dist/drive/typeorm/datasourceTypes.js.map +1 -0
- package/dist/drive/types.d.ts +48 -0
- package/dist/drive/types.d.ts.map +1 -0
- package/dist/drive/types.js +2 -0
- package/dist/drive/types.js.map +1 -0
- package/dist/env/apiKey.d.ts +2 -0
- package/dist/env/apiKey.d.ts.map +1 -0
- package/dist/env/apiKey.js +11 -0
- package/dist/env/apiKey.js.map +1 -0
- package/dist/env/baseUrl.d.ts +3 -0
- package/dist/env/baseUrl.d.ts.map +1 -0
- package/dist/env/baseUrl.js +31 -0
- package/dist/env/baseUrl.js.map +1 -0
- package/dist/inbox/inboxTypes.d.ts +34 -0
- package/dist/inbox/inboxTypes.d.ts.map +1 -0
- package/dist/inbox/inboxTypes.js +5 -0
- package/dist/inbox/inboxTypes.js.map +1 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/llmRouter/llmRouter.d.ts +23 -0
- package/dist/llmRouter/llmRouter.d.ts.map +1 -0
- package/dist/llmRouter/llmRouter.js +566 -0
- package/dist/llmRouter/llmRouter.js.map +1 -0
- package/dist/llmRouter/llmRouterTypes.d.ts +350 -0
- package/dist/llmRouter/llmRouterTypes.d.ts.map +1 -0
- package/dist/llmRouter/llmRouterTypes.js +5 -0
- package/dist/llmRouter/llmRouterTypes.js.map +1 -0
- package/dist/mcpHub/mcpHub.d.ts +23 -0
- package/dist/mcpHub/mcpHub.d.ts.map +1 -0
- package/dist/mcpHub/mcpHub.js +223 -0
- package/dist/mcpHub/mcpHub.js.map +1 -0
- package/dist/mcpHub/mcpHubTypes.d.ts +228 -0
- package/dist/mcpHub/mcpHubTypes.d.ts.map +1 -0
- package/dist/mcpHub/mcpHubTypes.js +5 -0
- package/dist/mcpHub/mcpHubTypes.js.map +1 -0
- package/dist/mcpTools/mcpTools.d.ts +31 -0
- package/dist/mcpTools/mcpTools.d.ts.map +1 -0
- package/dist/mcpTools/mcpTools.js +144 -0
- package/dist/mcpTools/mcpTools.js.map +1 -0
- package/dist/mcpTools/mcpToolsTypes.d.ts +45 -0
- package/dist/mcpTools/mcpToolsTypes.d.ts.map +1 -0
- package/dist/mcpTools/mcpToolsTypes.js +5 -0
- package/dist/mcpTools/mcpToolsTypes.js.map +1 -0
- package/dist/messagesStore/messagesStore.d.ts +22 -0
- package/dist/messagesStore/messagesStore.d.ts.map +1 -0
- package/dist/messagesStore/messagesStore.js +402 -0
- package/dist/messagesStore/messagesStore.js.map +1 -0
- package/dist/messagesStore/messagesStoreTypes.d.ts +327 -0
- package/dist/messagesStore/messagesStoreTypes.d.ts.map +1 -0
- package/dist/messagesStore/messagesStoreTypes.js +11 -0
- package/dist/messagesStore/messagesStoreTypes.js.map +1 -0
- package/dist/node/fastDns.d.ts +2 -0
- package/dist/node/fastDns.d.ts.map +1 -0
- package/dist/node/fastDns.js +119 -0
- package/dist/node/fastDns.js.map +1 -0
- package/dist/operatives/operatives.d.ts +22 -0
- package/dist/operatives/operatives.d.ts.map +1 -0
- package/dist/operatives/operatives.js +199 -0
- package/dist/operatives/operatives.js.map +1 -0
- package/dist/operatives/operativesTypes.d.ts +141 -0
- package/dist/operatives/operativesTypes.d.ts.map +1 -0
- package/dist/operatives/operativesTypes.js +6 -0
- package/dist/operatives/operativesTypes.js.map +1 -0
- package/dist/platformEvents/platformEvents.d.ts +14 -0
- package/dist/platformEvents/platformEvents.d.ts.map +1 -0
- package/dist/platformEvents/platformEvents.js +70 -0
- package/dist/platformEvents/platformEvents.js.map +1 -0
- package/dist/platformEvents/platformEventsTypes.d.ts +31 -0
- package/dist/platformEvents/platformEventsTypes.d.ts.map +1 -0
- package/dist/platformEvents/platformEventsTypes.js +8 -0
- package/dist/platformEvents/platformEventsTypes.js.map +1 -0
- package/dist/projects/projects.d.ts +19 -0
- package/dist/projects/projects.d.ts.map +1 -0
- package/dist/projects/projects.js +52 -0
- package/dist/projects/projects.js.map +1 -0
- package/dist/projects/projectsTypes.d.ts +47 -0
- package/dist/projects/projectsTypes.d.ts.map +1 -0
- package/dist/projects/projectsTypes.js +4 -0
- package/dist/projects/projectsTypes.js.map +1 -0
- package/dist/routineRuns/routineRuns.d.ts +19 -0
- package/dist/routineRuns/routineRuns.d.ts.map +1 -0
- package/dist/routineRuns/routineRuns.js +47 -0
- package/dist/routineRuns/routineRuns.js.map +1 -0
- package/dist/routineRuns/routineRunsTypes.d.ts +39 -0
- package/dist/routineRuns/routineRunsTypes.d.ts.map +1 -0
- package/dist/routineRuns/routineRunsTypes.js +4 -0
- package/dist/routineRuns/routineRunsTypes.js.map +1 -0
- package/dist/routines/routines.d.ts +19 -0
- package/dist/routines/routines.d.ts.map +1 -0
- package/dist/routines/routines.js +77 -0
- package/dist/routines/routines.js.map +1 -0
- package/dist/routines/routinesTypes.d.ts +106 -0
- package/dist/routines/routinesTypes.d.ts.map +1 -0
- package/dist/routines/routinesTypes.js +4 -0
- package/dist/routines/routinesTypes.js.map +1 -0
- package/dist/sdk/diskd.d.ts +3 -0
- package/dist/sdk/diskd.d.ts.map +1 -0
- package/dist/sdk/diskd.js +126 -0
- package/dist/sdk/diskd.js.map +1 -0
- package/dist/sdk/http.d.ts +13 -0
- package/dist/sdk/http.d.ts.map +1 -0
- package/dist/sdk/http.js +80 -0
- package/dist/sdk/http.js.map +1 -0
- package/dist/sdk/types.d.ts +115 -0
- package/dist/sdk/types.d.ts.map +1 -0
- package/dist/sdk/types.js +2 -0
- package/dist/sdk/types.js.map +1 -0
- package/dist/testing/auth.d.ts +8 -0
- package/dist/testing/auth.d.ts.map +1 -0
- package/dist/testing/auth.js +14 -0
- package/dist/testing/auth.js.map +1 -0
- package/dist/testing/fetchMock.d.ts +17 -0
- package/dist/testing/fetchMock.d.ts.map +1 -0
- package/dist/testing/fetchMock.js +46 -0
- package/dist/testing/fetchMock.js.map +1 -0
- package/dist/testing/index.d.ts +11 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +11 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/integration.d.ts +33 -0
- package/dist/testing/integration.d.ts.map +1 -0
- package/dist/testing/integration.js +32 -0
- package/dist/testing/integration.js.map +1 -0
- package/dist/testing/jsonRpc.d.ts +9 -0
- package/dist/testing/jsonRpc.d.ts.map +1 -0
- package/dist/testing/jsonRpc.js +24 -0
- package/dist/testing/jsonRpc.js.map +1 -0
- package/dist/testing/rpcMock.d.ts +16 -0
- package/dist/testing/rpcMock.d.ts.map +1 -0
- package/dist/testing/rpcMock.js +28 -0
- package/dist/testing/rpcMock.js.map +1 -0
- package/dist/tgUserbot/tgUserbot.d.ts +23 -0
- package/dist/tgUserbot/tgUserbot.d.ts.map +1 -0
- package/dist/tgUserbot/tgUserbot.js +314 -0
- package/dist/tgUserbot/tgUserbot.js.map +1 -0
- package/dist/tgUserbot/tgUserbotTypes.d.ts +124 -0
- package/dist/tgUserbot/tgUserbotTypes.d.ts.map +1 -0
- package/dist/tgUserbot/tgUserbotTypes.js +5 -0
- package/dist/tgUserbot/tgUserbotTypes.js.map +1 -0
- package/dist/webNavigator/webNavigator.d.ts +22 -0
- package/dist/webNavigator/webNavigator.d.ts.map +1 -0
- package/dist/webNavigator/webNavigator.js +46 -0
- package/dist/webNavigator/webNavigator.js.map +1 -0
- package/dist/webNavigator/webNavigatorTypes.d.ts +133 -0
- package/dist/webNavigator/webNavigatorTypes.d.ts.map +1 -0
- package/dist/webNavigator/webNavigatorTypes.js +5 -0
- package/dist/webNavigator/webNavigatorTypes.js.map +1 -0
- package/package.json +90 -0
package/README.md
ADDED
|
@@ -0,0 +1,1036 @@
|
|
|
1
|
+
# @diskd-ai/sdk
|
|
2
|
+
|
|
3
|
+
Unified TypeScript SDK for the Upgraide platform APIs.
|
|
4
|
+
|
|
5
|
+
All services are accessible via the `diskd` factory, which provides a consistent
|
|
6
|
+
`diskd.auth.*` + namespaced service pattern across `diskd.os.*`, `diskd.platform.*`,
|
|
7
|
+
and `diskd.utils.*`:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { diskd } from '@diskd-ai/sdk';
|
|
11
|
+
|
|
12
|
+
const auth = diskd.auth.apiKey({ workspaceId: '...' });
|
|
13
|
+
|
|
14
|
+
const drive = diskd.os.drive({ version: 'v1', auth });
|
|
15
|
+
const sessions = diskd.platform.sessions({
|
|
16
|
+
auth,
|
|
17
|
+
scope: { scopeType: 'project', projectId: 'proj-1' },
|
|
18
|
+
});
|
|
19
|
+
const crontab = diskd.platform.crontab({
|
|
20
|
+
auth,
|
|
21
|
+
scope: { scopeType: 'project', projectId: 'proj-1' },
|
|
22
|
+
});
|
|
23
|
+
const db = diskd.os.database({ auth, dbName: '...', schema: { ... } });
|
|
24
|
+
const ds = diskd.os.datasource({ auth, dbName: '...', entities: [...] });
|
|
25
|
+
const llm = diskd.os.llm({ auth });
|
|
26
|
+
const agents = diskd.os.agents({ auth, workspaceId: '...' });
|
|
27
|
+
const mcp = diskd.os.mcp({ auth, workspaceId: '...' });
|
|
28
|
+
const messages = diskd.os.messagesStore({ auth });
|
|
29
|
+
const routines = diskd.platform.routines({ auth });
|
|
30
|
+
const operatives = diskd.platform.operatives({ auth });
|
|
31
|
+
const calendar = diskd.platform.calendar({ auth });
|
|
32
|
+
const tg = diskd.utils.tgUserBot({ auth, workspaceId: '...' });
|
|
33
|
+
const webNav = diskd.utils.webNavigator({ auth, workspaceId: '...' });
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Installation
|
|
37
|
+
------------
|
|
38
|
+
|
|
39
|
+
1. Configure `.npmrc` in your project (or `~/.npmrc`):
|
|
40
|
+
|
|
41
|
+
```ini
|
|
42
|
+
@diskd:registry=https://gitlab.iosya.com/api/v4/projects/80/packages/npm/
|
|
43
|
+
//gitlab.iosya.com/api/v4/projects/80/packages/npm/:_authToken=${NPM_TOKEN}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
2. Set `NPM_TOKEN` to a GitLab personal access token with `read_api` scope:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
export NPM_TOKEN=glpat-xxxxxxxxxxxx
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
3. Install:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
bun add @diskd-ai/sdk
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Install / build (repo)
|
|
59
|
+
----------------------
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
cd mono/platform-api
|
|
63
|
+
bun install
|
|
64
|
+
bun run build
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Authentication
|
|
68
|
+
--------------
|
|
69
|
+
|
|
70
|
+
The SDK supports two authentication modes via the `AuthModule` interface.
|
|
71
|
+
|
|
72
|
+
### External clients (OAuth2)
|
|
73
|
+
|
|
74
|
+
Use `diskd.auth.credentials()` for OAuth2 service-account or PKCE browser flows:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { diskd } from '@diskd-ai/sdk';
|
|
78
|
+
|
|
79
|
+
const auth = await diskd.auth.credentials({
|
|
80
|
+
scopes: ['openid'],
|
|
81
|
+
keyfilePath: 'credentials.json',
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const drive = diskd.os.drive({ version: 'v1', auth });
|
|
85
|
+
const sessions = diskd.platform.sessions({
|
|
86
|
+
auth,
|
|
87
|
+
scope: { scopeType: 'project', projectId: 'proj-1' },
|
|
88
|
+
});
|
|
89
|
+
const crontab = diskd.platform.crontab({
|
|
90
|
+
auth,
|
|
91
|
+
scope: { scopeType: 'project', projectId: 'proj-1' },
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Internal services (API key)
|
|
96
|
+
|
|
97
|
+
Use `diskd.auth.apiKey()` for service-to-service communication within the cluster:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
import { diskd } from '@diskd-ai/sdk';
|
|
101
|
+
|
|
102
|
+
const auth = diskd.auth.apiKey({ workspaceId: process.env.WORKSPACE_ID! });
|
|
103
|
+
|
|
104
|
+
const drive = diskd.os.drive({ version: 'v1', auth });
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`diskd.auth.apiKey()` reads `APIS_API_KEY` from the environment and fails fast when
|
|
108
|
+
either `APIS_API_KEY` or `APIS_BASE_URL` is missing.
|
|
109
|
+
|
|
110
|
+
Both auth modes produce identical client instances.
|
|
111
|
+
|
|
112
|
+
Environment variables
|
|
113
|
+
---------------------
|
|
114
|
+
|
|
115
|
+
All resource APIs resolve from the centralized gateway base URL:
|
|
116
|
+
|
|
117
|
+
| Env Variable | Default |
|
|
118
|
+
|--------------|---------|
|
|
119
|
+
| `APIS_BASE_URL` | `https://apis.diskd.local:8080` |
|
|
120
|
+
| `APIS_API_KEY` | none |
|
|
121
|
+
|
|
122
|
+
The gateway is the single resource entrypoint. Public gateway URLs follow the
|
|
123
|
+
versioned convention `https://apis.example/v1/{namespace}/{module}`. The SDK
|
|
124
|
+
derives API paths from the same namespace structure as the public SDK surface
|
|
125
|
+
and lets the gateway handle API orchestration and auth strategy.
|
|
126
|
+
|
|
127
|
+
Derived default paths:
|
|
128
|
+
- `/v1/os/drive`
|
|
129
|
+
- `/v1/os/database`
|
|
130
|
+
- `/v1/os/llm`
|
|
131
|
+
- `/v1/os/agents`
|
|
132
|
+
- `/v1/os/mcp`
|
|
133
|
+
- `/v1/platform/sessions`
|
|
134
|
+
- `/v1/platform/crontab`
|
|
135
|
+
- `/v1/platform/operatives`
|
|
136
|
+
- `/v1/platform/projects`
|
|
137
|
+
- `/v1/platform/routines`
|
|
138
|
+
- `/v1/platform/events`
|
|
139
|
+
- `/v1/platform/calendar`
|
|
140
|
+
- `/v1/utils/tg-userbot`
|
|
141
|
+
- `/v1/utils/web-navigator`
|
|
142
|
+
|
|
143
|
+
You can still override a client with an explicit `url`, but the default mode is
|
|
144
|
+
the centralized gateway.
|
|
145
|
+
|
|
146
|
+
Gateway Decision
|
|
147
|
+
----------------
|
|
148
|
+
|
|
149
|
+
This SDK does not treat resource APIs as independently-discovered hosts.
|
|
150
|
+
The canonical model is one centralized `apis` gateway behind `APIS_BASE_URL`.
|
|
151
|
+
|
|
152
|
+
That means:
|
|
153
|
+
- no per-service default env vars such as `LLM_ROUTER_BASE_URL`, `AGENT_HUB_BASE_URL`, or `MCP_HUB_BASE_URL`
|
|
154
|
+
- resource clients derive their route from `APIS_BASE_URL` plus a namespace-derived path prefix
|
|
155
|
+
- the gateway is responsible for request routing, API orchestration, and auth-strategy handling
|
|
156
|
+
|
|
157
|
+
Per-client `url` remains available only as an explicit override.
|
|
158
|
+
|
|
159
|
+
Drive API
|
|
160
|
+
---------
|
|
161
|
+
|
|
162
|
+
### Path operations
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
await drive.init();
|
|
166
|
+
const entries = await drive.list({ path: '/' });
|
|
167
|
+
const dir = await drive.create({ dirName: 'my-folder' });
|
|
168
|
+
await drive.rename({ inode: dir.inode, newName: 'renamed-folder' });
|
|
169
|
+
await drive.delete({ inodes: [dir.inode], recursive: true });
|
|
170
|
+
const resolved = await drive.resolve({ inodes: ['inode1', 'inode2'] });
|
|
171
|
+
await drive.updateMetadata({ inode: 'abc', metadata: { key: 'value' } });
|
|
172
|
+
await drive.updateAttributes({ inode: 'abc', attributes: ['pinned'] });
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Upload (buffer + stream)
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
// Buffer upload
|
|
179
|
+
const result = await drive.upload.file({
|
|
180
|
+
name: 'hello.txt',
|
|
181
|
+
data: new TextEncoder().encode('Hello, world!'),
|
|
182
|
+
mimeType: 'text/plain',
|
|
183
|
+
onProgress: (uploaded, total) => console.log(`${uploaded}/${total}`),
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// Stream upload (large files)
|
|
187
|
+
const result = await drive.upload.file({
|
|
188
|
+
name: 'large.bin',
|
|
189
|
+
stream: readableStream,
|
|
190
|
+
size: 1_000_000_000,
|
|
191
|
+
sha256Root: 'precomputed-hex',
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Download (streaming)
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
const file = await drive.download.file({
|
|
199
|
+
inode: 'abc123',
|
|
200
|
+
onProgress: (downloaded, total) => console.log(`${downloaded}/${total}`),
|
|
201
|
+
});
|
|
202
|
+
await file.stream.pipeTo(writableStream);
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### File metadata, disk usage, tools
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
const meta = await drive.files.metadata({ inode: 'abc' });
|
|
209
|
+
const usage = await drive.diskUsage();
|
|
210
|
+
const ls = await drive.tools.ls({ path: '/', recursive: true });
|
|
211
|
+
const grep = await drive.tools.grep({ pattern: 'TODO' });
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Sessions
|
|
215
|
+
|
|
216
|
+
The SDK exposes these session methods on `diskd.platform.sessions({ auth, scope })`:
|
|
217
|
+
|
|
218
|
+
- `start`
|
|
219
|
+
- `open`
|
|
220
|
+
- `save`
|
|
221
|
+
- `list`
|
|
222
|
+
- `delete`
|
|
223
|
+
- `message`
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
const session = await sessions.start({
|
|
227
|
+
title: 'Deployment help',
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
await session.append([
|
|
231
|
+
sessions.message({ role: 'user', content: 'How do I deploy to production?' }),
|
|
232
|
+
]);
|
|
233
|
+
|
|
234
|
+
const sessionList = await sessions.list();
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Crontab scheduler
|
|
238
|
+
|
|
239
|
+
The SDK exposes these scheduler methods on `diskd.platform.crontab({ auth, scope, timezone? })`.
|
|
240
|
+
If `timezone` is omitted, the SDK uses the caller runtime timezone by default.
|
|
241
|
+
|
|
242
|
+
- `save`
|
|
243
|
+
- `get`
|
|
244
|
+
- `getStatus`
|
|
245
|
+
- `listJobs`
|
|
246
|
+
- `runJob`
|
|
247
|
+
- `createJob`
|
|
248
|
+
|
|
249
|
+
```ts
|
|
250
|
+
await crontab.createJob({
|
|
251
|
+
job: {
|
|
252
|
+
jobId: '01JABCD2FGH3JK4MNP5QRST6VW',
|
|
253
|
+
enabled: true,
|
|
254
|
+
schedule: {
|
|
255
|
+
minute: '*/5',
|
|
256
|
+
hour: '*',
|
|
257
|
+
dayOfMonth: '*',
|
|
258
|
+
month: '*',
|
|
259
|
+
dayOfWeek: '*',
|
|
260
|
+
},
|
|
261
|
+
request: {
|
|
262
|
+
method: 'POST',
|
|
263
|
+
url: 'https://example.internal/hooks/sync',
|
|
264
|
+
payload: {
|
|
265
|
+
kind: 'json',
|
|
266
|
+
value: { source: 'sdk-example' },
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
const status = await crontab.getStatus();
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
See `examples/node/drive-upload-download.ts`, `examples/node/drive-session-external.ts`, and `examples/node/drive-crontab.ts`.
|
|
276
|
+
|
|
277
|
+
Messages Store API
|
|
278
|
+
------------------
|
|
279
|
+
|
|
280
|
+
Channel-agnostic message storage on top of Drive. Each workspace mailbox is one
|
|
281
|
+
SQLite file under `/Mailboxes/<mailboxId>.mailbox`; attachment bytes live in
|
|
282
|
+
Drive under `/Mailboxes/<mailboxId>/<per-message-folder>/`. The wire is the
|
|
283
|
+
`messages_store/*` JSON-RPC namespace served by drive.
|
|
284
|
+
|
|
285
|
+
Use it to persist email (IMAP / JMAP), Telegram, WhatsApp, or any other
|
|
286
|
+
channel where messages live in folders inside per-account mailboxes. Message
|
|
287
|
+
`payload` is opaque JSON; the store never inspects it.
|
|
288
|
+
|
|
289
|
+
The client exposes four boundaries -- mailboxes, folders, messages, attachments
|
|
290
|
+
-- via a **functional scoping pattern**: each level returns a client that
|
|
291
|
+
captures its identifiers in a closure, so callers never repeat
|
|
292
|
+
`(mailboxId, folderId, externalId)` on every call.
|
|
293
|
+
|
|
294
|
+
```ts
|
|
295
|
+
const messagesStore = diskd.os.messagesStore({ auth });
|
|
296
|
+
const mailbox = messagesStore.mailbox({ mailboxId: 'gmail-acme' });
|
|
297
|
+
const folder = mailbox.folder({ folderId: 'INBOX' });
|
|
298
|
+
const message = folder.message({ externalId: 'imap-uid-1001' });
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Mailboxes
|
|
302
|
+
|
|
303
|
+
```ts
|
|
304
|
+
// Allocate the mailbox SQLite file under /Mailboxes/.
|
|
305
|
+
// metadata is opaque JSON, stashed on the underlying drive_databases record.
|
|
306
|
+
const created = await messagesStore.createMailbox({
|
|
307
|
+
mailboxId: 'gmail-acme',
|
|
308
|
+
displayName: 'acme@gmail.com',
|
|
309
|
+
metadata: { protocol: 'imap', host: 'imap.gmail.com' },
|
|
310
|
+
});
|
|
311
|
+
// → { mailboxId, dbInode, drivePath: '/Mailboxes/gmail-acme.mailbox' }
|
|
312
|
+
|
|
313
|
+
// Bind a mailbox-scoped client; subsequent calls don't repeat mailboxId.
|
|
314
|
+
const mailbox = messagesStore.mailbox({ mailboxId: 'gmail-acme' });
|
|
315
|
+
|
|
316
|
+
// Idempotent SQLite-schema bootstrap. Required before any folder/message ops.
|
|
317
|
+
await mailbox.init();
|
|
318
|
+
|
|
319
|
+
// Workspace-scoped enumeration.
|
|
320
|
+
const all = await messagesStore.listMailboxes();
|
|
321
|
+
// → readonly { mailboxId, displayName, dbInode, recordCount,
|
|
322
|
+
// sizeBytes, updatedAt }[]
|
|
323
|
+
|
|
324
|
+
// Cascade-delete (mailbox file + per-mailbox attachment subtree).
|
|
325
|
+
await mailbox.delete();
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Folders
|
|
329
|
+
|
|
330
|
+
`folderId` is opaque (caller-chosen) -- IMAP folder name, JMAP id, Telegram
|
|
331
|
+
chat_id, etc. Folder `metadata` is the natural place for protocol-specific
|
|
332
|
+
sync state (`UIDVALIDITY`/`UIDNEXT`/`HIGHESTMODSEQ` for IMAP, JMAP `state`,
|
|
333
|
+
Telegram pts, etc.). The store never reads it.
|
|
334
|
+
|
|
335
|
+
```ts
|
|
336
|
+
// Idempotent upsert. created=true on first call, false thereafter.
|
|
337
|
+
await mailbox.upsertFolder({
|
|
338
|
+
folderId: 'INBOX',
|
|
339
|
+
displayName: 'Inbox',
|
|
340
|
+
metadata: { uidvalidity: 12345, uidnext: 1101 },
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
// List folders in this mailbox.
|
|
344
|
+
const folders = await mailbox.listFolders();
|
|
345
|
+
|
|
346
|
+
// Bind a folder-scoped client.
|
|
347
|
+
const folder = mailbox.folder({ folderId: 'INBOX' });
|
|
348
|
+
|
|
349
|
+
// Update display name / sync metadata via the scoped client (folderId implicit).
|
|
350
|
+
await folder.upsert({
|
|
351
|
+
displayName: 'Inbox',
|
|
352
|
+
metadata: { uidvalidity: 12345, uidnext: 1200 },
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// Read one folder.
|
|
356
|
+
const summary = await folder.get();
|
|
357
|
+
// → { folderId, displayName, metadata, messageCount, updatedAt }
|
|
358
|
+
|
|
359
|
+
// Cascade-delete folder + messages + per-message attachments.
|
|
360
|
+
const result = await folder.delete();
|
|
361
|
+
// → { folderId, deleted, deletedMessageCount }
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### Messages
|
|
365
|
+
|
|
366
|
+
`externalId` is the caller's idempotency key within the folder (IMAP UID
|
|
367
|
+
stringified, Telegram `message_id`, JMAP id, ...). `payload` is opaque JSON
|
|
368
|
+
the store never inspects.
|
|
369
|
+
|
|
370
|
+
A successful `upsertBatch` response means the batch is durable in S3 -- the
|
|
371
|
+
SQLite head is committed before the call returns.
|
|
372
|
+
|
|
373
|
+
```ts
|
|
374
|
+
// Bulk insert-or-update by externalId.
|
|
375
|
+
const ub = await folder.upsertBatch({
|
|
376
|
+
items: [
|
|
377
|
+
{
|
|
378
|
+
externalId: 'imap-uid-1001',
|
|
379
|
+
payload: {
|
|
380
|
+
subject: 'Welcome to upgraide',
|
|
381
|
+
from: 'noreply@upgraide.dev',
|
|
382
|
+
receivedAt: '2026-04-28T13:21:32Z',
|
|
383
|
+
labels: ['inbox', 'unread'],
|
|
384
|
+
},
|
|
385
|
+
},
|
|
386
|
+
{ externalId: 'imap-uid-1002', payload: { subject: 'Your weekly digest' } },
|
|
387
|
+
],
|
|
388
|
+
});
|
|
389
|
+
// → { inserted: 2, updated: 0 }
|
|
390
|
+
|
|
391
|
+
// Cursor-paginated read.
|
|
392
|
+
let cursor: string | null = null;
|
|
393
|
+
do {
|
|
394
|
+
const page = await folder.listMessages({ limit: 100, cursor: cursor ?? undefined });
|
|
395
|
+
for (const m of page.items) {
|
|
396
|
+
// m.externalId, m.payload, m.createdAt, m.updatedAt
|
|
397
|
+
}
|
|
398
|
+
cursor = page.nextCursor;
|
|
399
|
+
} while (cursor);
|
|
400
|
+
|
|
401
|
+
// Single-message lookup.
|
|
402
|
+
const msg = await folder.getMessage({ externalId: 'imap-uid-1001' });
|
|
403
|
+
|
|
404
|
+
// Bulk delete; missing ids are silently skipped.
|
|
405
|
+
const del = await folder.deleteBatch({
|
|
406
|
+
externalIds: ['imap-uid-1001', 'imap-uid-1002'],
|
|
407
|
+
});
|
|
408
|
+
// → { deleted: 2 }
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### Attachments
|
|
412
|
+
|
|
413
|
+
Attachments follow Drive's upload-intent contract (start → PUT bytes →
|
|
414
|
+
commit) but are scoped to a single message. The per-message Drive folder is
|
|
415
|
+
created lazily on the first `uploadStart` call.
|
|
416
|
+
|
|
417
|
+
```ts
|
|
418
|
+
const message = folder.message({ externalId: 'imap-uid-1001' });
|
|
419
|
+
|
|
420
|
+
// 1. Begin upload -- get an intent + presigned URL.
|
|
421
|
+
const intent = await message.attachments.uploadStart({
|
|
422
|
+
attachmentId: 'att-1',
|
|
423
|
+
filename: 'invoice.pdf',
|
|
424
|
+
contentType: 'application/pdf',
|
|
425
|
+
sizeBytes: 12345,
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
// 2. PUT the bytes to intent.uploadUrl with header X-Upload-Intent-Id.
|
|
429
|
+
// (See Drive upload examples for streaming/buffer modes.)
|
|
430
|
+
const putRes = await fetch(intent.uploadUrl, {
|
|
431
|
+
method: 'PUT',
|
|
432
|
+
headers: { 'X-Upload-Intent-Id': intent.intentId, 'Content-Type': 'application/pdf' },
|
|
433
|
+
body: pdfBytes,
|
|
434
|
+
});
|
|
435
|
+
const { etag } = (await putRes.json()) as { etag: string };
|
|
436
|
+
|
|
437
|
+
// 3. Commit -- registers the attachment row.
|
|
438
|
+
await message.attachments.uploadCommit({
|
|
439
|
+
attachmentId: 'att-1',
|
|
440
|
+
intentId: intent.intentId,
|
|
441
|
+
etag,
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
// Enumerate this message's attachments.
|
|
445
|
+
const list = await message.attachments.list();
|
|
446
|
+
|
|
447
|
+
// Presigned download URL (with explicit expiresAt).
|
|
448
|
+
const dl = await message.attachments.downloadUrl({ attachmentId: 'att-1' });
|
|
449
|
+
|
|
450
|
+
// Delete the attachment row + its Drive file.
|
|
451
|
+
await message.attachments.delete({ attachmentId: 'att-1' });
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Auth modes
|
|
455
|
+
|
|
456
|
+
Same as the rest of the SDK -- both work:
|
|
457
|
+
|
|
458
|
+
```ts
|
|
459
|
+
// API key (internal services / Tilt / port-forward).
|
|
460
|
+
const auth = diskd.auth.apiKey({ workspaceId: 'ws-...' });
|
|
461
|
+
|
|
462
|
+
// OAuth2 client-credentials (external clients).
|
|
463
|
+
const auth = await diskd.auth.credentials({
|
|
464
|
+
scopes: ['openid'],
|
|
465
|
+
keyfilePath: '.agents/credentials.json',
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
const messagesStore = diskd.os.messagesStore({ auth });
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
Workspace identity is always auth-derived (`X-Workspace-Id` header from API
|
|
472
|
+
key, `ext.workspace_id` claim from OAuth JWT) -- never sent on the wire as a
|
|
473
|
+
parameter. See `examples/node/messages-store-example.ts` for a full
|
|
474
|
+
end-to-end walk-through.
|
|
475
|
+
|
|
476
|
+
Routines API
|
|
477
|
+
------------
|
|
478
|
+
|
|
479
|
+
REST client for managing routines (automated workflows) scoped to profile or project:
|
|
480
|
+
|
|
481
|
+
```ts
|
|
482
|
+
const routines = diskd.platform.routines({ auth });
|
|
483
|
+
|
|
484
|
+
// List routines in a scope
|
|
485
|
+
const all = await routines.list({ scope: 'workspace' });
|
|
486
|
+
const projectRoutines = await routines.list({ scope: 'project', projectName: 'my-project' });
|
|
487
|
+
|
|
488
|
+
// Get by slug
|
|
489
|
+
const routine = await routines.get({ slug: 'daily-summary', scope: 'workspace' });
|
|
490
|
+
|
|
491
|
+
// Create
|
|
492
|
+
const created = await routines.create({
|
|
493
|
+
name: 'Daily Summary',
|
|
494
|
+
scope: 'workspace',
|
|
495
|
+
operativeSlug: 'research-agent',
|
|
496
|
+
triggerType: 'rhythm',
|
|
497
|
+
trigger: { cron: '0 9 * * *' },
|
|
498
|
+
steps: [{ id: 'step-1', name: 'Summarize', action: 'summarize', order: 0 }],
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
// Update
|
|
502
|
+
const updated = await routines.update(
|
|
503
|
+
'daily-summary',
|
|
504
|
+
{ status: 'paused' },
|
|
505
|
+
{ scopeType: 'workspace' },
|
|
506
|
+
);
|
|
507
|
+
|
|
508
|
+
// Delete
|
|
509
|
+
await routines.delete({ slug: 'daily-summary', scope: 'workspace' });
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
Operatives API
|
|
513
|
+
--------------
|
|
514
|
+
|
|
515
|
+
REST client for managing operatives (AI agents) with attached files, skills, and MCP tools:
|
|
516
|
+
|
|
517
|
+
```ts
|
|
518
|
+
const ops = diskd.platform.operatives({ auth });
|
|
519
|
+
|
|
520
|
+
// List operatives in a project
|
|
521
|
+
const list = await ops.list({ projectId: 'proj-1' });
|
|
522
|
+
|
|
523
|
+
// Get by id or slug
|
|
524
|
+
const operative = await ops.get('op-01');
|
|
525
|
+
const bySlug = await ops.getBySlug({ projectId: 'proj-1', slug: 'research-agent' });
|
|
526
|
+
|
|
527
|
+
// Create
|
|
528
|
+
const created = await ops.create({
|
|
529
|
+
projectId: 'proj-1',
|
|
530
|
+
name: 'Research Agent',
|
|
531
|
+
engine: 'deep',
|
|
532
|
+
engineProvider: 'anthropic',
|
|
533
|
+
engineModel: 'claude-4',
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
// Update
|
|
537
|
+
await ops.update('op-01', {
|
|
538
|
+
orders: 'You are a research assistant focused on academic papers.',
|
|
539
|
+
fileAccess: 'selected',
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
// Delete
|
|
543
|
+
await ops.delete('op-01');
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
### Operative files (Drive knowledge sources)
|
|
547
|
+
|
|
548
|
+
Attach Drive files from the operative's project chroot as knowledge sources:
|
|
549
|
+
|
|
550
|
+
```ts
|
|
551
|
+
// Attach files (paths relative to project chroot)
|
|
552
|
+
await ops.files.add('op-01', { paths: ['/docs/knowledge-base', '/docs/readme.md'] });
|
|
553
|
+
|
|
554
|
+
// List attached files
|
|
555
|
+
const files = await ops.files.list('op-01');
|
|
556
|
+
|
|
557
|
+
// Detach a file
|
|
558
|
+
await ops.files.remove('op-01', files[0].id);
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
### Operative skills
|
|
562
|
+
|
|
563
|
+
```ts
|
|
564
|
+
// Attach skills
|
|
565
|
+
await ops.skills.add('op-01', { refIds: ['web-search', 'code-review'] });
|
|
566
|
+
|
|
567
|
+
// List attached skills
|
|
568
|
+
const skills = await ops.skills.list('op-01');
|
|
569
|
+
|
|
570
|
+
// Detach a skill
|
|
571
|
+
await ops.skills.remove('op-01', skills[0].id);
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
### Operative MCP tools
|
|
575
|
+
|
|
576
|
+
```ts
|
|
577
|
+
// Attach MCP tools
|
|
578
|
+
await ops.tools.add('op-01', { selectors: ['github/search_repos', 'slack/send_message'] });
|
|
579
|
+
|
|
580
|
+
// List attached tools
|
|
581
|
+
const tools = await ops.tools.list('op-01');
|
|
582
|
+
|
|
583
|
+
// Detach a tool
|
|
584
|
+
await ops.tools.remove('op-01', tools[0].id);
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
Calendar API
|
|
588
|
+
------------
|
|
589
|
+
|
|
590
|
+
REST client for workspace calendar management -- events, attendees, note links, attachments, and settings:
|
|
591
|
+
|
|
592
|
+
```ts
|
|
593
|
+
const calendar = diskd.platform.calendar({ auth });
|
|
594
|
+
|
|
595
|
+
// Accounts and events
|
|
596
|
+
const accounts = await calendar.listAccounts();
|
|
597
|
+
const events = await calendar.listEvents({
|
|
598
|
+
startAfter: '2026-03-01T00:00:00Z',
|
|
599
|
+
startBefore: '2026-03-31T23:59:59Z',
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
// Event CRUD
|
|
603
|
+
const event = await calendar.createEvent({
|
|
604
|
+
calendarId: accounts[0].calendars[0].id,
|
|
605
|
+
title: 'Sprint Planning',
|
|
606
|
+
startAt: '2026-03-25T10:00:00Z',
|
|
607
|
+
endAt: '2026-03-25T11:00:00Z',
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
await calendar.updateEvent(event.id, {
|
|
611
|
+
title: 'Sprint Planning (updated)',
|
|
612
|
+
metadata: { timeBlockCategory: 'meeting' },
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
await calendar.deleteEvent(event.id);
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
### Attendees
|
|
619
|
+
|
|
620
|
+
```ts
|
|
621
|
+
const attendee = await calendar.attendees.add(event.id, {
|
|
622
|
+
email: 'alice@example.com',
|
|
623
|
+
role: 'required',
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
await calendar.attendees.updateRsvp(event.id, attendee.id, 'yes');
|
|
627
|
+
await calendar.attendees.remove(event.id, attendee.id);
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
### Note links
|
|
631
|
+
|
|
632
|
+
```ts
|
|
633
|
+
const link = await calendar.noteLinks.add(event.id, {
|
|
634
|
+
noteDiskPath: '/Projects/sprint/notes/planning.md',
|
|
635
|
+
title: 'Planning Notes',
|
|
636
|
+
linkType: 'context',
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
await calendar.noteLinks.remove(event.id, link.id);
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
### Attachments
|
|
643
|
+
|
|
644
|
+
```ts
|
|
645
|
+
const attachment = await calendar.attachments.add(event.id, {
|
|
646
|
+
type: 'url',
|
|
647
|
+
title: 'Meeting Recording',
|
|
648
|
+
url: 'https://meet.example.com/recording/123',
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
await calendar.attachments.remove(event.id, attachment.id);
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
### Event metadata
|
|
655
|
+
|
|
656
|
+
Events support an extensible `metadata` JSONB field for cross-domain data:
|
|
657
|
+
|
|
658
|
+
```ts
|
|
659
|
+
await calendar.updateEvent(event.id, {
|
|
660
|
+
metadata: {
|
|
661
|
+
timeBlockCategory: 'focus',
|
|
662
|
+
linkedNotes: [
|
|
663
|
+
{ noteDiskPath: '/docs/spec.md', title: 'Spec', linkType: 'context' },
|
|
664
|
+
],
|
|
665
|
+
},
|
|
666
|
+
});
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
### Settings
|
|
670
|
+
|
|
671
|
+
```ts
|
|
672
|
+
const settings = await calendar.getSettings();
|
|
673
|
+
await calendar.updateSettings({
|
|
674
|
+
weekStartDay: 0,
|
|
675
|
+
defaultView: 'month',
|
|
676
|
+
timezone: 'America/New_York',
|
|
677
|
+
});
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
Drive Database API
|
|
681
|
+
------------------
|
|
682
|
+
|
|
683
|
+
JSON-RPC client for Drive's SQLite-backed database operations:
|
|
684
|
+
|
|
685
|
+
```ts
|
|
686
|
+
const drive = diskd.os.drive({ version: 'v1', auth });
|
|
687
|
+
|
|
688
|
+
// Create a database with schema
|
|
689
|
+
const db = await drive.db.create({
|
|
690
|
+
name: 'myapp.workspace-123.main',
|
|
691
|
+
schema: {
|
|
692
|
+
users: {
|
|
693
|
+
id: { type: 'TEXT', primaryKey: true },
|
|
694
|
+
name: { type: 'TEXT', notNull: true },
|
|
695
|
+
email: { type: 'TEXT', notNull: true },
|
|
696
|
+
},
|
|
697
|
+
},
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
// Insert rows
|
|
701
|
+
await drive.db.insert({
|
|
702
|
+
name: 'myapp.workspace-123.main',
|
|
703
|
+
table: 'users',
|
|
704
|
+
rows: [{ id: '1', name: 'Alice', email: 'alice@example.com' }],
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
// Query with parameters
|
|
708
|
+
const result = await drive.db.query({
|
|
709
|
+
name: 'myapp.workspace-123.main',
|
|
710
|
+
sql: 'SELECT * FROM users WHERE id = ?',
|
|
711
|
+
parameters: ['1'],
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
// Commit, metadata, drop, resolve
|
|
715
|
+
await drive.db.commit({ name: 'myapp.workspace-123.main' });
|
|
716
|
+
const meta = await drive.db.metadata({ name: 'myapp.workspace-123.main' });
|
|
717
|
+
const resolved = await drive.db.resolveByInode({ dbInode: db.dbInode });
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
Drive Repository (CRUD pattern)
|
|
721
|
+
--------------------------------
|
|
722
|
+
|
|
723
|
+
Higher-level database + table-scoped repository pattern -- ideal for services
|
|
724
|
+
that use Drive DB as their persistence layer:
|
|
725
|
+
|
|
726
|
+
```ts
|
|
727
|
+
// Create database with schema
|
|
728
|
+
const db = diskd.os.database({
|
|
729
|
+
auth,
|
|
730
|
+
dbName: 'shop.workspace-123.main',
|
|
731
|
+
dbType: 'database',
|
|
732
|
+
schema: {
|
|
733
|
+
users: { id: { type: 'TEXT', primaryKey: true }, name: { type: 'TEXT', notNull: true } },
|
|
734
|
+
orders: { id: { type: 'TEXT', primaryKey: true }, user_id: { type: 'TEXT' }, total: { type: 'INTEGER' } },
|
|
735
|
+
},
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
await db.ensureCreated();
|
|
739
|
+
|
|
740
|
+
// Get table-scoped repositories
|
|
741
|
+
const users = db.repository('users');
|
|
742
|
+
const orders = db.repository('orders');
|
|
743
|
+
|
|
744
|
+
// Insert
|
|
745
|
+
await users.insert([{ id: 'u1', name: 'Alice' }, { id: 'u2', name: 'Bob' }]);
|
|
746
|
+
|
|
747
|
+
// Find with where, orderBy, limit, offset
|
|
748
|
+
const results = await users.find({
|
|
749
|
+
where: { name: 'Alice' },
|
|
750
|
+
orderBy: { column: 'name', direction: 'ASC' },
|
|
751
|
+
limit: 10,
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
// Find one (returns null if not found)
|
|
755
|
+
const alice = await users.findOne({ id: 'u1' });
|
|
756
|
+
|
|
757
|
+
// Count
|
|
758
|
+
const total = await orders.count();
|
|
759
|
+
const pending = await orders.count({ status: 'pending' });
|
|
760
|
+
|
|
761
|
+
// Update
|
|
762
|
+
await orders.update({ where: { id: 'o1' }, set: { status: 'shipped' } });
|
|
763
|
+
|
|
764
|
+
// Delete
|
|
765
|
+
await orders.deleteRows({ status: 'cancelled' });
|
|
766
|
+
|
|
767
|
+
// Raw SQL at database level for joins and complex queries
|
|
768
|
+
const summary = await db.query(`
|
|
769
|
+
SELECT u.name, SUM(o.total) AS revenue
|
|
770
|
+
FROM users u JOIN orders o ON o.user_id = u.id
|
|
771
|
+
GROUP BY u.id ORDER BY revenue DESC
|
|
772
|
+
`);
|
|
773
|
+
|
|
774
|
+
// Commit and metadata (database-level operations)
|
|
775
|
+
await db.commit();
|
|
776
|
+
const meta = await db.metadata();
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
See `examples/node/drive-db-repository-example.ts`.
|
|
780
|
+
|
|
781
|
+
TypeORM Driver (`diskd.os.datasource()`)
|
|
782
|
+
-------------------------------------
|
|
783
|
+
|
|
784
|
+
Use TypeORM entities, relations, and repositories against Drive DB. SQL is routed
|
|
785
|
+
through Drive DB JSON-RPC, and TypeORM's transaction lifecycle maps to Drive DB's
|
|
786
|
+
commit/rollback semantics. Requires `typeorm` as a peer dependency.
|
|
787
|
+
|
|
788
|
+
### Installation
|
|
789
|
+
|
|
790
|
+
```bash
|
|
791
|
+
npm install @diskd-ai/sdk typeorm
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
### Usage
|
|
795
|
+
|
|
796
|
+
```ts
|
|
797
|
+
import { diskd } from '@diskd-ai/sdk';
|
|
798
|
+
import { Entity, PrimaryColumn, Column } from 'typeorm';
|
|
799
|
+
|
|
800
|
+
// Define entities
|
|
801
|
+
@Entity({ name: 'users' })
|
|
802
|
+
class User {
|
|
803
|
+
@PrimaryColumn({ type: 'varchar', length: 26 })
|
|
804
|
+
id!: string;
|
|
805
|
+
|
|
806
|
+
@Column({ type: 'varchar' })
|
|
807
|
+
name!: string;
|
|
808
|
+
|
|
809
|
+
@Column({ type: 'varchar' })
|
|
810
|
+
email!: string;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
// Create DataSource backed by Drive DB
|
|
814
|
+
process.env.APIS_BASE_URL ??= 'https://apis.diskd.local:8080';
|
|
815
|
+
|
|
816
|
+
const auth = diskd.auth.apiKey({ workspaceId: 'workspace-123' });
|
|
817
|
+
|
|
818
|
+
const ds = diskd.os.datasource({
|
|
819
|
+
auth,
|
|
820
|
+
url: `${process.env.APIS_BASE_URL}/v1/os/database/api/v1`,
|
|
821
|
+
dbName: 'shop.workspace-123.main',
|
|
822
|
+
entities: [User],
|
|
823
|
+
synchronize: true,
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
await ds.initialize();
|
|
827
|
+
|
|
828
|
+
// Standard TypeORM repository operations
|
|
829
|
+
const userRepo = ds.getRepository(User);
|
|
830
|
+
await userRepo.save({ id: 'u1', name: 'Alice', email: 'alice@example.com' });
|
|
831
|
+
|
|
832
|
+
const alice = await userRepo.findOneBy({ id: 'u1' });
|
|
833
|
+
const users = await userRepo.find({ order: { name: 'ASC' } });
|
|
834
|
+
|
|
835
|
+
// Persist to S3 (flush WAL)
|
|
836
|
+
await ds.driver.commit();
|
|
837
|
+
|
|
838
|
+
// Rollback discards uncommitted changes (revert to last commit)
|
|
839
|
+
await ds.driver.driveRollback();
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
### Transaction mapping
|
|
843
|
+
|
|
844
|
+
| TypeORM operation | Drive DB action |
|
|
845
|
+
|------------------------|----------------------------------------|
|
|
846
|
+
| `BEGIN TRANSACTION` | No-op (writes auto-accumulate in WAL) |
|
|
847
|
+
| `COMMIT` | `drive.db.commit()` -- flush WAL to S3 |
|
|
848
|
+
| `ROLLBACK` | `drive.db.rollback()` -- discard WAL |
|
|
849
|
+
|
|
850
|
+
### Limitations (v1)
|
|
851
|
+
|
|
852
|
+
- No nested transactions / savepoints (deferred to v2)
|
|
853
|
+
- Affected row count returns 0 (each JSON-RPC call is a separate SQLite
|
|
854
|
+
connection; works fine for ULID-based entities)
|
|
855
|
+
- Schema introspection from live database is limited; `synchronize: true`
|
|
856
|
+
generates DDL directly
|
|
857
|
+
|
|
858
|
+
See `examples/node/typeorm-drive-example.ts` and `docs/typeorm-driver-design.md`.
|
|
859
|
+
|
|
860
|
+
LLM Router API
|
|
861
|
+
--------------
|
|
862
|
+
|
|
863
|
+
JSON-RPC 2.0 + NDJSON streaming for multi-provider LLM completions:
|
|
864
|
+
|
|
865
|
+
```ts
|
|
866
|
+
const llm = diskd.os.llm({ auth });
|
|
867
|
+
|
|
868
|
+
// Non-streaming completion
|
|
869
|
+
const result = await llm.completions.create({
|
|
870
|
+
provider: 'openai', model: 'gpt-4o-mini',
|
|
871
|
+
messages: [{ role: 'user', content: 'Hello' }],
|
|
872
|
+
maxTokens: 64,
|
|
873
|
+
});
|
|
874
|
+
|
|
875
|
+
// Streaming
|
|
876
|
+
for await (const chunk of llm.completions.stream(params)) {
|
|
877
|
+
process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
// Models, embeddings, OCR, audio transcription
|
|
881
|
+
const models = await llm.models.listAll();
|
|
882
|
+
const embeddings = await llm.embeddings.create({ provider: 'openai', model: 'text-embedding-3-small', input: ['text'] });
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
See `examples/node/llm-router-example.ts`.
|
|
886
|
+
|
|
887
|
+
Agent Hub API
|
|
888
|
+
-------------
|
|
889
|
+
|
|
890
|
+
SSE streaming with `StreamProtocolHandler` + `StreamProtocolFetcher` for agent invocation:
|
|
891
|
+
|
|
892
|
+
```ts
|
|
893
|
+
import { diskd, StreamProtocolHandler } from '@diskd-ai/sdk';
|
|
894
|
+
|
|
895
|
+
const agents = diskd.os.agents({ auth, workspaceId: '...' });
|
|
896
|
+
|
|
897
|
+
// List agents and models
|
|
898
|
+
const agentList = await agents.agents.list();
|
|
899
|
+
const models = await agents.agents.getSupportedModels('assistant');
|
|
900
|
+
const billing = await agents.billing.getAliases();
|
|
901
|
+
|
|
902
|
+
// Invoke with fluent stream handling
|
|
903
|
+
const handler = new StreamProtocolHandler()
|
|
904
|
+
.on('response.output_text.delta', (e) => process.stdout.write(e.delta))
|
|
905
|
+
.on('response.completed', (e) => console.log('done', e.response.usage))
|
|
906
|
+
.on('response.failed', (e) => console.error(e.response.error.message))
|
|
907
|
+
.on('error', (e) => console.error(e.message));
|
|
908
|
+
|
|
909
|
+
const stream = await agents.invoke({
|
|
910
|
+
agentName: 'assistant',
|
|
911
|
+
query: 'Hello',
|
|
912
|
+
agentOptions: { maxTokens: 256 },
|
|
913
|
+
});
|
|
914
|
+
|
|
915
|
+
stream.map((event) => handler.handle(event))
|
|
916
|
+
.stop(() => console.log('stream closed'))
|
|
917
|
+
.catch((err) => console.error(err));
|
|
918
|
+
```
|
|
919
|
+
|
|
920
|
+
Stream protocol events include text deltas, function calls/results, content parts
|
|
921
|
+
(images, files, audio), web/file search lifecycle, external sources, plan updates,
|
|
922
|
+
notifications, and error/completion signals.
|
|
923
|
+
|
|
924
|
+
See `examples/node/agent-hub-example.ts`.
|
|
925
|
+
|
|
926
|
+
MCP Hub API
|
|
927
|
+
-----------
|
|
928
|
+
|
|
929
|
+
REST client for MCP server catalog, registry, and integrations:
|
|
930
|
+
|
|
931
|
+
```ts
|
|
932
|
+
const mcp = diskd.os.mcp({ auth, workspaceId: '...' });
|
|
933
|
+
|
|
934
|
+
// Catalog
|
|
935
|
+
const catalog = await mcp.catalog.list({ search: 'github' });
|
|
936
|
+
const details = await mcp.catalog.getServerDetails(serverId);
|
|
937
|
+
|
|
938
|
+
// Registry (installed servers)
|
|
939
|
+
const registry = await mcp.registry.list();
|
|
940
|
+
const added = await mcp.registry.addServer({ catalogServerId: '...' });
|
|
941
|
+
await mcp.registry.toggleTool(serverId, toolId, false);
|
|
942
|
+
const logs = await mcp.registry.getServerLogs(serverId, { limit: 10 });
|
|
943
|
+
await mcp.registry.deleteServer(serverId);
|
|
944
|
+
|
|
945
|
+
// Env vars, connection settings, remote servers
|
|
946
|
+
await mcp.registry.upsertEnvVar(serverId, { key: 'TOKEN', value: '...' });
|
|
947
|
+
await mcp.registry.addRemoteServer({ name: 'My MCP', url: '...', authType: 'pat' });
|
|
948
|
+
```
|
|
949
|
+
|
|
950
|
+
See `examples/node/mcp-hub-example.ts`.
|
|
951
|
+
|
|
952
|
+
Telegram Userbot API
|
|
953
|
+
--------------------
|
|
954
|
+
|
|
955
|
+
REST client for Telegram channel resolution, importing, and message retrieval:
|
|
956
|
+
|
|
957
|
+
```ts
|
|
958
|
+
const tg = diskd.utils.tgUserBot({ auth, workspaceId: '...' });
|
|
959
|
+
|
|
960
|
+
// Resolve channel (public, no auth required)
|
|
961
|
+
const resolved = await tg.channels.resolve('durov');
|
|
962
|
+
|
|
963
|
+
// Channel operations
|
|
964
|
+
const channels = await tg.channels.list();
|
|
965
|
+
await tg.channels.add({ channelIdentifier: '@mychannel', limit: 1000 });
|
|
966
|
+
await tg.channels.sync({ telegramId: -1001234567890 });
|
|
967
|
+
|
|
968
|
+
// Messages and stats
|
|
969
|
+
const messages = await tg.channels.getMessages(channelId, { limit: 50, searchText: 'keyword' });
|
|
970
|
+
const stats = await tg.channels.getStats(channelId);
|
|
971
|
+
const status = await tg.channels.getStatus(channelId);
|
|
972
|
+
|
|
973
|
+
// Tasks
|
|
974
|
+
const tasks = await tg.tasks.list();
|
|
975
|
+
await tg.tasks.cancel(taskUuid);
|
|
976
|
+
```
|
|
977
|
+
|
|
978
|
+
See `examples/node/tg-userbot-example.ts`.
|
|
979
|
+
|
|
980
|
+
Web Navigator API
|
|
981
|
+
-----------------
|
|
982
|
+
|
|
983
|
+
REST client for URL resolution and web scraping jobs:
|
|
984
|
+
|
|
985
|
+
```ts
|
|
986
|
+
const webNav = diskd.utils.webNavigator({ auth, workspaceId: '...' });
|
|
987
|
+
|
|
988
|
+
// Resolve URL metadata
|
|
989
|
+
const meta = await webNav.resolve({ url: 'https://example.com' });
|
|
990
|
+
|
|
991
|
+
// Submit scrape job
|
|
992
|
+
const job = await webNav.scrape.submit({ url: 'https://example.com', depth: 1, maxPages: 10 });
|
|
993
|
+
const status = await webNav.scrape.getStatus(job.jobId);
|
|
994
|
+
const result = await webNav.scrape.getResult(job.jobId);
|
|
995
|
+
await webNav.scrape.cancel(job.jobId);
|
|
996
|
+
```
|
|
997
|
+
|
|
998
|
+
See `examples/node/web-navigator-example.ts`.
|
|
999
|
+
|
|
1000
|
+
Web quickstart (Vite + PKCE)
|
|
1001
|
+
----------------------------
|
|
1002
|
+
|
|
1003
|
+
Use `@diskd-ai/sdk/browser` and a standard OAuth2 Authorization Code + PKCE redirect.
|
|
1004
|
+
|
|
1005
|
+
Runnable example: `examples/web/` (see `examples/README.md`).
|
|
1006
|
+
|
|
1007
|
+
Publishing a new version
|
|
1008
|
+
------------------------
|
|
1009
|
+
|
|
1010
|
+
1. Bump the version in `package.json`:
|
|
1011
|
+
|
|
1012
|
+
```bash
|
|
1013
|
+
npm version patch # 0.3.0 -> 0.3.1
|
|
1014
|
+
npm version minor # 0.3.0 -> 0.4.0
|
|
1015
|
+
npm version major # 0.3.0 -> 1.0.0
|
|
1016
|
+
```
|
|
1017
|
+
|
|
1018
|
+
2. Push the commit and tag:
|
|
1019
|
+
|
|
1020
|
+
```bash
|
|
1021
|
+
git push gitlab main --tags
|
|
1022
|
+
```
|
|
1023
|
+
|
|
1024
|
+
3. The GitLab CI pipeline triggers on `v*.*.*` tags and automatically:
|
|
1025
|
+
- Builds the project
|
|
1026
|
+
- Runs unit tests and typecheck
|
|
1027
|
+
- Publishes to the GitLab Package Registry
|
|
1028
|
+
|
|
1029
|
+
4. Verify at: `https://gitlab.iosya.com/upgraide-v2/platform-api/-/packages`
|
|
1030
|
+
|
|
1031
|
+
Docs and examples
|
|
1032
|
+
-----------------
|
|
1033
|
+
|
|
1034
|
+
- Quickstart: `docs/sdk-quickstart.md`
|
|
1035
|
+
- Examples: `examples/README.md`
|
|
1036
|
+
- Design: `docs/drive-session-sdk-design.md`
|