-
Notifications
You must be signed in to change notification settings - Fork 5
Provide a package selection dialog when installing skills #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
00d13ad
9b54eb1
b8e3f8d
4ac6a7b
1f1f0b3
303424f
5ffeba2
1493322
63eb014
24546b4
3404053
64bcc64
bc46071
93384a0
cdedb56
cab7f98
17ea6fc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,14 +21,16 @@ import 'package:skills/src/models/global_config.dart'; | |
| import '../models/skill_manifest.dart'; | ||
|
|
||
| /// Installs skills from package dependencies for [ides]. | ||
| /// | ||
| /// Returns `true` on success or `false` otherwise. | ||
| Future<bool> getSkills({ | ||
| required List<Ide> ides, | ||
| required Logger logger, | ||
| required WorkspaceLayout workspace, | ||
| DialogSupport? dialogSupport, | ||
| GitRunner gitRunner = const GitRunner(), | ||
| String usage = '', | ||
| String? packageName, | ||
| Set<String>? packageNames, | ||
| }) async { | ||
| final ready = await PubRunner.ensureWorkspaceConfigs(workspace); | ||
| if (!ready) { | ||
|
|
@@ -37,12 +39,23 @@ Future<bool> getSkills({ | |
|
|
||
| final packages = await PackageResolver.resolveWorkspace( | ||
| workspace, | ||
| packageName: packageName, | ||
| packageNames: packageNames, | ||
| ); | ||
|
|
||
| if (packageName != null && packages.isEmpty) { | ||
| logger.severe('Package "$packageName" not found in dependencies.'); | ||
| return false; | ||
| if (packageNames != null) { | ||
| if (packages.isEmpty) { | ||
| logger | ||
| .severe('None of the requested packages were found in dependencies.'); | ||
| return false; | ||
| } | ||
|
|
||
| final foundNames = packages.map((p) => p.name).toSet(); | ||
| final missing = packageNames.difference(foundNames)..remove('all'); | ||
| if (missing.isNotEmpty) { | ||
| logger.warning( | ||
| 'Warning: The following requested packages were not found in ' | ||
| 'dependencies: ${missing.join(', ')}'); | ||
| } | ||
| } | ||
|
|
||
| final rootPath = workspace.rootPath; | ||
|
|
@@ -109,14 +122,51 @@ Future<bool> getSkills({ | |
| final dartSkills = await scanner.scan(packages); | ||
|
|
||
| final resolvedPackageNames = packages.map((p) => p.name).toSet(); | ||
| final skills = mergeSkills( | ||
| var skills = mergeSkills( | ||
| dartSkills: dartSkills, | ||
| registrySkills: registrySkills, | ||
| resolvedPackageNames: resolvedPackageNames, | ||
| ); | ||
|
|
||
| if (skills.isEmpty) { | ||
| logger.info('No skills found in ${packageName ?? "any"} packages.'); | ||
| logger.info('No skills found in ${packageNames ?? "any"} packages.'); | ||
| return false; | ||
| } | ||
|
|
||
| if (packageNames == null) { | ||
| final packagesWithSkills = | ||
| skills.map((skill) => skill.packageName).toSet().toList()..sort(); | ||
| if (packagesWithSkills.isNotEmpty) { | ||
| if (dialogSupport != null) { | ||
| final initialSelected = | ||
| Iterable<int>.generate(packagesWithSkills.length).toSet(); | ||
| final selectedIndices = await dialogSupport.showMultiSelectDialog( | ||
| packagesWithSkills, | ||
| title: 'Select packages to install skills from:', | ||
| initialSelected: initialSelected, | ||
| ); | ||
| if (selectedIndices != null) { | ||
| final selectedPackages = | ||
| selectedIndices.map((i) => packagesWithSkills[i]).toSet(); | ||
| skills.removeWhere((s) => !selectedPackages.contains(s.packageName)); | ||
| } else { | ||
| logger.info('Installation aborted by user.'); | ||
| return false; | ||
| } | ||
| } else { | ||
| logger.info('Available packages with skills:'); | ||
| for (final pkg in packagesWithSkills) { | ||
| logger.info(' $pkg'); | ||
| } | ||
| logger.info('Rerun with trailing arguments for each package you want ' | ||
| 'to install skills for, or `all` to install all skills.'); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if there is no dialogSupport, should we just default to all to mimic the previous behavior of
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think so - I want that to be more explicit personally. We do have the Primarily this is here for agentic usage and I think this message should help agents in terms of choosing which skills to actually install on the next call. Maybe they will just pass |
||
| return false; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (skills.isEmpty) { | ||
| logger.info('No skills selected to install.'); | ||
| return false; | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.