sf-aidev 1.0.2 → 1.0.3

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 (137) hide show
  1. package/lib/commands/aidev/add/agent.d.ts +57 -0
  2. package/lib/commands/aidev/add/agent.js +168 -0
  3. package/lib/commands/aidev/add/agent.js.map +1 -0
  4. package/lib/commands/aidev/add/command.d.ts +57 -0
  5. package/lib/commands/aidev/add/command.js +168 -0
  6. package/lib/commands/aidev/add/command.js.map +1 -0
  7. package/lib/commands/aidev/add/prompt.d.ts +57 -0
  8. package/lib/commands/aidev/add/prompt.js +168 -0
  9. package/lib/commands/aidev/add/prompt.js.map +1 -0
  10. package/lib/commands/aidev/add/skill.d.ts +57 -0
  11. package/lib/commands/aidev/add/skill.js +168 -0
  12. package/lib/commands/aidev/add/skill.js.map +1 -0
  13. package/lib/commands/aidev/add.d.ts +49 -0
  14. package/lib/commands/aidev/add.js +180 -0
  15. package/lib/commands/aidev/add.js.map +1 -0
  16. package/lib/commands/aidev/init.d.ts +29 -0
  17. package/lib/commands/aidev/init.js +190 -0
  18. package/lib/commands/aidev/init.js.map +1 -0
  19. package/lib/commands/aidev/list/agents.d.ts +47 -0
  20. package/lib/commands/aidev/list/agents.js +217 -0
  21. package/lib/commands/aidev/list/agents.js.map +1 -0
  22. package/lib/commands/aidev/list/commands.d.ts +49 -0
  23. package/lib/commands/aidev/list/commands.js +220 -0
  24. package/lib/commands/aidev/list/commands.js.map +1 -0
  25. package/lib/commands/aidev/list/index.d.ts +37 -0
  26. package/lib/commands/aidev/list/index.js +123 -0
  27. package/lib/commands/aidev/list/index.js.map +1 -0
  28. package/lib/commands/aidev/list/instructions.d.ts +27 -0
  29. package/lib/commands/aidev/list/instructions.js +100 -0
  30. package/lib/commands/aidev/list/instructions.js.map +1 -0
  31. package/lib/commands/aidev/list/skills.d.ts +49 -0
  32. package/lib/commands/aidev/list/skills.js +220 -0
  33. package/lib/commands/aidev/list/skills.js.map +1 -0
  34. package/lib/commands/aidev/remove/agent.d.ts +17 -0
  35. package/lib/commands/aidev/remove/agent.js +55 -0
  36. package/lib/commands/aidev/remove/agent.js.map +1 -0
  37. package/lib/commands/aidev/remove/command.d.ts +17 -0
  38. package/lib/commands/aidev/remove/command.js +55 -0
  39. package/lib/commands/aidev/remove/command.js.map +1 -0
  40. package/lib/commands/aidev/remove/index.d.ts +44 -0
  41. package/lib/commands/aidev/remove/index.js +135 -0
  42. package/lib/commands/aidev/remove/index.js.map +1 -0
  43. package/lib/commands/aidev/remove/prompt.d.ts +17 -0
  44. package/lib/commands/aidev/remove/prompt.js +55 -0
  45. package/lib/commands/aidev/remove/prompt.js.map +1 -0
  46. package/lib/commands/aidev/remove/skill.d.ts +17 -0
  47. package/lib/commands/aidev/remove/skill.js +55 -0
  48. package/lib/commands/aidev/remove/skill.js.map +1 -0
  49. package/lib/commands/aidev/source/add.d.ts +21 -0
  50. package/lib/commands/aidev/source/add.js +84 -0
  51. package/lib/commands/aidev/source/add.js.map +1 -0
  52. package/lib/commands/aidev/source/list.d.ts +16 -0
  53. package/lib/commands/aidev/source/list.js +47 -0
  54. package/lib/commands/aidev/source/list.js.map +1 -0
  55. package/lib/commands/aidev/source/refresh.d.ts +36 -0
  56. package/lib/commands/aidev/source/refresh.js +133 -0
  57. package/lib/commands/aidev/source/refresh.js.map +1 -0
  58. package/lib/commands/aidev/source/remove.d.ts +20 -0
  59. package/lib/commands/aidev/source/remove.js +86 -0
  60. package/lib/commands/aidev/source/remove.js.map +1 -0
  61. package/lib/commands/aidev/source/set-default.d.ts +18 -0
  62. package/lib/commands/aidev/source/set-default.js +59 -0
  63. package/lib/commands/aidev/source/set-default.js.map +1 -0
  64. package/lib/config/aiDevConfig.d.ts +62 -0
  65. package/lib/config/aiDevConfig.js +138 -0
  66. package/lib/config/aiDevConfig.js.map +1 -0
  67. package/lib/detectors/claudeDetector.d.ts +12 -0
  68. package/lib/detectors/claudeDetector.js +39 -0
  69. package/lib/detectors/claudeDetector.js.map +1 -0
  70. package/lib/detectors/copilotDetector.d.ts +13 -0
  71. package/lib/detectors/copilotDetector.js +40 -0
  72. package/lib/detectors/copilotDetector.js.map +1 -0
  73. package/lib/detectors/detector.d.ts +21 -0
  74. package/lib/detectors/detector.js +13 -0
  75. package/lib/detectors/detector.js.map +1 -0
  76. package/lib/detectors/registry.d.ts +55 -0
  77. package/lib/detectors/registry.js +68 -0
  78. package/lib/detectors/registry.js.map +1 -0
  79. package/lib/index.d.ts +2 -0
  80. package/lib/index.js +2 -0
  81. package/lib/index.js.map +1 -0
  82. package/lib/installers/agentInstaller.d.ts +17 -0
  83. package/lib/installers/agentInstaller.js +44 -0
  84. package/lib/installers/agentInstaller.js.map +1 -0
  85. package/lib/installers/installer.d.ts +31 -0
  86. package/lib/installers/installer.js +13 -0
  87. package/lib/installers/installer.js.map +1 -0
  88. package/lib/installers/pathResolver.d.ts +51 -0
  89. package/lib/installers/pathResolver.js +102 -0
  90. package/lib/installers/pathResolver.js.map +1 -0
  91. package/lib/installers/promptInstaller.d.ts +17 -0
  92. package/lib/installers/promptInstaller.js +44 -0
  93. package/lib/installers/promptInstaller.js.map +1 -0
  94. package/lib/installers/skillInstaller.d.ts +17 -0
  95. package/lib/installers/skillInstaller.js +44 -0
  96. package/lib/installers/skillInstaller.js.map +1 -0
  97. package/lib/services/artifactService.d.ts +140 -0
  98. package/lib/services/artifactService.js +350 -0
  99. package/lib/services/artifactService.js.map +1 -0
  100. package/lib/services/localFileScanner.d.ts +135 -0
  101. package/lib/services/localFileScanner.js +265 -0
  102. package/lib/services/localFileScanner.js.map +1 -0
  103. package/lib/services/sourceService.d.ts +91 -0
  104. package/lib/services/sourceService.js +213 -0
  105. package/lib/services/sourceService.js.map +1 -0
  106. package/lib/sources/gitHubFetcher.d.ts +51 -0
  107. package/lib/sources/gitHubFetcher.js +138 -0
  108. package/lib/sources/gitHubFetcher.js.map +1 -0
  109. package/lib/sources/manifestBuilder.d.ts +62 -0
  110. package/lib/sources/manifestBuilder.js +215 -0
  111. package/lib/sources/manifestBuilder.js.map +1 -0
  112. package/lib/sources/manifestCache.d.ts +88 -0
  113. package/lib/sources/manifestCache.js +160 -0
  114. package/lib/sources/manifestCache.js.map +1 -0
  115. package/lib/sources/sourceManager.d.ts +60 -0
  116. package/lib/sources/sourceManager.js +107 -0
  117. package/lib/sources/sourceManager.js.map +1 -0
  118. package/lib/types/config.d.ts +39 -0
  119. package/lib/types/config.js +8 -0
  120. package/lib/types/config.js.map +1 -0
  121. package/lib/types/manifest.d.ts +37 -0
  122. package/lib/types/manifest.js +8 -0
  123. package/lib/types/manifest.js.map +1 -0
  124. package/lib/ui/expandableSelect.d.ts +49 -0
  125. package/lib/ui/expandableSelect.js +167 -0
  126. package/lib/ui/expandableSelect.js.map +1 -0
  127. package/lib/ui/interactivePrompts.d.ts +134 -0
  128. package/lib/ui/interactivePrompts.js +384 -0
  129. package/lib/ui/interactivePrompts.js.map +1 -0
  130. package/lib/ui/interactiveTable.d.ts +119 -0
  131. package/lib/ui/interactiveTable.js +232 -0
  132. package/lib/ui/interactiveTable.js.map +1 -0
  133. package/lib/utils/frontmatterParser.d.ts +54 -0
  134. package/lib/utils/frontmatterParser.js +106 -0
  135. package/lib/utils/frontmatterParser.js.map +1 -0
  136. package/oclif.manifest.json +1377 -2
  137. package/package.json +1 -1
