@nimbalyst/extension-sdk 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/LICENSE +21 -0
- package/README.md +1 -1
- package/dist/__tests__/buildEmitStability.test.js +1 -1
- package/dist/__tests__/fileDirectoryTree.test.js +34 -0
- package/dist/__tests__/gitOperationLog.test.d.ts +2 -0
- package/dist/__tests__/gitOperationLog.test.d.ts.map +1 -0
- package/dist/__tests__/gitOperationLog.test.js +51 -0
- package/dist/agents/AgentProtocol.d.ts +16 -1
- package/dist/agents/AgentProtocol.d.ts.map +1 -1
- package/dist/agents/AgentProtocolHost.d.ts +1 -1
- package/dist/agents/AgentProtocolHost.d.ts.map +1 -1
- package/dist/createReadOnlyHost.d.ts +11 -1
- package/dist/createReadOnlyHost.d.ts.map +1 -1
- package/dist/createReadOnlyHost.js +3 -0
- package/dist/externalsPlugin.d.ts.map +1 -1
- package/dist/externalsPlugin.js +1 -5
- package/dist/fileDirectoryTree.d.ts +9 -2
- package/dist/fileDirectoryTree.d.ts.map +1 -1
- package/dist/fileDirectoryTree.js +82 -14
- package/dist/gitOperationLog.d.ts +104 -0
- package/dist/gitOperationLog.d.ts.map +1 -0
- package/dist/gitOperationLog.js +88 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/manifestValidation.d.ts.map +1 -1
- package/dist/manifestValidation.js +1 -0
- package/dist/types/backendPanels.d.ts +27 -0
- package/dist/types/backendPanels.d.ts.map +1 -0
- package/dist/types/backendPanels.js +12 -0
- package/dist/types/backendSessions.d.ts +262 -0
- package/dist/types/backendSessions.d.ts.map +1 -0
- package/dist/types/backendSessions.js +21 -0
- package/dist/types/collab.d.ts +31 -2
- package/dist/types/collab.d.ts.map +1 -1
- package/dist/types/comments.d.ts +104 -0
- package/dist/types/comments.d.ts.map +1 -0
- package/dist/types/comments.js +2 -0
- package/dist/types/editor.d.ts +87 -0
- package/dist/types/editor.d.ts.map +1 -1
- package/dist/types/extension.d.ts +16 -0
- package/dist/types/extension.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +3 -0
- package/dist/types/panel.d.ts +112 -0
- package/dist/types/panel.d.ts.map +1 -1
- package/dist/types/permissions.d.ts +1 -1
- package/dist/types/permissions.d.ts.map +1 -1
- package/package.json +23 -12
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire contract and pure selectors for the host's Git operation journal.
|
|
3
|
+
*
|
|
4
|
+
* The journal lives in the Electron main process and is published over two host
|
|
5
|
+
* channels: `git:operation-log:get` (hydration) and `git:operation-log-changed`
|
|
6
|
+
* (live upsert/clear). Both the Git extension's Output tab and Nimbalyst's own
|
|
7
|
+
* menu-bar indicator project the same journal, so the merge and "what is running
|
|
8
|
+
* right now" rules have to agree exactly -- two surfaces disagreeing about
|
|
9
|
+
* whether a push is still in flight is the bug this module exists to prevent.
|
|
10
|
+
*
|
|
11
|
+
* Everything here is pure: no React, no IPC, no host runtime.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Window CustomEvent the host dispatches when the user asks to see Git activity
|
|
15
|
+
* detail (for example from the menu-bar indicator's running-command row).
|
|
16
|
+
*
|
|
17
|
+
* The Git panel owns which tab is showing, and that state is private to the
|
|
18
|
+
* extension bundle. Rather than let the host reach into it, the host states the
|
|
19
|
+
* intent and the panel decides how to honour it. `detail.workspacePath` lets a
|
|
20
|
+
* panel bound to a different workspace ignore the request.
|
|
21
|
+
*/
|
|
22
|
+
export const GIT_SHOW_OUTPUT_REQUEST_EVENT = 'nimbalyst:git-show-output';
|
|
23
|
+
function toMillis(timestamp) {
|
|
24
|
+
return typeof timestamp === 'number' ? timestamp : timestamp.getTime();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Fill in metadata that predates the field. A journal written before agent
|
|
28
|
+
* activity existed only ever recorded app-owned direct `git` invocations, so
|
|
29
|
+
* that is what an absent `source`/`executor` means -- resolved here at the
|
|
30
|
+
* projection boundary rather than by rewriting the persisted journal.
|
|
31
|
+
*/
|
|
32
|
+
export function normalizeGitOperationEntry(entry) {
|
|
33
|
+
return {
|
|
34
|
+
...entry,
|
|
35
|
+
source: entry.source ?? 'nimbalyst',
|
|
36
|
+
executor: entry.executor ?? 'git',
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Fold incoming entries into the current list, newest write per id wins.
|
|
41
|
+
*
|
|
42
|
+
* `updatedAt` is the tiebreak rather than arrival order because hydration and
|
|
43
|
+
* the live subscription race: a `git:operation-log:get` response can land after
|
|
44
|
+
* upserts it predates, and applying it blindly would rewind a finished
|
|
45
|
+
* operation back to `running`.
|
|
46
|
+
*/
|
|
47
|
+
export function mergeGitOperationEntries(current, incoming) {
|
|
48
|
+
const byId = new Map(current.map((entry) => [entry.id, entry]));
|
|
49
|
+
for (const entry of incoming) {
|
|
50
|
+
const existing = byId.get(entry.id);
|
|
51
|
+
if (!existing || entry.updatedAt >= existing.updatedAt) {
|
|
52
|
+
byId.set(entry.id, entry);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return Array.from(byId.values()).sort((a, b) => toMillis(a.timestamp) - toMillis(b.timestamp));
|
|
56
|
+
}
|
|
57
|
+
/** Every entry still in flight, oldest first. */
|
|
58
|
+
export function selectRunningGitOperations(entries) {
|
|
59
|
+
return entries.filter((entry) => entry.status === 'running');
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The entry a single-line indicator should name. Newest start wins: when an
|
|
63
|
+
* agent kicks off a fetch while a push is already running, the thing the user
|
|
64
|
+
* just caused is the more informative label.
|
|
65
|
+
*/
|
|
66
|
+
export function selectLatestRunningGitOperation(entries) {
|
|
67
|
+
let latest;
|
|
68
|
+
for (const entry of entries) {
|
|
69
|
+
if (entry.status !== 'running')
|
|
70
|
+
continue;
|
|
71
|
+
if (!latest || toMillis(entry.timestamp) >= toMillis(latest.timestamp)) {
|
|
72
|
+
latest = entry;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return latest;
|
|
76
|
+
}
|
|
77
|
+
/** The most recently updated entry that has already settled, if any. */
|
|
78
|
+
export function selectLatestTerminalGitOperation(entries) {
|
|
79
|
+
let latest;
|
|
80
|
+
for (const entry of entries) {
|
|
81
|
+
if (entry.status === 'running')
|
|
82
|
+
continue;
|
|
83
|
+
if (!latest || entry.updatedAt >= latest.updatedAt) {
|
|
84
|
+
latest = entry;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return latest;
|
|
88
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -38,4 +38,5 @@ export { buildFileDirectoryTree, getFileDirectoryPaths, getFilePathBasename, get
|
|
|
38
38
|
export { validateExtensionBundle, printValidationResult, type ValidationResult, } from './validate.js';
|
|
39
39
|
export { validateBackendModules, assertBackendModulesValid, effectiveModulePermissions, validateAgentProviders, assertAgentProvidersValid, extractBackendModuleIds, MAX_AGENT_PROVIDERS_PER_EXTENSION, type BackendModuleValidationIssue, type AgentProviderValidationIssue, } from './manifestValidation.js';
|
|
40
40
|
export type { AgentProtocol, ProtocolEvent, ProtocolMessage, ProtocolSession, SessionOptions, ProtocolEventType, ToolResult as ProtocolToolResult, MCPServerConfig, RawProtocolSession, AgentProtocolHost, PermissionMode, McpToolDefinition, } from './agents/index.js';
|
|
41
|
+
export { screenshotService } from '@nimbalyst/runtime';
|
|
41
42
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAC;AAGxB,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,SAAS,GACf,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,EACjC,KAAK,0BAA0B,GAChC,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,8BAA8B,EAC9B,6CAA6C,EAC7C,yBAAyB,EACzB,KAAK,+BAA+B,GACrC,MAAM,4CAA4C,CAAC;AAEpD,OAAO,EACL,aAAa,EACb,YAAY,EACZ,KAAK,aAAa,GACnB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,eAAe,EACf,KAAK,wBAAwB,GAC9B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIrD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,2BAA2B,GACjC,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EACL,kBAAkB,EAClB,KAAK,YAAY,EACjB,KAAK,mBAAmB,GACzB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGhE,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,mBAAmB,EACnB,4BAA4B,EAC5B,iBAAiB,EACjB,KAAK,iBAAiB,GACvB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,KAAK,gBAAgB,GACtB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,0BAA0B,EAC1B,sBAAsB,EACtB,yBAAyB,EACzB,uBAAuB,EACvB,iCAAiC,EACjC,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,GAClC,MAAM,yBAAyB,CAAC;AAYjC,YAAY,EACV,aAAa,EACb,aAAa,EACb,eAAe,EACf,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,UAAU,IAAI,kBAAkB,EAChC,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GAClB,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAC;AAGxB,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,SAAS,GACf,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,EACjC,KAAK,0BAA0B,GAChC,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,8BAA8B,EAC9B,6CAA6C,EAC7C,yBAAyB,EACzB,KAAK,+BAA+B,GACrC,MAAM,4CAA4C,CAAC;AAEpD,OAAO,EACL,aAAa,EACb,YAAY,EACZ,KAAK,aAAa,GACnB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,eAAe,EACf,KAAK,wBAAwB,GAC9B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIrD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,2BAA2B,GACjC,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EACL,kBAAkB,EAClB,KAAK,YAAY,EACjB,KAAK,mBAAmB,GACzB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGhE,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,mBAAmB,EACnB,4BAA4B,EAC5B,iBAAiB,EACjB,KAAK,iBAAiB,GACvB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,KAAK,gBAAgB,GACtB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,0BAA0B,EAC1B,sBAAsB,EACtB,yBAAyB,EACzB,uBAAuB,EACvB,iCAAiC,EACjC,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,GAClC,MAAM,yBAAyB,CAAC;AAYjC,YAAY,EACV,aAAa,EACb,aAAa,EACb,eAAe,EACf,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,UAAU,IAAI,kBAAkB,EAChC,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -47,3 +47,5 @@ export { buildFileDirectoryTree, getFileDirectoryPaths, getFilePathBasename, get
|
|
|
47
47
|
// Re-export validation
|
|
48
48
|
export { validateExtensionBundle, printValidationResult, } from './validate.js';
|
|
49
49
|
export { validateBackendModules, assertBackendModulesValid, effectiveModulePermissions, validateAgentProviders, assertAgentProvidersValid, extractBackendModuleIds, MAX_AGENT_PROVIDERS_PER_EXTENSION, } from './manifestValidation.js';
|
|
50
|
+
// Host-owned native screenshots for every built-in and extension editor.
|
|
51
|
+
export { screenshotService } from '@nimbalyst/runtime';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifestValidation.d.ts","sourceRoot":"","sources":["../src/manifestValidation.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAGV,qBAAqB,EACtB,MAAM,wBAAwB,CAAC;AAEhC;;;;;;;;GAQG;AACH,eAAO,MAAM,iCAAiC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"manifestValidation.d.ts","sourceRoot":"","sources":["../src/manifestValidation.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAGV,qBAAqB,EACtB,MAAM,wBAAwB,CAAC;AAEhC;;;;;;;;GAQG;AACH,eAAO,MAAM,iCAAiC,IAAI,CAAC;AAwCnD,MAAM,WAAW,4BAA4B;IAC3C,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,OAAO,GACtB,4BAA4B,EAAE,CAoKhC;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,OAAO,GACtB,IAAI,CAYN;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,OAAO,GACX,qBAAqB,EAAE,CAazB;AAED;;;;GAIG;AACH,MAAM,WAAW,4BAA4B;IAC3C,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAW5E;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,sBAAsB,CACpC,gBAAgB,EAAE,OAAO,EACzB,cAAc,EAAE,OAAO,GACtB,4BAA4B,EAAE,CAgMhC;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,OAAO,EACzB,cAAc,EAAE,OAAO,GACtB,IAAI,CAYN"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend-module panel API: `ctx.services.panels`.
|
|
3
|
+
*
|
|
4
|
+
* Lets a backend module update its own panels' gutter buttons while the panel
|
|
5
|
+
* is not mounted (a fullscreen panel unmounts when the user leaves it), so an
|
|
6
|
+
* event the module sees in the background (a new flag, a budget crossing)
|
|
7
|
+
* reaches the gutter without the user reopening the panel.
|
|
8
|
+
*
|
|
9
|
+
* No permission is required: the only thing a module can change is the badge
|
|
10
|
+
* on a panel its own manifest declares.
|
|
11
|
+
*/
|
|
12
|
+
export type PanelGutterBadgeTone = 'default' | 'warning';
|
|
13
|
+
export interface BackendPanelsService {
|
|
14
|
+
/**
|
|
15
|
+
* Show a badge on one of this extension's panel gutter buttons, in the
|
|
16
|
+
* windows showing this module's workspace. Same values as the panel's own
|
|
17
|
+
* `host.setGutterBadge`: `null` clears, `0` shows a dot, a positive number
|
|
18
|
+
* shows the count. Whichever of the two writes last wins.
|
|
19
|
+
*
|
|
20
|
+
* `panelId` is the id from this extension's manifest `contributions.panels`
|
|
21
|
+
* (not prefixed with the extension id). Rejects for any other id.
|
|
22
|
+
*/
|
|
23
|
+
setGutterBadge(panelId: string, value: number | null, options?: {
|
|
24
|
+
tone?: PanelGutterBadgeTone;
|
|
25
|
+
}): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=backendPanels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backendPanels.d.ts","sourceRoot":"","sources":["../../src/types/backendPanels.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,SAAS,CAAC;AAEzD,MAAM,WAAW,oBAAoB;IACnC;;;;;;;;OAQG;IACH,cAAc,CACZ,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,oBAAoB,CAAA;KAAE,GACxC,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend-module panel API: `ctx.services.panels`.
|
|
3
|
+
*
|
|
4
|
+
* Lets a backend module update its own panels' gutter buttons while the panel
|
|
5
|
+
* is not mounted (a fullscreen panel unmounts when the user leaves it), so an
|
|
6
|
+
* event the module sees in the background (a new flag, a budget crossing)
|
|
7
|
+
* reaches the gutter without the user reopening the panel.
|
|
8
|
+
*
|
|
9
|
+
* No permission is required: the only thing a module can change is the badge
|
|
10
|
+
* on a panel its own manifest declares.
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend-module session API and tool call context.
|
|
3
|
+
*
|
|
4
|
+
* These types describe what a privileged backend module (see
|
|
5
|
+
* `BackendModuleContribution` in `./permissions`) receives from the host when
|
|
6
|
+
* it drives AI agent sessions:
|
|
7
|
+
*
|
|
8
|
+
* - `BackendToolCallContext`: passed to a backend MCP tool handler as
|
|
9
|
+
* `ctx.call`, so the handler knows which session called it.
|
|
10
|
+
* - `BackendSessionsService`: `ctx.services.sessions`, gated by the
|
|
11
|
+
* `ai-sessions` permission. Every call is scoped by the host to the
|
|
12
|
+
* calling module's extension and bound workspace; a module can only read
|
|
13
|
+
* or drive sessions its own extension owns.
|
|
14
|
+
* - `BackendMcpToolDefinition`: the shape passed to
|
|
15
|
+
* `ctx.services.registerMcpTools`, including `panelOnly`.
|
|
16
|
+
*
|
|
17
|
+
* Ownership lives in the session row's metadata (`sessionOwner`), written at
|
|
18
|
+
* creation. Sessions an owned session spawns (`spawn_session`, `create_session`,
|
|
19
|
+
* a child created under it in the UI) inherit the owner, but not the directive.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Which extension owns a session, and under what key. `key` is the owner's own
|
|
23
|
+
* grouping id (for example a member slug); the host never interprets it.
|
|
24
|
+
*/
|
|
25
|
+
export interface SessionOwner {
|
|
26
|
+
extensionId: string;
|
|
27
|
+
key: string;
|
|
28
|
+
/**
|
|
29
|
+
* When true, an owned child's settle does NOT queue a `[Child Session
|
|
30
|
+
* Update]` prompt on the session that spawned it and does not re-drive that
|
|
31
|
+
* session. The owner gets the settle through `sessions.onSettled` instead.
|
|
32
|
+
*/
|
|
33
|
+
routeChildUpdatesToOwner?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Identity of the caller of a backend MCP tool. Present on `ctx.call` when the
|
|
37
|
+
* method was invoked as a tool; absent for plain RPC calls.
|
|
38
|
+
*/
|
|
39
|
+
export interface BackendToolCallContext {
|
|
40
|
+
/** Calling AI session, or null when the call did not come from a session (panel, voice). */
|
|
41
|
+
sessionId: string | null;
|
|
42
|
+
/** Workspace the module is bound to. */
|
|
43
|
+
workspacePath: string;
|
|
44
|
+
/**
|
|
45
|
+
* The calling session's owner, populated ONLY when that session is owned by
|
|
46
|
+
* this same extension. Null for unowned sessions and for sessions another
|
|
47
|
+
* extension owns.
|
|
48
|
+
*/
|
|
49
|
+
sessionOwner: SessionOwner | null;
|
|
50
|
+
/** Where the call came from. */
|
|
51
|
+
caller: 'agent' | 'panel' | 'voice';
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* One tool passed to `ctx.services.registerMcpTools`. The advertised name is
|
|
55
|
+
* namespaced by the host as `<extension short name>.<name>`; `name` is also the
|
|
56
|
+
* backend method the host invokes.
|
|
57
|
+
*/
|
|
58
|
+
export interface BackendMcpToolDefinition {
|
|
59
|
+
name: string;
|
|
60
|
+
description?: string;
|
|
61
|
+
inputSchema?: unknown;
|
|
62
|
+
/** Also expose the tool to the voice agent. Ignored when `panelOnly` is set. */
|
|
63
|
+
voiceAgent?: boolean;
|
|
64
|
+
scope?: 'global' | 'editor';
|
|
65
|
+
/**
|
|
66
|
+
* Callable only from this extension's own renderer via `callBackendTool`.
|
|
67
|
+
* The tool is not listed to agents or the voice agent, and an agent call to
|
|
68
|
+
* it is rejected.
|
|
69
|
+
*/
|
|
70
|
+
panelOnly?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Which agent sessions see the tool. `'all'` (default) lists it to every
|
|
73
|
+
* session in the workspace. `'owned-sessions'` lists it only to sessions this
|
|
74
|
+
* extension owns (`metadata.sessionOwner.extensionId`, inherited by spawned
|
|
75
|
+
* descendants); any other session's call is rejected as an unknown tool, and
|
|
76
|
+
* the voice agent never sees it. Use it for tools that only make sense inside
|
|
77
|
+
* the extension's own sessions, so they cost other sessions no context.
|
|
78
|
+
*/
|
|
79
|
+
audience?: 'all' | 'owned-sessions';
|
|
80
|
+
}
|
|
81
|
+
/** Session lifecycle states as stored by the host. */
|
|
82
|
+
export type OwnedSessionStatus = 'idle' | 'running' | 'waiting_for_input' | 'error' | 'interrupted';
|
|
83
|
+
export interface CreateOwnedSessionOptions {
|
|
84
|
+
/** Owner key recorded in `sessionOwner.key`. The extension id is supplied by the host. */
|
|
85
|
+
ownerKey: string;
|
|
86
|
+
/** Session title. The session is treated as named, so it does not rename itself. */
|
|
87
|
+
name: string;
|
|
88
|
+
/** Agent provider id, e.g. `claude-code`, `openai-codex`. */
|
|
89
|
+
provider: string;
|
|
90
|
+
/** Model id, either `provider:model` or a bare model for `provider`. */
|
|
91
|
+
model: string;
|
|
92
|
+
/** Optional first prompt. Queued and dispatched immediately when present. */
|
|
93
|
+
prompt?: string;
|
|
94
|
+
/** Reasoning effort (`low` | `medium` | `high` | `xhigh` | `max`), clamped to the model. */
|
|
95
|
+
effortLevel?: string;
|
|
96
|
+
/**
|
|
97
|
+
* Text appended to the session's system prompt, frozen at the first turn.
|
|
98
|
+
* `create` rejects it for providers that do not apply it: the chat
|
|
99
|
+
* providers (`claude`, `openai`, `lmstudio`), `claude-code-cli`, and
|
|
100
|
+
* extension-contributed agent providers.
|
|
101
|
+
*/
|
|
102
|
+
directive?: string;
|
|
103
|
+
/** Owned workstream container to file the session under (see `createWorkstream`). */
|
|
104
|
+
workstreamId?: string;
|
|
105
|
+
/**
|
|
106
|
+
* Owned session that logically spawned this one. Its settle routing follows
|
|
107
|
+
* `routeChildUpdatesToOwner`.
|
|
108
|
+
*/
|
|
109
|
+
createdBySessionId?: string;
|
|
110
|
+
/** Initial owner metadata bag. Only this extension can change it later. */
|
|
111
|
+
ownerMetadata?: Record<string, unknown>;
|
|
112
|
+
/** See `SessionOwner.routeChildUpdatesToOwner`. Inherited by descendants. */
|
|
113
|
+
routeChildUpdatesToOwner?: boolean;
|
|
114
|
+
}
|
|
115
|
+
export interface CreateOwnedWorkstreamOptions {
|
|
116
|
+
ownerKey: string;
|
|
117
|
+
name: string;
|
|
118
|
+
/** Provider recorded on the container row. Defaults to `claude-code`. */
|
|
119
|
+
provider?: string;
|
|
120
|
+
ownerMetadata?: Record<string, unknown>;
|
|
121
|
+
}
|
|
122
|
+
export interface OwnedSessionStatusResult {
|
|
123
|
+
sessionId: string;
|
|
124
|
+
status: OwnedSessionStatus;
|
|
125
|
+
title: string;
|
|
126
|
+
lastActivity: number | null;
|
|
127
|
+
updatedAt: number | null;
|
|
128
|
+
/** The session has an unanswered durable prompt (question, plan approval, permission). */
|
|
129
|
+
hasPendingPrompt: boolean;
|
|
130
|
+
/** Queued prompts not yet delivered. */
|
|
131
|
+
queuedPromptCount: number;
|
|
132
|
+
}
|
|
133
|
+
export interface OwnedSessionContextFill {
|
|
134
|
+
/** Tokens currently in the context window. */
|
|
135
|
+
tokens: number;
|
|
136
|
+
contextWindow: number;
|
|
137
|
+
}
|
|
138
|
+
export interface OwnedSessionResult {
|
|
139
|
+
sessionId: string;
|
|
140
|
+
status: OwnedSessionStatus;
|
|
141
|
+
/** Text of the last assistant turn, or null if the session has not answered. */
|
|
142
|
+
lastResponse: string | null;
|
|
143
|
+
errorMessage: string | null;
|
|
144
|
+
/** Current context fill as last reported by the provider; null before the first report. */
|
|
145
|
+
contextFill: OwnedSessionContextFill | null;
|
|
146
|
+
pendingPrompt: {
|
|
147
|
+
promptId: string;
|
|
148
|
+
promptType: string;
|
|
149
|
+
} | null;
|
|
150
|
+
editedFiles: string[];
|
|
151
|
+
}
|
|
152
|
+
export interface OwnedSessionSummary {
|
|
153
|
+
sessionId: string;
|
|
154
|
+
key: string;
|
|
155
|
+
sessionType: 'session' | 'workstream' | string;
|
|
156
|
+
title: string;
|
|
157
|
+
/** Owned workstream container this session is filed under, if any. */
|
|
158
|
+
workstreamId: string | null;
|
|
159
|
+
/** Session that spawned this one, if any. */
|
|
160
|
+
createdBySessionId: string | null;
|
|
161
|
+
status: OwnedSessionStatus;
|
|
162
|
+
hasPendingPrompt: boolean;
|
|
163
|
+
queuedPromptCount: number;
|
|
164
|
+
createdAt: number;
|
|
165
|
+
updatedAt: number;
|
|
166
|
+
ownerMetadata: Record<string, unknown>;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Token usage for one session over its whole lifetime, as persisted by the
|
|
170
|
+
* host (the same counters the session's usage display reads). `costUSD` is
|
|
171
|
+
* 0 when the provider does not report cost.
|
|
172
|
+
*
|
|
173
|
+
* The four token counters are disjoint: `inputTokens` is uncached input only,
|
|
174
|
+
* and cache reads/writes are counted separately (0 for providers that report
|
|
175
|
+
* no cache split, and for sessions recorded before the host stored them).
|
|
176
|
+
* `totalTokens` keeps its historical meaning, input + output without cache;
|
|
177
|
+
* budget over `allTokens` to count everything the session consumed.
|
|
178
|
+
*/
|
|
179
|
+
export interface OwnedSessionUsage {
|
|
180
|
+
inputTokens: number;
|
|
181
|
+
outputTokens: number;
|
|
182
|
+
totalTokens: number;
|
|
183
|
+
costUSD: number;
|
|
184
|
+
cacheReadInputTokens: number;
|
|
185
|
+
cacheCreationInputTokens: number;
|
|
186
|
+
/** inputTokens + outputTokens + cacheReadInputTokens + cacheCreationInputTokens. */
|
|
187
|
+
allTokens: number;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Usage is session-granular: a session counts in full when its last activity
|
|
191
|
+
* is at or after `since`. The host keeps no per-turn usage history. For an
|
|
192
|
+
* exact time window, record `OwnedSessionSettledEvent.tokenUsage` deltas in
|
|
193
|
+
* the module's own storage.
|
|
194
|
+
*/
|
|
195
|
+
export interface OwnedUsageReport {
|
|
196
|
+
since: number;
|
|
197
|
+
totals: OwnedSessionUsage;
|
|
198
|
+
sessions: Array<OwnedSessionUsage & {
|
|
199
|
+
sessionId: string;
|
|
200
|
+
key: string;
|
|
201
|
+
lastActivity: number;
|
|
202
|
+
}>;
|
|
203
|
+
}
|
|
204
|
+
export type OwnedSessionSettleOutcome = 'completed' | 'error' | 'waiting' | 'interrupted';
|
|
205
|
+
/**
|
|
206
|
+
* Delivered to `onSettled` handlers. `completed` fires once the session's
|
|
207
|
+
* prompt queue is empty, not between queued prompts.
|
|
208
|
+
*/
|
|
209
|
+
export interface OwnedSessionSettledEvent {
|
|
210
|
+
sessionId: string;
|
|
211
|
+
ownerKey: string;
|
|
212
|
+
outcome: OwnedSessionSettleOutcome;
|
|
213
|
+
createdBySessionId: string | null;
|
|
214
|
+
workstreamId: string | null;
|
|
215
|
+
at: number;
|
|
216
|
+
/** The session's lifetime usage at settle time; diff consecutive events for per-turn usage. */
|
|
217
|
+
tokenUsage: OwnedSessionUsage;
|
|
218
|
+
}
|
|
219
|
+
export interface NotifyUserOptions {
|
|
220
|
+
/** Owned session the notification is about; clicking it opens this session. */
|
|
221
|
+
sessionId: string;
|
|
222
|
+
title: string;
|
|
223
|
+
body: string;
|
|
224
|
+
/** `critical` also pushes to the user's phone. Defaults to `normal`. */
|
|
225
|
+
urgency?: 'low' | 'normal' | 'critical';
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* `ctx.services.sessions`. Requires the `ai-sessions` permission. Every method
|
|
229
|
+
* that takes a session id rejects sessions this extension does not own.
|
|
230
|
+
*/
|
|
231
|
+
export interface BackendSessionsService {
|
|
232
|
+
create(options: CreateOwnedSessionOptions): Promise<{
|
|
233
|
+
sessionId: string;
|
|
234
|
+
queuedPromptId: string | null;
|
|
235
|
+
}>;
|
|
236
|
+
createWorkstream(options: CreateOwnedWorkstreamOptions): Promise<{
|
|
237
|
+
workstreamId: string;
|
|
238
|
+
}>;
|
|
239
|
+
/** Queue a prompt; it is delivered when the session is idle. */
|
|
240
|
+
sendPrompt(sessionId: string, prompt: string): Promise<{
|
|
241
|
+
queuedPromptId: string;
|
|
242
|
+
}>;
|
|
243
|
+
getStatus(sessionId: string): Promise<OwnedSessionStatusResult>;
|
|
244
|
+
getResult(sessionId: string): Promise<OwnedSessionResult>;
|
|
245
|
+
/** Owned sessions in this workspace, optionally filtered to one owner key. Newest first. */
|
|
246
|
+
listOwned(options?: {
|
|
247
|
+
key?: string;
|
|
248
|
+
}): Promise<OwnedSessionSummary[]>;
|
|
249
|
+
/** Lifetime usage of owned sessions active at or after `since` (epoch ms). See `OwnedUsageReport`. */
|
|
250
|
+
getUsage(options: {
|
|
251
|
+
key?: string;
|
|
252
|
+
since: number;
|
|
253
|
+
}): Promise<OwnedUsageReport>;
|
|
254
|
+
/** Shallow-merge `patch` into the session's owner metadata bag. A `null` value deletes the key. */
|
|
255
|
+
updateOwnerMetadata(sessionId: string, patch: Record<string, unknown>): Promise<{
|
|
256
|
+
ownerMetadata: Record<string, unknown>;
|
|
257
|
+
}>;
|
|
258
|
+
notifyUser(options: NotifyUserOptions): Promise<void>;
|
|
259
|
+
/** Subscribe to settle events for sessions this extension owns in this workspace. Returns an unsubscribe. */
|
|
260
|
+
onSettled(handler: (event: OwnedSessionSettledEvent) => void): () => void;
|
|
261
|
+
}
|
|
262
|
+
//# sourceMappingURL=backendSessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backendSessions.d.ts","sourceRoot":"","sources":["../../src/types/backendSessions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend-module session API and tool call context.
|
|
3
|
+
*
|
|
4
|
+
* These types describe what a privileged backend module (see
|
|
5
|
+
* `BackendModuleContribution` in `./permissions`) receives from the host when
|
|
6
|
+
* it drives AI agent sessions:
|
|
7
|
+
*
|
|
8
|
+
* - `BackendToolCallContext`: passed to a backend MCP tool handler as
|
|
9
|
+
* `ctx.call`, so the handler knows which session called it.
|
|
10
|
+
* - `BackendSessionsService`: `ctx.services.sessions`, gated by the
|
|
11
|
+
* `ai-sessions` permission. Every call is scoped by the host to the
|
|
12
|
+
* calling module's extension and bound workspace; a module can only read
|
|
13
|
+
* or drive sessions its own extension owns.
|
|
14
|
+
* - `BackendMcpToolDefinition`: the shape passed to
|
|
15
|
+
* `ctx.services.registerMcpTools`, including `panelOnly`.
|
|
16
|
+
*
|
|
17
|
+
* Ownership lives in the session row's metadata (`sessionOwner`), written at
|
|
18
|
+
* creation. Sessions an owned session spawns (`spawn_session`, `create_session`,
|
|
19
|
+
* a child created under it in the UI) inherit the owner, but not the directive.
|
|
20
|
+
*/
|
|
21
|
+
export {};
|
package/dist/types/collab.d.ts
CHANGED
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
* @see CollabContentAdapter -- the former name, kept as a deprecated alias.
|
|
31
31
|
*/
|
|
32
32
|
import type { Doc } from 'yjs';
|
|
33
|
+
import type { CommentAnchor } from './comments';
|
|
33
34
|
export type CollabContentFileSource = string | Uint8Array;
|
|
34
35
|
/**
|
|
35
36
|
* Serializable description of a CollabContentAdapter that lets the HOST
|
|
@@ -52,6 +53,17 @@ export interface CollabCodecMigration {
|
|
|
52
53
|
to: number;
|
|
53
54
|
run(yDoc: Doc): void;
|
|
54
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Structured-comment anchor support for headless hosts. Hosts invoke these
|
|
58
|
+
* reads against a detached, disposable Y.Doc snapshot rather than the live
|
|
59
|
+
* collaborative document, so an accidental mutation cannot alter or sync the
|
|
60
|
+
* real document. Codecs should still treat the snapshot as read-only.
|
|
61
|
+
*/
|
|
62
|
+
export interface CollabCommentAnchorCodec {
|
|
63
|
+
handles(anchor: CommentAnchor): boolean;
|
|
64
|
+
getState(snapshot: Doc, anchor: CommentAnchor): 'attached' | 'orphaned';
|
|
65
|
+
describe(snapshot: Doc, anchor: CommentAnchor): string;
|
|
66
|
+
}
|
|
55
67
|
/** @deprecated Renamed to {@link CollabCodecMigration}. */
|
|
56
68
|
export type CollabContentAdapterMigration = CollabCodecMigration;
|
|
57
69
|
export interface CollabCodec<TStructured = unknown> {
|
|
@@ -95,9 +107,26 @@ export interface CollabCodec<TStructured = unknown> {
|
|
|
95
107
|
* `applyStructuredPatch`. */
|
|
96
108
|
toStructured?(yDoc: Doc): TStructured;
|
|
97
109
|
/** Optional: write structured edits back. Paired with
|
|
98
|
-
* `toStructured`. AI-write surface
|
|
99
|
-
* both this
|
|
110
|
+
* `toStructured`. The PREFERRED AI-write surface: implementing
|
|
111
|
+
* both lets an agent edit this document type structurally.
|
|
112
|
+
*
|
|
113
|
+
* It is NOT a gate. When an adapter does not implement the pair,
|
|
114
|
+
* an agent edit falls back to `exportToFile` -> text replacement
|
|
115
|
+
* -> `applyFromFile`, so every adapter is AI-writable whether or
|
|
116
|
+
* not it opted in. Two consequences an adapter author must know:
|
|
117
|
+
*
|
|
118
|
+
* - `applyFromFile` is called with agent-authored content, not
|
|
119
|
+
* just on-disk content, so it must be safe to call on a
|
|
120
|
+
* populated Y.Doc (it already must be) AND must be able to
|
|
121
|
+
* consume its own `exportToFile` output unchanged. That
|
|
122
|
+
* round-trip is asserted for every registered adapter in
|
|
123
|
+
* `codecOnlyHeadlessEdit.test.ts`.
|
|
124
|
+
* - The fallback rewrites the whole document, so a concurrent
|
|
125
|
+
* human edit can interleave. Implement the structured pair to
|
|
126
|
+
* get minimal deltas instead. */
|
|
100
127
|
applyStructuredPatch?(yDoc: Doc, patch: unknown): void;
|
|
128
|
+
/** Optional snapshot-isolated resolver for structured comment anchors. */
|
|
129
|
+
commentAnchors?: CollabCommentAnchorCodec;
|
|
101
130
|
/** Optional: produce a snapshot for revision history. Defaults to
|
|
102
131
|
* `Y.encodeStateAsUpdateV2(yDoc)`. Override if you need a denser
|
|
103
132
|
* snapshot format. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collab.d.ts","sourceRoot":"","sources":["../../src/types/collab.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"collab.d.ts","sourceRoot":"","sources":["../../src/types/collab.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/** Editor-neutral collaborative comment contracts exposed to extensions. */
|
|
2
|
+
export type TextQuoteCommentAnchor = {
|
|
3
|
+
kind: 'text-quote';
|
|
4
|
+
exact: string;
|
|
5
|
+
prefix?: string;
|
|
6
|
+
suffix?: string;
|
|
7
|
+
};
|
|
8
|
+
export type EntityCommentAnchor = {
|
|
9
|
+
kind: 'entity';
|
|
10
|
+
entityType: string;
|
|
11
|
+
entityId: string;
|
|
12
|
+
field?: string;
|
|
13
|
+
labelSnapshot?: string;
|
|
14
|
+
};
|
|
15
|
+
export type CommentAnchor = TextQuoteCommentAnchor | EntityCommentAnchor;
|
|
16
|
+
export type CollaborativeUserCommentActor = {
|
|
17
|
+
kind: 'user';
|
|
18
|
+
userId?: string;
|
|
19
|
+
displayName: string;
|
|
20
|
+
};
|
|
21
|
+
export type CollaborativeAgentCommentActor = {
|
|
22
|
+
kind: 'agent';
|
|
23
|
+
sessionId: string;
|
|
24
|
+
sessionName: string;
|
|
25
|
+
onBehalfOfUserId: string;
|
|
26
|
+
onBehalfOfDisplayName?: string;
|
|
27
|
+
};
|
|
28
|
+
export type CollaborativeCommentActor = CollaborativeUserCommentActor | CollaborativeAgentCommentActor;
|
|
29
|
+
export interface CollaborativeComment {
|
|
30
|
+
readonly actor?: CollaborativeCommentActor;
|
|
31
|
+
readonly author: string;
|
|
32
|
+
readonly clientMutationId?: string;
|
|
33
|
+
readonly content: string;
|
|
34
|
+
readonly deleted: boolean;
|
|
35
|
+
readonly id: string;
|
|
36
|
+
readonly replyToCommentId?: string;
|
|
37
|
+
readonly timeStamp: number;
|
|
38
|
+
readonly type: 'comment';
|
|
39
|
+
}
|
|
40
|
+
export interface CollaborativeCommentThread {
|
|
41
|
+
readonly anchor?: CommentAnchor;
|
|
42
|
+
readonly comments: ReadonlyArray<CollaborativeComment>;
|
|
43
|
+
readonly id: string;
|
|
44
|
+
readonly quote: string;
|
|
45
|
+
readonly resolved: boolean;
|
|
46
|
+
readonly type: 'thread';
|
|
47
|
+
}
|
|
48
|
+
/** The immutable canonical view of the document's top-level comments array. */
|
|
49
|
+
export type CollaborativeCommentsSnapshot = ReadonlyArray<CollaborativeComment | CollaborativeCommentThread>;
|
|
50
|
+
export interface CommentCapabilities {
|
|
51
|
+
read: boolean;
|
|
52
|
+
comment: boolean;
|
|
53
|
+
}
|
|
54
|
+
export interface CommentMember {
|
|
55
|
+
userId: string;
|
|
56
|
+
name: string;
|
|
57
|
+
email?: string | null;
|
|
58
|
+
personalOrgId?: string | null;
|
|
59
|
+
}
|
|
60
|
+
export interface CreateCommentThreadInput {
|
|
61
|
+
anchor: CommentAnchor;
|
|
62
|
+
content: string;
|
|
63
|
+
clientMutationId: string;
|
|
64
|
+
mentionedUserIds?: string[];
|
|
65
|
+
}
|
|
66
|
+
export interface CreateCommentThreadResult {
|
|
67
|
+
comment: CollaborativeComment;
|
|
68
|
+
duplicate: boolean;
|
|
69
|
+
thread: CollaborativeCommentThread;
|
|
70
|
+
}
|
|
71
|
+
export interface ReplyToCommentInput {
|
|
72
|
+
threadId: string;
|
|
73
|
+
content: string;
|
|
74
|
+
clientMutationId: string;
|
|
75
|
+
mentionedUserIds?: string[];
|
|
76
|
+
replyToCommentId?: string;
|
|
77
|
+
}
|
|
78
|
+
export interface ReplyToCommentResult {
|
|
79
|
+
comment: CollaborativeComment;
|
|
80
|
+
duplicate: boolean;
|
|
81
|
+
threadId: string;
|
|
82
|
+
}
|
|
83
|
+
export interface MountedCommentAnchorAdapter {
|
|
84
|
+
handles(anchor: CommentAnchor): boolean;
|
|
85
|
+
getState(anchor: CommentAnchor): 'attached' | 'orphaned';
|
|
86
|
+
describe(anchor: CommentAnchor): string;
|
|
87
|
+
focus(anchor: CommentAnchor): boolean | Promise<boolean>;
|
|
88
|
+
}
|
|
89
|
+
export interface CollaborationCommentsService {
|
|
90
|
+
getSnapshot(): CollaborativeCommentsSnapshot;
|
|
91
|
+
subscribe(listener: () => void): () => void;
|
|
92
|
+
getCapabilities(): CommentCapabilities;
|
|
93
|
+
getMentionableMembers(): CommentMember[];
|
|
94
|
+
createThread(input: CreateCommentThreadInput): Promise<CreateCommentThreadResult>;
|
|
95
|
+
reply(input: ReplyToCommentInput): Promise<ReplyToCommentResult>;
|
|
96
|
+
setResolved(threadId: string, resolved: boolean): Promise<void>;
|
|
97
|
+
focusThread(threadId: string): Promise<boolean>;
|
|
98
|
+
openPanel(input?: {
|
|
99
|
+
threadId?: string;
|
|
100
|
+
anchor?: CommentAnchor;
|
|
101
|
+
}): void;
|
|
102
|
+
registerAnchorAdapter(adapter: MountedCommentAnchorAdapter): () => void;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=comments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../src/types/comments.ts"],"names":[],"mappings":"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"}
|