@ai-outfitter/outfitter 0.3.0

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 (156) hide show
  1. package/LICENSE.md +58 -0
  2. package/README.md +256 -0
  3. package/dist/agents/AdapterProfileControls.d.ts +20 -0
  4. package/dist/agents/AdapterProfileControls.js +63 -0
  5. package/dist/agents/AdapterProfileControls.js.map +1 -0
  6. package/dist/agents/AdapterStatePaths.d.ts +12 -0
  7. package/dist/agents/AdapterStatePaths.js +44 -0
  8. package/dist/agents/AdapterStatePaths.js.map +1 -0
  9. package/dist/agents/AgentAdapter.d.ts +32 -0
  10. package/dist/agents/AgentAdapter.js +2 -0
  11. package/dist/agents/AgentAdapter.js.map +1 -0
  12. package/dist/agents/AgentRegistry.d.ts +6 -0
  13. package/dist/agents/AgentRegistry.js +17 -0
  14. package/dist/agents/AgentRegistry.js.map +1 -0
  15. package/dist/agents/LaunchResources.d.ts +13 -0
  16. package/dist/agents/LaunchResources.js +35 -0
  17. package/dist/agents/LaunchResources.js.map +1 -0
  18. package/dist/agents/ResourceIdentity.d.ts +2 -0
  19. package/dist/agents/ResourceIdentity.js +51 -0
  20. package/dist/agents/ResourceIdentity.js.map +1 -0
  21. package/dist/agents/claude/ClaudeAdapter.d.ts +2 -0
  22. package/dist/agents/claude/ClaudeAdapter.js +117 -0
  23. package/dist/agents/claude/ClaudeAdapter.js.map +1 -0
  24. package/dist/agents/claude/ClaudeCompositeProfileWriter.d.ts +5 -0
  25. package/dist/agents/claude/ClaudeCompositeProfileWriter.js +7 -0
  26. package/dist/agents/claude/ClaudeCompositeProfileWriter.js.map +1 -0
  27. package/dist/agents/pi/PiAdapter.d.ts +2 -0
  28. package/dist/agents/pi/PiAdapter.js +229 -0
  29. package/dist/agents/pi/PiAdapter.js.map +1 -0
  30. package/dist/agents/pi/PiCompositeProfileWriter.d.ts +5 -0
  31. package/dist/agents/pi/PiCompositeProfileWriter.js +7 -0
  32. package/dist/agents/pi/PiCompositeProfileWriter.js.map +1 -0
  33. package/dist/agents/pi/PiMcpConfig.d.ts +2 -0
  34. package/dist/agents/pi/PiMcpConfig.js +114 -0
  35. package/dist/agents/pi/PiMcpConfig.js.map +1 -0
  36. package/dist/agents/pi/PiSettingsMergePolicy.d.ts +17 -0
  37. package/dist/agents/pi/PiSettingsMergePolicy.js +59 -0
  38. package/dist/agents/pi/PiSettingsMergePolicy.js.map +1 -0
  39. package/dist/cli/OutfitterCli.d.ts +4 -0
  40. package/dist/cli/OutfitterCli.js +32 -0
  41. package/dist/cli/OutfitterCli.js.map +1 -0
  42. package/dist/cli/commands/CommandObject.d.ts +11 -0
  43. package/dist/cli/commands/CommandObject.js +5 -0
  44. package/dist/cli/commands/CommandObject.js.map +1 -0
  45. package/dist/cli/commands/FirstRunWelcomeProfile.d.ts +11 -0
  46. package/dist/cli/commands/FirstRunWelcomeProfile.js +107 -0
  47. package/dist/cli/commands/FirstRunWelcomeProfile.js.map +1 -0
  48. package/dist/cli/commands/PiLoginLaunch.d.ts +10 -0
  49. package/dist/cli/commands/PiLoginLaunch.js +76 -0
  50. package/dist/cli/commands/PiLoginLaunch.js.map +1 -0
  51. package/dist/cli/commands/RunCommand.d.ts +30 -0
  52. package/dist/cli/commands/RunCommand.js +299 -0
  53. package/dist/cli/commands/RunCommand.js.map +1 -0
  54. package/dist/cli/commands/SetupCommand.d.ts +34 -0
  55. package/dist/cli/commands/SetupCommand.js +379 -0
  56. package/dist/cli/commands/SetupCommand.js.map +1 -0
  57. package/dist/cli/commands/SyncCommand.d.ts +28 -0
  58. package/dist/cli/commands/SyncCommand.js +178 -0
  59. package/dist/cli/commands/SyncCommand.js.map +1 -0
  60. package/dist/cli/commands/WelcomeCommand.d.ts +54 -0
  61. package/dist/cli/commands/WelcomeCommand.js +214 -0
  62. package/dist/cli/commands/WelcomeCommand.js.map +1 -0
  63. package/dist/cli/commands/profile/Command.d.ts +6 -0
  64. package/dist/cli/commands/profile/Command.js +21 -0
  65. package/dist/cli/commands/profile/Command.js.map +1 -0
  66. package/dist/cli/commands/profile/CreateCommand.d.ts +19 -0
  67. package/dist/cli/commands/profile/CreateCommand.js +115 -0
  68. package/dist/cli/commands/profile/CreateCommand.js.map +1 -0
  69. package/dist/cli/commands/profile/ListCommand.d.ts +17 -0
  70. package/dist/cli/commands/profile/ListCommand.js +85 -0
  71. package/dist/cli/commands/profile/ListCommand.js.map +1 -0
  72. package/dist/cli/commands/profile/Shared.d.ts +9 -0
  73. package/dist/cli/commands/profile/Shared.js +10 -0
  74. package/dist/cli/commands/profile/Shared.js.map +1 -0
  75. package/dist/cli.d.ts +3 -0
  76. package/dist/cli.js +22 -0
  77. package/dist/cli.js.map +1 -0
  78. package/dist/compositeProfile/CompositeProfile.d.ts +8 -0
  79. package/dist/compositeProfile/CompositeProfile.js +6 -0
  80. package/dist/compositeProfile/CompositeProfile.js.map +1 -0
  81. package/dist/compositeProfile/CompositeProfileAssembler.d.ts +12 -0
  82. package/dist/compositeProfile/CompositeProfileAssembler.js +32 -0
  83. package/dist/compositeProfile/CompositeProfileAssembler.js.map +1 -0
  84. package/dist/compositeProfile/CompositeProfileFile.d.ts +16 -0
  85. package/dist/compositeProfile/CompositeProfileFile.js +16 -0
  86. package/dist/compositeProfile/CompositeProfileFile.js.map +1 -0
  87. package/dist/compositeProfile/CompositeProfileTemplate.d.ts +15 -0
  88. package/dist/compositeProfile/CompositeProfileTemplate.js +65 -0
  89. package/dist/compositeProfile/CompositeProfileTemplate.js.map +1 -0
  90. package/dist/compositeProfile/CompositeProfileWatcher.d.ts +18 -0
  91. package/dist/compositeProfile/CompositeProfileWatcher.js +46 -0
  92. package/dist/compositeProfile/CompositeProfileWatcher.js.map +1 -0
  93. package/dist/compositeProfile/StatePersistence.d.ts +24 -0
  94. package/dist/compositeProfile/StatePersistence.js +224 -0
  95. package/dist/compositeProfile/StatePersistence.js.map +1 -0
  96. package/dist/merge/ArrayMergePolicy.d.ts +8 -0
  97. package/dist/merge/ArrayMergePolicy.js +45 -0
  98. package/dist/merge/ArrayMergePolicy.js.map +1 -0
  99. package/dist/merge/SettingsValueMerger.d.ts +11 -0
  100. package/dist/merge/SettingsValueMerger.js +34 -0
  101. package/dist/merge/SettingsValueMerger.js.map +1 -0
  102. package/dist/profiles/Profile.d.ts +32 -0
  103. package/dist/profiles/Profile.js +7 -0
  104. package/dist/profiles/Profile.js.map +1 -0
  105. package/dist/profiles/ProfileCache.d.ts +8 -0
  106. package/dist/profiles/ProfileCache.js +36 -0
  107. package/dist/profiles/ProfileCache.js.map +1 -0
  108. package/dist/profiles/ProfileLoader.d.ts +24 -0
  109. package/dist/profiles/ProfileLoader.js +169 -0
  110. package/dist/profiles/ProfileLoader.js.map +1 -0
  111. package/dist/profiles/ProfileMerger.d.ts +20 -0
  112. package/dist/profiles/ProfileMerger.js +97 -0
  113. package/dist/profiles/ProfileMerger.js.map +1 -0
  114. package/dist/profiles/ProfileSource.d.ts +35 -0
  115. package/dist/profiles/ProfileSource.js +13 -0
  116. package/dist/profiles/ProfileSource.js.map +1 -0
  117. package/dist/schemas/profile-source.schema.json +29 -0
  118. package/dist/schemas/profile.schema.json +115 -0
  119. package/dist/schemas/settings.schema.json +37 -0
  120. package/dist/settings/Settings.d.ts +17 -0
  121. package/dist/settings/Settings.js +5 -0
  122. package/dist/settings/Settings.js.map +1 -0
  123. package/dist/settings/SettingsLoader.d.ts +33 -0
  124. package/dist/settings/SettingsLoader.js +129 -0
  125. package/dist/settings/SettingsLoader.js.map +1 -0
  126. package/dist/settings/SettingsMerger.d.ts +2 -0
  127. package/dist/settings/SettingsMerger.js +31 -0
  128. package/dist/settings/SettingsMerger.js.map +1 -0
  129. package/dist/validation/SchemaValidator.d.ts +11 -0
  130. package/dist/validation/SchemaValidator.js +36 -0
  131. package/dist/validation/SchemaValidator.js.map +1 -0
  132. package/dist/validation/YamlDocument.d.ts +13 -0
  133. package/dist/validation/YamlDocument.js +11 -0
  134. package/dist/validation/YamlDocument.js.map +1 -0
  135. package/doc/.deepreview +30 -0
  136. package/doc/architecture.md +834 -0
  137. package/doc/controllable-elements.md +162 -0
  138. package/doc/file_structure.md +133 -0
  139. package/doc/integration_test_system.md +214 -0
  140. package/doc/specs/validating_requirements_with_rules.md +55 -0
  141. package/doc/state_writeback_strategy.md +334 -0
  142. package/package.json +73 -0
  143. package/requirements/OFTR-001-project-foundation.md +53 -0
  144. package/requirements/OFTR-002-settings.md +65 -0
  145. package/requirements/OFTR-003-profiles.md +51 -0
  146. package/requirements/OFTR-004-sync-and-setup.md +57 -0
  147. package/requirements/OFTR-005-run-and-composite-profile.md +60 -0
  148. package/requirements/OFTR-006-agent-adapters.md +64 -0
  149. package/requirements/OFTR-007-controllable-elements.md +32 -0
  150. package/requirements/OFTR-008-requirements-governance.md +42 -0
  151. package/requirements/OFTR-009-release-publishing.md +25 -0
  152. package/requirements/OFTR-010-onboarding-welcome.md +38 -0
  153. package/src/schemas/SchemaDocument.ts +20 -0
  154. package/src/schemas/profile-source.schema.json +29 -0
  155. package/src/schemas/profile.schema.json +115 -0
  156. package/src/schemas/settings.schema.json +37 -0
