@myagentroam/node 0.1.3 → 0.1.6

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.
Files changed (195) hide show
  1. package/README.md +9 -1
  2. package/dist/capabilities.d.ts +2 -0
  3. package/dist/capabilities.js +15 -4
  4. package/dist/claude-agent-sdk.d.ts +4 -16
  5. package/dist/claude-agent-sdk.js +18 -79
  6. package/dist/claude-channel.js +0 -1
  7. package/dist/codex-app-server.d.ts +5 -0
  8. package/dist/codex-app-server.js +26 -5
  9. package/dist/config.d.ts +3 -0
  10. package/dist/config.js +18 -2
  11. package/dist/connector/node-connector-options.d.ts +26 -0
  12. package/dist/connector/node-connector-options.js +1 -0
  13. package/dist/connector/node-operation-router.d.ts +9 -0
  14. package/dist/connector/node-operation-router.js +22 -0
  15. package/dist/connector.d.ts +62 -356
  16. package/dist/connector.js +714 -6176
  17. package/dist/control-outbound-scheduler.d.ts +26 -0
  18. package/dist/control-outbound-scheduler.js +121 -0
  19. package/dist/database.d.ts +4 -0
  20. package/dist/database.js +15 -10
  21. package/dist/event-buffer.js +0 -1
  22. package/dist/fake-runner.js +0 -1
  23. package/dist/health.js +0 -1
  24. package/dist/main.js +6 -1
  25. package/dist/migrations/v001.js +0 -1
  26. package/dist/migrations/v002.js +0 -1
  27. package/dist/migrations/v003.d.ts +4 -0
  28. package/dist/migrations/v003.js +44 -0
  29. package/dist/native-jsonl-reader.d.ts +14 -0
  30. package/dist/native-jsonl-reader.js +97 -0
  31. package/dist/native-session-history.d.ts +41 -4
  32. package/dist/native-session-history.js +340 -159
  33. package/dist/opencode-runtime.d.ts +33 -0
  34. package/dist/opencode-runtime.js +80 -0
  35. package/dist/opencode-server.d.ts +47 -0
  36. package/dist/opencode-server.js +250 -0
  37. package/dist/operational.js +10 -3
  38. package/dist/process-tree.js +0 -1
  39. package/dist/runner/abstract-runner.d.ts +153 -0
  40. package/dist/runner/abstract-runner.js +154 -0
  41. package/dist/runner/claude/managed-run-controller.d.ts +52 -0
  42. package/dist/runner/claude/managed-run-controller.js +326 -0
  43. package/dist/runner/claude-code-runner.d.ts +70 -0
  44. package/dist/runner/claude-code-runner.js +286 -0
  45. package/dist/runner/codex/conversation-parser.d.ts +59 -0
  46. package/dist/runner/codex/conversation-parser.js +816 -0
  47. package/dist/runner/codex/managed-run-controller.d.ts +80 -0
  48. package/dist/runner/codex/managed-run-controller.js +388 -0
  49. package/dist/runner/codex-runner.d.ts +85 -0
  50. package/dist/runner/codex-runner.js +365 -0
  51. package/dist/runner/fake-test-runner.d.ts +26 -0
  52. package/dist/runner/fake-test-runner.js +47 -0
  53. package/dist/runner/opencode/conversation-parser.d.ts +27 -0
  54. package/dist/runner/opencode/conversation-parser.js +217 -0
  55. package/dist/runner/opencode/managed-run-controller.d.ts +76 -0
  56. package/dist/runner/opencode/managed-run-controller.js +451 -0
  57. package/dist/runner/opencode-runner.d.ts +60 -0
  58. package/dist/runner/opencode-runner.js +330 -0
  59. package/dist/runner/runner-registry.d.ts +19 -0
  60. package/dist/runner/runner-registry.js +75 -0
  61. package/dist/runner-command-engine.js +0 -1
  62. package/dist/runner-profiles.d.ts +4 -0
  63. package/dist/runner-profiles.js +76 -3
  64. package/dist/runner-usage.d.ts +2 -2
  65. package/dist/runner-usage.js +3 -6
  66. package/dist/runtime-state.js +26 -14
  67. package/dist/service/attachment-domain-state.d.ts +5 -0
  68. package/dist/service/attachment-domain-state.js +5 -0
  69. package/dist/service/conversation-history-service.d.ts +34 -0
  70. package/dist/service/conversation-history-service.js +158 -0
  71. package/dist/service/external-session-resume-service.d.ts +32 -0
  72. package/dist/service/external-session-resume-service.js +98 -0
  73. package/dist/service/fake-managed-run-service.d.ts +29 -0
  74. package/dist/service/fake-managed-run-service.js +62 -0
  75. package/dist/service/managed-runner-session-service.d.ts +12 -0
  76. package/dist/service/managed-runner-session-service.js +35 -0
  77. package/dist/service/native-session-projection-service.d.ts +51 -0
  78. package/dist/service/native-session-projection-service.js +271 -0
  79. package/dist/service/native-session-watch-service.d.ts +37 -0
  80. package/dist/service/native-session-watch-service.js +150 -0
  81. package/dist/service/node-connection-lifecycle-service.d.ts +37 -0
  82. package/dist/service/node-connection-lifecycle-service.js +85 -0
  83. package/dist/service/node-control-channel.d.ts +32 -0
  84. package/dist/service/node-control-channel.js +85 -0
  85. package/dist/service/node-control-message-service.d.ts +28 -0
  86. package/dist/service/node-control-message-service.js +104 -0
  87. package/dist/service/node-request-service.d.ts +14 -0
  88. package/dist/service/node-request-service.js +50 -0
  89. package/dist/service/node-run-event-bridge.d.ts +40 -0
  90. package/dist/service/node-run-event-bridge.js +83 -0
  91. package/dist/service/node-terminal-channel.d.ts +29 -0
  92. package/dist/service/node-terminal-channel.js +182 -0
  93. package/dist/service/node-upgrade-coordinator.d.ts +29 -0
  94. package/dist/service/node-upgrade-coordinator.js +137 -0
  95. package/dist/service/node-workspace-coordinator.d.ts +32 -0
  96. package/dist/service/node-workspace-coordinator.js +80 -0
  97. package/dist/service/run-attachment-service.d.ts +37 -0
  98. package/dist/service/run-attachment-service.js +160 -0
  99. package/dist/service/run-domain-state.d.ts +4 -0
  100. package/dist/service/run-domain-state.js +4 -0
  101. package/dist/service/run-event-service.d.ts +31 -0
  102. package/dist/service/run-event-service.js +102 -0
  103. package/dist/service/run-workbench-service.d.ts +27 -0
  104. package/dist/service/run-workbench-service.js +113 -0
  105. package/dist/service/runner-channel-message-service.d.ts +13 -0
  106. package/dist/service/runner-channel-message-service.js +20 -0
  107. package/dist/service/runner-interaction-service.d.ts +40 -0
  108. package/dist/service/runner-interaction-service.js +246 -0
  109. package/dist/service/runner-service.d.ts +44 -0
  110. package/dist/service/runner-service.js +68 -0
  111. package/dist/service/session-catalog-service.d.ts +45 -0
  112. package/dist/service/session-catalog-service.js +224 -0
  113. package/dist/service/session-command-service.d.ts +23 -0
  114. package/dist/service/session-command-service.js +69 -0
  115. package/dist/service/session-context-service.d.ts +34 -0
  116. package/dist/service/session-context-service.js +87 -0
  117. package/dist/service/session-domain-state.d.ts +8 -0
  118. package/dist/service/session-domain-state.js +8 -0
  119. package/dist/service/session-identity-service.d.ts +24 -0
  120. package/dist/service/session-identity-service.js +86 -0
  121. package/dist/service/session-lifecycle-service.d.ts +31 -0
  122. package/dist/service/session-lifecycle-service.js +242 -0
  123. package/dist/service/session-message-service.d.ts +33 -0
  124. package/dist/service/session-message-service.js +157 -0
  125. package/dist/service/session-presentation-service.d.ts +33 -0
  126. package/dist/service/session-presentation-service.js +36 -0
  127. package/dist/service/session-query-service.d.ts +31 -0
  128. package/dist/service/session-query-service.js +77 -0
  129. package/dist/service/terminal-relay-state.d.ts +6 -0
  130. package/dist/service/terminal-relay-state.js +3 -0
  131. package/dist/service/terminal-service.d.ts +12 -0
  132. package/dist/service/terminal-service.js +52 -0
  133. package/dist/service/workbench-event-service.d.ts +21 -0
  134. package/dist/service/workbench-event-service.js +53 -0
  135. package/dist/service/workbench-manifest-service.d.ts +89 -0
  136. package/dist/service/workbench-manifest-service.js +70 -0
  137. package/dist/service/workspace-change-service.d.ts +9 -0
  138. package/dist/service/workspace-change-service.js +86 -0
  139. package/dist/service/workspace-content-search-service.d.ts +14 -0
  140. package/dist/service/workspace-content-search-service.js +477 -0
  141. package/dist/service/workspace-domain-state.d.ts +75 -0
  142. package/dist/service/workspace-domain-state.js +40 -0
  143. package/dist/service/workspace-file-service.d.ts +17 -0
  144. package/dist/service/workspace-file-service.js +109 -0
  145. package/dist/service/workspace-queue-workbench-service.d.ts +55 -0
  146. package/dist/service/workspace-queue-workbench-service.js +226 -0
  147. package/dist/service/workspace-service.d.ts +15 -0
  148. package/dist/service/workspace-service.js +67 -0
  149. package/dist/service/workspace-session-service.d.ts +23 -0
  150. package/dist/service/workspace-session-service.js +139 -0
  151. package/dist/service/workspace-upload-service.d.ts +37 -0
  152. package/dist/service/workspace-upload-service.js +240 -0
  153. package/dist/service/workspace-watch-service.d.ts +18 -0
  154. package/dist/service/workspace-watch-service.js +120 -0
  155. package/dist/service/workspace-workbench-service.d.ts +47 -0
  156. package/dist/service/workspace-workbench-service.js +223 -0
  157. package/dist/service.js +2 -3
  158. package/dist/storage.js +0 -1
  159. package/dist/supervisor.d.ts +1 -0
  160. package/dist/supervisor.js +154 -0
  161. package/dist/terminal.d.ts +1 -0
  162. package/dist/terminal.js +1 -2
  163. package/dist/util/node-operation-parsers.d.ts +92 -0
  164. package/dist/util/node-operation-parsers.js +382 -0
  165. package/dist/util/runner-native-session-parsers.d.ts +72 -0
  166. package/dist/util/runner-native-session-parsers.js +381 -0
  167. package/dist/util/secret-environment.d.ts +1 -0
  168. package/dist/util/secret-environment.js +25 -0
  169. package/dist/workspace.d.ts +62 -2
  170. package/dist/workspace.js +539 -57
  171. package/package.json +3 -2
  172. package/dist/capabilities.js.map +0 -1
  173. package/dist/claude-agent-sdk.js.map +0 -1
  174. package/dist/claude-channel.js.map +0 -1
  175. package/dist/codex-app-server.js.map +0 -1
  176. package/dist/config.js.map +0 -1
  177. package/dist/connector.js.map +0 -1
  178. package/dist/database.js.map +0 -1
  179. package/dist/event-buffer.js.map +0 -1
  180. package/dist/fake-runner.js.map +0 -1
  181. package/dist/health.js.map +0 -1
  182. package/dist/main.js.map +0 -1
  183. package/dist/migrations/v001.js.map +0 -1
  184. package/dist/migrations/v002.js.map +0 -1
  185. package/dist/native-session-history.js.map +0 -1
  186. package/dist/operational.js.map +0 -1
  187. package/dist/process-tree.js.map +0 -1
  188. package/dist/runner-command-engine.js.map +0 -1
  189. package/dist/runner-profiles.js.map +0 -1
  190. package/dist/runner-usage.js.map +0 -1
  191. package/dist/runtime-state.js.map +0 -1
  192. package/dist/service.js.map +0 -1
  193. package/dist/storage.js.map +0 -1
  194. package/dist/terminal.js.map +0 -1
  195. package/dist/workspace.js.map +0 -1
