@puredesktop/puredesktop-ui-bridge 2.1.7 → 2.1.9
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/package.json +89 -5
- package/src/agents/mcpServerPresets.test.ts +105 -0
- package/src/agents/mcpServerPresets.ts +380 -0
- package/src/agents/runtime/index.ts +7 -0
- package/src/agents/runtime/mapAgentSnapshot.ts +11 -8
- package/src/agents/runtime/pendingAsks.test.ts +117 -0
- package/src/agents/runtime/pendingAsks.ts +110 -0
- package/src/bridge/agentScopeDefaults.ts +65 -0
- package/src/bridge/agentTypes.ts +57 -3
- package/src/bridge/agents.d.mts +6 -0
- package/src/bridge/agents.mjs +10 -0
- package/src/bridge/agents.ts +4 -0
- package/src/bridge/collectionImagePaste.ts +19 -1
- package/src/bridge/context.mjs +32 -0
- package/src/bridge/credentials.d.mts +62 -0
- package/src/bridge/credentials.mjs +53 -0
- package/src/bridge/documents.d.mts +76 -0
- package/src/bridge/documents.mjs +40 -0
- package/src/bridge/events.d.mts +1 -0
- package/src/bridge/events.mjs +1 -0
- package/src/bridge/googleAuth.ts +7 -152
- package/src/bridge/mcpClient.d.mts +74 -0
- package/src/bridge/mcpClient.mjs +79 -0
- package/src/bridge/methods.d.mts +45 -0
- package/src/bridge/methods.mjs +46 -0
- package/src/bridge/notifications.d.mts +12 -0
- package/src/bridge/notifications.mjs +36 -0
- package/src/bridge/operations.d.mts +44 -0
- package/src/bridge/operations.mjs +40 -0
- package/src/bridge/pureRender/base.css +44 -0
- package/src/bridge/pureRender/document.ts +29 -2
- package/src/bridge/pureRender/index.ts +3 -0
- package/src/bridge/pureRender/normalize.ts +167 -0
- package/src/bridge/pureRender/sanitizeExportBody.test.ts +51 -0
- package/src/bridge/pureRender/sanitizeExportBody.ts +61 -0
- package/src/bridge/pureRender/styles.ts +125 -5
- package/src/bridge/pureRender/theme.test.ts +259 -0
- package/src/bridge/pureRender/theme.ts +19 -1
- package/src/bridge/pureRender/types.ts +33 -0
- package/src/bridge/pureRender/visualLayoutInspection.test.ts +26 -0
- package/src/bridge/pureRender/visualLayoutInspection.ts +75 -0
- package/src/bridge/react/useDocumentHotkeys.ts +41 -0
- package/src/bridge/react/useDocumentLifecycle.tsx +359 -0
- package/src/bridge/react/usePlatformAgentSessionDrive.test.tsx +29 -10
- package/src/bridge/react/usePlatformAgentSessionDrive.tsx +10 -81
- package/src/bridge/react/usePlatformAppSettings.test.tsx +105 -0
- package/src/bridge/react/usePlatformAppSettings.tsx +104 -0
- package/src/bridge/react/usePlatformJsonStore.test.tsx +152 -0
- package/src/bridge/react/usePlatformJsonStore.tsx +149 -0
- package/src/bridge/react/usePlatformOperations.tsx +75 -0
- package/src/bridge/storage.d.mts +23 -10
- package/src/bridge/storage.mjs +6 -3
- package/src/bridge/storage.test.ts +6 -6
- package/src/bridge/types.ts +7 -0
- package/src/components/agents/AgentComposer.tsx +10 -6
- package/src/components/agents/AgentDrawerPanel.test.tsx +2 -205
- package/src/components/agents/AgentDrawerPanel.tsx +23 -62
- package/src/components/agents/AgentMessageBubble.tsx +59 -33
- package/src/components/agents/AgentMessageList.tsx +4 -4
- package/src/components/agents/AgentQuestionPromptList.tsx +34 -212
- package/src/components/agents/AgentToolApprovalActions.tsx +13 -11
- package/src/components/agents/AgentToolCallCard.tsx +20 -20
- package/src/components/agents/AgentToolPendingList.tsx +6 -6
- package/src/components/agents/AgentToolPendingReview.tsx +6 -6
- package/src/components/agents/ContextPicker.tsx +239 -0
- package/src/components/agents/QuestionRequestList.tsx +278 -0
- package/src/components/agents/agentPanelStyles.ts +8 -31
- package/src/components/agents/agentTypes.ts +25 -41
- package/src/components/agents/index.ts +4 -0
- package/src/components/assets/asset-library/sidebar/AssetLibraryList.tsx +10 -4
- package/src/components/chrome/WorkspaceTabStrip.tsx +22 -4
- package/src/components/chrome/workspaceTabTypes.ts +2 -0
- package/src/components/common/chat/ChatBox.tsx +9 -9
- package/src/components/common/chat/ChatModelMenu.tsx +34 -4
- package/src/components/common/chat/ChatThread.tsx +23 -7
- package/src/components/common/connections/ProviderConnection.test.tsx +208 -0
- package/src/components/common/connections/ProviderConnection.tsx +277 -0
- package/src/components/common/connections/index.ts +5 -0
- package/src/components/common/containers/AppFrame.test.tsx +4 -4
- package/src/components/common/containers/AppFrame.tsx +26 -10
- package/src/components/common/containers/AppHeader.tsx +37 -15
- package/src/components/common/documents/DocumentHeaderActions.tsx +206 -0
- package/src/components/common/documents/DocumentSwitcher.tsx +1181 -0
- package/src/components/common/documents/index.ts +8 -0
- package/src/components/common/dropdown/MenuDropdownItem.tsx +14 -2
- package/src/components/common/dropdown/MenuPortal.tsx +3 -1
- package/src/components/common/dropdown/menuViewportPosition.test.ts +20 -10
- package/src/components/common/dropdown/menuViewportPosition.ts +35 -27
- package/src/components/common/overlays/Modal.tsx +13 -2
- package/src/components/common/research/EvidenceDossier.tsx +1232 -150
- package/src/components/common/research/index.ts +2 -0
- package/src/components/editor/EditorLinkPromptDialog.tsx +1 -1
- package/src/components/print-design/PrintDesignPanel.test.tsx +430 -40
- package/src/components/print-design/PrintDesignPanel.tsx +1770 -207
- package/src/components/print-design/index.ts +2 -0
- package/src/components/print-design/previewContent.test.ts +32 -0
- package/src/components/print-design/previewContent.ts +31 -0
- package/src/context/buildContextDocument.test.ts +240 -0
- package/src/context/buildContextDocument.ts +309 -0
- package/src/context/contextAccess.ts +66 -0
- package/src/context/contextConfig.ts +72 -0
- package/src/context/contextDocument.test.ts +155 -0
- package/src/context/contextDocument.ts +300 -0
- package/src/context/contextSections.test.ts +88 -0
- package/src/context/contextSections.ts +84 -0
- package/src/context/htmlToContextMarkdown.test.ts +134 -0
- package/src/context/htmlToContextMarkdown.ts +369 -0
- package/src/ics/generateIcs.test.ts +153 -0
- package/src/ics/generateIcs.ts +197 -0
- package/src/index.ts +3 -0
- package/src/net/httpRetry.test.ts +117 -0
- package/src/net/httpRetry.ts +111 -0
- package/src/theme/appAccents.test.ts +36 -35
- package/src/theme/appAccents.ts +93 -104
- package/src/theme/appIdentityCss.mjs +178 -229
- package/src/theme/appIdentityCss.ts +222 -231
- package/src/theme/themes/dark.ts +3 -1
- package/src/theme/themes/light.ts +3 -1
- package/src/bridge/googleProviderConfig.ts +0 -73
package/src/bridge/googleAuth.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Google OAuth scope sets apps request through the shell-owned credential
|
|
3
|
+
* flow (`credentials.connectOAuth`). The OAuth client machinery itself —
|
|
4
|
+
* PKCE, authorize URL, token exchange, refresh — lives in the Electron main
|
|
5
|
+
* process (`packages/shell/src/modules/credentials/googleOAuth.ts`); no
|
|
6
|
+
* renderer ever handles credential material.
|
|
7
|
+
*/
|
|
7
8
|
|
|
8
9
|
export const GMAIL_SCOPES = [
|
|
9
10
|
'https://www.googleapis.com/auth/gmail.modify',
|
|
@@ -13,149 +14,3 @@ export const GMAIL_SCOPES = [
|
|
|
13
14
|
export const CALENDAR_SCOPES = [
|
|
14
15
|
'https://www.googleapis.com/auth/calendar.events',
|
|
15
16
|
]
|
|
16
|
-
|
|
17
|
-
export const GOOGLE_AUTHORIZATION_ENDPOINT =
|
|
18
|
-
'https://accounts.google.com/o/oauth2/v2/auth'
|
|
19
|
-
export const GOOGLE_TOKEN_ENDPOINT = 'https://oauth2.googleapis.com/token'
|
|
20
|
-
|
|
21
|
-
const EXPIRY_SLACK_MS = 60_000
|
|
22
|
-
|
|
23
|
-
export interface PkcePair {
|
|
24
|
-
verifier: string
|
|
25
|
-
challenge: string
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function base64UrlEncode(bytes: Uint8Array): string {
|
|
29
|
-
let binary = ''
|
|
30
|
-
for (const byte of bytes) {
|
|
31
|
-
binary += String.fromCharCode(byte)
|
|
32
|
-
}
|
|
33
|
-
return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function randomUrlSafeString(byteLength = 32): string {
|
|
37
|
-
const bytes = new Uint8Array(byteLength)
|
|
38
|
-
crypto.getRandomValues(bytes)
|
|
39
|
-
return base64UrlEncode(bytes)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export async function createPkcePair(): Promise<PkcePair> {
|
|
43
|
-
const verifier = randomUrlSafeString(48)
|
|
44
|
-
const digest = await crypto.subtle.digest(
|
|
45
|
-
'SHA-256',
|
|
46
|
-
new TextEncoder().encode(verifier),
|
|
47
|
-
)
|
|
48
|
-
return { verifier, challenge: base64UrlEncode(new Uint8Array(digest)) }
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export interface GoogleAuthUrlInput {
|
|
52
|
-
clientId: string
|
|
53
|
-
challenge: string
|
|
54
|
-
state: string
|
|
55
|
-
scopes?: string[]
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function buildGoogleAuthorizationUrl(input: GoogleAuthUrlInput): string {
|
|
59
|
-
const url = new URL(GOOGLE_AUTHORIZATION_ENDPOINT)
|
|
60
|
-
url.searchParams.set('client_id', input.clientId)
|
|
61
|
-
url.searchParams.set('response_type', 'code')
|
|
62
|
-
url.searchParams.set('scope', (input.scopes ?? CALENDAR_SCOPES).join(' '))
|
|
63
|
-
url.searchParams.set('code_challenge', input.challenge)
|
|
64
|
-
url.searchParams.set('code_challenge_method', 'S256')
|
|
65
|
-
url.searchParams.set('state', input.state)
|
|
66
|
-
url.searchParams.set('access_type', 'offline')
|
|
67
|
-
url.searchParams.set('prompt', 'consent')
|
|
68
|
-
return url.toString()
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
interface GoogleTokenResponse {
|
|
72
|
-
access_token: string
|
|
73
|
-
refresh_token?: string
|
|
74
|
-
expires_in: number
|
|
75
|
-
scope: string
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function tokensFromTokenResponse(
|
|
79
|
-
payload: GoogleTokenResponse,
|
|
80
|
-
previousRefreshToken?: string,
|
|
81
|
-
now = Date.now(),
|
|
82
|
-
): GoogleOauthTokens {
|
|
83
|
-
const refreshToken = payload.refresh_token ?? previousRefreshToken
|
|
84
|
-
return {
|
|
85
|
-
accessToken: payload.access_token,
|
|
86
|
-
...(refreshToken === undefined ? {} : { refreshToken }),
|
|
87
|
-
expiresAt: now + payload.expires_in * 1000,
|
|
88
|
-
scope: payload.scope,
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export function accessTokenIsFresh(
|
|
93
|
-
tokens: GoogleOauthTokens,
|
|
94
|
-
now = Date.now(),
|
|
95
|
-
): boolean {
|
|
96
|
-
return tokens.expiresAt - EXPIRY_SLACK_MS > now
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export interface TokenExchangeInput {
|
|
100
|
-
clientId: string
|
|
101
|
-
clientSecret?: string
|
|
102
|
-
code: string
|
|
103
|
-
verifier: string
|
|
104
|
-
redirectUri: string
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
type FormPost = (
|
|
108
|
-
url: string,
|
|
109
|
-
body: string,
|
|
110
|
-
) => Promise<{ ok: boolean; status: number; body: string }>
|
|
111
|
-
|
|
112
|
-
export async function exchangeCodeForTokens(
|
|
113
|
-
post: FormPost,
|
|
114
|
-
input: TokenExchangeInput,
|
|
115
|
-
): Promise<GoogleOauthTokens> {
|
|
116
|
-
const body = new URLSearchParams({
|
|
117
|
-
client_id: input.clientId,
|
|
118
|
-
grant_type: 'authorization_code',
|
|
119
|
-
code: input.code,
|
|
120
|
-
code_verifier: input.verifier,
|
|
121
|
-
redirect_uri: input.redirectUri,
|
|
122
|
-
})
|
|
123
|
-
if (input.clientSecret) body.set('client_secret', input.clientSecret)
|
|
124
|
-
const response = await post(GOOGLE_TOKEN_ENDPOINT, body.toString())
|
|
125
|
-
if (!response.ok) {
|
|
126
|
-
throw new Error(
|
|
127
|
-
`Google token exchange failed (${response.status}): ${response.body}`,
|
|
128
|
-
)
|
|
129
|
-
}
|
|
130
|
-
return tokensFromTokenResponse(
|
|
131
|
-
JSON.parse(response.body) as GoogleTokenResponse,
|
|
132
|
-
)
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
export interface TokenRefreshInput {
|
|
136
|
-
clientId: string
|
|
137
|
-
clientSecret?: string
|
|
138
|
-
refreshToken: string
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
export async function refreshAccessToken(
|
|
142
|
-
post: FormPost,
|
|
143
|
-
input: TokenRefreshInput,
|
|
144
|
-
): Promise<GoogleOauthTokens> {
|
|
145
|
-
const body = new URLSearchParams({
|
|
146
|
-
client_id: input.clientId,
|
|
147
|
-
grant_type: 'refresh_token',
|
|
148
|
-
refresh_token: input.refreshToken,
|
|
149
|
-
})
|
|
150
|
-
if (input.clientSecret) body.set('client_secret', input.clientSecret)
|
|
151
|
-
const response = await post(GOOGLE_TOKEN_ENDPOINT, body.toString())
|
|
152
|
-
if (!response.ok) {
|
|
153
|
-
throw new Error(
|
|
154
|
-
`Google token refresh failed (${response.status}): ${response.body}`,
|
|
155
|
-
)
|
|
156
|
-
}
|
|
157
|
-
return tokensFromTokenResponse(
|
|
158
|
-
JSON.parse(response.body) as GoogleTokenResponse,
|
|
159
|
-
input.refreshToken,
|
|
160
|
-
)
|
|
161
|
-
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export type McpClientTransportType = 'http' | 'sse' | 'stdio'
|
|
2
|
+
export type McpClientAuthType = 'none' | 'bearer' | 'apiKey'
|
|
3
|
+
|
|
4
|
+
/** A configured external MCP server (no secret material — that stays shell-side). */
|
|
5
|
+
export interface McpClientServerConfig {
|
|
6
|
+
/** Stable slug — `[a-z0-9-]+`. */
|
|
7
|
+
id: string
|
|
8
|
+
label: string
|
|
9
|
+
transport: McpClientTransportType
|
|
10
|
+
/** Remote endpoint for `http` / `sse` transports. */
|
|
11
|
+
url?: string
|
|
12
|
+
/** Executable for the `stdio` transport. */
|
|
13
|
+
command?: string
|
|
14
|
+
args?: string[]
|
|
15
|
+
enabled: boolean
|
|
16
|
+
authType: McpClientAuthType
|
|
17
|
+
/** Env var the stored secret is injected as, when `authType` is `apiKey`. */
|
|
18
|
+
apiKeyEnvVar?: string
|
|
19
|
+
/** Short tool names opted into auto-run; everything else asks first. */
|
|
20
|
+
autoApproveTools?: string[]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface McpClientServerView extends McpClientServerConfig {
|
|
24
|
+
hasSecret: boolean
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface McpClientSettingsView {
|
|
28
|
+
enabled: boolean
|
|
29
|
+
servers: McpClientServerView[]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface McpClientTestResult {
|
|
33
|
+
ok: boolean
|
|
34
|
+
serverId: string
|
|
35
|
+
toolNames: string[]
|
|
36
|
+
error?: string
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface McpToolInfo {
|
|
40
|
+
name: string
|
|
41
|
+
description?: string
|
|
42
|
+
inputSchema: Record<string, unknown>
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface McpToolRunResult {
|
|
46
|
+
content: string
|
|
47
|
+
isError: boolean
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function listMcpClientSettings(): Promise<McpClientSettingsView>
|
|
51
|
+
export function setMcpClientEnabled(
|
|
52
|
+
enabled: boolean,
|
|
53
|
+
): Promise<McpClientSettingsView>
|
|
54
|
+
export function upsertMcpClientServer(
|
|
55
|
+
config: McpClientServerConfig,
|
|
56
|
+
): Promise<McpClientSettingsView>
|
|
57
|
+
export function removeMcpClientServer(
|
|
58
|
+
serverId: string,
|
|
59
|
+
): Promise<McpClientSettingsView>
|
|
60
|
+
export function setMcpClientServerSecret(
|
|
61
|
+
serverId: string,
|
|
62
|
+
value: string | null,
|
|
63
|
+
): Promise<McpClientSettingsView>
|
|
64
|
+
export function testMcpClientServer(
|
|
65
|
+
config: McpClientServerConfig,
|
|
66
|
+
): Promise<McpClientTestResult>
|
|
67
|
+
export function listMcpClientServerTools(
|
|
68
|
+
serverId: string,
|
|
69
|
+
): Promise<McpToolInfo[]>
|
|
70
|
+
export function callMcpClientServerTool(
|
|
71
|
+
serverId: string,
|
|
72
|
+
toolName: string,
|
|
73
|
+
args: Record<string, unknown>,
|
|
74
|
+
): Promise<McpToolRunResult>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { bridge } from './client.mjs'
|
|
2
|
+
import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Outbound MCP client registry (external MCP servers whose tools in-app
|
|
6
|
+
* agents can call). Secret material never crosses this bridge — only the
|
|
7
|
+
* redacted settings view does. The shell gates these methods to the
|
|
8
|
+
* assistant app: this is machine-level, secret-bearing configuration.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @returns {Promise<import('./mcpClient.d.mts').McpClientSettingsView>}
|
|
13
|
+
*/
|
|
14
|
+
export async function listMcpClientSettings() {
|
|
15
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.MCPCLIENT_LIST, [])
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {boolean} enabled
|
|
20
|
+
* @returns {Promise<import('./mcpClient.d.mts').McpClientSettingsView>}
|
|
21
|
+
*/
|
|
22
|
+
export async function setMcpClientEnabled(enabled) {
|
|
23
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.MCPCLIENT_SET_ENABLED, [enabled])
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {import('./mcpClient.d.mts').McpClientServerConfig} config
|
|
28
|
+
* @returns {Promise<import('./mcpClient.d.mts').McpClientSettingsView>}
|
|
29
|
+
*/
|
|
30
|
+
export async function upsertMcpClientServer(config) {
|
|
31
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.MCPCLIENT_UPSERT, [config])
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param {string} serverId
|
|
36
|
+
* @returns {Promise<import('./mcpClient.d.mts').McpClientSettingsView>}
|
|
37
|
+
*/
|
|
38
|
+
export async function removeMcpClientServer(serverId) {
|
|
39
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.MCPCLIENT_REMOVE, [serverId])
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {string} serverId
|
|
44
|
+
* @param {string | null} value
|
|
45
|
+
* @returns {Promise<import('./mcpClient.d.mts').McpClientSettingsView>}
|
|
46
|
+
*/
|
|
47
|
+
export async function setMcpClientServerSecret(serverId, value) {
|
|
48
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.MCPCLIENT_SET_SECRET, [
|
|
49
|
+
{ serverId, value },
|
|
50
|
+
])
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @param {import('./mcpClient.d.mts').McpClientServerConfig} config
|
|
55
|
+
* @returns {Promise<import('./mcpClient.d.mts').McpClientTestResult>}
|
|
56
|
+
*/
|
|
57
|
+
export async function testMcpClientServer(config) {
|
|
58
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.MCPCLIENT_TEST, [config])
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {string} serverId
|
|
63
|
+
* @returns {Promise<import('./mcpClient.d.mts').McpToolInfo[]>}
|
|
64
|
+
*/
|
|
65
|
+
export async function listMcpClientServerTools(serverId) {
|
|
66
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.MCPCLIENT_LIST_TOOLS, [serverId])
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @param {string} serverId
|
|
71
|
+
* @param {string} toolName
|
|
72
|
+
* @param {Record<string, unknown>} args
|
|
73
|
+
* @returns {Promise<import('./mcpClient.d.mts').McpToolRunResult>}
|
|
74
|
+
*/
|
|
75
|
+
export async function callMcpClientServerTool(serverId, toolName, args) {
|
|
76
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.MCPCLIENT_CALL_TOOL, [
|
|
77
|
+
{ serverId, toolName, arguments: args },
|
|
78
|
+
])
|
|
79
|
+
}
|
package/src/bridge/methods.d.mts
CHANGED
|
@@ -8,6 +8,7 @@ export declare const PLATFORM_BRIDGE_METHODS: {
|
|
|
8
8
|
readonly WORKSPACE_OPEN_APP: 'workspace.openApp'
|
|
9
9
|
readonly WORKSPACE_OPEN_PALETTE: 'workspace.openPalette'
|
|
10
10
|
readonly WORKSPACE_UPDATE_CURRENT_TAB: 'workspace.updateCurrentTab'
|
|
11
|
+
readonly WORKSPACE_SET_OVERLAY_OPEN: 'workspace.setOverlayOpen'
|
|
11
12
|
readonly SCHEDULER_REGISTER: 'scheduler.register'
|
|
12
13
|
readonly SCHEDULER_UNREGISTER: 'scheduler.unregister'
|
|
13
14
|
readonly CATALOG_CONSUME_PENDING_OPEN: 'catalog.consumePendingOpen'
|
|
@@ -19,6 +20,8 @@ export declare const PLATFORM_BRIDGE_METHODS: {
|
|
|
19
20
|
readonly SETTINGS_APP_UPDATE: 'settings.app.update'
|
|
20
21
|
readonly STORAGE_READ_JSON: 'storage.readJson'
|
|
21
22
|
readonly STORAGE_WRITE_JSON: 'storage.writeJson'
|
|
23
|
+
readonly OPERATIONS_RECORD: 'operations.record'
|
|
24
|
+
readonly OPERATIONS_LIST: 'operations.list'
|
|
22
25
|
readonly FS_LIST: 'fs.list'
|
|
23
26
|
readonly FS_READ_PREVIEW: 'fs.readPreview'
|
|
24
27
|
readonly FS_READ_BINARY: 'fs.readBinary'
|
|
@@ -60,23 +63,49 @@ export declare const PLATFORM_BRIDGE_METHODS: {
|
|
|
60
63
|
readonly ASSETS_TRANSFORM: 'assets.transform'
|
|
61
64
|
readonly ASSETS_GET_CONTEXT: 'assets.getContext'
|
|
62
65
|
readonly NETWORK_FETCH: 'network.fetch'
|
|
66
|
+
readonly RESEARCH_QUERY: 'research.query'
|
|
63
67
|
readonly VISION_GENERATE_IMAGE: 'vision.generateImage'
|
|
68
|
+
readonly NOTIFICATIONS_SCHEDULE: 'notifications.schedule'
|
|
69
|
+
readonly NOTIFICATIONS_CANCEL: 'notifications.cancel'
|
|
70
|
+
readonly NOTIFICATIONS_CANCEL_ALL: 'notifications.cancelAll'
|
|
64
71
|
readonly OAUTH_LOOPBACK_AUTHORIZE: 'oauth.loopbackAuthorize'
|
|
65
72
|
readonly SECRETS_GET: 'secrets.get'
|
|
66
73
|
readonly SECRETS_SET: 'secrets.set'
|
|
67
74
|
readonly SECRETS_DELETE: 'secrets.delete'
|
|
68
75
|
readonly SECRETS_STATUS: 'secrets.status'
|
|
76
|
+
readonly MYTOOLS_LIST: 'mytools.list'
|
|
77
|
+
readonly MYTOOLS_SAVE: 'mytools.save'
|
|
78
|
+
readonly MYTOOLS_UPDATE: 'mytools.update'
|
|
79
|
+
readonly MYTOOLS_DELETE: 'mytools.delete'
|
|
80
|
+
readonly MYTOOLS_TEST: 'mytools.test'
|
|
81
|
+
readonly MYTOOLS_RESEARCH: 'mytools.research'
|
|
82
|
+
readonly MCPCLIENT_LIST: 'mcpClient.list'
|
|
83
|
+
readonly MCPCLIENT_SET_ENABLED: 'mcpClient.setEnabled'
|
|
84
|
+
readonly MCPCLIENT_UPSERT: 'mcpClient.upsertServer'
|
|
85
|
+
readonly MCPCLIENT_REMOVE: 'mcpClient.removeServer'
|
|
86
|
+
readonly MCPCLIENT_SET_SECRET: 'mcpClient.setSecret'
|
|
87
|
+
readonly MCPCLIENT_TEST: 'mcpClient.testServer'
|
|
88
|
+
readonly MCPCLIENT_LIST_TOOLS: 'mcpClient.listTools'
|
|
89
|
+
readonly MCPCLIENT_CALL_TOOL: 'mcpClient.callTool'
|
|
69
90
|
readonly DEBUG_EMIT_EVENT: 'debug.emitEvent'
|
|
70
91
|
readonly PLUGINS_INSTALL: 'plugins.install'
|
|
71
92
|
readonly PLUGINS_EVALUATE_BUILD: 'plugins.evaluateBuild'
|
|
72
93
|
readonly PLUGINS_PREPARE_REGISTRATION: 'plugins.prepareRegistration'
|
|
73
94
|
readonly CONTEXT_PUBLISH: 'context.publish'
|
|
95
|
+
readonly CONTEXT_RESOLVE: 'context.resolve'
|
|
96
|
+
readonly CONTEXT_READ: 'context.read'
|
|
97
|
+
readonly CONTEXT_SEARCH: 'context.search'
|
|
74
98
|
readonly PEOPLE_SUGGEST: 'people.suggest'
|
|
75
99
|
readonly PEOPLE_RESEARCH: 'people.research'
|
|
76
100
|
readonly CREDENTIALS_STORAGE_STATUS: 'credentials.storageStatus'
|
|
77
101
|
readonly CREDENTIALS_LIST: 'credentials.list'
|
|
78
102
|
readonly CREDENTIALS_SET: 'credentials.set'
|
|
79
103
|
readonly CREDENTIALS_DELETE: 'credentials.delete'
|
|
104
|
+
readonly CREDENTIALS_STATUS: 'credentials.status'
|
|
105
|
+
readonly CREDENTIALS_SET_OAUTH_CONFIG: 'credentials.setOAuthConfig'
|
|
106
|
+
readonly CREDENTIALS_CONNECT_OAUTH: 'credentials.connectOAuth'
|
|
107
|
+
readonly CREDENTIALS_DISCONNECT: 'credentials.disconnect'
|
|
108
|
+
readonly CREDENTIALS_OAUTH_ACCESS_TOKEN: 'credentials.oauthAccessToken'
|
|
80
109
|
readonly AGENTS_SESSIONS_CREATE: 'agents.sessions.create'
|
|
81
110
|
readonly AGENTS_SESSIONS_LIST: 'agents.sessions.list'
|
|
82
111
|
readonly AGENTS_SESSIONS_READ: 'agents.sessions.read'
|
|
@@ -87,6 +116,7 @@ export declare const PLATFORM_BRIDGE_METHODS: {
|
|
|
87
116
|
readonly AGENTS_JOBS_READ: 'agents.jobs.read'
|
|
88
117
|
readonly AGENTS_JOBS_CANCEL: 'agents.jobs.cancel'
|
|
89
118
|
readonly AGENTS_JOBS_RUN_NOW: 'agents.jobs.runNow'
|
|
119
|
+
readonly AGENTS_DELEGATIONS_LIST: 'agents.delegations.list'
|
|
90
120
|
readonly AGENTS_SESSION_SEND_MESSAGE: 'agents.session.sendMessage'
|
|
91
121
|
readonly AGENTS_SESSION_APPROVE_TOOLS: 'agents.session.approveTools'
|
|
92
122
|
readonly AGENTS_SESSION_REJECT_TOOLS: 'agents.session.rejectTools'
|
|
@@ -102,6 +132,15 @@ export declare const PLATFORM_BRIDGE_METHODS: {
|
|
|
102
132
|
readonly AGENTS_LOCAL_MODELS_STATUS: 'agents.localModels.status'
|
|
103
133
|
readonly AGENTS_TOOLS_REGISTER: 'agents.tools.register'
|
|
104
134
|
readonly AGENTS_TOOLS_COMPLETE: 'agents.tools.complete'
|
|
135
|
+
readonly DOCUMENTS_CREATE_DRAFT: 'documents.createDraft'
|
|
136
|
+
readonly DOCUMENTS_AUTOSAVE: 'documents.autosave'
|
|
137
|
+
readonly DOCUMENTS_PROMOTE: 'documents.promote'
|
|
138
|
+
readonly DOCUMENTS_RENAME: 'documents.rename'
|
|
139
|
+
readonly DOCUMENTS_DUPLICATE: 'documents.duplicate'
|
|
140
|
+
readonly DOCUMENTS_LIST_BY_TYPE: 'documents.listByType'
|
|
141
|
+
readonly DOCUMENTS_RECENTS_LIST: 'documents.recents.list'
|
|
142
|
+
readonly DOCUMENTS_RECENTS_TOUCH: 'documents.recents.touch'
|
|
143
|
+
readonly DOCUMENTS_SUGGEST_LOCATION: 'documents.suggestLocation'
|
|
105
144
|
}
|
|
106
145
|
|
|
107
146
|
export declare const PLATFORM_BRIDGE_METHOD_PREFIXES: {
|
|
@@ -119,12 +158,18 @@ export declare const PLATFORM_BRIDGE_METHOD_PREFIXES: {
|
|
|
119
158
|
readonly WATCH: 'watch.'
|
|
120
159
|
readonly ASSETS: 'assets.'
|
|
121
160
|
readonly NETWORK: 'network.'
|
|
161
|
+
readonly RESEARCH: 'research.'
|
|
122
162
|
readonly VISION: 'vision.'
|
|
163
|
+
readonly NOTIFICATIONS: 'notifications.'
|
|
123
164
|
readonly OAUTH: 'oauth.'
|
|
124
165
|
readonly SECRETS: 'secrets.'
|
|
166
|
+
readonly MYTOOLS: 'mytools.'
|
|
167
|
+
readonly MCPCLIENT: 'mcpClient.'
|
|
125
168
|
readonly AGENTS: 'agents.'
|
|
126
169
|
readonly PEOPLE: 'people.'
|
|
127
170
|
readonly DEBUG: 'debug.'
|
|
171
|
+
readonly DOCUMENTS: 'documents.'
|
|
172
|
+
readonly OPERATIONS: 'operations.'
|
|
128
173
|
}
|
|
129
174
|
|
|
130
175
|
export type PlatformBridgeMethodName =
|
package/src/bridge/methods.mjs
CHANGED
|
@@ -11,6 +11,7 @@ export const PLATFORM_BRIDGE_METHODS = {
|
|
|
11
11
|
WORKSPACE_OPEN_APP: 'workspace.openApp',
|
|
12
12
|
WORKSPACE_OPEN_PALETTE: 'workspace.openPalette',
|
|
13
13
|
WORKSPACE_UPDATE_CURRENT_TAB: 'workspace.updateCurrentTab',
|
|
14
|
+
WORKSPACE_SET_OVERLAY_OPEN: 'workspace.setOverlayOpen',
|
|
14
15
|
SCHEDULER_REGISTER: 'scheduler.register',
|
|
15
16
|
SCHEDULER_UNREGISTER: 'scheduler.unregister',
|
|
16
17
|
CATALOG_CONSUME_PENDING_OPEN: 'catalog.consumePendingOpen',
|
|
@@ -26,6 +27,8 @@ export const PLATFORM_BRIDGE_METHODS = {
|
|
|
26
27
|
|
|
27
28
|
STORAGE_READ_JSON: 'storage.readJson',
|
|
28
29
|
STORAGE_WRITE_JSON: 'storage.writeJson',
|
|
30
|
+
OPERATIONS_RECORD: 'operations.record',
|
|
31
|
+
OPERATIONS_LIST: 'operations.list',
|
|
29
32
|
|
|
30
33
|
FS_LIST: 'fs.list',
|
|
31
34
|
FS_READ_PREVIEW: 'fs.readPreview',
|
|
@@ -75,12 +78,31 @@ export const PLATFORM_BRIDGE_METHODS = {
|
|
|
75
78
|
ASSETS_GET_CONTEXT: 'assets.getContext',
|
|
76
79
|
|
|
77
80
|
NETWORK_FETCH: 'network.fetch',
|
|
81
|
+
RESEARCH_QUERY: 'research.query',
|
|
78
82
|
VISION_GENERATE_IMAGE: 'vision.generateImage',
|
|
83
|
+
NOTIFICATIONS_SCHEDULE: 'notifications.schedule',
|
|
84
|
+
NOTIFICATIONS_CANCEL: 'notifications.cancel',
|
|
85
|
+
NOTIFICATIONS_CANCEL_ALL: 'notifications.cancelAll',
|
|
79
86
|
OAUTH_LOOPBACK_AUTHORIZE: 'oauth.loopbackAuthorize',
|
|
80
87
|
SECRETS_GET: 'secrets.get',
|
|
81
88
|
SECRETS_SET: 'secrets.set',
|
|
82
89
|
SECRETS_DELETE: 'secrets.delete',
|
|
83
90
|
SECRETS_STATUS: 'secrets.status',
|
|
91
|
+
MYTOOLS_LIST: 'mytools.list',
|
|
92
|
+
MYTOOLS_SAVE: 'mytools.save',
|
|
93
|
+
MYTOOLS_UPDATE: 'mytools.update',
|
|
94
|
+
MYTOOLS_DELETE: 'mytools.delete',
|
|
95
|
+
MYTOOLS_TEST: 'mytools.test',
|
|
96
|
+
MYTOOLS_RESEARCH: 'mytools.research',
|
|
97
|
+
|
|
98
|
+
MCPCLIENT_LIST: 'mcpClient.list',
|
|
99
|
+
MCPCLIENT_SET_ENABLED: 'mcpClient.setEnabled',
|
|
100
|
+
MCPCLIENT_UPSERT: 'mcpClient.upsertServer',
|
|
101
|
+
MCPCLIENT_REMOVE: 'mcpClient.removeServer',
|
|
102
|
+
MCPCLIENT_SET_SECRET: 'mcpClient.setSecret',
|
|
103
|
+
MCPCLIENT_TEST: 'mcpClient.testServer',
|
|
104
|
+
MCPCLIENT_LIST_TOOLS: 'mcpClient.listTools',
|
|
105
|
+
MCPCLIENT_CALL_TOOL: 'mcpClient.callTool',
|
|
84
106
|
|
|
85
107
|
DEBUG_EMIT_EVENT: 'debug.emitEvent',
|
|
86
108
|
|
|
@@ -88,6 +110,9 @@ export const PLATFORM_BRIDGE_METHODS = {
|
|
|
88
110
|
PLUGINS_EVALUATE_BUILD: 'plugins.evaluateBuild',
|
|
89
111
|
PLUGINS_PREPARE_REGISTRATION: 'plugins.prepareRegistration',
|
|
90
112
|
CONTEXT_PUBLISH: 'context.publish',
|
|
113
|
+
CONTEXT_RESOLVE: 'context.resolve',
|
|
114
|
+
CONTEXT_READ: 'context.read',
|
|
115
|
+
CONTEXT_SEARCH: 'context.search',
|
|
91
116
|
PEOPLE_SUGGEST: 'people.suggest',
|
|
92
117
|
PEOPLE_RESEARCH: 'people.research',
|
|
93
118
|
|
|
@@ -95,6 +120,11 @@ export const PLATFORM_BRIDGE_METHODS = {
|
|
|
95
120
|
CREDENTIALS_LIST: 'credentials.list',
|
|
96
121
|
CREDENTIALS_SET: 'credentials.set',
|
|
97
122
|
CREDENTIALS_DELETE: 'credentials.delete',
|
|
123
|
+
CREDENTIALS_STATUS: 'credentials.status',
|
|
124
|
+
CREDENTIALS_SET_OAUTH_CONFIG: 'credentials.setOAuthConfig',
|
|
125
|
+
CREDENTIALS_CONNECT_OAUTH: 'credentials.connectOAuth',
|
|
126
|
+
CREDENTIALS_DISCONNECT: 'credentials.disconnect',
|
|
127
|
+
CREDENTIALS_OAUTH_ACCESS_TOKEN: 'credentials.oauthAccessToken',
|
|
98
128
|
|
|
99
129
|
AGENTS_SESSIONS_CREATE: 'agents.sessions.create',
|
|
100
130
|
AGENTS_SESSIONS_LIST: 'agents.sessions.list',
|
|
@@ -107,6 +137,7 @@ export const PLATFORM_BRIDGE_METHODS = {
|
|
|
107
137
|
AGENTS_JOBS_READ: 'agents.jobs.read',
|
|
108
138
|
AGENTS_JOBS_CANCEL: 'agents.jobs.cancel',
|
|
109
139
|
AGENTS_JOBS_RUN_NOW: 'agents.jobs.runNow',
|
|
140
|
+
AGENTS_DELEGATIONS_LIST: 'agents.delegations.list',
|
|
110
141
|
|
|
111
142
|
AGENTS_SESSION_SEND_MESSAGE: 'agents.session.sendMessage',
|
|
112
143
|
AGENTS_SESSION_APPROVE_TOOLS: 'agents.session.approveTools',
|
|
@@ -124,6 +155,15 @@ export const PLATFORM_BRIDGE_METHODS = {
|
|
|
124
155
|
AGENTS_LOCAL_MODELS_STATUS: 'agents.localModels.status',
|
|
125
156
|
AGENTS_TOOLS_REGISTER: 'agents.tools.register',
|
|
126
157
|
AGENTS_TOOLS_COMPLETE: 'agents.tools.complete',
|
|
158
|
+
DOCUMENTS_CREATE_DRAFT: 'documents.createDraft',
|
|
159
|
+
DOCUMENTS_AUTOSAVE: 'documents.autosave',
|
|
160
|
+
DOCUMENTS_PROMOTE: 'documents.promote',
|
|
161
|
+
DOCUMENTS_RENAME: 'documents.rename',
|
|
162
|
+
DOCUMENTS_DUPLICATE: 'documents.duplicate',
|
|
163
|
+
DOCUMENTS_LIST_BY_TYPE: 'documents.listByType',
|
|
164
|
+
DOCUMENTS_RECENTS_LIST: 'documents.recents.list',
|
|
165
|
+
DOCUMENTS_RECENTS_TOUCH: 'documents.recents.touch',
|
|
166
|
+
DOCUMENTS_SUGGEST_LOCATION: 'documents.suggestLocation',
|
|
127
167
|
}
|
|
128
168
|
|
|
129
169
|
export const PLATFORM_BRIDGE_METHOD_PREFIXES = {
|
|
@@ -141,10 +181,16 @@ export const PLATFORM_BRIDGE_METHOD_PREFIXES = {
|
|
|
141
181
|
WATCH: 'watch.',
|
|
142
182
|
ASSETS: 'assets.',
|
|
143
183
|
NETWORK: 'network.',
|
|
184
|
+
RESEARCH: 'research.',
|
|
144
185
|
VISION: 'vision.',
|
|
186
|
+
NOTIFICATIONS: 'notifications.',
|
|
145
187
|
OAUTH: 'oauth.',
|
|
146
188
|
SECRETS: 'secrets.',
|
|
189
|
+
MYTOOLS: 'mytools.',
|
|
190
|
+
MCPCLIENT: 'mcpClient.',
|
|
147
191
|
AGENTS: 'agents.',
|
|
148
192
|
PEOPLE: 'people.',
|
|
149
193
|
DEBUG: 'debug.',
|
|
194
|
+
DOCUMENTS: 'documents.',
|
|
195
|
+
OPERATIONS: 'operations.',
|
|
150
196
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function scheduleNotification(request: {
|
|
2
|
+
id: string
|
|
3
|
+
title: string
|
|
4
|
+
body?: string
|
|
5
|
+
fireAt: number
|
|
6
|
+
}): Promise<{ ok: true }>
|
|
7
|
+
|
|
8
|
+
export function cancelNotification(request: {
|
|
9
|
+
id: string
|
|
10
|
+
}): Promise<{ ok: true }>
|
|
11
|
+
|
|
12
|
+
export function cancelAllNotifications(): Promise<{ ok: true }>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { bridge } from './client.mjs'
|
|
2
|
+
import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* OS notification scheduling — a benign local capability (no plugin permission).
|
|
6
|
+
* Schedules are held in the shell main process and die when the app quits;
|
|
7
|
+
* reminders while the app is closed are out of scope. The app-side scheduler
|
|
8
|
+
* that decides *what* to schedule is the caller's responsibility.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Schedule an OS notification to fire at `fireAt`. Reusing an `id` replaces any
|
|
13
|
+
* pending schedule (dedupe). `fireAt` in the past fires ~immediately.
|
|
14
|
+
* @param {{ id: string, title: string, body?: string, fireAt: number }} request
|
|
15
|
+
* @returns {Promise<{ ok: true }>}
|
|
16
|
+
*/
|
|
17
|
+
export async function scheduleNotification(request) {
|
|
18
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.NOTIFICATIONS_SCHEDULE, [request])
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Cancel a pending schedule; no-op if the id is unknown.
|
|
23
|
+
* @param {{ id: string }} request
|
|
24
|
+
* @returns {Promise<{ ok: true }>}
|
|
25
|
+
*/
|
|
26
|
+
export async function cancelNotification(request) {
|
|
27
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.NOTIFICATIONS_CANCEL, [request])
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Clear every pending schedule (used when an app reloads its reminder set).
|
|
32
|
+
* @returns {Promise<{ ok: true }>}
|
|
33
|
+
*/
|
|
34
|
+
export async function cancelAllNotifications() {
|
|
35
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.NOTIFICATIONS_CANCEL_ALL, [])
|
|
36
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export type PlatformOperationLane = 'user' | 'agent'
|
|
2
|
+
|
|
3
|
+
export interface PlatformOperationInput {
|
|
4
|
+
/** Who acted: a person in the UI, or an agent doing work. */
|
|
5
|
+
lane: PlatformOperationLane
|
|
6
|
+
/** Stable machine-readable kind, dot-namespaced, e.g. `document.save`. */
|
|
7
|
+
kind: string
|
|
8
|
+
/** Originating app slug, or `shell` for platform-level operations. */
|
|
9
|
+
appSlug: string
|
|
10
|
+
/** One human-readable sentence describing the operation. */
|
|
11
|
+
summary: string
|
|
12
|
+
/** Optional free-form elaboration. */
|
|
13
|
+
detail?: string
|
|
14
|
+
/** Optional references (path, sessionId, runId, …) for drill-down. */
|
|
15
|
+
refs?: Record<string, string>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface PlatformOperation extends PlatformOperationInput {
|
|
19
|
+
id: string
|
|
20
|
+
/** ISO timestamp stamped by the shell. */
|
|
21
|
+
at: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface PlatformOperationsListQuery {
|
|
25
|
+
lane?: PlatformOperationLane
|
|
26
|
+
/** Max entries returned, newest first. */
|
|
27
|
+
limit?: number
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface PlatformOperationsListResult {
|
|
31
|
+
operations: PlatformOperation[]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export declare function recordPlatformOperation(
|
|
35
|
+
input: PlatformOperationInput,
|
|
36
|
+
): Promise<PlatformOperation>
|
|
37
|
+
|
|
38
|
+
export declare function listPlatformOperations(
|
|
39
|
+
query?: PlatformOperationsListQuery,
|
|
40
|
+
): Promise<PlatformOperationsListResult>
|
|
41
|
+
|
|
42
|
+
export declare function onPlatformOperationRecorded(
|
|
43
|
+
listener: (operation: PlatformOperation) => void,
|
|
44
|
+
): () => void
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { bridge } from './client.mjs'
|
|
2
|
+
import { PLATFORM_BRIDGE_EVENTS } from './events.mjs'
|
|
3
|
+
import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Platform operations ledger: one suite-wide record of what happened,
|
|
7
|
+
* split into two lanes — `user` interactions and `agent` interactions.
|
|
8
|
+
* The shell stores every entry and broadcasts each append, so UIs (the
|
|
9
|
+
* PureAssistant tab in particular) can follow activity in real time.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Record one operation into the ledger.
|
|
14
|
+
*
|
|
15
|
+
* @param {import('./operations.d.mts').PlatformOperationInput} input
|
|
16
|
+
* @returns {Promise<import('./operations.d.mts').PlatformOperation>}
|
|
17
|
+
*/
|
|
18
|
+
export async function recordPlatformOperation(input) {
|
|
19
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.OPERATIONS_RECORD, [input])
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* List recorded operations, newest first.
|
|
24
|
+
*
|
|
25
|
+
* @param {import('./operations.d.mts').PlatformOperationsListQuery} [query]
|
|
26
|
+
* @returns {Promise<import('./operations.d.mts').PlatformOperationsListResult>}
|
|
27
|
+
*/
|
|
28
|
+
export async function listPlatformOperations(query) {
|
|
29
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.OPERATIONS_LIST, [query ?? {}])
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Subscribe to ledger appends. The listener receives each new operation.
|
|
34
|
+
*
|
|
35
|
+
* @param {(operation: import('./operations.d.mts').PlatformOperation) => void} listener
|
|
36
|
+
* @returns {() => void} unsubscribe
|
|
37
|
+
*/
|
|
38
|
+
export function onPlatformOperationRecorded(listener) {
|
|
39
|
+
return bridge.onEvent(PLATFORM_BRIDGE_EVENTS.OPERATIONS_CHANGED, listener)
|
|
40
|
+
}
|