@@ -0,0 +1,379 @@
1
+ /* eslint-disable max-lines */
2
+ // Provides the command object for first-run Outfitter setup.
3
+ import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
4
+ import { createInterface } from 'node:readline/promises';
5
+ import { homedir } from 'node:os';
6
+ import { dirname, join } from 'node:path';
7
+ import spawn from 'cross-spawn';
8
+ import { createProfileSourceCachePath, createRemoteRepositoryCachePath, normalizeGitUri, redactProfileSourceUriCredentials, resolveRemoteRepositorySubpath, } from '../../profiles/ProfileCache.js';
9
+ import { isValidProfileId, loadLocalProfileSource } from '../../profiles/ProfileLoader.js';
10
+ import { createSettingsLoadPlan, discoverSettingsLoadPlan, loadSettings, loadSettingsFiles, loadSettingsWithCachedRemoteSettings, } from '../../settings/SettingsLoader.js';
11
+ import { persistFirstRunWelcomeProfile, updateSettingsDefaultProfile, } from './FirstRunWelcomeProfile.js';
12
+ import { executeSyncCommand } from './SyncCommand.js';
13
+ import { executeWelcomeCommand } from './WelcomeCommand.js';
14
+ const builtInSetupProfileChoices = [
15
+ { id: 'engineer', label: 'Engineer' },
16
+ { id: 'data_analyst', label: 'Data Analyst' },
17
+ ];
18
+ /* eslint-disable complexity -- setup orchestration coordinates settings, sync, prompts, and welcome persistence. */
19
+ export const executeSetupCommand = async (input, dependencies = {}) => {
20
+ requireInteractiveTerminalIfNeeded(dependencies);
21
+ const settingsPath = join(input.homeDirectory, '.outfitter', 'settings.yml');
22
+ const initialSettingsMissing = !existsSync(settingsPath);
23
+ const starterLayout = input.setupSourceUri
24
+ ? prepareStarterLayout(input.homeDirectory, input.setupSourceUri, dependencies.setupSourceSynchronizer)
25
+ : undefined;
26
+ const loadedSettings = loadSettings(discoverSettingsLoadPlan(input));
27
+ if (loadedSettings.issues.length > 0) {
28
+ throw new Error(`Cannot setup with invalid settings: ${loadedSettings.issues.map(formatSettingsIssue).join('; ')}`);
29
+ }
30
+ const defaultProfileId = initialSettingsMissing
31
+ ? readStarterDefaultProfileId(starterLayout?.settingsPath)
32
+ : readUserDefaultProfileId(loadedSettings.files);
33
+ assertValidDefaultProfileId(defaultProfileId);
34
+ const createdSettings = createInitialSettingsIfMissing(settingsPath, starterLayout?.settingsPath);
35
+ ensureExistingUserSettingsDefaultProfile(settingsPath, loadedSettings.files, defaultProfileId);
36
+ const copiedStarterProfileFiles = copyStarterProfileFilesIfPresent(starterLayout?.profilesPath, join(input.homeDirectory, '.outfitter', 'profiles'));
37
+ const rollbackCreatedSettings = createdSettings ? () => rmSync(settingsPath, { force: true }) : () => undefined;
38
+ const syncResult = executeSyncCommand(input, dependencies);
39
+ failOnInitialDefaultProfileSyncFailure(initialSettingsMissing, rollbackCreatedSettings, syncResult);
40
+ const selectedDefaultProfileId = shouldSkipInitialDefaultProfilePrompt(initialSettingsMissing, dependencies)
41
+ ? defaultProfileId
42
+ : await selectDefaultProfileIfInteractive(input, settingsPath, defaultProfileId, dependencies);
43
+ const welcomeResult = await runWelcomeAfterInteractiveSetup(input, dependencies);
44
+ const welcomeProfile = persistWelcomeProfileForSetup(input, settingsPath, welcomeResult);
45
+ const finalDefaultProfile = prepareFinalDefaultProfile(input.homeDirectory, selectedDefaultProfileId, welcomeProfile);
46
+ return {
47
+ settingsPath,
48
+ defaultProfilePath: finalDefaultProfile.path,
49
+ createdSettings,
50
+ copiedStarterProfileFiles,
51
+ createdDefaultProfile: finalDefaultProfile.created,
52
+ syncResult,
53
+ welcomeResult,
54
+ messages: buildSetupMessages({
55
+ input,
56
+ starterLayout,
57
+ settingsPath,
58
+ createdSettings,
59
+ copiedStarterProfileFiles,
60
+ defaultProfileId: finalDefaultProfile.id,
61
+ defaultProfilePath: finalDefaultProfile.path,
62
+ createdDefaultProfile: finalDefaultProfile.created,
63
+ syncResult,
64
+ welcomeProfileMessages: welcomeProfile?.messages ?? [],
65
+ }),
66
+ };
67
+ };
68
+ /* eslint-enable complexity */
69
+ const defaultProfilesSourceUri = 'git+https://github.com/ai-outfitter/default-profiles.git:profiles';
70
+ const failOnInitialDefaultProfileSyncFailure = (initialSettingsMissing, rollbackCreatedSettings, syncResult) => {
71
+ if (!initialSettingsMissing) {
72
+ return;
73
+ }
74
+ const failedDefaultProfilesSource = syncResult.sources.find((source) => source.uri === defaultProfilesSourceUri && source.status === 'failed');
75
+ if (failedDefaultProfilesSource === undefined) {
76
+ return;
77
+ }
78
+ rollbackCreatedSettings();
79
+ throw new Error(`Cannot complete first-run setup because the default profiles source failed to sync: ${failedDefaultProfilesSource.message}. ` +
80
+ 'Fix the network/git issue and rerun `outfitter setup` once the source is reachable.');
81
+ };
82
+ const prepareFinalDefaultProfile = (homeDirectory, selectedDefaultProfileId, welcomeProfile) => {
83
+ const finalDefaultProfileId = welcomeProfile?.profileId ?? selectedDefaultProfileId;
84
+ const finalDefaultProfilePath = join(homeDirectory, '.outfitter', 'profiles', finalDefaultProfileId, 'profile.yml');
85
+ const createdDefaultProfile = welcomeProfile?.createdProfile ?? createDefaultProfileIfMissing(finalDefaultProfilePath, finalDefaultProfileId);
86
+ return { id: finalDefaultProfileId, path: finalDefaultProfilePath, created: createdDefaultProfile };
87
+ };
88
+ const buildSetupMessages = (input) => {
89
+ const messages = [];
90
+ if (input.input.setupSourceUri !== undefined && input.starterLayout !== undefined) {
91
+ messages.push(`Prepared setup source ${redactProfileSourceUriCredentials(input.input.setupSourceUri)} at ${input.starterLayout.cachePath}.`);
92
+ }
93
+ messages.push(input.createdSettings
94
+ ? `Created user settings at ${input.settingsPath}.`
95
+ : `User settings already exist at ${input.settingsPath}; left unchanged.`);
96
+ if (input.starterLayout?.profilesPath !== undefined) {
97
+ messages.push(`Copied ${input.copiedStarterProfileFiles} starter profile file(s) into ${join(input.input.homeDirectory, '.outfitter', 'profiles')}.`);
98
+ }
99
+ messages.push(input.createdDefaultProfile
100
+ ? `Created default user profile at ${input.defaultProfilePath}.`
101
+ : `Default user profile at ${input.defaultProfilePath} already exists; left unchanged.`, `Selected default profile '${input.defaultProfileId}'.`, ...input.welcomeProfileMessages, ...input.syncResult.messages);
102
+ return messages;
103
+ };
104
+ export const createSetupCommand = (dependencies = {}) => {
105
+ const command = {
106
+ name: 'setup',
107
+ description: 'Create initial Outfitter settings and a default profile.',
108
+ register(program) {
109
+ program
110
+ .command(`${command.name} [source]`)
111
+ .description(command.description)
112
+ .action(async (source) => {
113
+ const result = await executeSetupCommand({
114
+ /* v8 ignore next -- default process home is exercised by the direct CLI entrypoint, not unit tests. */
115
+ homeDirectory: dependencies.homeDirectory ?? homedir(),
116
+ /* v8 ignore next -- default process cwd is exercised by the direct CLI entrypoint, not unit tests. */
117
+ projectDirectory: dependencies.projectDirectory ?? process.cwd(),
118
+ setupSourceUri: source,
119
+ }, { ...dependencies, interactive: true });
120
+ for (const message of result.messages) {
121
+ /* v8 ignore next -- console fallback is direct CLI behavior; tests inject a writer. */
122
+ (dependencies.writeLine ?? console.log)(message);
123
+ }
124
+ });
125
+ },
126
+ };
127
+ return command;
128
+ };
129
+ const prepareStarterLayout = (homeDirectory, setupSourceUri, synchronizer = createGitSetupSourceSynchronizer()) => {
130
+ const cachePath = createSetupSourceCachePath(homeDirectory, setupSourceUri);
131
+ synchronizer.sync(setupSourceUri, cachePath);
132
+ const settingsPath = firstExistingPath(join(cachePath, 'settings.yml'), join(cachePath, '.outfitter', 'settings.yml'));
133
+ validateStarterSettingsIfPresent(settingsPath);
134
+ const preferredProfilesPath = settingsPath?.endsWith(join('.outfitter', 'settings.yml'))
135
+ ? join(cachePath, '.outfitter', 'profiles')
136
+ : join(cachePath, 'profiles');
137
+ const profilesPath = firstExistingPath(preferredProfilesPath, join(cachePath, 'profiles'), join(cachePath, '.outfitter', 'profiles'));
138
+ return { cachePath, settingsPath, profilesPath };
139
+ };
140
+ const createSetupSourceCachePath = (homeDirectory, setupSourceUri) => createRemoteRepositoryCachePath(homeDirectory, { uri: setupSourceUri });
141
+ const createGitSetupSourceSynchronizer = () => ({
142
+ sync(uri, cachePath) {
143
+ mkdirSync(dirname(cachePath), { recursive: true });
144
+ if (existsSync(cachePath)) {
145
+ runGit(['-C', cachePath, 'pull', '--ff-only'], uri);
146
+ return;
147
+ }
148
+ runGit(['clone', '--', normalizeGitUri(uri), cachePath], uri);
149
+ },
150
+ });
151
+ const runGit = (args, sensitiveUri) => {
152
+ const result = spawn.sync('git', args, { stdio: 'pipe', encoding: 'utf8' });
153
+ if (result.status !== 0) {
154
+ /* v8 ignore next -- the final fallback only applies if git emits no stdout or stderr. */
155
+ throw new Error(redactSensitiveText((result.stderr || result.stdout || `git ${args.join(' ')} failed`).trim(), sensitiveUri));
156
+ }
157
+ };
158
+ const redactSensitiveText = (message, uri) => message
159
+ .split(uri)
160
+ .join(redactProfileSourceUriCredentials(uri))
161
+ .split(normalizeGitUri(uri))
162
+ .join(redactProfileSourceUriCredentials(normalizeGitUri(uri)));
163
+ const firstExistingPath = (...paths) => paths.find((path) => existsSync(path));
164
+ const validateStarterSettingsIfPresent = (settingsPath) => {
165
+ if (settingsPath === undefined) {
166
+ return;
167
+ }
168
+ const loaded = loadSettingsFiles(createSettingsLoadPlan([{ scope: 'user', path: settingsPath }]));
169
+ if (loaded.issues.length > 0) {
170
+ throw new Error(`Cannot setup from invalid starter settings: ${loaded.issues.map(formatSettingsIssue).join('; ')}`);
171
+ }
172
+ };
173
+ const readStarterDefaultProfileId = (settingsPath) => {
174
+ if (settingsPath === undefined) {
175
+ return 'engineer';
176
+ }
177
+ const loaded = loadSettingsFiles(createSettingsLoadPlan([{ scope: 'user', path: settingsPath }]));
178
+ return loaded.files[0]?.settings.defaultProfile ?? 'engineer';
179
+ };
180
+ const readUserDefaultProfileId = (files) => files.find((file) => file.location.scope === 'user')?.settings.defaultProfile ?? 'engineer';
181
+ const ensureExistingUserSettingsDefaultProfile = (settingsPath, files, defaultProfileId) => {
182
+ const userSettings = files.find((file) => file.location.scope === 'user');
183
+ if (userSettings === undefined || userSettings.settings.defaultProfile !== undefined) {
184
+ return;
185
+ }
186
+ const content = readFileSync(settingsPath, 'utf8');
187
+ writeFileSync(settingsPath, `${content}\ndefault_profile: ${defaultProfileId}\n`);
188
+ };
189
+ const assertValidDefaultProfileId = (profileId) => {
190
+ if (!isValidProfileId(profileId)) {
191
+ throw new Error(`Default profile '${profileId}' is not a filesystem-safe Outfitter profile id.`);
192
+ }
193
+ };
194
+ const createDefaultSettingsContent = () => [
195
+ 'default_profile: engineer',
196
+ 'profile_sources:',
197
+ ' - github: ai-outfitter/default-profiles',
198
+ ' path: profiles',
199
+ ' - path: ./profiles',
200
+ '',
201
+ ].join('\n');
202
+ const createInitialSettingsIfMissing = (settingsPath, starterSettingsPath) => {
203
+ if (existsSync(settingsPath)) {
204
+ return false;
205
+ }
206
+ mkdirSync(dirname(settingsPath), { recursive: true });
207
+ writeFileSync(settingsPath, starterSettingsPath === undefined
208
+ ? createDefaultSettingsContent()
209
+ : readStarterSettingsContent(starterSettingsPath));
210
+ return true;
211
+ };
212
+ const readStarterSettingsContent = (starterSettingsPath) => {
213
+ const content = readFileSync(starterSettingsPath, 'utf8');
214
+ const loaded = loadSettingsFiles(createSettingsLoadPlan([{ scope: 'user', path: starterSettingsPath }]));
215
+ if (loaded.files[0]?.settings.defaultProfile !== undefined) {
216
+ return content;
217
+ }
218
+ return `default_profile: engineer\n${content}`;
219
+ };
220
+ const copyStarterProfileFilesIfPresent = (sourceProfilesPath, targetProfilesPath) => {
221
+ if (sourceProfilesPath === undefined) {
222
+ return 0;
223
+ }
224
+ return copyDirectoryContentsWithoutOverwriting(sourceProfilesPath, targetProfilesPath);
225
+ };
226
+ const copyDirectoryContentsWithoutOverwriting = (sourceDirectory, targetDirectory) => {
227
+ mkdirSync(targetDirectory, { recursive: true });
228
+ let copiedFiles = 0;
229
+ for (const entry of readdirSync(sourceDirectory, { withFileTypes: true })) {
230
+ const sourcePath = join(sourceDirectory, entry.name);
231
+ const targetPath = join(targetDirectory, entry.name);
232
+ if (entry.isDirectory()) {
233
+ copiedFiles += copyDirectoryContentsWithoutOverwriting(sourcePath, targetPath);
234
+ continue;
235
+ }
236
+ if (entry.isFile() && !existsSync(targetPath)) {
237
+ mkdirSync(dirname(targetPath), { recursive: true });
238
+ cpSync(sourcePath, targetPath, { force: false });
239
+ copiedFiles += 1;
240
+ }
241
+ }
242
+ return copiedFiles;
243
+ };
244
+ const createDefaultProfileIfMissing = (profilePath, profileId) => {
245
+ if (existsSync(profilePath)) {
246
+ return false;
247
+ }
248
+ mkdirSync(dirname(profilePath), { recursive: true });
249
+ writeFileSync(profilePath, `id: ${profileId}\nlabel: Default\ncontrols: {}\n`);
250
+ return true;
251
+ };
252
+ const persistWelcomeProfileForSetup = (input, settingsPath, welcomeResult) => persistFirstRunWelcomeProfile(input.homeDirectory, settingsPath, welcomeResult, {
253
+ sourceProfileDirectory: findWelcomeSourceProfileDirectory(input, welcomeResult?.selectedRole?.id),
254
+ });
255
+ const findWelcomeSourceProfileDirectory = (input, profileId) => {
256
+ if (profileId === undefined) {
257
+ return undefined;
258
+ }
259
+ const loadedSettings = loadSettingsWithCachedRemoteSettings(input);
260
+ /* v8 ignore next -- setup already rejected invalid settings; this fallback handles cache mutation during welcome. */
261
+ if (loadedSettings.issues.length > 0) {
262
+ return undefined;
263
+ }
264
+ for (const source of loadedSettings.settings.profileSources) {
265
+ const materializedPath = materializeSetupProfileSource(input.homeDirectory, source);
266
+ const loadedProfiles = loadLocalProfileSource({ path: materializedPath, only: source.only, except: source.except });
267
+ const loadedProfile = loadedProfiles.profiles.find((profile) => profile.profile.id === profileId);
268
+ if (loadedProfile !== undefined) {
269
+ return loadedProfile.folderPath;
270
+ }
271
+ }
272
+ return undefined;
273
+ };
274
+ const runWelcomeAfterInteractiveSetup = async (input, dependencies) => {
275
+ if (dependencies.interactive !== true) {
276
+ return undefined;
277
+ }
278
+ if (dependencies.runWelcome !== undefined) {
279
+ return dependencies.runWelcome(input, dependencies);
280
+ }
281
+ return executeWelcomeCommand(input, dependencies);
282
+ };
283
+ const requireInteractiveTerminalIfNeeded = (dependencies) => {
284
+ if (dependencies.interactive !== true) {
285
+ return;
286
+ }
287
+ /* v8 ignore next -- default process streams are direct terminal behavior; tests inject streams. */
288
+ const inputIsTty = (dependencies.input ?? process.stdin).isTTY === true;
289
+ /* v8 ignore next -- default process streams are direct terminal behavior; tests inject streams. */
290
+ const outputIsTty = (dependencies.output ?? process.stdout).isTTY === true;
291
+ if (!inputIsTty || !outputIsTty) {
292
+ throw new Error('`outfitter setup` requires an interactive TTY on both stdin and stdout.');
293
+ }
294
+ };
295
+ const shouldSkipInitialDefaultProfilePrompt = (initialSettingsMissing, dependencies) => initialSettingsMissing && dependencies.interactive === true;
296
+ const selectDefaultProfileIfInteractive = async (input, settingsPath, currentDefault, dependencies) => {
297
+ if (dependencies.interactive !== true) {
298
+ return currentDefault;
299
+ }
300
+ const discoveredProfiles = discoverSetupProfileChoices(input);
301
+ const profiles = discoveredProfiles.length > 0 || builtInSetupProfileChoices.every((profile) => profile.id !== currentDefault)
302
+ ? discoveredProfiles
303
+ : builtInSetupProfileChoices;
304
+ const writer = dependencies.writeLine ?? console.log;
305
+ writer('Welcome to Outfitter. Outfitter is the easiest way to run Pi.');
306
+ writer('Outfitter manages full pi configurations for you, so you can use different profiles in different situations.');
307
+ const selectedProfile = await selectSetupProfile(profiles, currentDefault, dependencies);
308
+ assertValidSelectedDefaultProfile(selectedProfile, profiles);
309
+ updateSettingsDefaultProfile(settingsPath, selectedProfile);
310
+ return selectedProfile;
311
+ };
312
+ const assertValidSelectedDefaultProfile = (selectedProfile, profiles) => {
313
+ assertValidDefaultProfileId(selectedProfile);
314
+ if (profiles.length > 0 && profiles.every((profile) => profile.id !== selectedProfile)) {
315
+ throw new Error(`Selected default profile '${selectedProfile}' was not one of the available setup profiles.`);
316
+ }
317
+ };
318
+ const discoverSetupProfileChoices = (input) => {
319
+ const loadedSettings = loadSettingsWithCachedRemoteSettings(input);
320
+ const choices = new Map();
321
+ for (const source of loadedSettings.settings.profileSources) {
322
+ const materializedPath = materializeSetupProfileSource(input.homeDirectory, source);
323
+ const loadedProfiles = loadLocalProfileSource({ path: materializedPath, only: source.only, except: source.except });
324
+ for (const profile of loadedProfiles.profiles) {
325
+ const existingChoice = choices.get(profile.profile.id);
326
+ choices.set(profile.profile.id, {
327
+ id: profile.profile.id,
328
+ label: profile.profile.label ?? existingChoice?.label,
329
+ });
330
+ }
331
+ }
332
+ return [...choices.values()].sort((left, right) => left.id.localeCompare(right.id));
333
+ };
334
+ const materializeSetupProfileSource = (homeDirectory, source) => {
335
+ if (source.path !== undefined && source.uri === undefined && source.github === undefined) {
336
+ return source.path;
337
+ }
338
+ if (source.uri !== undefined && source.ref === undefined && source.path === undefined) {
339
+ return createProfileSourceCachePath(homeDirectory, source.uri);
340
+ }
341
+ if (source.uri !== undefined) {
342
+ return resolveRemoteRepositorySubpath(createRemoteRepositoryCachePath(homeDirectory, { uri: source.uri, ref: source.ref }), source.path);
343
+ }
344
+ return resolveRemoteRepositorySubpath(createRemoteRepositoryCachePath(homeDirectory, { github: source.github, ref: source.ref }), source.path);
345
+ };
346
+ const selectSetupProfile = async (profiles, currentDefault, dependencies) => {
347
+ if (dependencies.selectDefaultProfile !== undefined) {
348
+ return dependencies.selectDefaultProfile(profiles, currentDefault);
349
+ }
350
+ return promptForSetupProfile(profiles, currentDefault, dependencies);
351
+ };
352
+ const promptForSetupProfile = async (profiles, currentDefault, dependencies) => {
353
+ const candidates = profiles.length > 0 ? profiles : [{ id: currentDefault }];
354
+ /* v8 ignore next -- default process streams are direct terminal behavior; tests inject streams. */
355
+ const output = dependencies.output ?? process.stdout;
356
+ /* v8 ignore next -- default process streams are direct terminal behavior; tests inject streams. */
357
+ const readline = createInterface({ input: dependencies.input ?? process.stdin, output });
358
+ try {
359
+ output.write('\nChoose the default profile for your sessions:\n');
360
+ candidates.forEach((profile, index) => {
361
+ const label = profile.label === undefined ? '' : ` - ${profile.label}`;
362
+ output.write(`${index + 1}. ${profile.id}${label}\n`);
363
+ });
364
+ const currentIndex = Math.max(candidates.findIndex((profile) => profile.id === currentDefault), 0);
365
+ const answer = await readline.question(`Default profile [${currentIndex + 1}]: `);
366
+ const selectedIndex = Number.parseInt(answer.trim() || String(currentIndex + 1), 10) - 1;
367
+ const selectedProfile = candidates[selectedIndex];
368
+ if (selectedProfile === undefined) {
369
+ throw new Error('Selected default profile number is out of range.');
370
+ }
371
+ return selectedProfile.id;
372
+ }
373
+ finally {
374
+ readline.close();
375
+ }
376
+ };
377
+ export { updateSettingsDefaultProfile };
378
+ const formatSettingsIssue = (issue) => `${issue.filePath}#${issue.path} ${issue.message}`;
379
+ //# sourceMappingURL=SetupCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SetupCommand.js","sourceRoot":"","sources":["../../../src/cli/commands/SetupCommand.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type RemoteSourceReference } from '../../profiles/ProfileSource.js';
2
+ import type { CommandObject } from './CommandObject.js';
3
+ export type SyncSourceStatus = 'updated' | 'unchanged' | 'skipped' | 'failed';
4
+ export interface SyncCommandInput {
5
+ readonly homeDirectory: string;
6
+ readonly projectDirectory: string;
7
+ }
8
+ export interface SyncSourceResult {
9
+ readonly uri: string;
10
+ readonly cachePath: string;
11
+ readonly status: SyncSourceStatus;
12
+ readonly message: string;
13
+ }
14
+ export interface SyncCommandResult {
15
+ readonly sources: readonly SyncSourceResult[];
16
+ readonly messages: readonly string[];
17
+ }
18
+ export interface UriProfileSourceSynchronizer {
19
+ sync(source: RemoteSourceReference, cachePath: string): SyncSourceStatus;
20
+ }
21
+ export interface SyncCommandDependencies {
22
+ readonly synchronizer?: UriProfileSourceSynchronizer;
23
+ readonly homeDirectory?: string;
24
+ readonly projectDirectory?: string;
25
+ readonly writeLine?: (message: string) => void;
26
+ }
27
+ export declare const executeSyncCommand: (input: SyncCommandInput, dependencies?: SyncCommandDependencies) => SyncCommandResult;
28
+ export declare const createSyncCommand: (dependencies?: SyncCommandDependencies) => CommandObject;
@@ -0,0 +1,178 @@
1
+ // Provides the command object for synchronizing URI-backed profile and settings sources.
2
+ import { existsSync, mkdirSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { dirname } from 'node:path';
5
+ import spawn from 'cross-spawn';
6
+ import { createProfileSourceCachePath, createRemoteRepositoryCachePath, normalizeGitUri, redactProfileSourceUriCredentials, resolveRemoteRepositorySubpath, } from '../../profiles/ProfileCache.js';
7
+ import { loadLocalProfileSource } from '../../profiles/ProfileLoader.js';
8
+ import { normalizeRemoteSourceUri, } from '../../profiles/ProfileSource.js';
9
+ import { discoverSettingsLoadPlan, loadSettings, loadSettingsWithCachedRemoteSettings, } from '../../settings/SettingsLoader.js';
10
+ export const executeSyncCommand = (input, dependencies = {}) => {
11
+ const localSettings = loadSettings(discoverSettingsLoadPlan(input));
12
+ if (localSettings.issues.length > 0) {
13
+ throw new Error(`Cannot sync with invalid settings: ${localSettings.issues.map(formatSettingsIssue).join('; ')}`);
14
+ }
15
+ const synchronizer = dependencies.synchronizer ?? createGitSynchronizer();
16
+ const remoteSettingsSources = localSettings.settings.remoteSettings;
17
+ const remoteSettingsResults = remoteSettingsSources.map((source) => syncRemoteSettingsSource(input.homeDirectory, source, synchronizer));
18
+ const syncedRemoteSettingsSources = remoteSettingsSources.filter((_source, index) => remoteSettingsResults[index]?.status !== 'failed');
19
+ const loadedSettings = loadSettingsWithCachedRemoteSettings(input, syncedRemoteSettingsSources);
20
+ if (loadedSettings.issues.length > 0) {
21
+ throw new Error(`Cannot sync with invalid settings: ${loadedSettings.issues.map(formatSettingsIssue).join('; ')}`);
22
+ }
23
+ const uriSources = loadedSettings.settings.profileSources.filter(isRemoteProfileSource);
24
+ const profileSourceResults = uriSources.map((source) => syncUriSource(input.homeDirectory, source, synchronizer));
25
+ const sourceResults = [...remoteSettingsResults, ...profileSourceResults];
26
+ return {
27
+ sources: sourceResults,
28
+ messages: sourceResults.length === 0
29
+ ? ['No URI profile or remote settings sources configured; nothing to sync.']
30
+ : sourceResults.map((result) => `${result.status}: ${result.uri} -> ${result.cachePath} (${result.message})`),
31
+ };
32
+ };
33
+ export const createSyncCommand = (dependencies = {}) => {
34
+ const command = {
35
+ name: 'sync',
36
+ description: 'Synchronize URI-backed Outfitter profile and remote settings sources into the local cache.',
37
+ register(program) {
38
+ program
39
+ .command(command.name)
40
+ .description(command.description)
41
+ .action(() => {
42
+ const result = executeSyncCommand({
43
+ /* v8 ignore next -- default process home is exercised by the direct CLI entrypoint, not unit tests. */
44
+ homeDirectory: dependencies.homeDirectory ?? homedir(),
45
+ /* v8 ignore next -- default process cwd is exercised by the direct CLI entrypoint, not unit tests. */
46
+ projectDirectory: dependencies.projectDirectory ?? process.cwd(),
47
+ }, dependencies);
48
+ for (const message of result.messages) {
49
+ /* v8 ignore next -- console fallback is direct CLI behavior; tests inject a writer. */
50
+ (dependencies.writeLine ?? console.log)(message);
51
+ }
52
+ });
53
+ },
54
+ };
55
+ return command;
56
+ };
57
+ const syncRemoteSettingsSource = (homeDirectory, source, synchronizer) => {
58
+ const cachePath = createRemoteRepositoryCachePath(homeDirectory, source);
59
+ const displayUri = formatDisplayUri(source);
60
+ try {
61
+ const settingsPath = resolveRemoteRepositorySubpath(cachePath, source.path);
62
+ const status = synchronizer.sync(source, cachePath);
63
+ if (!existsSync(settingsPath)) {
64
+ return {
65
+ uri: displayUri,
66
+ cachePath,
67
+ status: 'failed',
68
+ message: `Remote settings file not found: ${settingsPath}`,
69
+ };
70
+ }
71
+ return { uri: displayUri, cachePath, status, message: `Remote settings file available at ${settingsPath}.` };
72
+ }
73
+ catch (error) {
74
+ return formatSyncFailure(displayUri, cachePath, source, error);
75
+ }
76
+ };
77
+ const syncUriSource = (homeDirectory, source, synchronizer) => {
78
+ const cachePath = remoteCachePathForProfileSource(homeDirectory, source);
79
+ const displayUri = formatDisplayUri(source);
80
+ try {
81
+ const profileSourcePath = resolveRemoteRepositorySubpath(cachePath, source.path);
82
+ const status = synchronizer.sync(source, cachePath);
83
+ const validation = loadLocalProfileSource({
84
+ path: profileSourcePath,
85
+ only: source.only,
86
+ except: source.except,
87
+ });
88
+ if (validation.issues.length > 0) {
89
+ return {
90
+ uri: displayUri,
91
+ cachePath,
92
+ status: 'failed',
93
+ message: `Synced source failed profile validation: ${validation.issues.map(formatProfileIssue).join('; ')}`,
94
+ };
95
+ }
96
+ return {
97
+ uri: displayUri,
98
+ cachePath,
99
+ status,
100
+ message: validation.profiles.length === 1 ? '1 profile validated.' : `${validation.profiles.length} profiles validated.`,
101
+ };
102
+ }
103
+ catch (error) {
104
+ return formatSyncFailure(displayUri, cachePath, source, error);
105
+ }
106
+ };
107
+ const createGitSynchronizer = () => ({
108
+ sync(source, cachePath) {
109
+ mkdirSync(dirname(cachePath), { recursive: true });
110
+ if (existsSync(cachePath)) {
111
+ runGit(['-C', cachePath, 'fetch', '--all', '--tags']);
112
+ if (source.ref === undefined) {
113
+ runGit(['-C', cachePath, 'pull', '--ff-only']);
114
+ }
115
+ else {
116
+ checkoutRefIfPresent(cachePath, source.ref);
117
+ }
118
+ return 'updated';
119
+ }
120
+ runGit(['clone', '--', normalizeGitUri(normalizeRemoteSourceUri(source)), cachePath]);
121
+ checkoutRefIfPresent(cachePath, source.ref);
122
+ return 'updated';
123
+ },
124
+ });
125
+ const checkoutRefIfPresent = (cachePath, ref) => {
126
+ if (ref === undefined) {
127
+ return;
128
+ }
129
+ assertSafeGitRef(ref);
130
+ if (gitSucceeds(['-C', cachePath, 'rev-parse', '--verify', '--quiet', `refs/remotes/origin/${ref}`])) {
131
+ runGit(['-C', cachePath, 'checkout', '-B', ref, `refs/remotes/origin/${ref}`]);
132
+ return;
133
+ }
134
+ runGit(['-C', cachePath, 'checkout', ref]);
135
+ };
136
+ const assertSafeGitRef = (ref) => {
137
+ if (ref.startsWith('-')) {
138
+ throw new Error(`Git ref '${ref}' must not start with '-'.`);
139
+ }
140
+ };
141
+ const gitSucceeds = (args) => spawn.sync('git', args, { stdio: 'pipe', encoding: 'utf8' }).status === 0;
142
+ const runGit = (args) => {
143
+ const result = spawn.sync('git', args, { stdio: 'pipe', encoding: 'utf8' });
144
+ if (result.status !== 0) {
145
+ /* v8 ignore next -- the final fallback only applies if git emits no stdout or stderr. */
146
+ throw new Error((result.stderr || result.stdout || `git ${args.join(' ')} failed`).trim());
147
+ }
148
+ };
149
+ const isRemoteProfileSource = (source) => source.uri !== undefined || source.github !== undefined;
150
+ const remoteCachePathForProfileSource = (homeDirectory, source) => {
151
+ if (source.ref === undefined && source.path === undefined && source.uri !== undefined) {
152
+ return createProfileSourceCachePath(homeDirectory, source.uri);
153
+ }
154
+ return createRemoteRepositoryCachePath(homeDirectory, source);
155
+ };
156
+ const formatDisplayUri = (source) => {
157
+ const uri = redactProfileSourceUriCredentials(normalizeRemoteSourceUri(source));
158
+ const ref = source.ref === undefined ? '' : `#${source.ref}`;
159
+ const path = source.path === undefined ? '' : `:${source.path}`;
160
+ return `${uri}${ref}${path}`;
161
+ };
162
+ const formatSyncFailure = (displayUri, cachePath, source, error) => {
163
+ const message = error instanceof Error ? error.message : String(error);
164
+ return {
165
+ uri: displayUri,
166
+ cachePath,
167
+ status: 'failed',
168
+ message: redactSensitiveText(message, normalizeRemoteSourceUri(source)),
169
+ };
170
+ };
171
+ const redactSensitiveText = (message, uri) => message
172
+ .split(uri)
173
+ .join(redactProfileSourceUriCredentials(uri))
174
+ .split(normalizeGitUri(uri))
175
+ .join(redactProfileSourceUriCredentials(normalizeGitUri(uri)));
176
+ const formatSettingsIssue = (issue) => `${issue.filePath}#${issue.path} ${issue.message}`;
177
+ const formatProfileIssue = (issue) => `${issue.path} ${issue.message}`;
178
+ //# sourceMappingURL=SyncCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SyncCommand.js","sourceRoot":"","sources":["../../../src/cli/commands/SyncCommand.ts"],"names":[],"mappings":"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"}