@@ -0,0 +1,52 @@
1
+ import { parseSecretEnvironment } from '../util/secret-environment.js';
2
+ export class TerminalService {
3
+ database;
4
+ terminalManager;
5
+ constructor(database, terminalManager) {
6
+ this.database = database;
7
+ this.terminalManager = terminalManager;
8
+ }
9
+ operations() {
10
+ return {
11
+ 'terminal.open': (data) => this.open(data),
12
+ 'terminal.list': () => ({ terminals: this.database().listTerminalSessions() }),
13
+ 'terminal.close': (data) => this.close(data),
14
+ 'terminal.attach.authorize': (data) => this.authorizeAttach(data)
15
+ };
16
+ }
17
+ open(data) {
18
+ if (data === null || typeof data !== 'object')
19
+ throw new Error('TERMINAL_OPEN_INVALID');
20
+ const input = data;
21
+ const secretEnvironment = parseSecretEnvironment(input.secretEnvironment);
22
+ let cwd;
23
+ if (input.workspaceId !== undefined) {
24
+ if (typeof input.workspaceId !== 'string')
25
+ throw new Error('TERMINAL_OPEN_INVALID');
26
+ const workspace = this.database().getWorkspace(input.workspaceId);
27
+ if (workspace === undefined)
28
+ throw new Error('WORKSPACE_NOT_FOUND');
29
+ cwd = workspace.path;
30
+ }
31
+ return {
32
+ terminal: this.terminalManager.open({
33
+ ...input,
34
+ workspaceId: typeof input.workspaceId === 'string' ? input.workspaceId : null,
35
+ environment: secretEnvironment,
36
+ ...(cwd === undefined ? {} : { cwd })
37
+ })
38
+ };
39
+ }
40
+ async close(data) {
41
+ const input = data;
42
+ if (typeof input.terminalId !== 'string')
43
+ throw new Error('TERMINAL_NOT_FOUND');
44
+ return { terminal: await this.terminalManager.close(input.terminalId) };
45
+ }
46
+ authorizeAttach(data) {
47
+ if (data === null || typeof data !== 'object')
48
+ throw new Error('TERMINAL_ATTACH_INVALID');
49
+ const attachment = this.terminalManager.authorizeAttach(data);
50
+ return { attachment, terminal: this.terminalManager.get(attachment.terminalId) };
51
+ }
52
+ }
@@ -0,0 +1,21 @@
1
+ import type { NodeEnvelope, WorkbenchEvent, WorkbenchEventCategory } from '@myagentroam/protocol';
2
+ import type { NodeOperationHandler } from '../connector/node-operation-router.js';
3
+ export declare class WorkbenchEventService {
4
+ private readonly send;
5
+ private readonly accepts;
6
+ private readonly buffer;
7
+ private sequence;
8
+ private readonly history;
9
+ constructor(send: (envelope: NodeEnvelope) => void, accepts: (category: WorkbenchEventCategory, payload: unknown) => boolean);
10
+ emit(category: WorkbenchEventCategory, payload: unknown): void;
11
+ read(after: number): {
12
+ readonly events: readonly WorkbenchEvent[];
13
+ readonly latestSequence: number;
14
+ readonly resyncRequired: boolean;
15
+ };
16
+ operations(): Readonly<Record<string, NodeOperationHandler>>;
17
+ snapshotSequence(): number;
18
+ acknowledge(replyTo: string | undefined): boolean;
19
+ replay(): void;
20
+ get pendingCount(): number;
21
+ }
@@ -0,0 +1,53 @@
1
+ import { ReliableWorkbenchEventBuffer } from '../event-buffer.js';
2
+ export class WorkbenchEventService {
3
+ send;
4
+ accepts;
5
+ buffer = new ReliableWorkbenchEventBuffer();
6
+ sequence = 0;
7
+ history = [];
8
+ constructor(send, accepts) {
9
+ this.send = send;
10
+ this.accepts = accepts;
11
+ }
12
+ emit(category, payload) {
13
+ if (!this.accepts(category, payload))
14
+ return;
15
+ const event = { sequence: ++this.sequence, category, payload };
16
+ this.history.push(event);
17
+ if (this.history.length > 1_000)
18
+ this.history.shift();
19
+ this.send(this.buffer.queue(event));
20
+ }
21
+ read(after) {
22
+ const first = this.history[0]?.sequence;
23
+ const reset = after > this.sequence || (first !== undefined && after < first - 1);
24
+ return {
25
+ events: reset ? [] : this.history.filter((event) => event.sequence > after),
26
+ latestSequence: this.sequence,
27
+ resyncRequired: reset
28
+ };
29
+ }
30
+ operations() {
31
+ return {
32
+ 'workbench.events.read': (data) => {
33
+ const afterValue = data?.after;
34
+ const after = typeof afterValue === 'number' && Number.isInteger(afterValue) && afterValue >= 0
35
+ ? afterValue
36
+ : 0;
37
+ return this.read(after);
38
+ }
39
+ };
40
+ }
41
+ snapshotSequence() {
42
+ return this.sequence;
43
+ }
44
+ acknowledge(replyTo) {
45
+ return this.buffer.acknowledge(replyTo);
46
+ }
47
+ replay() {
48
+ this.buffer.replay(this.send);
49
+ }
50
+ get pendingCount() {
51
+ return this.buffer.size;
52
+ }
53
+ }
@@ -0,0 +1,89 @@
1
+ import type { NodeCapabilities } from '@myagentroam/protocol';
2
+ import type { TerminalManager } from '../terminal.js';
3
+ import type { RunnerService } from './runner-service.js';
4
+ interface WorkbenchManifestServiceOptions {
5
+ readonly capabilities: () => NodeCapabilities;
6
+ readonly runners: RunnerService;
7
+ readonly terminals: TerminalManager;
8
+ }
9
+ /** Builds the capability-driven Workbench contract exposed by this Node. */
10
+ export declare class WorkbenchManifestService {
11
+ private readonly options;
12
+ constructor(options: WorkbenchManifestServiceOptions);
13
+ read(): Promise<{
14
+ manifestVersion: 1;
15
+ revision: number;
16
+ observedAt: number;
17
+ platform: "linux" | "windows";
18
+ architecture: string;
19
+ conversation: {
20
+ available: boolean;
21
+ reasonCode: null;
22
+ itemVersions: number[];
23
+ supportsSessionCursor: boolean;
24
+ supportsWorkspaceActivityCursor: boolean;
25
+ supportsHistoryPaging: boolean;
26
+ supportsItemFinalSnapshots: boolean;
27
+ maxPageSize: number;
28
+ };
29
+ runners: readonly {
30
+ runner: "codex" | "claude-code" | "opencode";
31
+ capabilities: string[];
32
+ models: {
33
+ id: string;
34
+ label: string;
35
+ supportedEfforts: string[];
36
+ }[];
37
+ accessOptions: {
38
+ id: string;
39
+ label: string;
40
+ description: string;
41
+ }[];
42
+ commands: {
43
+ id: string;
44
+ available: boolean;
45
+ runner: "codex" | "claude-code" | "opencode";
46
+ reasonCode: string | null;
47
+ label: string;
48
+ description: string;
49
+ inputHint: string;
50
+ source: "CODEX_APP_SERVER" | "CLAUDE_AGENT_SDK" | "OPENCODE_SERVER";
51
+ interaction: "RUNNER_TEXT" | "IMMEDIATE_ACTION" | "TOGGLE" | "VALUE";
52
+ stateLabel?: string | undefined;
53
+ }[];
54
+ }[];
55
+ files: {
56
+ available: boolean;
57
+ reasonCode: null;
58
+ supportsList: boolean;
59
+ supportsReadRange: boolean;
60
+ supportsSearch: boolean;
61
+ maxDirectoryPageSize: number;
62
+ maxReadBytes: number;
63
+ maxSearchResults: number;
64
+ };
65
+ git: {
66
+ available: boolean;
67
+ reasonCode: null;
68
+ supportsCurrentChanges: boolean;
69
+ supportsTurnChanges: boolean;
70
+ supportsHistory: boolean;
71
+ maxDiffBytes: number;
72
+ };
73
+ terminal: {
74
+ profiles: readonly Pick<import("../terminal.js").TerminalProfile, "id" | "label" | "isDefault">[];
75
+ maxTerminals: number;
76
+ maxTerminalsPerWorkspace: number;
77
+ maxReplayBytes: number;
78
+ reconnectWindowMs: number;
79
+ available: boolean;
80
+ reasonCode: null;
81
+ supportsPty: boolean;
82
+ supportsConPty: boolean;
83
+ supportsReplay: boolean;
84
+ supportsReadonlyAttach: boolean;
85
+ supportsTakeover: boolean;
86
+ };
87
+ }>;
88
+ }
89
+ export {};
@@ -0,0 +1,70 @@
1
+ function revisionFor(capabilities) {
2
+ const source = JSON.stringify({
3
+ platform: capabilities.platform,
4
+ architecture: capabilities.architecture,
5
+ codex: capabilities.codex,
6
+ claudeCode: capabilities.claudeCode,
7
+ openCode: capabilities.openCode
8
+ });
9
+ let hash = 2_166_136_261;
10
+ for (const character of source)
11
+ hash = Math.imul(hash ^ character.charCodeAt(0), 16_777_619);
12
+ return hash >>> 0;
13
+ }
14
+ /** Builds the capability-driven Workbench contract exposed by this Node. */
15
+ export class WorkbenchManifestService {
16
+ options;
17
+ constructor(options) {
18
+ this.options = options;
19
+ }
20
+ async read() {
21
+ const capabilities = this.options.capabilities();
22
+ return {
23
+ manifestVersion: 1,
24
+ revision: revisionFor(capabilities),
25
+ observedAt: Date.now(),
26
+ platform: capabilities.platform,
27
+ architecture: capabilities.architecture,
28
+ conversation: {
29
+ available: true,
30
+ reasonCode: null,
31
+ itemVersions: [1],
32
+ supportsSessionCursor: true,
33
+ supportsWorkspaceActivityCursor: true,
34
+ supportsHistoryPaging: true,
35
+ supportsItemFinalSnapshots: true,
36
+ maxPageSize: 500
37
+ },
38
+ runners: await this.options.runners.profiles(),
39
+ files: {
40
+ available: true,
41
+ reasonCode: null,
42
+ supportsList: true,
43
+ supportsReadRange: true,
44
+ supportsSearch: true,
45
+ maxDirectoryPageSize: 200,
46
+ maxReadBytes: 512 * 1024,
47
+ maxSearchResults: 200
48
+ },
49
+ git: {
50
+ available: true,
51
+ reasonCode: null,
52
+ supportsCurrentChanges: true,
53
+ supportsTurnChanges: true,
54
+ supportsHistory: true,
55
+ maxDiffBytes: 512 * 1024
56
+ },
57
+ terminal: {
58
+ available: true,
59
+ reasonCode: null,
60
+ supportsPty: capabilities.platform === 'linux',
61
+ supportsConPty: capabilities.platform === 'windows',
62
+ supportsReplay: true,
63
+ supportsReadonlyAttach: true,
64
+ supportsTakeover: true,
65
+ ...this.options.terminals.limits(),
66
+ profiles: this.options.terminals.availableProfiles()
67
+ }
68
+ };
69
+ }
70
+ }
@@ -0,0 +1,9 @@
1
+ import type { NodeWorkspace } from '../database.js';
2
+ import { WorkspaceDomainState } from './workspace-domain-state.js';
3
+ export declare class WorkspaceChangeService {
4
+ private readonly state;
5
+ constructor(state: WorkspaceDomainState);
6
+ invalidate(workspaceId: string): void;
7
+ clear(): void;
8
+ current(workspace: NodeWorkspace): Promise<unknown>;
9
+ }
@@ -0,0 +1,86 @@
1
+ import { basename, posix } from 'node:path';
2
+ import { isWorkspaceChangeVisible, listInitializedSubmodulePaths, readCurrentChangesSummary, resolveGitRepository } from '../workspace.js';
3
+ const CACHE_TTL_MS = 5_000;
4
+ export class WorkspaceChangeService {
5
+ state;
6
+ constructor(state) {
7
+ this.state = state;
8
+ }
9
+ invalidate(workspaceId) {
10
+ this.state.changesReads.delete(workspaceId);
11
+ this.state.changesCache.delete(workspaceId);
12
+ this.state.changesVersions.set(workspaceId, (this.state.changesVersions.get(workspaceId) ?? 0) + 1);
13
+ }
14
+ clear() {
15
+ this.state.changesReads.clear();
16
+ this.state.changesCache.clear();
17
+ this.state.changesVersions.clear();
18
+ }
19
+ async current(workspace) {
20
+ if (workspace.kind !== 'GIT_WORKSPACE')
21
+ throw new Error('WORKSPACE_NOT_GIT');
22
+ const cached = this.state.changesCache.get(workspace.id);
23
+ if (cached !== undefined && cached.expiresAt > Date.now())
24
+ return cached.value;
25
+ const existing = this.state.changesReads.get(workspace.id);
26
+ if (existing !== undefined)
27
+ return existing;
28
+ const version = this.state.changesVersions.get(workspace.id) ?? 0;
29
+ const request = this.state.changesLimiter.run(async () => {
30
+ const paths = ['', ...(await listInitializedSubmodulePaths(workspace.path))];
31
+ const readRepository = async (repositoryPath) => {
32
+ const repository = repositoryPath === ''
33
+ ? workspace.path
34
+ : await resolveGitRepository(workspace.path, repositoryPath);
35
+ const summary = await readCurrentChangesSummary(repository);
36
+ const changes = (await Promise.all(summary.changes.map(async (change) => ({
37
+ change,
38
+ visible: await isWorkspaceChangeVisible(repository, change.path)
39
+ }))))
40
+ .filter(({ visible }) => visible)
41
+ .map(({ change }) => change);
42
+ return {
43
+ repositoryPath,
44
+ repositoryName: repositoryPath === '' ? basename(repository) : posix.basename(repositoryPath),
45
+ branch: summary.branch,
46
+ changes
47
+ };
48
+ };
49
+ const root = await readRepository('');
50
+ const children = (await Promise.all(paths.slice(1).map(async (path) => {
51
+ try {
52
+ return await readRepository(path);
53
+ }
54
+ catch {
55
+ return undefined;
56
+ }
57
+ }))).filter((value) => value !== undefined);
58
+ const decorate = (change) => ({
59
+ ...change,
60
+ additions: null,
61
+ deletions: null,
62
+ binary: false,
63
+ diffAvailable: change.state !== 'UNTRACKED'
64
+ });
65
+ const value = {
66
+ branch: root.branch,
67
+ changes: root.changes.map(decorate),
68
+ repositories: [root, ...children].map((repository) => ({
69
+ ...repository,
70
+ changes: repository.changes.map(decorate)
71
+ }))
72
+ };
73
+ if ((this.state.changesVersions.get(workspace.id) ?? 0) === version)
74
+ this.state.changesCache.set(workspace.id, { value, expiresAt: Date.now() + CACHE_TTL_MS });
75
+ return value;
76
+ });
77
+ this.state.changesReads.set(workspace.id, request);
78
+ try {
79
+ return await request;
80
+ }
81
+ finally {
82
+ if (this.state.changesReads.get(workspace.id) === request)
83
+ this.state.changesReads.delete(workspace.id);
84
+ }
85
+ }
86
+ }
@@ -0,0 +1,14 @@
1
+ import type { WorkspaceContentSearch } from '@myagentroam/protocol';
2
+ import type { NodeWorkspace } from '../database.js';
3
+ import type { WorkspaceFileService } from './workspace-file-service.js';
4
+ export declare class WorkspaceContentSearchService {
5
+ private readonly files;
6
+ private readonly platform;
7
+ private readonly pending;
8
+ constructor(files: WorkspaceFileService, platform?: NodeJS.Platform);
9
+ search(workspace: NodeWorkspace, input: Record<string, unknown>): Promise<WorkspaceContentSearch>;
10
+ private perform;
11
+ private engines;
12
+ private candidates;
13
+ private nativeSearch;
14
+ }