@nimbalyst/extension-sdk 0.5.0 → 0.6.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 +24 -0
- 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 +8 -0
- 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/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 +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/panel.d.ts +21 -0
- package/dist/types/panel.d.ts.map +1 -1
- package/package.json +14 -2
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,7 @@ The SDK is versioned independently of the Nimbalyst app. Each release declares i
|
|
|
8
8
|
|
|
9
9
|
| SDK version | Minimum Nimbalyst app version |
|
|
10
10
|
| --- | --- |
|
|
11
|
+
| 0.6.0 | 0.78.0 |
|
|
11
12
|
| 0.5.0 | 0.70.0 |
|
|
12
13
|
| 0.4.0 | 0.70.0 |
|
|
13
14
|
| 0.3.0 | 0.70.0 |
|
|
@@ -19,6 +20,29 @@ The SDK is versioned independently of the Nimbalyst app. Each release declares i
|
|
|
19
20
|
|
|
20
21
|
## [Unreleased]
|
|
21
22
|
|
|
23
|
+
## [0.6.0] - 2026-09-14
|
|
24
|
+
|
|
25
|
+
Requires Nimbalyst 0.78.0, available on the alpha channel at publication, for the complete host API including native screenshots.
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- `CollaborationCommentsService`, `CommentAnchor`, and codec-level `commentAnchors` let collaborative editors mount the platform comment experience and resolve structured anchors both live and headlessly.
|
|
30
|
+
- `host.registerViewport()` and `EditorViewport` let an editor expose proportional scroll position to hosts that carry the reader's place between related documents; `createReadOnlyHost()` can receive those registrations.
|
|
31
|
+
- `contributions.customEditors[].collaboration.documentType` lets a host identify a collaborative document type from the manifest before its extension bundle and codec are loaded.
|
|
32
|
+
- `screenshotService` exposes host-provided element and file screenshots, including unopened documents.
|
|
33
|
+
- `PanelHost.getWorkspaceFolders()` and `getPrimaryFolderPath()` expose multiple workspace roots; file-tree helpers accept those roots.
|
|
34
|
+
- `EditorHost.getAssetUrl()` and the `assetUrls` capability let media editors stream local files through a host-provided URL.
|
|
35
|
+
- The `agents`, `types/editor`, and `git-operation-log` entry points expose agent contracts, editor types, and Git operation selectors.
|
|
36
|
+
- `ProtocolSession.appliedModel` and `deliveredMcpServerCount` report the model and MCP servers actually used by an agent.
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- `CollabCodec` documents file-form fallback for headless agent edits when no structured patch pair exists, while recommending structured edits for minimal concurrent deltas.
|
|
41
|
+
|
|
42
|
+
### Fixed
|
|
43
|
+
|
|
44
|
+
- Agent host declarations use a Node-compatible relative import for consumers using Node16 or NodeNext module resolution.
|
|
45
|
+
|
|
22
46
|
## [0.5.0]
|
|
23
47
|
|
|
24
48
|
Still runs on Nimbalyst 0.70.0: a host that declares no capabilities is treated as fully capable, so an extension written against this release keeps working on older desktop builds.
|
|
@@ -56,4 +56,38 @@ describe('buildFileDirectoryTree', () => {
|
|
|
56
56
|
expect(tree.fileCount).toBe(1);
|
|
57
57
|
expect(tree.files).toHaveLength(1);
|
|
58
58
|
});
|
|
59
|
+
describe('multi-root workspaces', () => {
|
|
60
|
+
const ROOTS = ['/repo', '/other/collab'];
|
|
61
|
+
it('leaves primary-root paths bare and names the attached root', () => {
|
|
62
|
+
expect(getWorkspaceRelativeFilePath('/repo/src/index.ts', ROOTS)).toBe('src/index.ts');
|
|
63
|
+
expect(getWorkspaceRelativeFilePath('/other/collab/src/index.ts', ROOTS))
|
|
64
|
+
.toBe('collab/src/index.ts');
|
|
65
|
+
});
|
|
66
|
+
it('keeps same-named files in different roots in separate groups', () => {
|
|
67
|
+
const tree = buildTree(['/repo/src/index.ts', '/other/collab/src/index.ts'], ROOTS);
|
|
68
|
+
// `collab/src` is the collapsed single-child chain; the point is that the
|
|
69
|
+
// two `src` directories do not merge into one group.
|
|
70
|
+
expect(getFileDirectoryPaths(tree)).toEqual(['src', 'collab/src']);
|
|
71
|
+
expect(tree.subdirectories.get('src')?.fileCount).toBe(1);
|
|
72
|
+
expect(tree.subdirectories.get('collab')?.fileCount).toBe(1);
|
|
73
|
+
});
|
|
74
|
+
it('prefers the deepest root for a root nested inside another root', () => {
|
|
75
|
+
expect(getWorkspaceRelativeFilePath('/repo/vendor/lib/a.ts', ['/repo', '/repo/vendor/lib']))
|
|
76
|
+
.toBe('lib/a.ts');
|
|
77
|
+
});
|
|
78
|
+
it('falls back to the absolute path for a file in no root', () => {
|
|
79
|
+
expect(getWorkspaceRelativeFilePath('/elsewhere/a.ts', ROOTS)).toBe('/elsewhere/a.ts');
|
|
80
|
+
});
|
|
81
|
+
it('disambiguates attached roots that share a basename', () => {
|
|
82
|
+
// `/app/api` and `/infra/api` are an ordinary pair, and a bare basename
|
|
83
|
+
// would collapse both repos into one `api` group in the tree.
|
|
84
|
+
const roots = ['/repo', '/app/api', '/infra/api'];
|
|
85
|
+
expect(getWorkspaceRelativeFilePath('/app/api/src/a.ts', roots)).toBe('app/api/src/a.ts');
|
|
86
|
+
expect(getWorkspaceRelativeFilePath('/infra/api/src/a.ts', roots)).toBe('infra/api/src/a.ts');
|
|
87
|
+
});
|
|
88
|
+
it('matches single-root behaviour when given one root', () => {
|
|
89
|
+
expect(getWorkspaceRelativeFilePath('/repo/src/index.ts', ['/repo']))
|
|
90
|
+
.toBe(getWorkspaceRelativeFilePath('/repo/src/index.ts', '/repo'));
|
|
91
|
+
});
|
|
92
|
+
});
|
|
59
93
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitOperationLog.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/gitOperationLog.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { mergeGitOperationEntries, normalizeGitOperationEntry, selectLatestRunningGitOperation, selectLatestTerminalGitOperation, selectRunningGitOperations, } from '../gitOperationLog';
|
|
3
|
+
function entry(overrides) {
|
|
4
|
+
return {
|
|
5
|
+
timestamp: 1000,
|
|
6
|
+
updatedAt: 1000,
|
|
7
|
+
command: 'git status',
|
|
8
|
+
executable: 'git',
|
|
9
|
+
args: ['status'],
|
|
10
|
+
cwd: '/repo',
|
|
11
|
+
status: 'running',
|
|
12
|
+
output: '',
|
|
13
|
+
stdout: '',
|
|
14
|
+
stderr: '',
|
|
15
|
+
...overrides,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
describe('git operation log selectors', () => {
|
|
19
|
+
it('keeps a live terminal event that landed while hydration was in flight', () => {
|
|
20
|
+
// The `git:operation-log:get` response is older than upserts that arrived
|
|
21
|
+
// after it was requested. Applying it blindly rewinds a finished push back
|
|
22
|
+
// to running, which is exactly the stale indicator this ordering prevents.
|
|
23
|
+
const hydrated = [entry({ id: 'a', status: 'running', updatedAt: 1000 })];
|
|
24
|
+
const live = [entry({ id: 'a', status: 'success', updatedAt: 2000 })];
|
|
25
|
+
expect(mergeGitOperationEntries(hydrated, live)[0].status).toBe('success');
|
|
26
|
+
expect(mergeGitOperationEntries(live, hydrated)[0].status).toBe('success');
|
|
27
|
+
});
|
|
28
|
+
it('names the newest running command and counts the rest', () => {
|
|
29
|
+
const entries = [
|
|
30
|
+
entry({ id: 'push', timestamp: 1000, command: 'git push' }),
|
|
31
|
+
entry({ id: 'fetch', timestamp: 3000, command: 'git fetch origin' }),
|
|
32
|
+
entry({ id: 'done', timestamp: 2000, status: 'success', updatedAt: 5000 }),
|
|
33
|
+
];
|
|
34
|
+
expect(selectLatestRunningGitOperation(entries)?.id).toBe('fetch');
|
|
35
|
+
expect(selectRunningGitOperations(entries).map((e) => e.id)).toEqual(['push', 'fetch']);
|
|
36
|
+
expect(selectLatestTerminalGitOperation(entries)?.id).toBe('done');
|
|
37
|
+
});
|
|
38
|
+
it('reads a journal written before source metadata existed as app-owned direct git', () => {
|
|
39
|
+
const legacy = entry({ id: 'legacy' });
|
|
40
|
+
delete legacy.source;
|
|
41
|
+
delete legacy.executor;
|
|
42
|
+
const normalized = normalizeGitOperationEntry(legacy);
|
|
43
|
+
expect(normalized.source).toBe('nimbalyst');
|
|
44
|
+
expect(normalized.executor).toBe('git');
|
|
45
|
+
});
|
|
46
|
+
it('does not let an agent entry inherit the app-owned default', () => {
|
|
47
|
+
const agent = entry({ id: 'agent', source: 'agent', executor: 'shell', sessionId: 's1' });
|
|
48
|
+
expect(normalizeGitOperationEntry(agent).source).toBe('agent');
|
|
49
|
+
expect(normalizeGitOperationEntry(agent).executor).toBe('shell');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -129,6 +129,14 @@ export interface ProtocolSession {
|
|
|
129
129
|
platform: string;
|
|
130
130
|
/** Platform-specific session data (for internal use) */
|
|
131
131
|
raw?: RawProtocolSession;
|
|
132
|
+
/** Number of host-supplied MCP servers this protocol actually delivered. */
|
|
133
|
+
deliveredMcpServerCount?: number;
|
|
134
|
+
/**
|
|
135
|
+
* Model the agent is actually running, when the protocol can observe it.
|
|
136
|
+
* Absent means "the protocol has no say"; the host then reports the model it
|
|
137
|
+
* asked for. Never report a requested model a protocol knows was not applied.
|
|
138
|
+
*/
|
|
139
|
+
appliedModel?: string;
|
|
132
140
|
}
|
|
133
141
|
/**
|
|
134
142
|
* Event types emitted during message streaming
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentProtocol.d.ts","sourceRoot":"","sources":["../../src/agents/AgentProtocol.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"AgentProtocol.d.ts","sourceRoot":"","sources":["../../src/agents/AgentProtocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
* See `docs/EXTENSION_ARCHITECTURE.md` and the Phase 4 SDK design doc
|
|
40
40
|
* (Section 4.3) for the full host contract.
|
|
41
41
|
*/
|
|
42
|
-
import type { MCPServerConfig } from './index';
|
|
42
|
+
import type { MCPServerConfig } from './index.js';
|
|
43
43
|
/**
|
|
44
44
|
* Permission posture the host has set for the current turn.
|
|
45
45
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentProtocolHost.d.ts","sourceRoot":"","sources":["../../src/agents/AgentProtocolHost.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;
|
|
1
|
+
{"version":3,"file":"AgentProtocolHost.d.ts","sourceRoot":"","sources":["../../src/agents/AgentProtocolHost.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAErD;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAGhC,uDAAuD;IACvD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B;;;OAGG;IACH,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IAExC;;;OAGG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAIjC,iDAAiD;IACjD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,wDAAwD;IACxD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAE/B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAExB;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAElC,yDAAyD;IACzD,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IAExC;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,eAAe,EAAE,CAAC;IAEhD;;;;OAIG;IACH,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAI/C;;;;;;;;;;;OAWG;IACH,MAAM,CACJ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,OAAO,GAAG,QAAQ,EAC7B,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;;;;;OAQG;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAE3D;;;;;;;OAOG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAErD;;;;OAIG;IACH,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErE;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D"}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* host.setTheme('light');
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
|
-
import type { EditorHost } from './types/editor.js';
|
|
24
|
+
import type { EditorHost, EditorViewport } from './types/editor.js';
|
|
25
25
|
export interface ReadOnlyHostOptions {
|
|
26
26
|
/** Current theme name (e.g., 'dark', 'light') */
|
|
27
27
|
theme: string;
|
|
@@ -34,6 +34,16 @@ export interface ReadOnlyHostOptions {
|
|
|
34
34
|
* When true, extensions may suppress chrome that doesn't fit inline contexts.
|
|
35
35
|
*/
|
|
36
36
|
embedded?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Receives the editor's scroll viewport when it publishes one.
|
|
39
|
+
*
|
|
40
|
+
* Supplied only by a surface that shows several documents in sequence and
|
|
41
|
+
* wants to carry the reader's place between them -- the feedback detail
|
|
42
|
+
* popover comparing design alternatives. Absent, `registerViewport` is
|
|
43
|
+
* absent too, so an extension that checks before registering gets a straight
|
|
44
|
+
* answer rather than a silent no-op.
|
|
45
|
+
*/
|
|
46
|
+
onViewportRegistered?(viewport: EditorViewport | null): void;
|
|
37
47
|
}
|
|
38
48
|
export interface ReadOnlyHost extends EditorHost {
|
|
39
49
|
/** Update the theme (call from viewer chrome's theme toggle) */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createReadOnlyHost.d.ts","sourceRoot":"","sources":["../src/createReadOnlyHost.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"createReadOnlyHost.d.ts","sourceRoot":"","sources":["../src/createReadOnlyHost.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAEV,UAAU,EAEV,cAAc,EACf,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,mBAAmB;IAClC,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IAEd,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IAEjB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;;;;;OAQG;IACH,oBAAoB,CAAC,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,GAAG,IAAI,CAAC;CAC9D;AAED,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C,gEAAgE;IAChE,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,mBAAmB,GACxB,YAAY,CAiEd"}
|
|
@@ -60,6 +60,9 @@ export function createReadOnlyHost(content, opts) {
|
|
|
60
60
|
openHistory: () => { },
|
|
61
61
|
registerMenuItems: (_items) => { },
|
|
62
62
|
registerEditorAPI: () => { },
|
|
63
|
+
...(opts.onViewportRegistered
|
|
64
|
+
? { registerViewport: opts.onViewportRegistered }
|
|
65
|
+
: {}),
|
|
63
66
|
setEditorContext: (_context) => { },
|
|
64
67
|
setEditorContextItems: () => { },
|
|
65
68
|
// -- Storage (in-memory, non-persistent) --
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"externalsPlugin.d.ts","sourceRoot":"","sources":["../src/externalsPlugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"externalsPlugin.d.ts","sourceRoot":"","sources":["../src/externalsPlugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAoDnC;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAyDjD"}
|
package/dist/externalsPlugin.js
CHANGED
|
@@ -45,7 +45,6 @@ const EXTERNALS_MAP = {
|
|
|
45
45
|
'@nimbalyst/editor-context': '@nimbalyst/editor-context',
|
|
46
46
|
'@nimbalyst/runtime/ui/icons/MaterialSymbol': '@nimbalyst/runtime/ui/icons/MaterialSymbol',
|
|
47
47
|
'@nimbalyst/screenshot-service': '@nimbalyst/screenshot-service',
|
|
48
|
-
'@nimbalyst/datamodel-platform-service': '@nimbalyst/datamodel-platform-service',
|
|
49
48
|
// Shared libraries
|
|
50
49
|
'pdfjs-dist': 'pdfjs-dist',
|
|
51
50
|
virtua: 'virtua',
|
|
@@ -230,7 +229,7 @@ function generateCommonExports(externalKey) {
|
|
|
230
229
|
}
|
|
231
230
|
else if (externalKey === '@nimbalyst/runtime') {
|
|
232
231
|
exports = [
|
|
233
|
-
'MaterialSymbol', 'useDocumentPath', 'useEditorLifecycle',
|
|
232
|
+
'MaterialSymbol', 'useDocumentPath', 'useEditorLifecycle', 'screenshotService',
|
|
234
233
|
'useCollaborativeEditor', 'COLLAB_INIT_ORIGIN',
|
|
235
234
|
'setTranscriptMarkdownContributions', 'clearTranscriptMarkdownContributions',
|
|
236
235
|
'MarkdownEditor', 'MonacoEditor', 'MonacoCodeEditor',
|
|
@@ -241,9 +240,6 @@ function generateCommonExports(externalKey) {
|
|
|
241
240
|
else if (externalKey === '@nimbalyst/screenshot-service') {
|
|
242
241
|
exports = ['screenshotService'];
|
|
243
242
|
}
|
|
244
|
-
else if (externalKey === '@nimbalyst/datamodel-platform-service') {
|
|
245
|
-
exports = ['DataModelPlatformServiceImpl', 'getInstance'];
|
|
246
|
-
}
|
|
247
243
|
else if (externalKey === 'pdfjs-dist') {
|
|
248
244
|
exports = ['getDocument', 'GlobalWorkerOptions', 'version'];
|
|
249
245
|
}
|
|
@@ -11,9 +11,16 @@ export declare function getFilePathBasename(filePath: string): string;
|
|
|
11
11
|
/**
|
|
12
12
|
* Return a forward-slash path relative to the workspace when the file is inside it.
|
|
13
13
|
* Windows drive paths are compared case-insensitively to match filesystem behavior.
|
|
14
|
+
*
|
|
15
|
+
* A multi-root workspace passes every root, primary first. The primary root
|
|
16
|
+
* still yields a bare relative path, so a single-folder workspace is unchanged;
|
|
17
|
+
* a file in an attached root is prefixed with that root's heading, which is
|
|
18
|
+
* what groups it under its own heading in the directory tree instead of
|
|
19
|
+
* spelling out an absolute path. Deepest matching root wins, so a root checked
|
|
20
|
+
* out inside another root keeps its own prefix.
|
|
14
21
|
*/
|
|
15
|
-
export declare function getWorkspaceRelativeFilePath(filePath: string, workspacePath?: string): string;
|
|
22
|
+
export declare function getWorkspaceRelativeFilePath(filePath: string, workspacePath?: string | string[]): string;
|
|
16
23
|
/** Build a collapsed directory tree for arbitrary file records. */
|
|
17
|
-
export declare function buildFileDirectoryTree<T>(files: T[], getFilePath: (file: T) => string, workspacePath?: string): FileDirectoryNode<T>;
|
|
24
|
+
export declare function buildFileDirectoryTree<T>(files: T[], getFilePath: (file: T) => string, workspacePath?: string | string[]): FileDirectoryNode<T>;
|
|
18
25
|
export declare function getFileDirectoryPaths<T>(node: FileDirectoryNode<T>): string[];
|
|
19
26
|
//# sourceMappingURL=fileDirectoryTree.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fileDirectoryTree.d.ts","sourceRoot":"","sources":["../src/fileDirectoryTree.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qFAAqF;AACrF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG5D;
|
|
1
|
+
{"version":3,"file":"fileDirectoryTree.d.ts","sourceRoot":"","sources":["../src/fileDirectoryTree.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qFAAqF;AACrF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG5D;AAwDD;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAChC,MAAM,CAwBR;AA6BD,mEAAmE;AACnE,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,KAAK,EAAE,CAAC,EAAE,EACV,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,EAChC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAChC,iBAAiB,CAAC,CAAC,CAAC,CAwCtB;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,CAM7E"}
|
|
@@ -6,27 +6,95 @@ export function getFilePathBasename(filePath) {
|
|
|
6
6
|
const normalizedPath = normalizeFilePath(filePath).replace(/\/+$/, '');
|
|
7
7
|
return normalizedPath.slice(normalizedPath.lastIndexOf('/') + 1);
|
|
8
8
|
}
|
|
9
|
+
/** Relative to one root, or null when the file is not inside it. */
|
|
10
|
+
function relativeToRoot(normalizedFile, rootPath) {
|
|
11
|
+
const normalizedRoot = normalizeFilePath(rootPath).replace(/\/$/, '');
|
|
12
|
+
if (!normalizedRoot)
|
|
13
|
+
return null;
|
|
14
|
+
const windowsDrivePath = /^[A-Za-z]:\//.test(normalizedFile)
|
|
15
|
+
&& /^[A-Za-z]:\//.test(normalizedRoot);
|
|
16
|
+
const comparableFile = windowsDrivePath ? normalizedFile.toLowerCase() : normalizedFile;
|
|
17
|
+
const comparableRoot = windowsDrivePath ? normalizedRoot.toLowerCase() : normalizedRoot;
|
|
18
|
+
if (comparableFile === comparableRoot)
|
|
19
|
+
return '';
|
|
20
|
+
if (comparableFile.startsWith(`${comparableRoot}/`)) {
|
|
21
|
+
return normalizedFile.slice(normalizedRoot.length + 1);
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Heading for each attached root, unique within the root list.
|
|
27
|
+
*
|
|
28
|
+
* Two roots sharing a basename is ordinary -- `app/api` and `infra/api`, or two
|
|
29
|
+
* checkouts of the same repo -- and a bare basename would collapse both into
|
|
30
|
+
* one directory group. Colliding roots grow parent segments until they differ;
|
|
31
|
+
* everything else stays the bare folder name. The primary root has no heading,
|
|
32
|
+
* so it never competes.
|
|
33
|
+
*/
|
|
34
|
+
function attachedRootLabels(roots) {
|
|
35
|
+
const segmentsPerRoot = roots.map((rootPath) => normalizeFilePath(rootPath).replace(/\/+$/, '').split('/').filter(Boolean));
|
|
36
|
+
const labels = roots.map((_, index) => segmentsPerRoot[index].slice(-1).join('/'));
|
|
37
|
+
// Grow every still-colliding label by one more parent segment per pass. A
|
|
38
|
+
// root can only run out of segments once it is the filesystem root, at which
|
|
39
|
+
// point its label is already unique.
|
|
40
|
+
for (let depth = 2; depth <= 16; depth++) {
|
|
41
|
+
const counts = new Map();
|
|
42
|
+
for (let index = 1; index < labels.length; index++) {
|
|
43
|
+
counts.set(labels[index], (counts.get(labels[index]) ?? 0) + 1);
|
|
44
|
+
}
|
|
45
|
+
if ([...counts.values()].every((count) => count < 2))
|
|
46
|
+
break;
|
|
47
|
+
let grew = false;
|
|
48
|
+
for (let index = 1; index < labels.length; index++) {
|
|
49
|
+
if ((counts.get(labels[index]) ?? 0) < 2)
|
|
50
|
+
continue;
|
|
51
|
+
if (segmentsPerRoot[index].length < depth)
|
|
52
|
+
continue;
|
|
53
|
+
labels[index] = segmentsPerRoot[index].slice(-depth).join('/');
|
|
54
|
+
grew = true;
|
|
55
|
+
}
|
|
56
|
+
if (!grew)
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
return labels;
|
|
60
|
+
}
|
|
9
61
|
/**
|
|
10
62
|
* Return a forward-slash path relative to the workspace when the file is inside it.
|
|
11
63
|
* Windows drive paths are compared case-insensitively to match filesystem behavior.
|
|
64
|
+
*
|
|
65
|
+
* A multi-root workspace passes every root, primary first. The primary root
|
|
66
|
+
* still yields a bare relative path, so a single-folder workspace is unchanged;
|
|
67
|
+
* a file in an attached root is prefixed with that root's heading, which is
|
|
68
|
+
* what groups it under its own heading in the directory tree instead of
|
|
69
|
+
* spelling out an absolute path. Deepest matching root wins, so a root checked
|
|
70
|
+
* out inside another root keeps its own prefix.
|
|
12
71
|
*/
|
|
13
72
|
export function getWorkspaceRelativeFilePath(filePath, workspacePath) {
|
|
14
73
|
const normalizedFile = normalizeFilePath(filePath);
|
|
15
|
-
|
|
74
|
+
const roots = typeof workspacePath === 'string' ? [workspacePath] : workspacePath;
|
|
75
|
+
if (!roots || roots.length === 0)
|
|
16
76
|
return normalizedFile;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
77
|
+
let bestIndex = -1;
|
|
78
|
+
let bestRelative = null;
|
|
79
|
+
let bestRootLength = -1;
|
|
80
|
+
roots.forEach((rootPath, index) => {
|
|
81
|
+
const relative = relativeToRoot(normalizedFile, rootPath);
|
|
82
|
+
if (relative === null)
|
|
83
|
+
return;
|
|
84
|
+
const rootLength = normalizeFilePath(rootPath).replace(/\/$/, '').length;
|
|
85
|
+
if (rootLength <= bestRootLength)
|
|
86
|
+
return;
|
|
87
|
+
bestIndex = index;
|
|
88
|
+
bestRelative = relative;
|
|
89
|
+
bestRootLength = rootLength;
|
|
90
|
+
});
|
|
91
|
+
if (bestRelative === null)
|
|
92
|
+
return normalizedFile;
|
|
93
|
+
if (bestIndex === 0)
|
|
94
|
+
return bestRelative;
|
|
95
|
+
// Attached root: name it, so two files called `src/index.ts` in two repos do
|
|
96
|
+
// not collapse into one directory group.
|
|
97
|
+
return `${attachedRootLabels(roots)[bestIndex]}/${bestRelative}`;
|
|
30
98
|
}
|
|
31
99
|
function collapseDirectoryTree(node) {
|
|
32
100
|
node.subdirectories.forEach((subdirectory, key) => {
|
|
@@ -0,0 +1,104 @@
|
|
|
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
|
+
/** Terminal states are everything except `running`. */
|
|
14
|
+
export type GitOperationStatus = 'running' | 'success' | 'error' | 'interrupted';
|
|
15
|
+
/** Who started the command. Absent on journals written before agent activity existed. */
|
|
16
|
+
export type GitOperationSource = 'nimbalyst' | 'agent';
|
|
17
|
+
/**
|
|
18
|
+
* How the command reached Git. `git` is an app-owned direct invocation with a
|
|
19
|
+
* meaningful `args` array; `shell` is an observed command line whose Git segment
|
|
20
|
+
* we detected but did not spawn ourselves.
|
|
21
|
+
*/
|
|
22
|
+
export type GitOperationExecutor = 'git' | 'shell';
|
|
23
|
+
/** An entry exactly as it crosses the IPC boundary (timestamps are epoch ms). */
|
|
24
|
+
export interface GitOperationLogWireEntry {
|
|
25
|
+
id: string;
|
|
26
|
+
timestamp: number;
|
|
27
|
+
updatedAt: number;
|
|
28
|
+
/** Redacted, display-ready command text. */
|
|
29
|
+
command: string;
|
|
30
|
+
executable: 'git';
|
|
31
|
+
args: string[];
|
|
32
|
+
cwd: string;
|
|
33
|
+
status: GitOperationStatus;
|
|
34
|
+
output: string;
|
|
35
|
+
stdout: string;
|
|
36
|
+
stderr: string;
|
|
37
|
+
error?: string;
|
|
38
|
+
exitCode?: number;
|
|
39
|
+
durationMs?: number;
|
|
40
|
+
source?: GitOperationSource;
|
|
41
|
+
executor?: GitOperationExecutor;
|
|
42
|
+
sessionId?: string;
|
|
43
|
+
provider?: string;
|
|
44
|
+
providerToolCallId?: string;
|
|
45
|
+
}
|
|
46
|
+
export type GitOperationLogEvent = {
|
|
47
|
+
workspacePath: string;
|
|
48
|
+
type: 'upsert';
|
|
49
|
+
entry: GitOperationLogWireEntry;
|
|
50
|
+
} | {
|
|
51
|
+
workspacePath: string;
|
|
52
|
+
type: 'clear';
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Window CustomEvent the host dispatches when the user asks to see Git activity
|
|
56
|
+
* detail (for example from the menu-bar indicator's running-command row).
|
|
57
|
+
*
|
|
58
|
+
* The Git panel owns which tab is showing, and that state is private to the
|
|
59
|
+
* extension bundle. Rather than let the host reach into it, the host states the
|
|
60
|
+
* intent and the panel decides how to honour it. `detail.workspacePath` lets a
|
|
61
|
+
* panel bound to a different workspace ignore the request.
|
|
62
|
+
*/
|
|
63
|
+
export declare const GIT_SHOW_OUTPUT_REQUEST_EVENT = "nimbalyst:git-show-output";
|
|
64
|
+
export interface GitShowOutputRequestDetail {
|
|
65
|
+
workspacePath: string;
|
|
66
|
+
}
|
|
67
|
+
/** The minimum shape the selectors below need. */
|
|
68
|
+
interface MergeableEntry {
|
|
69
|
+
id: string;
|
|
70
|
+
timestamp: number | Date;
|
|
71
|
+
updatedAt: number;
|
|
72
|
+
status: GitOperationStatus;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Fill in metadata that predates the field. A journal written before agent
|
|
76
|
+
* activity existed only ever recorded app-owned direct `git` invocations, so
|
|
77
|
+
* that is what an absent `source`/`executor` means -- resolved here at the
|
|
78
|
+
* projection boundary rather than by rewriting the persisted journal.
|
|
79
|
+
*/
|
|
80
|
+
export declare function normalizeGitOperationEntry(entry: GitOperationLogWireEntry): GitOperationLogWireEntry & {
|
|
81
|
+
source: GitOperationSource;
|
|
82
|
+
executor: GitOperationExecutor;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Fold incoming entries into the current list, newest write per id wins.
|
|
86
|
+
*
|
|
87
|
+
* `updatedAt` is the tiebreak rather than arrival order because hydration and
|
|
88
|
+
* the live subscription race: a `git:operation-log:get` response can land after
|
|
89
|
+
* upserts it predates, and applying it blindly would rewind a finished
|
|
90
|
+
* operation back to `running`.
|
|
91
|
+
*/
|
|
92
|
+
export declare function mergeGitOperationEntries<T extends MergeableEntry>(current: T[], incoming: T[]): T[];
|
|
93
|
+
/** Every entry still in flight, oldest first. */
|
|
94
|
+
export declare function selectRunningGitOperations<T extends MergeableEntry>(entries: T[]): T[];
|
|
95
|
+
/**
|
|
96
|
+
* The entry a single-line indicator should name. Newest start wins: when an
|
|
97
|
+
* agent kicks off a fetch while a push is already running, the thing the user
|
|
98
|
+
* just caused is the more informative label.
|
|
99
|
+
*/
|
|
100
|
+
export declare function selectLatestRunningGitOperation<T extends MergeableEntry>(entries: T[]): T | undefined;
|
|
101
|
+
/** The most recently updated entry that has already settled, if any. */
|
|
102
|
+
export declare function selectLatestTerminalGitOperation<T extends MergeableEntry>(entries: T[]): T | undefined;
|
|
103
|
+
export {};
|
|
104
|
+
//# sourceMappingURL=gitOperationLog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitOperationLog.d.ts","sourceRoot":"","sources":["../src/gitOperationLog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,uDAAuD;AACvD,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,aAAa,CAAC;AAEjF,yFAAyF;AACzF,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,OAAO,CAAC;AAEvD;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,KAAK,GAAG,OAAO,CAAC;AAEnD,iFAAiF;AACjF,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,KAAK,CAAC;IAClB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,wBAAwB,CAAA;CAAE,GAC1E;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAE7C;;;;;;;;GAQG;AACH,eAAO,MAAM,6BAA6B,8BAA8B,CAAC;AAEzE,MAAM,WAAW,0BAA0B;IACzC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,kDAAkD;AAClD,UAAU,cAAc;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAMD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,wBAAwB,GAC9B,wBAAwB,GAAG;IAC5B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,QAAQ,EAAE,oBAAoB,CAAC;CAChC,CAMA;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,SAAS,cAAc,EAC/D,OAAO,EAAE,CAAC,EAAE,EACZ,QAAQ,EAAE,CAAC,EAAE,GACZ,CAAC,EAAE,CAWL;AAED,iDAAiD;AACjD,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,cAAc,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAEtF;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAAC,CAAC,SAAS,cAAc,EACtE,OAAO,EAAE,CAAC,EAAE,GACX,CAAC,GAAG,SAAS,CASf;AAED,wEAAwE;AACxE,wBAAgB,gCAAgC,CAAC,CAAC,SAAS,cAAc,EACvE,OAAO,EAAE,CAAC,EAAE,GACX,CAAC,GAAG,SAAS,CASf"}
|
|
@@ -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';
|