@orion-agents/orion-code 0.3.4 → 0.3.7

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 (86) hide show
  1. package/CHANGELOG.md +124 -0
  2. package/README.md +61 -5
  3. package/README.zh-CN.md +7 -3
  4. package/dist/commands/context-tool-command-handlers.js +1 -5
  5. package/dist/commands/registry.js +1 -4
  6. package/dist/harness/intent.js +69 -16
  7. package/dist/harness/turn-summary.js +3 -1
  8. package/dist/memory/embeddings.js +2 -3
  9. package/dist/memory/prompts.js +1 -1
  10. package/dist/memory/relevant-finder.js +125 -15
  11. package/dist/memory/vector-store.js +13 -8
  12. package/dist/migration/migrate.js +8 -12
  13. package/dist/runtime/composer/history.js +1 -3
  14. package/dist/runtime/composer/layout.js +7 -4
  15. package/dist/runtime/legacy-thread-materializer.d.ts +3 -1
  16. package/dist/runtime/legacy-thread-materializer.js +15 -3
  17. package/dist/runtime/product-bootstrap.d.ts +12 -0
  18. package/dist/runtime/product-bootstrap.js +37 -22
  19. package/dist/runtime/rich-text/ansi-parser.js +12 -2
  20. package/dist/runtime/rich-text/layout.js +15 -19
  21. package/dist/runtime/subagents/budget.js +4 -1
  22. package/dist/runtime/subagents/policy.js +11 -4
  23. package/dist/runtime/subagents/provider-gate.js +6 -4
  24. package/dist/runtime/subagents/research-quality.js +3 -1
  25. package/dist/runtime/subagents/research-renderer.js +9 -2
  26. package/dist/runtime/subagents/result-parser.js +18 -7
  27. package/dist/runtime/thread-event-store.d.ts +5 -3
  28. package/dist/runtime/thread-event-store.js +29 -8
  29. package/dist/runtime/thread-projection.d.ts +17 -0
  30. package/dist/runtime/thread-projection.js +42 -1
  31. package/dist/runtime/tool-output-presentation.js +7 -7
  32. package/dist/runtime/turn-controller.js +1 -2
  33. package/dist/services/auth/auth.js +1 -4
  34. package/dist/services/auth/aws.js +24 -14
  35. package/dist/services/auto-fix/autoFixRunner.js +1 -1
  36. package/dist/services/auto-fix/index.d.ts +1 -1
  37. package/dist/services/diagnostic-tracking/diagnosticTracking.js +4 -2
  38. package/dist/services/diagnostic-tracking/index.d.ts +1 -1
  39. package/dist/services/effort.js +1 -9
  40. package/dist/services/file-glob.js +3 -4
  41. package/dist/services/mcp/transports.js +4 -4
  42. package/dist/services/model-catalog.js +179 -30
  43. package/dist/services/model-context.js +1 -1
  44. package/dist/services/provider-resilience/stream-recovery.js +1 -3
  45. package/dist/services/session-storage.d.ts +28 -3
  46. package/dist/services/session-storage.js +70 -6
  47. package/dist/services/smart-routing.js +19 -11
  48. package/dist/services/verification-profile.js +17 -22
  49. package/dist/services/web-search-provider.js +21 -9
  50. package/dist/services/workspace-diff.js +10 -4
  51. package/dist/skills/builtin/code-review/SKILL.md +1 -1
  52. package/dist/skills/builtin/security-check/SKILL.md +1 -1
  53. package/dist/skills/builtin/test-gen/SKILL.md +1 -1
  54. package/dist/terminal-ui/editor.js +6 -2
  55. package/dist/terminal-ui/output-queue.js +9 -3
  56. package/dist/tools/lsp.js +12 -6
  57. package/dist/tui-core/frame.js +9 -7
  58. package/dist/tui-ui/transcript-cache.js +6 -6
  59. package/dist/tui-ui/transcript-inspector-surface.js +4 -1
  60. package/dist/tui-ui/transcript-inspector.js +3 -8
  61. package/dist/ui/box.js +14 -7
  62. package/dist/ui/markdown.js +4 -2
  63. package/dist/ui/shared/input-frame.js +12 -8
  64. package/dist/ui/stream-markdown.js +1 -1
  65. package/dist/ui/tool-preview.js +11 -3
  66. package/dist/ui/user-input.js +16 -10
  67. package/dist/web/protocol.d.ts +2 -0
  68. package/dist/web/protocol.js +1 -0
  69. package/dist/web/server.js +69 -0
  70. package/dist/web/session-runtime-registry.d.ts +14 -0
  71. package/dist/web/session-runtime-registry.js +23 -0
  72. package/dist/web/workbench-controller.d.ts +55 -0
  73. package/dist/web/workbench-controller.js +224 -14
  74. package/dist/web-client/assets/{DiffViewer-D6mG729y.js → DiffViewer-DqbZ02RN.js} +1 -1
  75. package/dist/web-client/assets/{FilesPanel-CCDoAZ1J.js → FilesPanel-Bu1Ab2kJ.js} +1 -1
  76. package/dist/web-client/assets/{GitPanel-DtNgiH7A.js → GitPanel-BixIWb4k.js} +1 -1
  77. package/dist/web-client/assets/ReviewPanel-DsqJpku_.js +1 -0
  78. package/dist/web-client/assets/{TerminalPanel-CNxMaBLp.js → TerminalPanel-DdjQP2mp.js} +1 -1
  79. package/dist/web-client/assets/index-30GT9Vnx.js +17 -0
  80. package/dist/web-client/assets/index-DQfpqPTD.css +1 -0
  81. package/dist/web-client/index.html +2 -2
  82. package/npm-shrinkwrap.json +356 -120
  83. package/package.json +3 -1
  84. package/dist/web-client/assets/ReviewPanel-CKEBSt6P.js +0 -1
  85. package/dist/web-client/assets/index-BBvNg3By.css +0 -1
  86. package/dist/web-client/assets/index-C6TDJwMC.js +0 -17