@@ -0,0 +1,57 @@
1
+ import { SfCommand } from '@salesforce/sf-plugins-core';
2
+ import { Separator } from '@inquirer/prompts';
3
+ import { type InstallResult, type AvailableArtifact } from '../../../services/artifactService.js';
4
+ /**
5
+ * Result type for single agent installation
6
+ */
7
+ export type AddAgentResult = InstallResult | AddAgentMultiResult;
8
+ /**
9
+ * Result type for multiple agent installation (interactive mode)
10
+ */
11
+ export type AddAgentMultiResult = {
12
+ installed: InstallResult[];
13
+ skipped: Array<{
14
+ name: string;
15
+ }>;
16
+ total: number;
17
+ };
18
+ /**
19
+ * Checkbox choice type for interactive selection
20
+ */
21
+ type CheckboxChoice = {
22
+ name: string;
23
+ value: AvailableArtifact;
24
+ };
25
+ export default class AddAgent extends SfCommand<AddAgentResult> {
26
+ static readonly summary: string;
27
+ static readonly description: string;
28
+ static readonly examples: string[];
29
+ static readonly enableJsonFlag = true;
30
+ static readonly flags: {
31
+ name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
32
+ source: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
33
+ };
34
+ run(): Promise<AddAgentResult>;
35
+ /**
36
+ * Prompt user with a multi-select checkbox.
37
+ * Extracted for test stubbing.
38
+ */
39
+ protected promptCheckbox(message: string, choices: Array<CheckboxChoice | Separator>): Promise<AvailableArtifact[]>;
40
+ /**
41
+ * Install a single agent by name (non-interactive mode).
42
+ */
43
+ private installSingle;
44
+ /**
45
+ * Run interactive mode - show checkbox list of available agents.
46
+ */
47
+ private runInteractive;
48
+ /**
49
+ * Build checkbox choices from available artifacts.
50
+ */
51
+ private buildChoices;
52
+ /**
53
+ * Report installation results to the user.
54
+ */
55
+ private reportResults;
56
+ }
57
+ export {};
@@ -0,0 +1,168 @@
1
+ /*
2
+ * Copyright (c) 2024, Yury Bondarau
3
+ * All rights reserved.
4
+ * Licensed under the BSD 3-Clause license.
5
+ */
6
+ import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
7
+ import { Messages, SfError } from '@salesforce/core';
8
+ import { ArtifactService } from '../../../services/artifactService.js';
9
+ import { AiDevConfig } from '../../../config/aiDevConfig.js';
10
+ import { isInteractive, promptCheckboxGeneric, CHECKBOX_THEME } from '../../../ui/interactivePrompts.js';
11
+ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
12
+ const messages = Messages.loadMessages('sf-aidev', 'aidev.add.agent');
13
+ export default class AddAgent extends SfCommand {
14
+ static summary = messages.getMessage('summary');
15
+ static description = messages.getMessage('description');
16
+ static examples = messages.getMessages('examples');
17
+ static enableJsonFlag = true;
18
+ static flags = {
19
+ name: Flags.string({
20
+ char: 'n',
21
+ summary: messages.getMessage('flags.name.summary'),
22
+ required: false,
23
+ }),
24
+ source: Flags.string({
25
+ char: 's',
26
+ summary: messages.getMessage('flags.source.summary'),
27
+ }),
28
+ };
29
+ async run() {
30
+ const { flags } = await this.parse(AddAgent);
31
+ const globalConfig = await AiDevConfig.create({ isGlobal: true });
32
+ const localConfig = await AiDevConfig.create({ isGlobal: false });
33
+ const service = new ArtifactService(globalConfig, localConfig, process.cwd());
34
+ // If name is provided, install directly (non-interactive mode)
35
+ if (flags.name) {
36
+ return this.installSingle(service, flags.name, flags.source);
37
+ }
38
+ // Interactive mode - name not provided
39
+ if (!isInteractive()) {
40
+ throw new SfError(messages.getMessage('error.NonInteractive'), 'NonInteractiveError', [
41
+ messages.getMessage('error.NonInteractiveActions'),
42
+ ]);
43
+ }
44
+ return this.runInteractive(service, flags.source);
45
+ }
46
+ /**
47
+ * Prompt user with a multi-select checkbox.
48
+ * Extracted for test stubbing.
49
+ */
50
+ // eslint-disable-next-line class-methods-use-this
51
+ async promptCheckbox(message, choices) {
52
+ return promptCheckboxGeneric({
53
+ message,
54
+ choices,
55
+ pageSize: 15,
56
+ theme: CHECKBOX_THEME,
57
+ });
58
+ }
59
+ /**
60
+ * Install a single agent by name (non-interactive mode).
61
+ */
62
+ async installSingle(service, name, source) {
63
+ const result = await service.install(name, { type: 'agent', source });
64
+ if (!result.success) {
65
+ throw new SfError(messages.getMessage('error.InstallFailed', [name, result.error ?? 'Unknown error']), 'InstallError');
66
+ }
67
+ this.log(messages.getMessage('info.AgentInstalled', [result.artifact, result.installedPath]));
68
+ return result;
69
+ }
70
+ /**
71
+ * Run interactive mode - show checkbox list of available agents.
72
+ */
73
+ async runInteractive(service, source) {
74
+ // Ensure a tool is configured
75
+ const tool = service.getActiveTool();
76
+ if (!tool) {
77
+ throw new SfError(messages.getMessage('error.NoTool'), 'NoToolError', [
78
+ messages.getMessage('error.NoToolActions'),
79
+ ]);
80
+ }
81
+ // Fetch available artifacts filtered to agents only
82
+ this.spinner.start(messages.getMessage('info.Fetching'));
83
+ const available = await service.listAvailable({ source, type: 'agent' });
84
+ this.spinner.stop();
85
+ // Filter out already installed
86
+ const notInstalled = available.filter((a) => !a.installed);
87
+ if (available.length === 0) {
88
+ this.log(messages.getMessage('info.NoArtifacts'));
89
+ return { installed: [], skipped: [], total: 0 };
90
+ }
91
+ if (notInstalled.length === 0) {
92
+ this.log(messages.getMessage('info.AllInstalled'));
93
+ return { installed: [], skipped: [], total: 0 };
94
+ }
95
+ // Build choices
96
+ const choices = this.buildChoices(notInstalled);
97
+ // Prompt user to select agents
98
+ const selected = await this.promptCheckbox(messages.getMessage('prompt.Select'), choices);
99
+ if (selected.length === 0) {
100
+ this.log(messages.getMessage('info.NoneSelected'));
101
+ return { installed: [], skipped: [], total: 0 };
102
+ }
103
+ // Install selected agents
104
+ const installed = [];
105
+ const skipped = [];
106
+ this.spinner.start(messages.getMessage('info.Installing', [selected.length.toString()]));
107
+ for (const artifact of selected) {
108
+ // Double-check if agent was installed in the meantime
109
+ if (service.isInstalled(artifact.name, 'agent')) {
110
+ skipped.push({ name: artifact.name });
111
+ continue;
112
+ }
113
+ // eslint-disable-next-line no-await-in-loop
114
+ const result = await service.install(artifact.name, {
115
+ type: 'agent',
116
+ source: artifact.source,
117
+ });
118
+ installed.push(result);
119
+ }
120
+ this.spinner.stop();
121
+ // Report results
122
+ this.reportResults(installed, skipped);
123
+ return {
124
+ installed,
125
+ skipped,
126
+ total: selected.length,
127
+ };
128
+ }
129
+ /**
130
+ * Build checkbox choices from available artifacts.
131
+ */
132
+ // eslint-disable-next-line class-methods-use-this
133
+ buildChoices(artifacts) {
134
+ return artifacts.map((artifact) => {
135
+ const displayName = artifact.description ? `${artifact.name} - ${artifact.description}` : artifact.name;
136
+ return {
137
+ name: displayName,
138
+ value: artifact,
139
+ };
140
+ });
141
+ }
142
+ /**
143
+ * Report installation results to the user.
144
+ */
145
+ reportResults(installed, skipped) {
146
+ const successful = installed.filter((r) => r.success);
147
+ const failed = installed.filter((r) => !r.success);
148
+ if (successful.length > 0) {
149
+ this.log(messages.getMessage('info.Installed', [successful.length.toString()]));
150
+ for (const result of successful) {
151
+ this.log(` - ${result.artifact} -> ${result.installedPath}`);
152
+ }
153
+ }
154
+ if (skipped.length > 0) {
155
+ this.log(messages.getMessage('info.Skipped', [skipped.length.toString()]));
156
+ for (const item of skipped) {
157
+ this.log(` - ${item.name}`);
158
+ }
159
+ }
160
+ if (failed.length > 0) {
161
+ this.warn(messages.getMessage('warning.Failed', [failed.length.toString()]));
162
+ for (const result of failed) {
163
+ this.log(` - ${result.artifact}: ${result.error ?? 'Unknown error'}`);
164
+ }
165
+ }
166
+ }
167
+ }
168
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../../src/commands/aidev/add/agent.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAAE,eAAe,EAA8C,MAAM,sCAAsC,CAAC;AACnH,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAEzG,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;AAwBtE,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,SAAyB;IACtD,MAAM,CAAU,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,CAAU,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IACjE,MAAM,CAAU,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAC5D,MAAM,CAAU,cAAc,GAAG,IAAI,CAAC;IAEtC,MAAM,CAAU,KAAK,GAAG;QAC7B,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;YACjB,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,oBAAoB,CAAC;YAClD,QAAQ,EAAE,KAAK;SAChB,CAAC;QACF,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;YACnB,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,sBAAsB,CAAC;SACrD,CAAC;KACH,CAAC;IAEK,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAE7C,MAAM,YAAY,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QAClE,MAAM,OAAO,GAAG,IAAI,eAAe,CAAC,YAAY,EAAE,WAAW,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAE9E,+DAA+D;QAC/D,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC/D,CAAC;QAED,uCAAuC;QACvC,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;YACrB,MAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE,qBAAqB,EAAE;gBACpF,QAAQ,CAAC,UAAU,CAAC,6BAA6B,CAAC;aACnD,CAAC,CAAC;QACL,CAAC;QAED,OAAO,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACpD,CAAC;IAED;;;OAGG;IACH,kDAAkD;IACxC,KAAK,CAAC,cAAc,CAC5B,OAAe,EACf,OAA0C;QAE1C,OAAO,qBAAqB,CAAoB;YAC9C,OAAO;YACP,OAAO;YACP,QAAQ,EAAE,EAAE;YACZ,KAAK,EAAE,cAAc;SACtB,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,aAAa,CAAC,OAAwB,EAAE,IAAY,EAAE,MAAe;QACjF,MAAM,MAAM,GAAkB,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAErF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,OAAO,CACf,QAAQ,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,IAAI,eAAe,CAAC,CAAC,EACnF,cAAc,CACf,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QAC9F,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc,CAAC,OAAwB,EAAE,MAAe;QACpE,8BAA8B;QAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;QACrC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,aAAa,EAAE;gBACpE,QAAQ,CAAC,UAAU,CAAC,qBAAqB,CAAC;aAC3C,CAAC,CAAC;QACL,CAAC;QAED,oDAAoD;QACpD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC;QACzD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACzE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAEpB,+BAA+B;QAC/B,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAE3D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC,CAAC;YAClD,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAClD,CAAC;QAED,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC;YACnD,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAClD,CAAC;QAED,gBAAgB;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAEhD,+BAA+B;QAC/B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC,CAAC;QAE1F,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC;YACnD,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAClD,CAAC;QAED,0BAA0B;QAC1B,MAAM,SAAS,GAAoB,EAAE,CAAC;QACtC,MAAM,OAAO,GAA4B,EAAE,CAAC;QAE5C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;QAEzF,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;YAChC,sDAAsD;YACtD,IAAI,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC;gBAChD,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;gBACtC,SAAS;YACX,CAAC;YAED,4CAA4C;YAC5C,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE;gBAClD,IAAI,EAAE,OAAO;gBACb,MAAM,EAAE,QAAQ,CAAC,MAAM;aACxB,CAAC,CAAC;YACH,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAEpB,iBAAiB;QACjB,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAEvC,OAAO;YACL,SAAS;YACT,OAAO;YACP,KAAK,EAAE,QAAQ,CAAC,MAAM;SACvB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,kDAAkD;IAC1C,YAAY,CAAC,SAA8B;QACjD,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;YAChC,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;YACxG,OAAO;gBACL,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,QAAQ;aAChB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,aAAa,CAAC,SAA0B,EAAE,OAAgC;QAChF,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAEnD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;YAChF,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;gBAChC,IAAI,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,QAAQ,OAAO,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;YAC3E,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;gBAC3B,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7E,KAAK,MAAM,MAAM,IAAI,MAAM,EAAE,CAAC;gBAC5B,IAAI,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,KAAK,IAAI,eAAe,EAAE,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;IACH,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { SfCommand } from '@salesforce/sf-plugins-core';
2
+ import { Separator } from '@inquirer/prompts';
3
+ import { type InstallResult, type AvailableArtifact } from '../../../services/artifactService.js';
4
+ /**
5
+ * Result type for single command installation
6
+ */
7
+ export type AddCommandResult = InstallResult | AddCommandMultiResult;
8
+ /**
9
+ * Result type for multiple command installation (interactive mode)
10
+ */
11
+ export type AddCommandMultiResult = {
12
+ installed: InstallResult[];
13
+ skipped: Array<{
14
+ name: string;
15
+ }>;
16
+ total: number;
17
+ };
18
+ /**
19
+ * Checkbox choice type for interactive selection
20
+ */
21
+ type CheckboxChoice = {
22
+ name: string;
23
+ value: AvailableArtifact;
24
+ };
25
+ export default class AddCommand extends SfCommand<AddCommandResult> {
26
+ static readonly summary: string;
27
+ static readonly description: string;
28
+ static readonly examples: string[];
29
+ static readonly enableJsonFlag = true;
30
+ static readonly flags: {
31
+ name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
32
+ source: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
33
+ };
34
+ run(): Promise<AddCommandResult>;
35
+ /**
36
+ * Prompt user with a multi-select checkbox.
37
+ * Extracted for test stubbing.
38
+ */
39
+ protected promptCheckbox(message: string, choices: Array<CheckboxChoice | Separator>): Promise<AvailableArtifact[]>;
40
+ /**
41
+ * Install a single command by name (non-interactive mode).
42
+ */
43
+ private installSingle;
44
+ /**
45
+ * Run interactive mode - show checkbox list of available commands.
46
+ */
47
+ private runInteractive;
48
+ /**
49
+ * Build checkbox choices from available artifacts.
50
+ */
51
+ private buildChoices;
52
+ /**
53
+ * Report installation results to the user.
54
+ */
55
+ private reportResults;
56
+ }
57
+ export {};
@@ -0,0 +1,168 @@
1
+ /*
2
+ * Copyright (c) 2024, Yury Bondarau
3
+ * All rights reserved.
4
+ * Licensed under the BSD 3-Clause license.
5
+ */
6
+ import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
7
+ import { Messages, SfError } from '@salesforce/core';
8
+ import { ArtifactService } from '../../../services/artifactService.js';
9
+ import { AiDevConfig } from '../../../config/aiDevConfig.js';
10
+ import { isInteractive, promptCheckboxGeneric, CHECKBOX_THEME } from '../../../ui/interactivePrompts.js';
11
+ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
12
+ const messages = Messages.loadMessages('sf-aidev', 'aidev.add.command');
13
+ export default class AddCommand extends SfCommand {
14
+ static summary = messages.getMessage('summary');
15
+ static description = messages.getMessage('description');
16
+ static examples = messages.getMessages('examples');
17
+ static enableJsonFlag = true;
18
+ static flags = {
19
+ name: Flags.string({
20
+ char: 'n',
21
+ summary: messages.getMessage('flags.name.summary'),
22
+ required: false,
23
+ }),
24
+ source: Flags.string({
25
+ char: 's',
26
+ summary: messages.getMessage('flags.source.summary'),
27
+ }),
28
+ };
29
+ async run() {
30
+ const { flags } = await this.parse(AddCommand);
31
+ const globalConfig = await AiDevConfig.create({ isGlobal: true });
32
+ const localConfig = await AiDevConfig.create({ isGlobal: false });
33
+ const service = new ArtifactService(globalConfig, localConfig, process.cwd());
34
+ // If name is provided, install directly (non-interactive mode)
35
+ if (flags.name) {
36
+ return this.installSingle(service, flags.name, flags.source);
37
+ }
38
+ // Interactive mode - name not provided
39
+ if (!isInteractive()) {
40
+ throw new SfError(messages.getMessage('error.NonInteractive'), 'NonInteractiveError', [
41
+ messages.getMessage('error.NonInteractiveActions'),
42
+ ]);
43
+ }
44
+ return this.runInteractive(service, flags.source);
45
+ }
46
+ /**
47
+ * Prompt user with a multi-select checkbox.
48
+ * Extracted for test stubbing.
49
+ */
50
+ // eslint-disable-next-line class-methods-use-this
51
+ async promptCheckbox(message, choices) {
52
+ return promptCheckboxGeneric({
53
+ message,
54
+ choices,
55
+ pageSize: 15,
56
+ theme: CHECKBOX_THEME,
57
+ });
58
+ }
59
+ /**
60
+ * Install a single command by name (non-interactive mode).
61
+ */
62
+ async installSingle(service, name, source) {
63
+ const result = await service.install(name, { type: 'command', source });
64
+ if (!result.success) {
65
+ throw new SfError(messages.getMessage('error.InstallFailed', [name, result.error ?? 'Unknown error']), 'InstallError');
66
+ }
67
+ this.log(messages.getMessage('info.CommandInstalled', [result.artifact, result.installedPath]));
68
+ return result;
69
+ }
70
+ /**
71
+ * Run interactive mode - show checkbox list of available commands.
72
+ */
73
+ async runInteractive(service, source) {
74
+ // Ensure a tool is configured
75
+ const tool = service.getActiveTool();
76
+ if (!tool) {
77
+ throw new SfError(messages.getMessage('error.NoTool'), 'NoToolError', [
78
+ messages.getMessage('error.NoToolActions'),
79
+ ]);
80
+ }
81
+ // Fetch available artifacts filtered to commands only
82
+ this.spinner.start(messages.getMessage('info.Fetching'));
83
+ const available = await service.listAvailable({ source, type: 'command' });
84
+ this.spinner.stop();
85
+ // Filter out already installed
86
+ const notInstalled = available.filter((a) => !a.installed);
87
+ if (available.length === 0) {
88
+ this.log(messages.getMessage('info.NoArtifacts'));
89
+ return { installed: [], skipped: [], total: 0 };
90
+ }
91
+ if (notInstalled.length === 0) {
92
+ this.log(messages.getMessage('info.AllInstalled'));
93
+ return { installed: [], skipped: [], total: 0 };
94
+ }
95
+ // Build choices
96
+ const choices = this.buildChoices(notInstalled);
97
+ // Prompt user to select commands
98
+ const selected = await this.promptCheckbox(messages.getMessage('prompt.Select'), choices);
99
+ if (selected.length === 0) {
100
+ this.log(messages.getMessage('info.NoneSelected'));
101
+ return { installed: [], skipped: [], total: 0 };
102
+ }
103
+ // Install selected commands
104
+ const installed = [];
105
+ const skipped = [];
106
+ this.spinner.start(messages.getMessage('info.Installing', [selected.length.toString()]));
107
+ for (const artifact of selected) {
108
+ // Double-check if command was installed in the meantime
109
+ if (service.isInstalled(artifact.name, 'command')) {
110
+ skipped.push({ name: artifact.name });
111
+ continue;
112
+ }
113
+ // eslint-disable-next-line no-await-in-loop
114
+ const result = await service.install(artifact.name, {
115
+ type: 'command',
116
+ source: artifact.source,
117
+ });
118
+ installed.push(result);
119
+ }
120
+ this.spinner.stop();
121
+ // Report results
122
+ this.reportResults(installed, skipped);
123
+ return {
124
+ installed,
125
+ skipped,
126
+ total: selected.length,
127
+ };
128
+ }
129
+ /**
130
+ * Build checkbox choices from available artifacts.
131
+ */
132
+ // eslint-disable-next-line class-methods-use-this
133
+ buildChoices(artifacts) {
134
+ return artifacts.map((artifact) => {
135
+ const displayName = artifact.description ? `${artifact.name} - ${artifact.description}` : artifact.name;
136
+ return {
137
+ name: displayName,
138
+ value: artifact,
139
+ };
140
+ });
141
+ }
142
+ /**
143
+ * Report installation results to the user.
144
+ */
145
+ reportResults(installed, skipped) {
146
+ const successful = installed.filter((r) => r.success);
147
+ const failed = installed.filter((r) => !r.success);
148
+ if (successful.length > 0) {
149
+ this.log(messages.getMessage('info.Installed', [successful.length.toString()]));
150
+ for (const result of successful) {
151
+ this.log(` - ${result.artifact} -> ${result.installedPath}`);
152
+ }
153
+ }
154
+ if (skipped.length > 0) {
155
+ this.log(messages.getMessage('info.Skipped', [skipped.length.toString()]));
156
+ for (const item of skipped) {
157
+ this.log(` - ${item.name}`);
158
+ }
159
+ }
160
+ if (failed.length > 0) {
161
+ this.warn(messages.getMessage('warning.Failed', [failed.length.toString()]));
162
+ for (const result of failed) {
163
+ this.log(` - ${result.artifact}: ${result.error ?? 'Unknown error'}`);
164
+ }
165
+ }
166
+ }
167
+ }
168
+ //# sourceMappingURL=command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../../../../src/commands/aidev/add/command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import { SfCommand } from '@salesforce/sf-plugins-core';
2
+ import { Separator } from '@inquirer/prompts';
3
+ import { type InstallResult, type AvailableArtifact } from '../../../services/artifactService.js';
4
+ /**
5
+ * Result type for single prompt installation
6
+ */
7
+ export type AddPromptResult = InstallResult | AddPromptMultiResult;
8
+ /**
9
+ * Result type for multiple prompt installation (interactive mode)
10
+ */
11
+ export type AddPromptMultiResult = {
12
+ installed: InstallResult[];
13
+ skipped: Array<{
14
+ name: string;
15
+ }>;
16
+ total: number;
17
+ };
18
+ /**
19
+ * Checkbox choice type for interactive selection
20
+ */
21
+ type CheckboxChoice = {
22
+ name: string;
23
+ value: AvailableArtifact;
24
+ };
25
+ export default class AddPrompt extends SfCommand<AddPromptResult> {
26
+ static readonly summary: string;
27
+ static readonly description: string;
28
+ static readonly examples: string[];
29
+ static readonly enableJsonFlag = true;
30
+ static readonly flags: {
31
+ name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
32
+ source: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
33
+ };
34
+ run(): Promise<AddPromptResult>;
35
+ /**
36
+ * Prompt user with a multi-select checkbox.
37
+ * Extracted for test stubbing.
38
+ */
39
+ protected promptCheckbox(message: string, choices: Array<CheckboxChoice | Separator>): Promise<AvailableArtifact[]>;
40
+ /**
41
+ * Install a single prompt by name (non-interactive mode).
42
+ */
43
+ private installSingle;
44
+ /**
45
+ * Run interactive mode - show checkbox list of available prompts.
46
+ */
47
+ private runInteractive;
48
+ /**
49
+ * Build checkbox choices from available artifacts.
50
+ */
51
+ private buildChoices;
52
+ /**
53
+ * Report installation results to the user.
54
+ */
55
+ private reportResults;
56
+ }
57
+ export {};