sessionCustomizationDiscovery.ts ×16

Frontier kind: Code frontier

unlabeled · c_4090e9d5348a

57 tests · 50524 LOC · 297 files · introduces 0 tests · 101 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
16 ranges101 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
4709 ranges50524 lines · 297 files · Browse complete extent
All tests (intent)
57 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 101 introduced LOC across 16 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/node/copilot/sessionCustomizationDiscovery.ts 101 introduced LOC · 16 ranges

Open complete file

826 */
827 public async scan(token: CancellationToken): Promise<readonly IDiscoveredDirectory[]> {
828 > await this.writeCustomizationDiscoveryDebugLog({ sessionCustomizationDiscovery.ts
829 > method: 'scan',
830 > workingDirectory: this._workingDirectory.toString(),
831 > userHome: this._userHome.toString(),
832 > });
833 > throwIfCancelled(token);
834 >
835 > const nextWatchRootUris = new ResourceMap<IWatchSpec>();
836 > const seen = new ResourceSet();
837 > const result: IDiscoveredDirectory[] = [];
838 >
839 > // Workspace first so it wins on URI conflicts.
840 > await Promise.all([
841 > ...searchRoots.workspace.map(root => this._scanRoot(this._workingDirectory, root, seen, result, nextWatchRootUris, token)),
842 > ...searchRoots.user.map(root => this._scanRoot(this._userHome, root, seen, result, nextWatchRootUris, token)),
843 > this._scanFixedDiscoveryFiles(this._workingDirectory, fixedDiscoveryFiles.workspace, seen, result, nextWatchRootUris, token),
844 > this._scanFixedDiscoveryFiles(this._userHome, fixedDiscoveryFiles.user, seen, result, nextWatchRootUris, token)
845 > ]);
846 >
847 > throwIfCancelled(token);
848 >
849 > this._reconcileWatchers(nextWatchRootUris);
850 > const sortedResult = result.sort(compareDiscoveredDirectory);
851 > await this.writeCustomizationDiscoveryDebugLog({
852 > method: 'scan',
853 > result: sortedResult.map(directory => ({
854 > type: directory.type,
855 > uri: directory.uri.toString(),
856 > files: directory.files.map(file => file.uri.toString()),
857 > })),
858 > });
859 > return sortedResult;
860 > }
861
862 /**
872 */
873 private async _watchAncestors(base: URI, path: readonly string[], watchRootUris: ResourceMap<IWatchSpec>, token: CancellationToken): Promise<boolean> {
874 > let current = base; sessionCustomizationDiscovery.ts
875 > for (const segment of path) {
876 > const parent = current;
877 > const child = joinPath(parent, segment);
878 > if (!watchRootUris.has(parent)) {
879 > throwIfCancelled(token);
880 > try {
881 > const stat = await this._fileService.resolve(parent);
882 if (!stat.isDirectory) {
883 return false;
884 }
886 > return false;
887 > }
888 > }
889 addWatch(watchRootUris, parent, false, child);
890 current = child;
891 }
893 > }
894
895 private _reconcileWatchers(nextWatchRootUris: ResourceMap<IWatchSpec>): void {
934 */
935 private async _scanFixedDiscoveryFiles(base: URI, roots: IFixedDiscoveryFile[], seen: ResourceSet, result: IDiscoveredDirectory[], watchRootUris: ResourceMap<IWatchSpec>, token: CancellationToken): Promise<void> {
936 > const filesByType = new Map<DiscoveredType, IDiscoveredFile[]>(); sessionCustomizationDiscovery.ts
937 > await Promise.all(roots.map(async root => {
938 > throwIfCancelled(token);
939 >
940 > if (!await this._watchAncestors(base, root.path, watchRootUris, token)) {
941 return;
942 }
944 > const rootUri = joinPath(base, ...root.path);
945 > let stat: IFileStatWithMetadata;
946 > try {
947 > stat = await this._fileService.resolve(rootUri, { resolveMetadata: true });
948 > } catch {
949 // Root does not exist (or is unreadable) — nothing to discover or watch.
950 return;
951 }
952 > if (!stat.isDirectory || !stat.children) { sessionCustomizationDiscovery.ts
953 return;
954 }
972 }
973 }
975 >
976 > for (const [type, files] of filesByType.entries()) {
977 if (files.length > 0) {
978 result.push({ uri: base, type, files: files.sort(compareDiscoveredFile), name: '', writable: false });
979 }
980 }
982
983 private async _scanRoot(base: URI, root: ISearchRoot, seen: ResourceSet, result: IDiscoveredDirectory[], watchRootUris: ResourceMap<IWatchSpec>, token: CancellationToken): Promise<void> {
984 > throwIfCancelled(token); sessionCustomizationDiscovery.ts
985 >
986 > const rootUri = joinPath(base, ...root.path);
987 > let stat: IFileStatWithMetadata | undefined = undefined;
988 > let children: IFileStatWithMetadata[] = [];
989 > try {
990 > stat = await this._fileService.resolve(rootUri, { resolveMetadata: true });
991 children = stat.children ?? [];
993 > // Root does not exist (or is unreadable) — still discover it as a possible source folder.
994 > }
995 >
996 > // Filenames are dynamic for these roots, so we watch the whole directory.
997 > // `addWatch` upgrades to recursive if any root requests it.
998 > await this._watchAncestors(base, root.path, watchRootUris, token);
999 > addWatch(watchRootUris, rootUri, root.recursive ?? false, rootUri);
1000 >
1001 > if (root.type === DiscoveredType.Skill) {
1002 > const files: IDiscoveredFile[] = [];
1003 > await Promise.all(children.map(async child => {
1004 throwIfCancelled(token);
1005
1016 }
1017 }
1019 > result.push({ uri: rootUri, type: root.type, files: files.sort(compareDiscoveredFile), name: root.name, writable: true });
1020 > } else if (root.type === DiscoveredType.Agent) {
1021 > const files: IDiscoveredFile[] = [];
1022 > // agents are markdown files directly under the root (no subdirectory scanning),
1023 > // excluding only exact-case README.md.
1024 > for (const child of children) {
1025 throwIfCancelled(token);
1026
1033 }
1034 }
1035 > result.push({ uri: rootUri, type: root.type, files: files.sort(compareDiscoveredFile), name: root.name, writable: true }); sessionCustomizationDiscovery.ts
1036 >
1037 > } else if (root.type === DiscoveredType.Instruction) {
1038 > const files: IDiscoveredFile[] = [];
1039 > // instructions are all .instructions.md files directly under the root or in a subdirectory
1040 > const findInstructions = async (stat: IFileStatWithMetadata, recursionLevel: number): Promise<void> => {
1041 throwIfCancelled(token);
1042
1063 }
1064 };
1066 await findInstructions(stat, 0);
1067 }
1068 > result.push({ uri: rootUri, type: root.type, files: files.sort(compareDiscoveredFile), name: root.name, writable: true }); sessionCustomizationDiscovery.ts
1069 > } else if (root.type === DiscoveredType.Hook) {
1070 > await this._scanForHooks(root, rootUri, stat, seen, result, token);
1071 > } else {
1072 this._logService.warn(`[SessionCustomizationDiscovery] Unrecognized root type '${root.type}' for root '${rootUri.toString()}'`);
1073 }
1075
1076 private async _scanForHooks(root: ISearchRoot, rootUri: URI, stat: IFileStatWithMetadata | undefined, seen: ResourceSet, result: IDiscoveredDirectory[], token: CancellationToken): Promise<void> {