@@ -26,6 +26,13 @@ export declare class WebWorkbenchController {
26
26
  private readonly createRuntime;
27
27
  private readonly createSessionRuntime;
28
28
  private sessionRegistry;
29
+ /**
30
+ * Workspace-scoped shared kernels owned by this Host. Control planes and
31
+ * Session actors both borrow from this pool, so a Workspace Context switch
32
+ * never tears down kernels that resident actors still reference. The pool is
33
+ * released only during Host shutdown.
34
+ */
35
+ private readonly workspaceKernels;
29
36
  private readonly workspaceRegistry;
30
37
  readonly terminalManager: TerminalManagerV1;
31
38
  private readonly mutationResults;
@@ -52,6 +59,13 @@ export declare class WebWorkbenchController {
52
59
  private contextTransitionReserved;
53
60
  private closed;
54
61
  private shutdownResult?;
62
+ /**
63
+ * Host-observed Web activity counters. Exposed through diagnostics() so E2E
64
+ * and the diagnostics panel can prove that a pure Session selection issues
65
+ * no control-plane reinstall (controlPlaneInstalls delta 0) and that
66
+ * snapshots stay bounded and fast (snapshotTotalMs / snapshotLastMs).
67
+ */
68
+ private readonly sessionActivity;
55
69
  private workspaceWatchers;
56
70
  private resourceInvalidationTimer?;
57
71
  private constructor();
@@ -64,11 +78,15 @@ export declare class WebWorkbenchController {
64
78
  settings(): WebSettingsSnapshotV1;
65
79
  listWorkspaces(context?: WebContextGuardV1): readonly WebWorkspaceSummaryV1[];
66
80
  listWorkspaceSessions(workspaceId: string, context?: WebContextGuardV1): readonly WebSessionSummaryV1[];
81
+ /** Archived sessions of a Workspace (v0.3.7), newest archive first. */
82
+ listArchivedWorkspaceSessions(workspaceId: string, context?: WebContextGuardV1): readonly WebSessionSummaryV1[];
67
83
  workspaceProjectSummary(workspaceId: string, context?: WebContextGuardV1): Promise<WebWorkspaceProjectSummaryV1>;
68
84
  setWorkspacePinned(workspaceId: string, pinned: boolean, context: WebContextGuardV1): WebWorkspaceSummaryV1;
69
85
  removeWorkspace(workspaceId: string, context: WebContextGuardV1): void;
70
86
  listSessions(context?: WebContextGuardV1): readonly WebSessionSummaryV1[];
71
87
  sessionSnapshot(sessionId: string, cursor?: string, pageSize?: number, tail?: boolean, context?: WebContextGuardV1): WebSessionSnapshotV1;
88
+ private snapshotSessionV1;
89
+ private recordSessionSnapshotActivity;
72
90
  composerState(sessionId: string, context?: WebContextGuardV1): WebComposerControlStateV1;
73
91
  sessionRuntimeSummary(sessionId: string): WebSessionRuntimeSummaryV1;
74
92
  waitForSessionIdle(sessionId: string): Promise<void>;
@@ -90,6 +108,22 @@ export declare class WebWorkbenchController {
90
108
  createSession(name?: string, context?: WebContextGuardV1): Promise<WebSessionSummaryV1>;
91
109
  activateSession(sessionId: string, context?: WebContextGuardV1): Promise<WebCommandResultV1>;
92
110
  renameSession(sessionId: string, name: string, context?: WebContextGuardV1): WebSessionSummaryV1;
111
+ setSessionTags(sessionId: string, tags: unknown, context?: WebContextGuardV1): WebSessionSummaryV1;
112
+ archiveSession(sessionId: string, context?: WebContextGuardV1): WebSessionSummaryV1;
113
+ restoreSession(sessionId: string, context?: WebContextGuardV1): WebSessionSummaryV1;
114
+ deleteSession(sessionId: string, context?: WebContextGuardV1): {
115
+ readonly deleted: boolean;
116
+ };
117
+ /**
118
+ * A busy Session (starting / queued / running / waiting approval / stopping)
119
+ * must not be archived or deleted while its actor is doing work.
120
+ */
121
+ private assertSessionNotBusy;
122
+ /**
123
+ * Deletion removes files under the Session while a resident actor may still
124
+ * hold them open — require that no actor exists at all (phase 'cold').
125
+ */
126
+ private assertSessionHasNoActor;
93
127
  switchWorkspace(path: string, context: WebContextGuardV1): Promise<void>;
94
128
  activateContext(input: Omit<WebContextActivateRequestV1, 'requestId'>): Promise<void>;
95
129
  dispatch(raw: unknown): Promise<WebCommandResultV1>;
@@ -102,6 +136,27 @@ export declare class WebWorkbenchController {
102
136
  diagnostics(context?: WebContextGuardV1): Promise<Record<string, unknown>>;
103
137
  shutdown(): Promise<void>;
104
138
  private shutdownOwnedResources;
139
+ /**
140
+ * Return the workspace kernel for `cwd`, creating and pooling one on first
141
+ * use. Control planes and Session actors borrow the same kernel instance per
142
+ * canonical Workspace; the pool is released only when the Host shuts down.
143
+ */
144
+ private workspaceKernelFor;
145
+ /**
146
+ * Settings invalidations from pooled kernels are only forwarded while their
147
+ * Workspace is the active Context. A background Workspace's coordinator
148
+ * keeps watching its own durable file; its next activation publishes a fresh
149
+ * Settings document through `emitSettingsWorkspaceChange()`.
150
+ */
151
+ private onWorkspaceKernelSettingsInvalidated;
152
+ /**
153
+ * Release the Host owner seat on every pooled kernel. Runtime shutdowns have
154
+ * already disposed their Settings participants (actors first, then the
155
+ * active control plane), so an unowned kernel with zero participants closes
156
+ * its Settings coordinator here. A kernel that still has a running actor
157
+ * participant survives until that actor actually terminates.
158
+ */
159
+ private releaseWorkspaceKernels;
105
160
  private createSessionRegistry;
106
161
  private createSessionActor;
107
162
  private closeSessionActor;
@@ -43,6 +43,13 @@ const CONTEXT_TRANSITION_MUTATIONS = new Set(['context.activate', 'workspace.act
43
43
  class WebWorkbenchController {
44
44
  constructor(options) {
45
45
  this.activeOrionRuntimes = new Map();
46
+ /**
47
+ * Workspace-scoped shared kernels owned by this Host. Control planes and
48
+ * Session actors both borrow from this pool, so a Workspace Context switch
49
+ * never tears down kernels that resident actors still reference. The pool is
50
+ * released only during Host shutdown.
51
+ */
52
+ this.workspaceKernels = new Map();
46
53
  this.mutationResults = new Map();
47
54
  this.sessionViews = new Map();
48
55
  this.sessionViewBytes = 0;
@@ -57,6 +64,20 @@ class WebWorkbenchController {
57
64
  this.activeMutationCount = 0;
58
65
  this.contextTransitionReserved = false;
59
66
  this.closed = false;
67
+ /**
68
+ * Host-observed Web activity counters. Exposed through diagnostics() so E2E
69
+ * and the diagnostics panel can prove that a pure Session selection issues
70
+ * no control-plane reinstall (controlPlaneInstalls delta 0) and that
71
+ * snapshots stay bounded and fast (snapshotTotalMs / snapshotLastMs).
72
+ */
73
+ this.sessionActivity = {
74
+ snapshotRequests: 0,
75
+ snapshotFailures: 0,
76
+ snapshotTotalMs: 0,
77
+ snapshotLastMs: 0,
78
+ controlPlaneInstalls: 0,
79
+ controlPlaneShutdowns: 0,
80
+ };
60
81
  this.workspaceWatchers = [];
61
82
  this.workspaceValue = canonicalDirectory(options.cwd);
62
83
  this.eventHub = options.eventHub ?? new event_hub_1.WebEventHub();
@@ -80,6 +101,10 @@ class WebWorkbenchController {
80
101
  options.createRuntime ??
81
102
  (cwd => (0, product_bootstrap_1.createProductUiRuntime)({
82
103
  cwd,
104
+ // Borrow the workspace kernel from the Host-owned pool so the
105
+ // control plane shares config/Tool/MCP/Settings services with the
106
+ // resident Session actors of the same Workspace.
107
+ workspaceRuntimeKernel: this.workspaceKernelFor(cwd),
83
108
  workspaceMutationCoordinator: this.workspaceMutations,
84
109
  shutdownReason: 'Orion Web Workbench shutdown',
85
110
  onActiveSessionRuntime: (runtime, sessionId, activation) => this.observeThreadRuntime(runtime, sessionId, activation),
@@ -99,7 +124,9 @@ class WebWorkbenchController {
99
124
  options.createRuntime ??
100
125
  (cwd => (0, product_bootstrap_1.createProductUiRuntime)({
101
126
  cwd,
102
- workspaceRuntimeKernel: this.runtimeValue.workspaceRuntimeKernel,
127
+ // Session actors must keep the kernel of the Workspace they were
128
+ // created for, never the currently active control plane's kernel.
129
+ workspaceRuntimeKernel: this.workspaceKernelFor(cwd),
103
130
  workspaceMutationCoordinator: this.workspaceMutations,
104
131
  shutdownReason: 'Orion Web Session actor shutdown',
105
132
  onActiveSessionRuntime: (runtime, sessionId, activation) => this.observeThreadRuntime(runtime, sessionId, activation),
@@ -210,6 +237,25 @@ class WebWorkbenchController {
210
237
  this.assertContextGuard(context);
211
238
  return result;
212
239
  }
240
+ /** Archived sessions of a Workspace (v0.3.7), newest archive first. */
241
+ listArchivedWorkspaceSessions(workspaceId, context) {
242
+ if (context)
243
+ this.assertContextGuard(context);
244
+ const entry = this.workspaceRegistry.find(workspaceId);
245
+ if (!entry) {
246
+ throw new errors_1.WebWorkbenchError(404, 'Workspace was not found.', 'workspace_not_found');
247
+ }
248
+ try {
249
+ canonicalDirectory(entry.canonicalPath);
250
+ }
251
+ catch {
252
+ throw new errors_1.WebWorkbenchError(409, 'Workspace is unavailable.', 'workspace_unavailable');
253
+ }
254
+ const result = Object.freeze((0, session_storage_1.listArchivedProjectSessions)(entry.canonicalPath).map(protocol_1.projectSessionSummary));
255
+ if (context)
256
+ this.assertContextGuard(context);
257
+ return result;
258
+ }
213
259
  async workspaceProjectSummary(workspaceId, context) {
214
260
  if (context)
215
261
  this.assertContextGuard(context);
@@ -276,6 +322,18 @@ class WebWorkbenchController {
276
322
  return result;
277
323
  }
278
324
  sessionSnapshot(sessionId, cursor, pageSize = 50, tail = false, context) {
325
+ const startedAt = Date.now();
326
+ try {
327
+ const snapshot = this.snapshotSessionV1(sessionId, cursor, pageSize, tail, context);
328
+ this.recordSessionSnapshotActivity(startedAt);
329
+ return snapshot;
330
+ }
331
+ catch (error) {
332
+ this.recordSessionSnapshotActivity(startedAt, true);
333
+ throw error;
334
+ }
335
+ }
336
+ snapshotSessionV1(sessionId, cursor, pageSize = 50, tail = false, context) {
279
337
  if (context)
280
338
  this.assertContextGuard(context);
281
339
  const session = requireSession(sessionId);
@@ -454,6 +512,14 @@ class WebWorkbenchController {
454
512
  this.assertContextGuard(context);
455
513
  return snapshot;
456
514
  }
515
+ recordSessionSnapshotActivity(startedAt, failed = false) {
516
+ const elapsedMs = Date.now() - startedAt;
517
+ this.sessionActivity.snapshotRequests += 1;
518
+ if (failed)
519
+ this.sessionActivity.snapshotFailures += 1;
520
+ this.sessionActivity.snapshotTotalMs += elapsedMs;
521
+ this.sessionActivity.snapshotLastMs = elapsedMs;
522
+ }
457
523
  composerState(sessionId, context) {
458
524
  if (context)
459
525
  this.assertContextGuard(context);
@@ -852,6 +918,84 @@ class WebWorkbenchController {
852
918
  throw new errors_1.WebWorkbenchError(404, 'Session no longer exists.');
853
919
  return (0, protocol_1.projectSessionSummary)(updated);
854
920
  }
921
+ setSessionTags(sessionId, tags, context) {
922
+ if (context)
923
+ this.assertContextGuard(context);
924
+ const session = requireSession(sessionId);
925
+ this.assertSessionWorkspace(session);
926
+ if (!Array.isArray(tags)) {
927
+ throw new errors_1.WebWorkbenchError(400, 'Tags must be an array of strings.', 'invalid_tags');
928
+ }
929
+ if (tags.length > session_storage_1.SESSION_TAG_LIMIT) {
930
+ throw new errors_1.WebWorkbenchError(400, `A session can have at most ${session_storage_1.SESSION_TAG_LIMIT} tags.`, 'invalid_tags');
931
+ }
932
+ for (const raw of tags) {
933
+ if (typeof raw !== 'string' || !raw.trim()) {
934
+ throw new errors_1.WebWorkbenchError(400, 'Every tag must be a non-empty string.', 'invalid_tags');
935
+ }
936
+ if (raw.trim().length > session_storage_1.SESSION_TAG_MAX_LENGTH) {
937
+ throw new errors_1.WebWorkbenchError(400, `Each tag is limited to ${session_storage_1.SESSION_TAG_MAX_LENGTH} characters.`, 'invalid_tags');
938
+ }
939
+ }
940
+ const updated = (0, session_storage_1.setSessionTags)(session.id, (0, session_storage_1.normalizeSessionTags)(tags));
941
+ if (!updated)
942
+ throw new errors_1.WebWorkbenchError(404, 'Session no longer exists.');
943
+ return (0, protocol_1.projectSessionSummary)(updated);
944
+ }
945
+ archiveSession(sessionId, context) {
946
+ if (context)
947
+ this.assertContextGuard(context);
948
+ const session = requireSession(sessionId);
949
+ this.assertSessionWorkspace(session);
950
+ this.assertSessionNotBusy(session);
951
+ const updated = (0, session_storage_1.archiveSession)(session.id);
952
+ if (!updated)
953
+ throw new errors_1.WebWorkbenchError(404, 'Session no longer exists.');
954
+ return (0, protocol_1.projectSessionSummary)(updated);
955
+ }
956
+ restoreSession(sessionId, context) {
957
+ if (context)
958
+ this.assertContextGuard(context);
959
+ const session = requireSession(sessionId);
960
+ this.assertSessionWorkspace(session);
961
+ const updated = (0, session_storage_1.restoreSession)(session.id);
962
+ if (!updated)
963
+ throw new errors_1.WebWorkbenchError(404, 'Session no longer exists.');
964
+ return (0, protocol_1.projectSessionSummary)(updated);
965
+ }
966
+ deleteSession(sessionId, context) {
967
+ if (context)
968
+ this.assertContextGuard(context);
969
+ const session = requireSession(sessionId);
970
+ this.assertSessionWorkspace(session);
971
+ this.assertSessionHasNoActor(session);
972
+ const removed = (0, session_storage_1.deleteSession)(session.id);
973
+ if (!removed) {
974
+ throw new errors_1.WebWorkbenchError(409, 'Session files could not be fully removed; nothing was deleted.', 'session_delete_failed');
975
+ }
976
+ return { deleted: true };
977
+ }
978
+ /**
979
+ * A busy Session (starting / queued / running / waiting approval / stopping)
980
+ * must not be archived or deleted while its actor is doing work.
981
+ */
982
+ assertSessionNotBusy(session) {
983
+ const runtime = this.sessionRegistry.summary(this.sessionActorKey(session));
984
+ const busy = new Set(['starting', 'queued', 'running', 'waiting_approval', 'stopping']);
985
+ if (busy.has(runtime.phase)) {
986
+ throw new errors_1.WebWorkbenchError(409, 'Session is busy; stop it before archiving or deleting.', 'session_busy');
987
+ }
988
+ }
989
+ /**
990
+ * Deletion removes files under the Session while a resident actor may still
991
+ * hold them open — require that no actor exists at all (phase 'cold').
992
+ */
993
+ assertSessionHasNoActor(session) {
994
+ const resident = this.sessionRegistry.residentActor(this.sessionActorKey(session));
995
+ if (resident) {
996
+ throw new errors_1.WebWorkbenchError(409, 'Session has an active runtime; stop it before deleting.', 'session_busy');
997
+ }
998
+ }
855
999
  async switchWorkspace(path, context) {
856
1000
  this.assertContextGuard(context);
857
1001
  const next = canonicalDirectory(path);
@@ -901,20 +1045,29 @@ class WebWorkbenchController {
901
1045
  await previousController.stopActiveTurn();
902
1046
  await previousController.waitForIdle();
903
1047
  if (targetWorkspace !== previousWorkspace) {
904
- await this.sessionRegistry.shutdown('Workspace Context changed');
905
- await previousRuntime.shutdown();
1048
+ // Detach the control-plane foreground first: releasing the previous
1049
+ // control plane must not end a Session that a resident actor of that
1050
+ // Workspace is still driving.
1051
+ await this.restoreContextSession(null);
1052
+ // P1-A runtime ownership: the Host-level Session registry and its
1053
+ // resident actors are preserved across a Workspace Context switch.
1054
+ // Only the active control plane is swapped. Both control planes
1055
+ // borrowed their Workspace kernel from the shared pool, so releasing
1056
+ // the previous one never tears down kernels that running Session
1057
+ // actors of that Workspace still reference. Install the target
1058
+ // control plane first, then release the previous one's mutable state.
906
1059
  await this.installRuntime(targetWorkspace, false);
907
- this.sessionRegistry = this.createSessionRegistry();
1060
+ await previousRuntime.shutdown();
908
1061
  }
909
1062
  this.workspaceRegistry.register(targetWorkspace, { activated: true });
910
1063
  }
911
1064
  catch (activationError) {
912
1065
  try {
913
- if (targetWorkspace !== previousWorkspace) {
914
- if (this.runtimeValue !== previousRuntime)
915
- await this.runtimeValue.shutdown();
1066
+ if (this.runtimeValue !== previousRuntime) {
1067
+ // The target control plane installed but a later step failed; tear
1068
+ // it down and reinstall the previous Workspace's control plane.
1069
+ await this.runtimeValue.shutdown();
916
1070
  await this.installRuntime(previousWorkspace, false);
917
- this.sessionRegistry = this.createSessionRegistry();
918
1071
  }
919
1072
  await this.restoreContextSession(previousSessionId);
920
1073
  }
@@ -1287,6 +1440,10 @@ class WebWorkbenchController {
1287
1440
  harness,
1288
1441
  eventStream: this.eventHub.snapshot(),
1289
1442
  workspaceKernel: this.runtimeValue.workspaceRuntimeKernel?.diagnostics() ?? null,
1443
+ session: {
1444
+ ...this.sessionActivity,
1445
+ actors: this.sessionRegistry.stats(),
1446
+ },
1290
1447
  performance: {
1291
1448
  files: this.fileService.performanceCounters(),
1292
1449
  git: this.gitService.performanceCounters(),
@@ -1309,6 +1466,7 @@ class WebWorkbenchController {
1309
1466
  }
1310
1467
  async shutdownOwnedResources() {
1311
1468
  const failures = [];
1469
+ this.sessionActivity.controlPlaneShutdowns += 1;
1312
1470
  this.workspaceMutations.close('Orion Web Workbench shutdown');
1313
1471
  try {
1314
1472
  await this.sessionRegistry.shutdown('Orion Web Workbench shutdown');
@@ -1343,10 +1501,61 @@ class WebWorkbenchController {
1343
1501
  }
1344
1502
  this.workspaceMutationOwners.clear();
1345
1503
  this.pendingWorkspaceMutationStates.clear();
1504
+ this.releaseWorkspaceKernels();
1346
1505
  if (failures.length > 0) {
1347
1506
  throw new errors_1.WebWorkbenchError(503, `${failures.length} Web Workbench resource(s) could not be closed safely.`, 'workbench_shutdown_incomplete');
1348
1507
  }
1349
1508
  }
1509
+ /**
1510
+ * Return the workspace kernel for `cwd`, creating and pooling one on first
1511
+ * use. Control planes and Session actors borrow the same kernel instance per
1512
+ * canonical Workspace; the pool is released only when the Host shuts down.
1513
+ */
1514
+ workspaceKernelFor(cwd) {
1515
+ const canonical = canonicalDirectory(cwd);
1516
+ const existing = this.workspaceKernels.get(canonical);
1517
+ if (existing && !existing.diagnostics().closed)
1518
+ return existing;
1519
+ if (existing)
1520
+ this.workspaceKernels.delete(canonical);
1521
+ const kernel = (0, product_bootstrap_1.createWorkspaceRuntimeKernelV1)({
1522
+ cwd: canonical,
1523
+ onSettingsInvalidated: event => this.onWorkspaceKernelSettingsInvalidated(canonical, event),
1524
+ });
1525
+ this.workspaceKernels.set(canonical, kernel);
1526
+ return kernel;
1527
+ }
1528
+ /**
1529
+ * Settings invalidations from pooled kernels are only forwarded while their
1530
+ * Workspace is the active Context. A background Workspace's coordinator
1531
+ * keeps watching its own durable file; its next activation publishes a fresh
1532
+ * Settings document through `emitSettingsWorkspaceChange()`.
1533
+ */
1534
+ onWorkspaceKernelSettingsInvalidated(kernelWorkspace, event) {
1535
+ if (this.suppressContextEdges > 0)
1536
+ return;
1537
+ if (kernelWorkspace !== this.workspaceValue)
1538
+ return;
1539
+ this.eventHub.emit({
1540
+ type: 'settings_invalidated',
1541
+ revision: event.revision,
1542
+ reason: event.reason,
1543
+ state: event.state,
1544
+ }, false);
1545
+ }
1546
+ /**
1547
+ * Release the Host owner seat on every pooled kernel. Runtime shutdowns have
1548
+ * already disposed their Settings participants (actors first, then the
1549
+ * active control plane), so an unowned kernel with zero participants closes
1550
+ * its Settings coordinator here. A kernel that still has a running actor
1551
+ * participant survives until that actor actually terminates.
1552
+ */
1553
+ releaseWorkspaceKernels() {
1554
+ for (const kernel of this.workspaceKernels.values()) {
1555
+ kernel.releaseOwner();
1556
+ }
1557
+ this.workspaceKernels.clear();
1558
+ }
1350
1559
  createSessionRegistry() {
1351
1560
  return new session_runtime_registry_1.WebSessionRuntimeRegistryV1({
1352
1561
  maxRunningSessions: 3,
@@ -1512,6 +1721,10 @@ class WebWorkbenchController {
1512
1721
  }
1513
1722
  }
1514
1723
  async installRuntime(workspace, publishState = true) {
1724
+ // Every control-plane install reloads the Workspace catalog, provider
1725
+ // wiring, Skills and MCP adapters, so this counter proxies "catalog
1726
+ // reload" for the runtime-ownership diagnostics matrix.
1727
+ this.sessionActivity.controlPlaneInstalls += 1;
1515
1728
  this.closeComposerObserver();
1516
1729
  const runtime = await this.createRuntime(workspace);
1517
1730
  this.closeWorkspaceWatchers();
@@ -1821,12 +2034,9 @@ class WebWorkbenchController {
1821
2034
  if (this.controllerValue.hasActiveTurn()) {
1822
2035
  throw new errors_1.WebWorkbenchError(409, `Cannot ${operation} while a turn is active.`, 'runtime_busy');
1823
2036
  }
1824
- const activeActor = this.sessionRegistry
1825
- .summaries()
1826
- .find(runtime => ['starting', 'queued', 'running', 'waiting_approval', 'stopping'].includes(runtime.phase));
1827
- if (activeActor) {
1828
- throw new errors_1.WebWorkbenchError(409, `Cannot ${operation} while Session ${activeActor.sessionId} is ${activeActor.phase}.`, 'runtime_busy');
1829
- }
2037
+ // P1-A: Session actors are scoped to their own Workspace and survive a
2038
+ // Context switch (WEB35-P0-08/09), so an active actor in a non-target
2039
+ // Workspace must not block switching the active control plane.
1830
2040
  }
1831
2041
  assertMutationAdmission() {
1832
2042
  if (this.closed)
@@ -1,4 +1,4 @@
1
- import{r as u,j as s,I as N}from"./index-C6TDJwMC.js";function v(t){const n=[];let i;for(const r of t)r.startsWith("@@")?(i&&n.push(i),i={title:r,lines:[r]}):i&&i.lines.push(r);return i&&n.push(i),n}function D(t,n){const i={schemaVersion:1,type:"review_context",repositoryRevision:t.repositoryRevision,path:t.path,hunk:n.title},r=n.lines.join(`
1
+ import{r as u,j as s,I as N}from"./index-30GT9Vnx.js";function v(t){const n=[];let i;for(const r of t)r.startsWith("@@")?(i&&n.push(i),i={title:r,lines:[r]}):i&&i.lines.push(r);return i&&n.push(i),n}function D(t,n){const i={schemaVersion:1,type:"review_context",repositoryRevision:t.repositoryRevision,path:t.path,hunk:n.title},r=n.lines.join(`
2
2
  `).slice(0,12e3);return[`请审阅 ${t.path} 的这个 diff hunk,并指出正确性、安全性和测试风险:`,"","```review_context",JSON.stringify(i,null,2),"```","","```diff",r,"```"].join(`
3
3
  `)}function H({page:t,loading:n=!1,onLoadMore:i,onSendToComposer:r}){const a=u.useMemo(()=>v(t.lines),[t.lines]),[m,h]=u.useState(0),[f,p]=u.useState(!1),[x,k]=u.useState(!1),[b,y]=u.useState(""),d=Math.min(m,Math.max(0,a.length-1)),c=a[d];u.useEffect(()=>{h(0),p(!1),y("")},[t.fileId,t.repositoryRevision]);const j=(e,l)=>{let o=l;if(e.key==="ArrowRight"||e.key==="ArrowDown")o=(l+1)%a.length;else if(e.key==="ArrowLeft"||e.key==="ArrowUp")o=(l-1+a.length)%a.length;else if(e.key==="Home")o=0;else if(e.key==="End")o=a.length-1;else return;e.preventDefault(),h(o);const w=e.currentTarget.parentElement;window.requestAnimationFrame(()=>w?.querySelector(`[data-hunk-index="${o}"]`)?.focus())};return t.binary?s.jsxs("div",{className:"resource-empty compact",children:[s.jsx(N,{name:"code"}),s.jsx("strong",{children:"二进制差异"}),s.jsx("p",{children:"只展示变更事实,不返回 binary patch。"})]}):s.jsxs("div",{className:"diff-viewer",children:[s.jsxs("header",{children:[s.jsx("strong",{title:t.path,children:t.path}),s.jsx("span",{children:t.truncated?"受限预览":`${t.lines.length} 行`})]}),a.length>1?s.jsx("div",{className:"diff-hunk-nav",role:"tablist","aria-label":"Diff hunks",children:a.map((e,l)=>s.jsx("button",{type:"button",role:"tab","data-hunk-index":l,"aria-selected":d===l,tabIndex:d===l?0:-1,onClick:()=>h(l),onKeyDown:o=>j(o,l),children:e.title||`Hunk ${l+1}`},`${e.title}-${l}`))}):null,s.jsxs("div",{className:"diff-actions","aria-label":"Diff 显示选项",children:[c?s.jsx("button",{type:"button",className:"text-button","aria-expanded":!f,onClick:()=>p(e=>!e),children:f?"展开 Hunk":"折叠 Hunk"}):null,s.jsx("button",{type:"button",className:"text-button","aria-pressed":x,onClick:()=>k(e=>!e),children:"显示空白字符"}),c?s.jsx("button",{type:"button",className:"text-button",onClick:()=>{$(c.lines.join(`
4
4
  `),y)},children:"复制 Hunk"}):null]}),f?null:s.jsx("pre",{className:"diff-lines",tabIndex:0,"aria-label":`Diff ${t.path}`,children:(c?.lines??t.lines).map((e,l)=>s.jsxs("span",{className:e.startsWith("+")?"addition":e.startsWith("-")?"deletion":"",children:[S(e,x)||" ",`
@@ -1,2 +1,2 @@
1
- import{r as c,j as e,I as C,s as I,W as ee}from"./index-C6TDJwMC.js";function ae({workspaceId:s,refreshEpoch:l,actions:i}){const[r,a]=c.useState({}),[m,j]=c.useState(new Set(["workspace-root"])),[o,f]=c.useState(null),[h,d]=c.useState(""),[N,$]=c.useState(null),[J,E]=c.useState(!1),[T,R]=c.useState(""),[B,g]=c.useState(""),[D,U]=c.useState(""),[M,X]=c.useState(!1),[K,Y]=c.useState("1"),[O,L]=c.useState({}),[P,F]=c.useState(""),W=c.useRef(null),x=c.useRef(0),k=c.useRef(0),w=async(t,n=!1,y=x.current)=>{if(y!==x.current)return;const p=r[t],v=n?p?.nextCursor:void 0;if(!(n&&!v)){a(u=>({...u,[t]:{items:p?.items??[],nextCursor:p?.nextCursor??null,revision:p?.revision??"",loading:!0}}));try{const u=await i.listFiles(t,v??void 0);if(y!==x.current)return;a(b=>({...b,[t]:{items:n?se(b[t]?.items??[],u.items):u.items,nextCursor:u.nextCursor,revision:u.revision,loading:!1}}))}catch(u){if(y!==x.current)return;if(n&&V(u)){g("目录已变化,已重新载入第一页。"),w(t,!1,y);return}a(b=>({...b,[t]:{items:b[t]?.items??[],nextCursor:b[t]?.nextCursor??null,revision:b[t]?.revision??"",loading:!1,error:G(u)}}))}}},_=async(t=x.current)=>{try{const n=await i.gitStatus();if(t!==x.current)return;L(re(n)),F(n.nextCursor?"Git 装饰仅显示首批 200 个变更;在 Git 面板继续分页查看。":"")}catch(n){if(t!==x.current)return;L({}),F(`Git 状态装饰不可用:${G(n)}`)}};c.useEffect(()=>{const t=x.current+1;x.current=t,k.current+=1,a({}),j(new Set(["workspace-root"])),f(null),d(""),$(null),E(!1),R(""),g(""),L({}),F(""),s&&(w("workspace-root",!1,t),_(t))},[l,s]);const S=async(t,n=!1,y=!1,p=x.current,v=k.current+1)=>{if(p===x.current&&!(!t.readable||t.sensitive||z(t))){k.current=v,f(t),R(""),n||(d(""),$(null),E(!1)),y||g("");try{const u=await i.readFileContent(t.id,n?N??void 0:void 0);if(p!==x.current||v!==k.current)return;E(u.binary),d(b=>n?`${b}${u.content??""}`:u.content??""),$(u.nextCursor),y&&g("文件已变化,已从第一页重新载入。")}catch(u){if(p!==x.current||v!==k.current)return;if(n&&V(u)){await S(t,!1,!0,p,v);return}R(G(u))}}},A=t=>{const n=new Set(m);n.has(t)?n.delete(t):(n.add(t),r[t]||w(t)),j(n)},Z=c.useMemo(()=>Object.values(r).flatMap(t=>t.items),[r]),Q=D.trim()?Z.filter(t=>t.name.toLocaleLowerCase().includes(D.toLocaleLowerCase())):null;return e.jsxs("div",{className:"work-resource-panel files-panel",children:[e.jsxs("div",{className:"resource-toolbar",children:[e.jsxs("label",{className:"resource-search",children:[e.jsx("span",{className:"sr-only",children:"搜索已加载文件"}),e.jsx(C,{name:"search",size:14}),e.jsx("input",{type:"search",value:D,onChange:t=>U(t.target.value),placeholder:"搜索已加载文件"})]}),e.jsx("button",{type:"button",className:"icon-button","aria-label":"刷新文件树",onClick:()=>{w("workspace-root"),_()},children:e.jsx(C,{name:"refresh",size:15})})]}),e.jsxs("div",{className:"files-layout",children:[e.jsxs("section",{className:"file-tree","aria-label":"工作区文件",children:[P?e.jsx("p",{className:"resource-hint",role:"status",children:P}):null,Q?e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"resource-hint",children:"搜索仅覆盖已加载的目录和文件。"}),e.jsx("ul",{role:"list",className:"file-node-list search-results",children:Q.map(t=>e.jsx(H,{node:t,depth:0,expanded:!1,selected:o?.id===t.id,gitLabels:O[t.displayPath]??[],onToggle:A,onSelect:n=>{S(n)}},t.id))})]}):e.jsx(q,{parentId:"workspace-root",depth:0,directories:r,expanded:m,selectedId:o?.id,gitDecorations:O,onToggle:A,onSelect:t=>{S(t)},onLoadMore:t=>{w(t,!0)}})]}),e.jsxs("section",{className:"file-preview","aria-label":"文件预览",children:[B?e.jsx("p",{className:"resource-notice",role:"status",children:B}):null,o?e.jsxs(e.Fragment,{children:[e.jsxs("header",{children:[e.jsx("strong",{children:o.name}),e.jsx("span",{children:ne(o.sizeBytes??0)})]}),T?e.jsx("p",{className:"resource-error",role:"alert",children:T}):J?e.jsxs("div",{className:"resource-empty",children:[e.jsx(C,{name:"code"}),e.jsx("strong",{children:"二进制文件"}),e.jsx("p",{children:"出于安全和性能考虑,只显示元数据。"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"file-preview-actions",children:[e.jsxs("label",{children:[e.jsx("span",{className:"sr-only",children:"跳到行"}),e.jsx("input",{type:"number",min:"1",value:K,"aria-label":"跳到行",onChange:t=>Y(t.target.value)})]}),e.jsx("button",{type:"button",className:"text-button",onClick:()=>ie(W.current,K),children:"跳转"}),e.jsx("button",{type:"button",className:"text-button",onClick:()=>{le(h,g)},children:"复制"}),e.jsx("button",{type:"button",className:"text-button","aria-pressed":M,onClick:()=>X(t=>!t),children:"自动换行"})]}),e.jsx("pre",{ref:W,tabIndex:0,className:`file-code-view ${M?"wrap":""}`,"aria-label":`文件内容 ${o.name}`,children:I(h).split(`
1
+ import{r as c,j as e,I as C,s as I,W as ee}from"./index-30GT9Vnx.js";function ae({workspaceId:s,refreshEpoch:l,actions:i}){const[r,a]=c.useState({}),[m,j]=c.useState(new Set(["workspace-root"])),[o,f]=c.useState(null),[h,d]=c.useState(""),[N,$]=c.useState(null),[J,E]=c.useState(!1),[T,R]=c.useState(""),[B,g]=c.useState(""),[D,U]=c.useState(""),[M,X]=c.useState(!1),[K,Y]=c.useState("1"),[O,L]=c.useState({}),[P,F]=c.useState(""),W=c.useRef(null),x=c.useRef(0),k=c.useRef(0),w=async(t,n=!1,y=x.current)=>{if(y!==x.current)return;const p=r[t],v=n?p?.nextCursor:void 0;if(!(n&&!v)){a(u=>({...u,[t]:{items:p?.items??[],nextCursor:p?.nextCursor??null,revision:p?.revision??"",loading:!0}}));try{const u=await i.listFiles(t,v??void 0);if(y!==x.current)return;a(b=>({...b,[t]:{items:n?se(b[t]?.items??[],u.items):u.items,nextCursor:u.nextCursor,revision:u.revision,loading:!1}}))}catch(u){if(y!==x.current)return;if(n&&V(u)){g("目录已变化,已重新载入第一页。"),w(t,!1,y);return}a(b=>({...b,[t]:{items:b[t]?.items??[],nextCursor:b[t]?.nextCursor??null,revision:b[t]?.revision??"",loading:!1,error:G(u)}}))}}},_=async(t=x.current)=>{try{const n=await i.gitStatus();if(t!==x.current)return;L(re(n)),F(n.nextCursor?"Git 装饰仅显示首批 200 个变更;在 Git 面板继续分页查看。":"")}catch(n){if(t!==x.current)return;L({}),F(`Git 状态装饰不可用:${G(n)}`)}};c.useEffect(()=>{const t=x.current+1;x.current=t,k.current+=1,a({}),j(new Set(["workspace-root"])),f(null),d(""),$(null),E(!1),R(""),g(""),L({}),F(""),s&&(w("workspace-root",!1,t),_(t))},[l,s]);const S=async(t,n=!1,y=!1,p=x.current,v=k.current+1)=>{if(p===x.current&&!(!t.readable||t.sensitive||z(t))){k.current=v,f(t),R(""),n||(d(""),$(null),E(!1)),y||g("");try{const u=await i.readFileContent(t.id,n?N??void 0:void 0);if(p!==x.current||v!==k.current)return;E(u.binary),d(b=>n?`${b}${u.content??""}`:u.content??""),$(u.nextCursor),y&&g("文件已变化,已从第一页重新载入。")}catch(u){if(p!==x.current||v!==k.current)return;if(n&&V(u)){await S(t,!1,!0,p,v);return}R(G(u))}}},A=t=>{const n=new Set(m);n.has(t)?n.delete(t):(n.add(t),r[t]||w(t)),j(n)},Z=c.useMemo(()=>Object.values(r).flatMap(t=>t.items),[r]),Q=D.trim()?Z.filter(t=>t.name.toLocaleLowerCase().includes(D.toLocaleLowerCase())):null;return e.jsxs("div",{className:"work-resource-panel files-panel",children:[e.jsxs("div",{className:"resource-toolbar",children:[e.jsxs("label",{className:"resource-search",children:[e.jsx("span",{className:"sr-only",children:"搜索已加载文件"}),e.jsx(C,{name:"search",size:14}),e.jsx("input",{type:"search",value:D,onChange:t=>U(t.target.value),placeholder:"搜索已加载文件"})]}),e.jsx("button",{type:"button",className:"icon-button","aria-label":"刷新文件树",onClick:()=>{w("workspace-root"),_()},children:e.jsx(C,{name:"refresh",size:15})})]}),e.jsxs("div",{className:"files-layout",children:[e.jsxs("section",{className:"file-tree","aria-label":"工作区文件",children:[P?e.jsx("p",{className:"resource-hint",role:"status",children:P}):null,Q?e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"resource-hint",children:"搜索仅覆盖已加载的目录和文件。"}),e.jsx("ul",{role:"list",className:"file-node-list search-results",children:Q.map(t=>e.jsx(H,{node:t,depth:0,expanded:!1,selected:o?.id===t.id,gitLabels:O[t.displayPath]??[],onToggle:A,onSelect:n=>{S(n)}},t.id))})]}):e.jsx(q,{parentId:"workspace-root",depth:0,directories:r,expanded:m,selectedId:o?.id,gitDecorations:O,onToggle:A,onSelect:t=>{S(t)},onLoadMore:t=>{w(t,!0)}})]}),e.jsxs("section",{className:"file-preview","aria-label":"文件预览",children:[B?e.jsx("p",{className:"resource-notice",role:"status",children:B}):null,o?e.jsxs(e.Fragment,{children:[e.jsxs("header",{children:[e.jsx("strong",{children:o.name}),e.jsx("span",{children:ne(o.sizeBytes??0)})]}),T?e.jsx("p",{className:"resource-error",role:"alert",children:T}):J?e.jsxs("div",{className:"resource-empty",children:[e.jsx(C,{name:"code"}),e.jsx("strong",{children:"二进制文件"}),e.jsx("p",{children:"出于安全和性能考虑,只显示元数据。"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"file-preview-actions",children:[e.jsxs("label",{children:[e.jsx("span",{className:"sr-only",children:"跳到行"}),e.jsx("input",{type:"number",min:"1",value:K,"aria-label":"跳到行",onChange:t=>Y(t.target.value)})]}),e.jsx("button",{type:"button",className:"text-button",onClick:()=>ie(W.current,K),children:"跳转"}),e.jsx("button",{type:"button",className:"text-button",onClick:()=>{le(h,g)},children:"复制"}),e.jsx("button",{type:"button",className:"text-button","aria-pressed":M,onClick:()=>X(t=>!t),children:"自动换行"})]}),e.jsx("pre",{ref:W,tabIndex:0,className:`file-code-view ${M?"wrap":""}`,"aria-label":`文件内容 ${o.name}`,children:I(h).split(`
2
2
  `).map((t,n)=>e.jsxs("span",{className:"file-code-line","data-line":n+1,children:[e.jsx("span",{className:"file-line-number","aria-hidden":"true",children:n+1}),e.jsx("span",{className:"file-line-content",children:t||" "})]},n))})]}),N?e.jsx("button",{type:"button",className:"secondary-button",onClick:()=>{S(o,!0)},children:"加载更多内容"}):null]}):e.jsxs("div",{className:"resource-empty",children:[e.jsx(C,{name:"workspace"}),e.jsx("strong",{children:"选择文件预览"}),e.jsx("p",{children:"敏感文件、工作区外链接和二进制正文不会返回浏览器。"})]})]})]})]})}function q({parentId:s,depth:l,directories:i,expanded:r,selectedId:a,gitDecorations:m,onToggle:j,onSelect:o,onLoadMore:f}){const h=i[s];return h?h.error?e.jsx("p",{className:"resource-error",role:"alert",children:h.error}):e.jsxs("ul",{role:"list",className:"file-node-list",children:[h.items.map(d=>{const N=r.has(d.id);return e.jsxs("li",{children:[e.jsx(H,{node:d,depth:l,expanded:N,selected:a===d.id,gitLabels:m[d.displayPath]??[],onToggle:j,onSelect:o}),z(d)&&N?e.jsx(q,{parentId:d.id,depth:l+1,directories:i,expanded:r,selectedId:a,gitDecorations:m,onToggle:j,onSelect:o,onLoadMore:f}):null]},d.id)}),h.loading?e.jsx("li",{className:"resource-loading",children:"正在读取…"}):null,h.nextCursor?e.jsx("li",{children:e.jsx("button",{type:"button",className:"text-button",onClick:()=>f(s),children:"加载更多"})}):null]}):e.jsx("p",{className:"resource-loading",children:"正在读取…"})}function H({node:s,depth:l,expanded:i,selected:r,gitLabels:a,onToggle:m,onSelect:j}){const o=s.sensitive||!s.readable,f=z(s);return e.jsxs("button",{type:"button",className:`file-node ${r?"selected":""} ${o?"blocked":""}`,style:{paddingInlineStart:`${8+l*15}px`},"aria-expanded":f?i:void 0,"aria-label":`${te(s)} ${s.name}${o?",不可读取":""}${a.length?`,Git ${a.join("、")}`:""}`,onClick:()=>f?m(s.id):j(s),disabled:o,children:[e.jsx(C,{name:f?"workspace":"code",size:14}),e.jsx("span",{children:s.name}),s.kind==="symlink"?e.jsx("small",{children:"链接"}):null,s.sensitive?e.jsx("small",{children:"敏感"}):null,a.length?e.jsx("small",{className:"file-git-status",title:`Git ${a.join("、")}`,children:a.join(" · ")}):null]})}function te(s){return s.kind==="directory"?"目录":s.kind==="symlink"?s.targetKind==="directory"?"符号链接目录":"符号链接":"文件"}function z(s){return s.kind==="directory"||s.kind==="symlink"&&s.targetKind==="directory"}function se(s,l){const i=new Map(s.map(r=>[r.id,r]));for(const r of l)i.set(r.id,r);return[...i.values()]}function re(s){if(!s.isRepository)return{};const l=new Map,i=(r,a)=>{const m=r.replace(/\\/gu,"/").replace(/^\.\//u,"");if(!m)return;const j=l.get(m)??new Set;j.add(a),l.set(m,j);const o=m.split("/");for(let f=1;f<o.length;f+=1){const h=o.slice(0,f).join("/"),d=l.get(h)??new Set;d.add("含变更"),l.set(h,d)}};return s.conflicted.forEach(r=>i(r.path,"冲突")),s.staged.forEach(r=>i(r.path,"已暂存")),s.unstaged.forEach(r=>i(r.path,"未暂存")),s.untracked.forEach(r=>i(r.path,"未跟踪")),Object.fromEntries([...l].map(([r,a])=>[r,Object.freeze([...a])]))}function ne(s){return s<1024?`${s} B`:s<1048576?`${(s/1024).toFixed(1)} KB`:`${(s/1048576).toFixed(1)} MB`}function V(s){return s instanceof ee&&s.code==="file_revision_conflict"}function ie(s,l){const i=Number(l);!s||!Number.isSafeInteger(i)||i<1||(s.querySelector(`[data-line="${i}"]`)?.scrollIntoView({block:"center"}),s.focus())}async function le(s,l){try{await navigator.clipboard.writeText(s),l("已复制当前加载的文件内容。")}catch{l("浏览器未允许复制,请手动选择文本。")}}function G(s){return s instanceof Error?s.message:"文件请求失败。"}export{ae as FilesPanel};
@@ -1 +1 @@
1
- import{r as d,j as e,I as g,W as _}from"./index-C6TDJwMC.js";import{D as W}from"./DiffViewer-D6mG729y.js";function K({workspaceId:c,refreshEpoch:m,actions:u,onSendToComposer:o}){const[a,I]=d.useState(null),[j,k]=d.useState(null),[G,y]=d.useState(null),[v,N]=d.useState(null),[R,h]=d.useState(!1),[w,f]=d.useState(""),[E,p]=d.useState(""),n=d.useRef(0),x=d.useRef(0),b=async(t=n.current)=>{if(t===n.current){h(!0),f("");try{const[s,l]=await Promise.all([u.gitStatus(),u.gitLog()]);if(t!==n.current)return;I(s),k(l),y(null),N(null)}catch(s){if(t!==n.current)return;f(S(s))}finally{t===n.current&&h(!1)}}},$=()=>{const t=n.current+1;n.current=t,x.current+=1,p(""),b(t)};d.useEffect(()=>{const t=n.current+1;n.current=t,x.current+=1,I(null),k(null),y(null),N(null),f(""),p(""),c&&b(t)},[m,c]);const M=async(t,s,l=n.current,r=x.current+1)=>{if(l===n.current){x.current=r,s||(y(t),N(null)),h(!0),f("");try{const i=await u.gitDiff(t.fileId,s);if(l!==n.current||r!==x.current||i.fileId!==t.fileId)return;y(t),N(D=>s&&D&&D.fileId===i.fileId?{...i,lines:[...D.lines,...i.lines]}:i)}catch(i){if(l!==n.current||r!==x.current)return;if(L(i)){p("仓库已变化,已重新载入 Git 状态。"),await b(l);return}f(S(i))}finally{l===n.current&&r===x.current&&h(!1)}}},z=async()=>{const t=a?.nextCursor;if(!t||!a)return;const s=n.current,l=a.repositoryRevision;h(!0),f("");try{const r=await u.gitStatus(t);if(s!==n.current)return;if(r.repositoryRevision!==l)throw A();I(i=>!i||i.repositoryRevision!==l?i:{...r,conflicted:C(i.conflicted,r.conflicted),staged:C(i.staged,r.staged),unstaged:C(i.unstaged,r.unstaged),untracked:C(i.untracked,r.untracked)})}catch(r){if(s!==n.current)return;if(L(r)){p("仓库已变化,已重新载入 Git 状态。"),await b(s);return}f(S(r))}finally{s===n.current&&h(!1)}},F=async()=>{const t=j?.nextCursor;if(!t||!j)return;const s=n.current,l=j.repositoryRevision;h(!0),f("");try{const r=await u.gitLog(t);if(s!==n.current)return;if(r.repositoryRevision!==l)throw A();k(i=>!i||i.repositoryRevision!==l?i:{...r,items:V(i.items,r.items)})}catch(r){if(s!==n.current)return;if(L(r)){p("提交历史已变化,已重新载入第一页。"),await b(s);return}f(S(r))}finally{s===n.current&&h(!1)}};if(w&&!a)return e.jsx(H,{message:w,onRetry:$});if(!a)return e.jsx("p",{className:"resource-loading",children:"正在读取 Git 状态…"});if(!a.isRepository)return e.jsxs("div",{className:"resource-empty",children:[e.jsx(g,{name:"branch"}),e.jsx("strong",{children:"当前项目不是 Git 仓库"}),e.jsx("p",{children:"文件和 Agent 仍可使用;Git 面板保持只读空状态。"})]});const P=[{label:"冲突",tone:"conflict",items:a.conflicted},{label:"已暂存",tone:"staged",items:a.staged},{label:"未暂存",tone:"unstaged",items:a.unstaged},{label:"未跟踪",tone:"untracked",items:a.untracked}];return e.jsxs("div",{className:"work-resource-panel git-panel",children:[e.jsxs("div",{className:"git-summary",children:[e.jsxs("div",{children:[e.jsx(g,{name:"branch",size:15}),e.jsx("strong",{children:a.detached?`detached ${a.head??""}`:a.branch||"HEAD"})]}),e.jsxs("span",{children:[a.upstream||"无 upstream",a.ahead||a.behind?` · ↑${a.ahead} ↓${a.behind}`:""]}),e.jsx("button",{type:"button",className:"icon-button","aria-label":"刷新 Git 状态",onClick:$,disabled:R,children:e.jsx(g,{name:"refresh",size:15})})]}),E?e.jsx("p",{className:"resource-notice",role:"status",children:E}):null,w?e.jsx("p",{className:"resource-error",role:"alert",children:w}):null,e.jsxs("div",{className:"git-layout",children:[e.jsxs("section",{className:"git-changes","aria-label":"Git 变更",children:[a.clean?e.jsxs("div",{className:"resource-empty compact",children:[e.jsx(g,{name:"check"}),e.jsx("strong",{children:"工作区干净"})]}):P.map(t=>t.items.length?e.jsxs("div",{className:"git-group",children:[e.jsxs("h3",{children:[t.label," ",e.jsx("span",{children:t.items.length})]}),t.items.map(s=>e.jsxs("button",{type:"button",className:G?.fileId===s.fileId?"selected":"",onClick:()=>{M(s)},children:[e.jsx("span",{className:`git-status-code ${t.tone}`,children:s.indexStatus.trim()||s.worktreeStatus.trim()||"?"}),e.jsx("span",{title:s.path,children:s.path})]},`${t.label}:${s.fileId}`))]},t.label):null),a.nextCursor?e.jsx("button",{type:"button",className:"text-button resource-load-more",onClick:()=>{z()},disabled:R,children:"加载更多变更"}):null,e.jsxs("div",{className:"git-history",children:[e.jsx("h3",{children:"提交历史"}),j?.items.map(t=>e.jsxs("article",{children:[e.jsx("code",{children:t.shortId}),e.jsx("strong",{children:t.subject}),e.jsxs("span",{children:[t.authorName," · ",new Date(t.authoredAt).toLocaleDateString("zh-CN")]})]},t.id)),j?.nextCursor?e.jsx("button",{type:"button",className:"text-button resource-load-more",onClick:()=>{F()},disabled:R,children:"加载更多提交"}):null]})]}),e.jsx("section",{className:"git-diff","aria-label":"Git Diff",children:v?e.jsx(W,{page:v,loading:R,onLoadMore:v.nextCursor&&G?()=>{M(G,v.nextCursor??void 0)}:void 0,onSendToComposer:o}):e.jsxs("div",{className:"resource-empty",children:[e.jsx(g,{name:"code"}),e.jsx("strong",{children:"选择变更查看 Diff"}),e.jsx("p",{children:"Diff 来自受限 Git read model,不解析对话或工具输出。"})]})})]})]})}function H({message:c,onRetry:m}){return e.jsxs("div",{className:"resource-empty",role:"alert",children:[e.jsx(g,{name:"warning"}),e.jsx("strong",{children:"Git 状态读取失败"}),e.jsx("p",{children:c}),e.jsx("button",{type:"button",className:"secondary-button",onClick:m,children:"重试"})]})}function S(c){return c instanceof Error?c.message:"Git 请求失败。"}function L(c){return c instanceof _&&c.code==="git_revision_conflict"}function A(){return new _("仓库版本已变化。",409,"git_revision_conflict")}function C(c,m){const u=new Map(c.map(o=>[o.fileId,o]));for(const o of m)u.set(o.fileId,o);return[...u.values()]}function V(c,m){const u=new Map(c.map(o=>[o.id,o]));for(const o of m)u.set(o.id,o);return[...u.values()]}export{K as GitPanel};
1
+ import{r as d,j as e,I as g,W as _}from"./index-30GT9Vnx.js";import{D as W}from"./DiffViewer-DqbZ02RN.js";function K({workspaceId:c,refreshEpoch:m,actions:u,onSendToComposer:o}){const[a,I]=d.useState(null),[j,k]=d.useState(null),[G,y]=d.useState(null),[v,N]=d.useState(null),[R,h]=d.useState(!1),[w,f]=d.useState(""),[E,p]=d.useState(""),n=d.useRef(0),x=d.useRef(0),b=async(t=n.current)=>{if(t===n.current){h(!0),f("");try{const[s,l]=await Promise.all([u.gitStatus(),u.gitLog()]);if(t!==n.current)return;I(s),k(l),y(null),N(null)}catch(s){if(t!==n.current)return;f(S(s))}finally{t===n.current&&h(!1)}}},$=()=>{const t=n.current+1;n.current=t,x.current+=1,p(""),b(t)};d.useEffect(()=>{const t=n.current+1;n.current=t,x.current+=1,I(null),k(null),y(null),N(null),f(""),p(""),c&&b(t)},[m,c]);const M=async(t,s,l=n.current,r=x.current+1)=>{if(l===n.current){x.current=r,s||(y(t),N(null)),h(!0),f("");try{const i=await u.gitDiff(t.fileId,s);if(l!==n.current||r!==x.current||i.fileId!==t.fileId)return;y(t),N(D=>s&&D&&D.fileId===i.fileId?{...i,lines:[...D.lines,...i.lines]}:i)}catch(i){if(l!==n.current||r!==x.current)return;if(L(i)){p("仓库已变化,已重新载入 Git 状态。"),await b(l);return}f(S(i))}finally{l===n.current&&r===x.current&&h(!1)}}},z=async()=>{const t=a?.nextCursor;if(!t||!a)return;const s=n.current,l=a.repositoryRevision;h(!0),f("");try{const r=await u.gitStatus(t);if(s!==n.current)return;if(r.repositoryRevision!==l)throw A();I(i=>!i||i.repositoryRevision!==l?i:{...r,conflicted:C(i.conflicted,r.conflicted),staged:C(i.staged,r.staged),unstaged:C(i.unstaged,r.unstaged),untracked:C(i.untracked,r.untracked)})}catch(r){if(s!==n.current)return;if(L(r)){p("仓库已变化,已重新载入 Git 状态。"),await b(s);return}f(S(r))}finally{s===n.current&&h(!1)}},F=async()=>{const t=j?.nextCursor;if(!t||!j)return;const s=n.current,l=j.repositoryRevision;h(!0),f("");try{const r=await u.gitLog(t);if(s!==n.current)return;if(r.repositoryRevision!==l)throw A();k(i=>!i||i.repositoryRevision!==l?i:{...r,items:V(i.items,r.items)})}catch(r){if(s!==n.current)return;if(L(r)){p("提交历史已变化,已重新载入第一页。"),await b(s);return}f(S(r))}finally{s===n.current&&h(!1)}};if(w&&!a)return e.jsx(H,{message:w,onRetry:$});if(!a)return e.jsx("p",{className:"resource-loading",children:"正在读取 Git 状态…"});if(!a.isRepository)return e.jsxs("div",{className:"resource-empty",children:[e.jsx(g,{name:"branch"}),e.jsx("strong",{children:"当前项目不是 Git 仓库"}),e.jsx("p",{children:"文件和 Agent 仍可使用;Git 面板保持只读空状态。"})]});const P=[{label:"冲突",tone:"conflict",items:a.conflicted},{label:"已暂存",tone:"staged",items:a.staged},{label:"未暂存",tone:"unstaged",items:a.unstaged},{label:"未跟踪",tone:"untracked",items:a.untracked}];return e.jsxs("div",{className:"work-resource-panel git-panel",children:[e.jsxs("div",{className:"git-summary",children:[e.jsxs("div",{children:[e.jsx(g,{name:"branch",size:15}),e.jsx("strong",{children:a.detached?`detached ${a.head??""}`:a.branch||"HEAD"})]}),e.jsxs("span",{children:[a.upstream||"无 upstream",a.ahead||a.behind?` · ↑${a.ahead} ↓${a.behind}`:""]}),e.jsx("button",{type:"button",className:"icon-button","aria-label":"刷新 Git 状态",onClick:$,disabled:R,children:e.jsx(g,{name:"refresh",size:15})})]}),E?e.jsx("p",{className:"resource-notice",role:"status",children:E}):null,w?e.jsx("p",{className:"resource-error",role:"alert",children:w}):null,e.jsxs("div",{className:"git-layout",children:[e.jsxs("section",{className:"git-changes","aria-label":"Git 变更",children:[a.clean?e.jsxs("div",{className:"resource-empty compact",children:[e.jsx(g,{name:"check"}),e.jsx("strong",{children:"工作区干净"})]}):P.map(t=>t.items.length?e.jsxs("div",{className:"git-group",children:[e.jsxs("h3",{children:[t.label," ",e.jsx("span",{children:t.items.length})]}),t.items.map(s=>e.jsxs("button",{type:"button",className:G?.fileId===s.fileId?"selected":"",onClick:()=>{M(s)},children:[e.jsx("span",{className:`git-status-code ${t.tone}`,children:s.indexStatus.trim()||s.worktreeStatus.trim()||"?"}),e.jsx("span",{title:s.path,children:s.path})]},`${t.label}:${s.fileId}`))]},t.label):null),a.nextCursor?e.jsx("button",{type:"button",className:"text-button resource-load-more",onClick:()=>{z()},disabled:R,children:"加载更多变更"}):null,e.jsxs("div",{className:"git-history",children:[e.jsx("h3",{children:"提交历史"}),j?.items.map(t=>e.jsxs("article",{children:[e.jsx("code",{children:t.shortId}),e.jsx("strong",{children:t.subject}),e.jsxs("span",{children:[t.authorName," · ",new Date(t.authoredAt).toLocaleDateString("zh-CN")]})]},t.id)),j?.nextCursor?e.jsx("button",{type:"button",className:"text-button resource-load-more",onClick:()=>{F()},disabled:R,children:"加载更多提交"}):null]})]}),e.jsx("section",{className:"git-diff","aria-label":"Git Diff",children:v?e.jsx(W,{page:v,loading:R,onLoadMore:v.nextCursor&&G?()=>{M(G,v.nextCursor??void 0)}:void 0,onSendToComposer:o}):e.jsxs("div",{className:"resource-empty",children:[e.jsx(g,{name:"code"}),e.jsx("strong",{children:"选择变更查看 Diff"}),e.jsx("p",{children:"Diff 来自受限 Git read model,不解析对话或工具输出。"})]})})]})]})}function H({message:c,onRetry:m}){return e.jsxs("div",{className:"resource-empty",role:"alert",children:[e.jsx(g,{name:"warning"}),e.jsx("strong",{children:"Git 状态读取失败"}),e.jsx("p",{children:c}),e.jsx("button",{type:"button",className:"secondary-button",onClick:m,children:"重试"})]})}function S(c){return c instanceof Error?c.message:"Git 请求失败。"}function L(c){return c instanceof _&&c.code==="git_revision_conflict"}function A(){return new _("仓库版本已变化。",409,"git_revision_conflict")}function C(c,m){const u=new Map(c.map(o=>[o.fileId,o]));for(const o of m)u.set(o.fileId,o);return[...u.values()]}function V(c,m){const u=new Map(c.map(o=>[o.id,o]));for(const o of m)u.set(o.id,o);return[...u.values()]}export{K as GitPanel};
@@ -0,0 +1 @@
1
+ import{r,j as e,I as o,S as $,W as F}from"./index-30GT9Vnx.js";import{D as z}from"./DiffViewer-DqbZ02RN.js";function W({workspaceId:c,refreshEpoch:D,actions:w,onSendToComposer:E}){const[t,b]=r.useState(null),[v,f]=r.useState(null),[h,x]=r.useState(null),[C,j]=r.useState(!1),[m,u]=r.useState(""),[S,g]=r.useState(""),n=r.useRef(0),i=r.useRef(0),N=async(s=n.current)=>{if(s===n.current){j(!0),u("");try{const l=await w.review();if(s!==n.current)return;b(l),f(null),x(null)}catch(l){if(s!==n.current)return;u(k(l))}finally{s===n.current&&j(!1)}}},I=()=>{const s=n.current+1;n.current=s,i.current+=1,g(""),N(s)};r.useEffect(()=>{const s=n.current+1;n.current=s,i.current+=1,b(null),f(null),x(null),u(""),g(""),c&&N(s)},[D,c]);const R=async(s,l,d=n.current,p=i.current+1)=>{if(d===n.current){i.current=p,l||(f(s),x(null)),j(!0),u("");try{const a=await w.gitDiff(s.fileId,l);if(d!==n.current||p!==i.current||a.fileId!==s.fileId)return;f(s),x(y=>l&&y&&y.fileId===a.fileId?{...a,lines:[...y.lines,...a.lines]}:a)}catch(a){if(d!==n.current||p!==i.current)return;if(A(a)){g("仓库已变化,已重新建立审阅快照。"),await N(d);return}u(k(a))}finally{d===n.current&&p===i.current&&j(!1)}}};return!t&&!m?e.jsx("p",{className:"resource-loading",children:"正在建立审阅快照…"}):t?e.jsxs("div",{className:"work-resource-panel review-panel",children:[e.jsxs("div",{className:"review-summary",children:[e.jsxs("div",{children:[e.jsx("span",{className:`review-score ${t.clean?"clean":"changed"}`,children:t.clean?e.jsx(o,{name:"check"}):e.jsx(o,{name:"edit"})}),e.jsxs("div",{children:[e.jsx("strong",{children:t.clean?"没有待审阅变更":`${t.totalChangedFiles} 个变更文件`}),e.jsxs("span",{children:[t.truncated?"当前显示 · ":"",t.stagedCount," staged · ",t.unstagedCount," unstaged ·"," ",t.untrackedCount," untracked · ",t.conflictCount," conflict"]})]})]}),e.jsx("button",{type:"button",className:"icon-button","aria-label":"刷新审阅快照",disabled:C,onClick:I,children:e.jsx(o,{name:"refresh",size:15})})]}),t.truncated?e.jsxs("p",{className:"resource-notice",role:"status",children:["当前显示 ",t.changedFiles.length," / ",t.totalChangedFiles," ","个变更文件;分类计数仅覆盖当前显示范围。"]}):null,S?e.jsx("p",{className:"resource-notice",role:"status",children:S}):null,m?e.jsx("p",{className:"resource-error",role:"alert",children:m}):null,e.jsxs("div",{className:"review-layout",children:[e.jsxs("section",{className:"review-files","aria-label":"待审阅文件",children:[t.changedFiles.map(s=>e.jsxs("button",{type:"button",className:v?.fileId===s.fileId?"selected":"",onClick:()=>{R(s)},children:[e.jsx(o,{name:"code",size:14}),e.jsx("span",{title:s.path,children:s.path}),e.jsx("small",{children:`${s.indexStatus}${s.worktreeStatus}`.trim()||"?"})]},s.fileId)),e.jsxs("div",{className:"review-verification",children:[e.jsx("h3",{children:"验证证据"}),t.verification.length?t.verification.map(s=>e.jsxs("article",{children:[e.jsx($,{state:s.state}),e.jsxs("div",{children:[e.jsx("strong",{children:s.toolName}),e.jsxs("small",{children:[s.state," · ",s.outputBytes," B",s.hasArtifact?" · artifact":""]})]})]},`${s.callId}:${s.toolName}`)):e.jsx("p",{className:"muted-copy",children:"当前没有持久化验证结果。"})]})]}),e.jsx("section",{className:"review-diff","aria-label":"审阅 Diff",children:h?e.jsx(z,{page:h,loading:C,onLoadMore:h.nextCursor&&v?()=>{R(v,h.nextCursor??void 0)}:void 0,onSendToComposer:E}):e.jsxs("div",{className:"resource-empty",children:[e.jsx(o,{name:"edit"}),e.jsx("strong",{children:"选择文件开始审阅"}),e.jsx("p",{children:"你可以把某个 Hunk 作为草稿送回对话,提交前仍由你确认。"})]})})]})]}):e.jsxs("div",{className:"resource-empty",role:"alert",children:[e.jsx(o,{name:"warning"}),e.jsx("strong",{children:"无法读取审阅快照"}),e.jsx("p",{children:m}),e.jsx("button",{type:"button",className:"secondary-button",onClick:I,children:"重试"})]})}function k(c){return c instanceof Error?c.message:"审阅请求失败。"}function A(c){return c instanceof F&&c.code==="git_revision_conflict"}export{W as ReviewPanel};
@@ -1,4 +1,4 @@
1
- var An=Object.defineProperty;var On=(e,t,i)=>t in e?An(e,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[t]=i;var _e=(e,t,i)=>On(e,typeof t!="symbol"?t+"":t,i);import{r as I,j as w,I as xt}from"./index-C6TDJwMC.js";var Nn=2,In=1,Hn=class{activate(e){this._terminal=e}dispose(){}fit(){let e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;let t=this._terminal._core;(this._terminal.rows!==e.rows||this._terminal.cols!==e.cols)&&(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal||!this._terminal.element||!this._terminal.element.parentElement)return;let e=this._terminal._core._renderService.dimensions;if(e.css.cell.width===0||e.css.cell.height===0)return;let t=this._terminal.options.scrollback===0?0:this._terminal.options.overviewRuler?.width||14,i=window.getComputedStyle(this._terminal.element.parentElement),s=parseInt(i.getPropertyValue("height")),r=Math.max(0,parseInt(i.getPropertyValue("width"))),n=window.getComputedStyle(this._terminal.element),o={top:parseInt(n.getPropertyValue("padding-top")),bottom:parseInt(n.getPropertyValue("padding-bottom")),right:parseInt(n.getPropertyValue("padding-right")),left:parseInt(n.getPropertyValue("padding-left"))},a=o.top+o.bottom,h=o.right+o.left,l=s-a,c=r-h-t;return{cols:Math.max(Nn,Math.floor(c/e.css.cell.width)),rows:Math.max(In,Math.floor(l/e.css.cell.height))}}};var Or=Object.defineProperty,Fn=Object.getOwnPropertyDescriptor,Wn=(e,t)=>{for(var i in t)Or(e,i,{get:t[i],enumerable:!0})},Q=(e,t,i,s)=>{for(var r=s>1?void 0:s?Fn(t,i):t,n=e.length-1,o;n>=0;n--)(o=e[n])&&(r=(s?o(t,i,r):o(r))||r);return s&&r&&Or(t,i,r),r},x=(e,t)=>(i,s)=>t(i,s,e),Ts="Terminal input",Li={get:()=>Ts,set:e=>Ts=e},Ps="Too much output to announce, navigate to rows manually to read",Ti={get:()=>Ps,set:e=>Ps=e};function zn(e){return e.replace(/\r?\n/g,"\r")}function $n(e,t){return t?"\x1B[200~"+e+"\x1B[201~":e}function Kn(e,t){e.clipboardData&&e.clipboardData.setData("text/plain",t.selectionText),e.preventDefault()}function Un(e,t,i,s){if(e.stopPropagation(),e.clipboardData){let r=e.clipboardData.getData("text/plain");Nr(r,t,i,s)}}function Nr(e,t,i,s){e=zn(e),e=$n(e,i.decPrivateModes.bracketedPasteMode&&s.rawOptions.ignoreBracketedPasteMode!==!0),i.triggerDataEvent(e,!0),t.value=""}function Ir(e,t,i){let s=i.getBoundingClientRect(),r=e.clientX-s.left-10,n=e.clientY-s.top-10;t.style.width="20px",t.style.height="20px",t.style.left=`${r}px`,t.style.top=`${n}px`,t.style.zIndex="1000",t.focus()}function As(e,t,i,s,r){Ir(e,t,i),r&&s.rightClickSelect(e),t.value=s.selectionText,t.select()}function st(e){return e>65535?(e-=65536,String.fromCharCode((e>>10)+55296)+String.fromCharCode(e%1024+56320)):String.fromCharCode(e)}function _i(e,t=0,i=e.length){let s="";for(let r=t;r<i;++r){let n=e[r];n>65535?(n-=65536,s+=String.fromCharCode((n>>10)+55296)+String.fromCharCode(n%1024+56320)):s+=String.fromCharCode(n)}return s}var qn=class{constructor(){this._interim=0}clear(){this._interim=0}decode(e,t){let i=e.length;if(!i)return 0;let s=0,r=0;if(this._interim){let n=e.charCodeAt(r++);56320<=n&&n<=57343?t[s++]=(this._interim-55296)*1024+n-56320+65536:(t[s++]=this._interim,t[s++]=n),this._interim=0}for(let n=r;n<i;++n){let o=e.charCodeAt(n);if(55296<=o&&o<=56319){if(++n>=i)return this._interim=o,s;let a=e.charCodeAt(n);56320<=a&&a<=57343?t[s++]=(o-55296)*1024+a-56320+65536:(t[s++]=o,t[s++]=a);continue}o!==65279&&(t[s++]=o)}return s}},Vn=class{constructor(){this.interim=new Uint8Array(3)}clear(){this.interim.fill(0)}decode(e,t){let i=e.length;if(!i)return 0;let s=0,r,n,o,a,h=0,l=0;if(this.interim[0]){let _=!1,f=this.interim[0];f&=(f&224)===192?31:(f&240)===224?15:7;let u=0,g;for(;(g=this.interim[++u]&63)&&u<4;)f<<=6,f|=g;let b=(this.interim[0]&224)===192?2:(this.interim[0]&240)===224?3:4,D=b-u;for(;l<D;){if(l>=i)return 0;if(g=e[l++],(g&192)!==128){l--,_=!0;break}else this.interim[u++]=g,f<<=6,f|=g&63}_||(b===2?f<128?l--:t[s++]=f:b===3?f<2048||f>=55296&&f<=57343||f===65279||(t[s++]=f):f<65536||f>1114111||(t[s++]=f)),this.interim.fill(0)}let c=i-4,d=l;for(;d<i;){for(;d<c&&!((r=e[d])&128)&&!((n=e[d+1])&128)&&!((o=e[d+2])&128)&&!((a=e[d+3])&128);)t[s++]=r,t[s++]=n,t[s++]=o,t[s++]=a,d+=4;if(r=e[d++],r<128)t[s++]=r;else if((r&224)===192){if(d>=i)return this.interim[0]=r,s;if(n=e[d++],(n&192)!==128){d--;continue}if(h=(r&31)<<6|n&63,h<128){d--;continue}t[s++]=h}else if((r&240)===224){if(d>=i)return this.interim[0]=r,s;if(n=e[d++],(n&192)!==128){d--;continue}if(d>=i)return this.interim[0]=r,this.interim[1]=n,s;if(o=e[d++],(o&192)!==128){d--;continue}if(h=(r&15)<<12|(n&63)<<6|o&63,h<2048||h>=55296&&h<=57343||h===65279)continue;t[s++]=h}else if((r&248)===240){if(d>=i)return this.interim[0]=r,s;if(n=e[d++],(n&192)!==128){d--;continue}if(d>=i)return this.interim[0]=r,this.interim[1]=n,s;if(o=e[d++],(o&192)!==128){d--;continue}if(d>=i)return this.interim[0]=r,this.interim[1]=n,this.interim[2]=o,s;if(a=e[d++],(a&192)!==128){d--;continue}if(h=(r&7)<<18|(n&63)<<12|(o&63)<<6|a&63,h<65536||h>1114111)continue;t[s++]=h}}return s}},Hr="",rt=" ",Kt=class Fr{constructor(){this.fg=0,this.bg=0,this.extended=new ai}static toColorRGB(t){return[t>>>16&255,t>>>8&255,t&255]}static fromColorRGB(t){return(t[0]&255)<<16|(t[1]&255)<<8|t[2]&255}clone(){let t=new Fr;return t.fg=this.fg,t.bg=this.bg,t.extended=this.extended.clone(),t}isInverse(){return this.fg&67108864}isBold(){return this.fg&134217728}isUnderline(){return this.hasExtendedAttrs()&&this.extended.underlineStyle!==0?1:this.fg&268435456}isBlink(){return this.fg&536870912}isInvisible(){return this.fg&1073741824}isItalic(){return this.bg&67108864}isDim(){return this.bg&134217728}isStrikethrough(){return this.fg&2147483648}isProtected(){return this.bg&536870912}isOverline(){return this.bg&1073741824}getFgColorMode(){return this.fg&50331648}getBgColorMode(){return this.bg&50331648}isFgRGB(){return(this.fg&50331648)===50331648}isBgRGB(){return(this.bg&50331648)===50331648}isFgPalette(){return(this.fg&50331648)===16777216||(this.fg&50331648)===33554432}isBgPalette(){return(this.bg&50331648)===16777216||(this.bg&50331648)===33554432}isFgDefault(){return(this.fg&50331648)===0}isBgDefault(){return(this.bg&50331648)===0}isAttributeDefault(){return this.fg===0&&this.bg===0}getFgColor(){switch(this.fg&50331648){case 16777216:case 33554432:return this.fg&255;case 50331648:return this.fg&16777215;default:return-1}}getBgColor(){switch(this.bg&50331648){case 16777216:case 33554432:return this.bg&255;case 50331648:return this.bg&16777215;default:return-1}}hasExtendedAttrs(){return this.bg&268435456}updateExtended(){this.extended.isEmpty()?this.bg&=-268435457:this.bg|=268435456}getUnderlineColor(){if(this.bg&268435456&&~this.extended.underlineColor)switch(this.extended.underlineColor&50331648){case 16777216:case 33554432:return this.extended.underlineColor&255;case 50331648:return this.extended.underlineColor&16777215;default:return this.getFgColor()}return this.getFgColor()}getUnderlineColorMode(){return this.bg&268435456&&~this.extended.underlineColor?this.extended.underlineColor&50331648:this.getFgColorMode()}isUnderlineColorRGB(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)===50331648:this.isFgRGB()}isUnderlineColorPalette(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)===16777216||(this.extended.underlineColor&50331648)===33554432:this.isFgPalette()}isUnderlineColorDefault(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)===0:this.isFgDefault()}getUnderlineStyle(){return this.fg&268435456?this.bg&268435456?this.extended.underlineStyle:1:0}getUnderlineVariantOffset(){return this.extended.underlineVariantOffset}},ai=class Wr{constructor(t=0,i=0){this._ext=0,this._urlId=0,this._ext=t,this._urlId=i}get ext(){return this._urlId?this._ext&-469762049|this.underlineStyle<<26:this._ext}set ext(t){this._ext=t}get underlineStyle(){return this._urlId?5:(this._ext&469762048)>>26}set underlineStyle(t){this._ext&=-469762049,this._ext|=t<<26&469762048}get underlineColor(){return this._ext&67108863}set underlineColor(t){this._ext&=-67108864,this._ext|=t&67108863}get urlId(){return this._urlId}set urlId(t){this._urlId=t}get underlineVariantOffset(){let t=(this._ext&3758096384)>>29;return t<0?t^4294967288:t}set underlineVariantOffset(t){this._ext&=536870911,this._ext|=t<<29&3758096384}clone(){return new Wr(this._ext,this._urlId)}isEmpty(){return this.underlineStyle===0&&this._urlId===0}},Oe=class zr extends Kt{constructor(){super(...arguments),this.content=0,this.fg=0,this.bg=0,this.extended=new ai,this.combinedData=""}static fromCharData(t){let i=new zr;return i.setFromCharData(t),i}isCombined(){return this.content&2097152}getWidth(){return this.content>>22}getChars(){return this.content&2097152?this.combinedData:this.content&2097151?st(this.content&2097151):""}getCode(){return this.isCombined()?this.combinedData.charCodeAt(this.combinedData.length-1):this.content&2097151}setFromCharData(t){this.fg=t[0],this.bg=0;let i=!1;if(t[1].length>2)i=!0;else if(t[1].length===2){let s=t[1].charCodeAt(0);if(55296<=s&&s<=56319){let r=t[1].charCodeAt(1);56320<=r&&r<=57343?this.content=(s-55296)*1024+r-56320+65536|t[2]<<22:i=!0}else i=!0}else this.content=t[1].charCodeAt(0)|t[2]<<22;i&&(this.combinedData=t[1],this.content=2097152|t[2]<<22)}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}},Os="di$target",Pi="di$dependencies",mi=new Map;function jn(e){return e[Pi]||[]}function ue(e){if(mi.has(e))return mi.get(e);let t=function(i,s,r){if(arguments.length!==3)throw new Error("@IServiceName-decorator can only be used to decorate a parameter");Yn(t,i,r)};return t._id=e,mi.set(e,t),t}function Yn(e,t,i){t[Os]===t?t[Pi].push({id:e,index:i}):(t[Pi]=[{id:e,index:i}],t[Os]=t)}var we=ue("BufferService"),$r=ue("CoreMouseService"),gt=ue("CoreService"),Xn=ue("CharsetService"),vs=ue("InstantiationService"),Kr=ue("LogService"),ye=ue("OptionsService"),Ur=ue("OscLinkService"),Gn=ue("UnicodeService"),Ut=ue("DecorationService"),Ai=class{constructor(e,t,i){this._bufferService=e,this._optionsService=t,this._oscLinkService=i}provideLinks(e,t){let i=this._bufferService.buffer.lines.get(e-1);if(!i){t(void 0);return}let s=[],r=this._optionsService.rawOptions.linkHandler,n=new Oe,o=i.getTrimmedLength(),a=-1,h=-1,l=!1;for(let c=0;c<o;c++)if(!(h===-1&&!i.hasContent(c))){if(i.loadCell(c,n),n.hasExtendedAttrs()&&n.extended.urlId)if(h===-1){h=c,a=n.extended.urlId;continue}else l=n.extended.urlId!==a;else h!==-1&&(l=!0);if(l||h!==-1&&c===o-1){let d=this._oscLinkService.getLinkData(a)?.uri;if(d){let _={start:{x:h+1,y:e},end:{x:c+(!l&&c===o-1?1:0),y:e}},f=!1;if(!r?.allowNonHttpProtocols)try{let u=new URL(d);["http:","https:"].includes(u.protocol)||(f=!0)}catch{f=!0}f||s.push({text:d,range:_,activate:(u,g)=>r?r.activate(u,g,_):Jn(u,g),hover:(u,g)=>r?.hover?.(u,g,_),leave:(u,g)=>r?.leave?.(u,g,_)})}l=!1,n.hasExtendedAttrs()&&n.extended.urlId?(h=c,a=n.extended.urlId):(h=-1,a=-1)}}t(s)}};Ai=Q([x(0,we),x(1,ye),x(2,Ur)],Ai);function Jn(e,t){if(confirm(`Do you want to navigate to ${t}?
1
+ var An=Object.defineProperty;var On=(e,t,i)=>t in e?An(e,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[t]=i;var _e=(e,t,i)=>On(e,typeof t!="symbol"?t+"":t,i);import{r as I,j as w,I as xt}from"./index-30GT9Vnx.js";var Nn=2,In=1,Hn=class{activate(e){this._terminal=e}dispose(){}fit(){let e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;let t=this._terminal._core;(this._terminal.rows!==e.rows||this._terminal.cols!==e.cols)&&(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal||!this._terminal.element||!this._terminal.element.parentElement)return;let e=this._terminal._core._renderService.dimensions;if(e.css.cell.width===0||e.css.cell.height===0)return;let t=this._terminal.options.scrollback===0?0:this._terminal.options.overviewRuler?.width||14,i=window.getComputedStyle(this._terminal.element.parentElement),s=parseInt(i.getPropertyValue("height")),r=Math.max(0,parseInt(i.getPropertyValue("width"))),n=window.getComputedStyle(this._terminal.element),o={top:parseInt(n.getPropertyValue("padding-top")),bottom:parseInt(n.getPropertyValue("padding-bottom")),right:parseInt(n.getPropertyValue("padding-right")),left:parseInt(n.getPropertyValue("padding-left"))},a=o.top+o.bottom,h=o.right+o.left,l=s-a,c=r-h-t;return{cols:Math.max(Nn,Math.floor(c/e.css.cell.width)),rows:Math.max(In,Math.floor(l/e.css.cell.height))}}};var Or=Object.defineProperty,Fn=Object.getOwnPropertyDescriptor,Wn=(e,t)=>{for(var i in t)Or(e,i,{get:t[i],enumerable:!0})},Q=(e,t,i,s)=>{for(var r=s>1?void 0:s?Fn(t,i):t,n=e.length-1,o;n>=0;n--)(o=e[n])&&(r=(s?o(t,i,r):o(r))||r);return s&&r&&Or(t,i,r),r},x=(e,t)=>(i,s)=>t(i,s,e),Ts="Terminal input",Li={get:()=>Ts,set:e=>Ts=e},Ps="Too much output to announce, navigate to rows manually to read",Ti={get:()=>Ps,set:e=>Ps=e};function zn(e){return e.replace(/\r?\n/g,"\r")}function $n(e,t){return t?"\x1B[200~"+e+"\x1B[201~":e}function Kn(e,t){e.clipboardData&&e.clipboardData.setData("text/plain",t.selectionText),e.preventDefault()}function Un(e,t,i,s){if(e.stopPropagation(),e.clipboardData){let r=e.clipboardData.getData("text/plain");Nr(r,t,i,s)}}function Nr(e,t,i,s){e=zn(e),e=$n(e,i.decPrivateModes.bracketedPasteMode&&s.rawOptions.ignoreBracketedPasteMode!==!0),i.triggerDataEvent(e,!0),t.value=""}function Ir(e,t,i){let s=i.getBoundingClientRect(),r=e.clientX-s.left-10,n=e.clientY-s.top-10;t.style.width="20px",t.style.height="20px",t.style.left=`${r}px`,t.style.top=`${n}px`,t.style.zIndex="1000",t.focus()}function As(e,t,i,s,r){Ir(e,t,i),r&&s.rightClickSelect(e),t.value=s.selectionText,t.select()}function st(e){return e>65535?(e-=65536,String.fromCharCode((e>>10)+55296)+String.fromCharCode(e%1024+56320)):String.fromCharCode(e)}function _i(e,t=0,i=e.length){let s="";for(let r=t;r<i;++r){let n=e[r];n>65535?(n-=65536,s+=String.fromCharCode((n>>10)+55296)+String.fromCharCode(n%1024+56320)):s+=String.fromCharCode(n)}return s}var qn=class{constructor(){this._interim=0}clear(){this._interim=0}decode(e,t){let i=e.length;if(!i)return 0;let s=0,r=0;if(this._interim){let n=e.charCodeAt(r++);56320<=n&&n<=57343?t[s++]=(this._interim-55296)*1024+n-56320+65536:(t[s++]=this._interim,t[s++]=n),this._interim=0}for(let n=r;n<i;++n){let o=e.charCodeAt(n);if(55296<=o&&o<=56319){if(++n>=i)return this._interim=o,s;let a=e.charCodeAt(n);56320<=a&&a<=57343?t[s++]=(o-55296)*1024+a-56320+65536:(t[s++]=o,t[s++]=a);continue}o!==65279&&(t[s++]=o)}return s}},Vn=class{constructor(){this.interim=new Uint8Array(3)}clear(){this.interim.fill(0)}decode(e,t){let i=e.length;if(!i)return 0;let s=0,r,n,o,a,h=0,l=0;if(this.interim[0]){let _=!1,f=this.interim[0];f&=(f&224)===192?31:(f&240)===224?15:7;let u=0,g;for(;(g=this.interim[++u]&63)&&u<4;)f<<=6,f|=g;let b=(this.interim[0]&224)===192?2:(this.interim[0]&240)===224?3:4,D=b-u;for(;l<D;){if(l>=i)return 0;if(g=e[l++],(g&192)!==128){l--,_=!0;break}else this.interim[u++]=g,f<<=6,f|=g&63}_||(b===2?f<128?l--:t[s++]=f:b===3?f<2048||f>=55296&&f<=57343||f===65279||(t[s++]=f):f<65536||f>1114111||(t[s++]=f)),this.interim.fill(0)}let c=i-4,d=l;for(;d<i;){for(;d<c&&!((r=e[d])&128)&&!((n=e[d+1])&128)&&!((o=e[d+2])&128)&&!((a=e[d+3])&128);)t[s++]=r,t[s++]=n,t[s++]=o,t[s++]=a,d+=4;if(r=e[d++],r<128)t[s++]=r;else if((r&224)===192){if(d>=i)return this.interim[0]=r,s;if(n=e[d++],(n&192)!==128){d--;continue}if(h=(r&31)<<6|n&63,h<128){d--;continue}t[s++]=h}else if((r&240)===224){if(d>=i)return this.interim[0]=r,s;if(n=e[d++],(n&192)!==128){d--;continue}if(d>=i)return this.interim[0]=r,this.interim[1]=n,s;if(o=e[d++],(o&192)!==128){d--;continue}if(h=(r&15)<<12|(n&63)<<6|o&63,h<2048||h>=55296&&h<=57343||h===65279)continue;t[s++]=h}else if((r&248)===240){if(d>=i)return this.interim[0]=r,s;if(n=e[d++],(n&192)!==128){d--;continue}if(d>=i)return this.interim[0]=r,this.interim[1]=n,s;if(o=e[d++],(o&192)!==128){d--;continue}if(d>=i)return this.interim[0]=r,this.interim[1]=n,this.interim[2]=o,s;if(a=e[d++],(a&192)!==128){d--;continue}if(h=(r&7)<<18|(n&63)<<12|(o&63)<<6|a&63,h<65536||h>1114111)continue;t[s++]=h}}return s}},Hr="",rt=" ",Kt=class Fr{constructor(){this.fg=0,this.bg=0,this.extended=new ai}static toColorRGB(t){return[t>>>16&255,t>>>8&255,t&255]}static fromColorRGB(t){return(t[0]&255)<<16|(t[1]&255)<<8|t[2]&255}clone(){let t=new Fr;return t.fg=this.fg,t.bg=this.bg,t.extended=this.extended.clone(),t}isInverse(){return this.fg&67108864}isBold(){return this.fg&134217728}isUnderline(){return this.hasExtendedAttrs()&&this.extended.underlineStyle!==0?1:this.fg&268435456}isBlink(){return this.fg&536870912}isInvisible(){return this.fg&1073741824}isItalic(){return this.bg&67108864}isDim(){return this.bg&134217728}isStrikethrough(){return this.fg&2147483648}isProtected(){return this.bg&536870912}isOverline(){return this.bg&1073741824}getFgColorMode(){return this.fg&50331648}getBgColorMode(){return this.bg&50331648}isFgRGB(){return(this.fg&50331648)===50331648}isBgRGB(){return(this.bg&50331648)===50331648}isFgPalette(){return(this.fg&50331648)===16777216||(this.fg&50331648)===33554432}isBgPalette(){return(this.bg&50331648)===16777216||(this.bg&50331648)===33554432}isFgDefault(){return(this.fg&50331648)===0}isBgDefault(){return(this.bg&50331648)===0}isAttributeDefault(){return this.fg===0&&this.bg===0}getFgColor(){switch(this.fg&50331648){case 16777216:case 33554432:return this.fg&255;case 50331648:return this.fg&16777215;default:return-1}}getBgColor(){switch(this.bg&50331648){case 16777216:case 33554432:return this.bg&255;case 50331648:return this.bg&16777215;default:return-1}}hasExtendedAttrs(){return this.bg&268435456}updateExtended(){this.extended.isEmpty()?this.bg&=-268435457:this.bg|=268435456}getUnderlineColor(){if(this.bg&268435456&&~this.extended.underlineColor)switch(this.extended.underlineColor&50331648){case 16777216:case 33554432:return this.extended.underlineColor&255;case 50331648:return this.extended.underlineColor&16777215;default:return this.getFgColor()}return this.getFgColor()}getUnderlineColorMode(){return this.bg&268435456&&~this.extended.underlineColor?this.extended.underlineColor&50331648:this.getFgColorMode()}isUnderlineColorRGB(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)===50331648:this.isFgRGB()}isUnderlineColorPalette(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)===16777216||(this.extended.underlineColor&50331648)===33554432:this.isFgPalette()}isUnderlineColorDefault(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)===0:this.isFgDefault()}getUnderlineStyle(){return this.fg&268435456?this.bg&268435456?this.extended.underlineStyle:1:0}getUnderlineVariantOffset(){return this.extended.underlineVariantOffset}},ai=class Wr{constructor(t=0,i=0){this._ext=0,this._urlId=0,this._ext=t,this._urlId=i}get ext(){return this._urlId?this._ext&-469762049|this.underlineStyle<<26:this._ext}set ext(t){this._ext=t}get underlineStyle(){return this._urlId?5:(this._ext&469762048)>>26}set underlineStyle(t){this._ext&=-469762049,this._ext|=t<<26&469762048}get underlineColor(){return this._ext&67108863}set underlineColor(t){this._ext&=-67108864,this._ext|=t&67108863}get urlId(){return this._urlId}set urlId(t){this._urlId=t}get underlineVariantOffset(){let t=(this._ext&3758096384)>>29;return t<0?t^4294967288:t}set underlineVariantOffset(t){this._ext&=536870911,this._ext|=t<<29&3758096384}clone(){return new Wr(this._ext,this._urlId)}isEmpty(){return this.underlineStyle===0&&this._urlId===0}},Oe=class zr extends Kt{constructor(){super(...arguments),this.content=0,this.fg=0,this.bg=0,this.extended=new ai,this.combinedData=""}static fromCharData(t){let i=new zr;return i.setFromCharData(t),i}isCombined(){return this.content&2097152}getWidth(){return this.content>>22}getChars(){return this.content&2097152?this.combinedData:this.content&2097151?st(this.content&2097151):""}getCode(){return this.isCombined()?this.combinedData.charCodeAt(this.combinedData.length-1):this.content&2097151}setFromCharData(t){this.fg=t[0],this.bg=0;let i=!1;if(t[1].length>2)i=!0;else if(t[1].length===2){let s=t[1].charCodeAt(0);if(55296<=s&&s<=56319){let r=t[1].charCodeAt(1);56320<=r&&r<=57343?this.content=(s-55296)*1024+r-56320+65536|t[2]<<22:i=!0}else i=!0}else this.content=t[1].charCodeAt(0)|t[2]<<22;i&&(this.combinedData=t[1],this.content=2097152|t[2]<<22)}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}},Os="di$target",Pi="di$dependencies",mi=new Map;function jn(e){return e[Pi]||[]}function ue(e){if(mi.has(e))return mi.get(e);let t=function(i,s,r){if(arguments.length!==3)throw new Error("@IServiceName-decorator can only be used to decorate a parameter");Yn(t,i,r)};return t._id=e,mi.set(e,t),t}function Yn(e,t,i){t[Os]===t?t[Pi].push({id:e,index:i}):(t[Pi]=[{id:e,index:i}],t[Os]=t)}var we=ue("BufferService"),$r=ue("CoreMouseService"),gt=ue("CoreService"),Xn=ue("CharsetService"),vs=ue("InstantiationService"),Kr=ue("LogService"),ye=ue("OptionsService"),Ur=ue("OscLinkService"),Gn=ue("UnicodeService"),Ut=ue("DecorationService"),Ai=class{constructor(e,t,i){this._bufferService=e,this._optionsService=t,this._oscLinkService=i}provideLinks(e,t){let i=this._bufferService.buffer.lines.get(e-1);if(!i){t(void 0);return}let s=[],r=this._optionsService.rawOptions.linkHandler,n=new Oe,o=i.getTrimmedLength(),a=-1,h=-1,l=!1;for(let c=0;c<o;c++)if(!(h===-1&&!i.hasContent(c))){if(i.loadCell(c,n),n.hasExtendedAttrs()&&n.extended.urlId)if(h===-1){h=c,a=n.extended.urlId;continue}else l=n.extended.urlId!==a;else h!==-1&&(l=!0);if(l||h!==-1&&c===o-1){let d=this._oscLinkService.getLinkData(a)?.uri;if(d){let _={start:{x:h+1,y:e},end:{x:c+(!l&&c===o-1?1:0),y:e}},f=!1;if(!r?.allowNonHttpProtocols)try{let u=new URL(d);["http:","https:"].includes(u.protocol)||(f=!0)}catch{f=!0}f||s.push({text:d,range:_,activate:(u,g)=>r?r.activate(u,g,_):Jn(u,g),hover:(u,g)=>r?.hover?.(u,g,_),leave:(u,g)=>r?.leave?.(u,g,_)})}l=!1,n.hasExtendedAttrs()&&n.extended.urlId?(h=c,a=n.extended.urlId):(h=-1,a=-1)}}t(s)}};Ai=Q([x(0,we),x(1,ye),x(2,Ur)],Ai);function Jn(e,t){if(confirm(`Do you want to navigate to ${t}?
2
2
 
3
3
  WARNING: This link could potentially be dangerous`)){let i=window.open();if(i){try{i.opener=null}catch{}i.location.href=t}else console.warn("Opening link blocked as opener could not be cleared")}}var fi=ue("CharSizeService"),Ge=ue("CoreBrowserService"),Ss=ue("MouseService"),Je=ue("RenderService"),Zn=ue("SelectionService"),qr=ue("CharacterJoinerService"),yt=ue("ThemeService"),Vr=ue("LinkProviderService"),Qn=class{constructor(){this.listeners=[],this.unexpectedErrorHandler=function(e){setTimeout(()=>{throw e.stack?Ns.isErrorNoTelemetry(e)?new Ns(e.message+`
4
4