@ai-outfitter/outfitter 0.11.0 → 1.0.2

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 (308) hide show
  1. package/.outfitter/skills/outfitter/SKILL.md +67 -37
  2. package/README.md +63 -35
  3. package/code/enterprise/cli/privateCatalogSettings.cjs +2 -2
  4. package/code/enterprise/pi-extension/privateCatalogOnboarding.js +5 -8
  5. package/code/enterprise/shared/privateCatalogPolicy.cjs +5 -5
  6. package/code/pi-extension/src/outfitter-extension.js +353 -553
  7. package/code/pi-extension/src/outfitter-runtime-extension.js +160 -0
  8. package/dist/agents/AgentLaunch.d.ts +9 -1
  9. package/dist/agents/AgentLaunch.js +19 -0
  10. package/dist/agents/AgentLaunch.js.map +1 -1
  11. package/dist/agents/PiCredentialPersistence.d.ts +6 -0
  12. package/dist/agents/PiCredentialPersistence.js +33 -0
  13. package/dist/agents/PiCredentialPersistence.js.map +1 -0
  14. package/dist/cli/OutfitterCli.js +10 -18
  15. package/dist/cli/OutfitterCli.js.map +1 -1
  16. package/dist/cli/commands/CommandObject.d.ts +0 -5
  17. package/dist/cli/commands/CommandObject.js +1 -4
  18. package/dist/cli/commands/CommandObject.js.map +1 -1
  19. package/dist/cli/commands/DumpCommand.d.ts +19 -0
  20. package/dist/cli/commands/DumpCommand.js +54 -0
  21. package/dist/cli/commands/DumpCommand.js.map +1 -0
  22. package/dist/cli/commands/ListCommand.d.ts +17 -0
  23. package/dist/cli/commands/ListCommand.js +77 -0
  24. package/dist/cli/commands/ListCommand.js.map +1 -0
  25. package/dist/cli/commands/PiRuntimeLaunch.d.ts +8 -0
  26. package/dist/cli/commands/PiRuntimeLaunch.js +47 -0
  27. package/dist/cli/commands/PiRuntimeLaunch.js.map +1 -0
  28. package/dist/cli/commands/ProcessDefaults.d.ts +2 -0
  29. package/dist/cli/commands/ProcessDefaults.js +5 -0
  30. package/dist/cli/commands/ProcessDefaults.js.map +1 -0
  31. package/dist/cli/commands/RunAgentCommand.d.ts +46 -0
  32. package/dist/cli/commands/RunAgentCommand.js +176 -0
  33. package/dist/cli/commands/RunAgentCommand.js.map +1 -0
  34. package/dist/cli/commands/SetupCommand.d.ts +38 -6
  35. package/dist/cli/commands/SetupCommand.js +194 -232
  36. package/dist/cli/commands/SetupCommand.js.map +1 -1
  37. package/dist/cli/commands/ValidateCommand.d.ts +20 -0
  38. package/dist/cli/commands/ValidateCommand.js +54 -0
  39. package/dist/cli/commands/ValidateCommand.js.map +1 -0
  40. package/dist/composer/Composer.d.ts +11 -0
  41. package/dist/composer/Composer.js +72 -0
  42. package/dist/composer/Composer.js.map +1 -0
  43. package/dist/composer/Composition.d.ts +33 -0
  44. package/dist/composer/Composition.js +2 -0
  45. package/dist/composer/Composition.js.map +1 -0
  46. package/dist/dump/Containment.d.ts +8 -0
  47. package/dist/dump/Containment.js +22 -0
  48. package/dist/dump/Containment.js.map +1 -0
  49. package/dist/dump/Dump.d.ts +8 -0
  50. package/dist/dump/Dump.js +182 -0
  51. package/dist/dump/Dump.js.map +1 -0
  52. package/dist/extensions/PiExtensionCache.d.ts +30 -0
  53. package/dist/extensions/PiExtensionCache.js +92 -0
  54. package/dist/extensions/PiExtensionCache.js.map +1 -0
  55. package/dist/fs/TypeConflict.d.ts +6 -0
  56. package/dist/fs/TypeConflict.js +21 -0
  57. package/dist/fs/TypeConflict.js.map +1 -0
  58. package/dist/paths/OutfitterCache.d.ts +6 -0
  59. package/dist/paths/OutfitterCache.js +17 -0
  60. package/dist/paths/OutfitterCache.js.map +1 -0
  61. package/dist/projection/Materialize.d.ts +24 -0
  62. package/dist/projection/Materialize.js +83 -0
  63. package/dist/projection/Materialize.js.map +1 -0
  64. package/dist/projection/ProjectHarness.d.ts +5 -0
  65. package/dist/projection/ProjectHarness.js +77 -0
  66. package/dist/projection/ProjectHarness.js.map +1 -0
  67. package/dist/projection/Projection.d.ts +23 -0
  68. package/dist/projection/Projection.js +2 -0
  69. package/dist/projection/Projection.js.map +1 -0
  70. package/dist/resolver/AgentDefinition.d.ts +30 -0
  71. package/dist/resolver/AgentDefinition.js +123 -0
  72. package/dist/resolver/AgentDefinition.js.map +1 -0
  73. package/dist/resolver/Layer.d.ts +12 -0
  74. package/dist/resolver/Layer.js +30 -0
  75. package/dist/resolver/Layer.js.map +1 -0
  76. package/dist/resolver/Resolver.d.ts +3 -0
  77. package/dist/resolver/Resolver.js +163 -0
  78. package/dist/resolver/Resolver.js.map +1 -0
  79. package/dist/resolver/ResolverContext.d.ts +15 -0
  80. package/dist/resolver/ResolverContext.js +11 -0
  81. package/dist/resolver/ResolverContext.js.map +1 -0
  82. package/dist/resolver/ResolverValidation.d.ts +11 -0
  83. package/dist/resolver/ResolverValidation.js +112 -0
  84. package/dist/resolver/ResolverValidation.js.map +1 -0
  85. package/dist/resolver/Resource.d.ts +88 -0
  86. package/dist/resolver/Resource.js +34 -0
  87. package/dist/resolver/Resource.js.map +1 -0
  88. package/dist/schemas/agent.schema.json +48 -0
  89. package/dist/schemas/settings.schema.json +32 -9
  90. package/dist/settings/Settings.d.ts +34 -5
  91. package/dist/settings/Settings.js +3 -1
  92. package/dist/settings/Settings.js.map +1 -1
  93. package/dist/settings/SettingsLoader.d.ts +1 -1
  94. package/dist/settings/SettingsLoader.js +23 -22
  95. package/dist/settings/SettingsLoader.js.map +1 -1
  96. package/dist/settings/SettingsMerger.js +12 -10
  97. package/dist/settings/SettingsMerger.js.map +1 -1
  98. package/dist/setup/DefaultCatalog.d.ts +20 -0
  99. package/dist/setup/DefaultCatalog.js +89 -0
  100. package/dist/setup/DefaultCatalog.js.map +1 -0
  101. package/dist/setup/Setup.d.ts +43 -0
  102. package/dist/setup/Setup.js +261 -0
  103. package/dist/setup/Setup.js.map +1 -0
  104. package/dist/skills/SkillDocument.d.ts +6 -1
  105. package/dist/skills/SkillDocument.js.map +1 -1
  106. package/dist/sources/SourceCache.d.ts +19 -0
  107. package/dist/{profiles/ProfileCache.js → sources/SourceCache.js} +22 -18
  108. package/dist/sources/SourceCache.js.map +1 -0
  109. package/dist/validation/SchemaValidator.d.ts +1 -1
  110. package/dist/validation/SchemaValidator.js +4 -13
  111. package/dist/validation/SchemaValidator.js.map +1 -1
  112. package/docs/architecture/state_writeback_strategy.md +54 -122
  113. package/docs/documentation/README.md +33 -12
  114. package/docs/documentation/actions.md +35 -52
  115. package/docs/documentation/agents.md +109 -0
  116. package/docs/documentation/best-practices.md +25 -63
  117. package/docs/documentation/catalogs.md +126 -0
  118. package/docs/documentation/cli.md +39 -41
  119. package/docs/documentation/concepts.md +66 -23
  120. package/docs/documentation/dump-and-bake.md +30 -0
  121. package/docs/documentation/first-time-cli-agent-users.md +8 -8
  122. package/docs/documentation/getting-started.md +28 -8
  123. package/docs/documentation/hooks.md +20 -0
  124. package/docs/documentation/iterating-on-profiles.md +56 -70
  125. package/docs/documentation/local-development.md +84 -0
  126. package/docs/documentation/migration.md +39 -0
  127. package/docs/documentation/personas.md +41 -0
  128. package/docs/documentation/porting-claude.md +54 -0
  129. package/docs/documentation/profiles.md +16 -169
  130. package/docs/documentation/settings.md +61 -0
  131. package/docs/documentation/skills.md +93 -334
  132. package/docs/documentation/state.md +24 -62
  133. package/docs/documentation/subagents.md +37 -0
  134. package/docs/documentation/support-matrix.md +40 -35
  135. package/docs/documentation/switching-to-outfitter.md +75 -81
  136. package/docs/documentation/tasks.md +13 -0
  137. package/docs/documentation/usecases/engineering.md +67 -84
  138. package/docs/documentation/usecases/organization-profile-catalog.md +83 -111
  139. package/docs/documentation/usecases/persona-reviews.md +133 -139
  140. package/docs/philosophy.md +2 -2
  141. package/package.json +3 -3
  142. package/src/schemas/agent.schema.json +48 -0
  143. package/src/schemas/settings.schema.json +32 -9
  144. package/dist/agents/AdapterProfileControls.d.ts +0 -21
  145. package/dist/agents/AdapterProfileControls.js +0 -76
  146. package/dist/agents/AdapterProfileControls.js.map +0 -1
  147. package/dist/agents/AdapterStatePaths.d.ts +0 -12
  148. package/dist/agents/AdapterStatePaths.js +0 -46
  149. package/dist/agents/AdapterStatePaths.js.map +0 -1
  150. package/dist/agents/AgentAdapter.d.ts +0 -44
  151. package/dist/agents/AgentAdapter.js +0 -2
  152. package/dist/agents/AgentAdapter.js.map +0 -1
  153. package/dist/agents/AgentRegistry.d.ts +0 -6
  154. package/dist/agents/AgentRegistry.js +0 -17
  155. package/dist/agents/AgentRegistry.js.map +0 -1
  156. package/dist/agents/LaunchResources.d.ts +0 -17
  157. package/dist/agents/LaunchResources.js +0 -61
  158. package/dist/agents/LaunchResources.js.map +0 -1
  159. package/dist/agents/OutfitterSkill.d.ts +0 -11
  160. package/dist/agents/OutfitterSkill.js +0 -128
  161. package/dist/agents/OutfitterSkill.js.map +0 -1
  162. package/dist/agents/ResourceIdentity.d.ts +0 -2
  163. package/dist/agents/ResourceIdentity.js +0 -51
  164. package/dist/agents/ResourceIdentity.js.map +0 -1
  165. package/dist/agents/claude/ClaudeAdapter.d.ts +0 -2
  166. package/dist/agents/claude/ClaudeAdapter.js +0 -148
  167. package/dist/agents/claude/ClaudeAdapter.js.map +0 -1
  168. package/dist/agents/claude/ClaudeCompositeProfileWriter.d.ts +0 -5
  169. package/dist/agents/claude/ClaudeCompositeProfileWriter.js +0 -7
  170. package/dist/agents/claude/ClaudeCompositeProfileWriter.js.map +0 -1
  171. package/dist/agents/pi/PiAdapter.d.ts +0 -2
  172. package/dist/agents/pi/PiAdapter.js +0 -363
  173. package/dist/agents/pi/PiAdapter.js.map +0 -1
  174. package/dist/agents/pi/PiArgs.d.ts +0 -2
  175. package/dist/agents/pi/PiArgs.js +0 -15
  176. package/dist/agents/pi/PiArgs.js.map +0 -1
  177. package/dist/agents/pi/PiCompositeProfileWriter.d.ts +0 -5
  178. package/dist/agents/pi/PiCompositeProfileWriter.js +0 -7
  179. package/dist/agents/pi/PiCompositeProfileWriter.js.map +0 -1
  180. package/dist/agents/pi/PiExtensionCache.d.ts +0 -12
  181. package/dist/agents/pi/PiExtensionCache.js +0 -195
  182. package/dist/agents/pi/PiExtensionCache.js.map +0 -1
  183. package/dist/agents/pi/PiMcpConfig.d.ts +0 -2
  184. package/dist/agents/pi/PiMcpConfig.js +0 -114
  185. package/dist/agents/pi/PiMcpConfig.js.map +0 -1
  186. package/dist/agents/pi/PiSettingsMergePolicy.d.ts +0 -17
  187. package/dist/agents/pi/PiSettingsMergePolicy.js +0 -59
  188. package/dist/agents/pi/PiSettingsMergePolicy.js.map +0 -1
  189. package/dist/agents/pi/PiSkillSources.d.ts +0 -8
  190. package/dist/agents/pi/PiSkillSources.js +0 -73
  191. package/dist/agents/pi/PiSkillSources.js.map +0 -1
  192. package/dist/cli/commands/FirstRunWelcomeProfile.d.ts +0 -11
  193. package/dist/cli/commands/FirstRunWelcomeProfile.js +0 -110
  194. package/dist/cli/commands/FirstRunWelcomeProfile.js.map +0 -1
  195. package/dist/cli/commands/PiLoginLaunch.d.ts +0 -22
  196. package/dist/cli/commands/PiLoginLaunch.js +0 -170
  197. package/dist/cli/commands/PiLoginLaunch.js.map +0 -1
  198. package/dist/cli/commands/RunCommand.d.ts +0 -36
  199. package/dist/cli/commands/RunCommand.js +0 -345
  200. package/dist/cli/commands/RunCommand.js.map +0 -1
  201. package/dist/cli/commands/SyncCommand.d.ts +0 -46
  202. package/dist/cli/commands/SyncCommand.js +0 -244
  203. package/dist/cli/commands/SyncCommand.js.map +0 -1
  204. package/dist/cli/commands/WelcomeCommand.d.ts +0 -56
  205. package/dist/cli/commands/WelcomeCommand.js +0 -224
  206. package/dist/cli/commands/WelcomeCommand.js.map +0 -1
  207. package/dist/cli/commands/assets/outfitter-ascii.txt +0 -5
  208. package/dist/cli/commands/profile/Command.d.ts +0 -7
  209. package/dist/cli/commands/profile/Command.js +0 -24
  210. package/dist/cli/commands/profile/Command.js.map +0 -1
  211. package/dist/cli/commands/profile/CreateCommand.d.ts +0 -19
  212. package/dist/cli/commands/profile/CreateCommand.js +0 -115
  213. package/dist/cli/commands/profile/CreateCommand.js.map +0 -1
  214. package/dist/cli/commands/profile/LintCommand.d.ts +0 -19
  215. package/dist/cli/commands/profile/LintCommand.js +0 -155
  216. package/dist/cli/commands/profile/LintCommand.js.map +0 -1
  217. package/dist/cli/commands/profile/ListCommand.d.ts +0 -19
  218. package/dist/cli/commands/profile/ListCommand.js +0 -91
  219. package/dist/cli/commands/profile/ListCommand.js.map +0 -1
  220. package/dist/cli/commands/profile/Shared.d.ts +0 -9
  221. package/dist/cli/commands/profile/Shared.js +0 -10
  222. package/dist/cli/commands/profile/Shared.js.map +0 -1
  223. package/dist/cli/commands/run/RunFirstRunOnboarding.d.ts +0 -7
  224. package/dist/cli/commands/run/RunFirstRunOnboarding.js +0 -52
  225. package/dist/cli/commands/run/RunFirstRunOnboarding.js.map +0 -1
  226. package/dist/cli/commands/run/RunLaunchSummary.d.ts +0 -2
  227. package/dist/cli/commands/run/RunLaunchSummary.js +0 -35
  228. package/dist/cli/commands/run/RunLaunchSummary.js.map +0 -1
  229. package/dist/cli/commands/run/RunProfileResolution.d.ts +0 -39
  230. package/dist/cli/commands/run/RunProfileResolution.js +0 -128
  231. package/dist/cli/commands/run/RunProfileResolution.js.map +0 -1
  232. package/dist/cli/commands/run/RunStateWritePrompt.d.ts +0 -2
  233. package/dist/cli/commands/run/RunStateWritePrompt.js +0 -29
  234. package/dist/cli/commands/run/RunStateWritePrompt.js.map +0 -1
  235. package/dist/cli/commands/setup/SetupPrompts.d.ts +0 -14
  236. package/dist/cli/commands/setup/SetupPrompts.js +0 -296
  237. package/dist/cli/commands/setup/SetupPrompts.js.map +0 -1
  238. package/dist/cli/commands/setup/SetupSourceImport.d.ts +0 -5
  239. package/dist/cli/commands/setup/SetupSourceImport.js +0 -177
  240. package/dist/cli/commands/setup/SetupSourceImport.js.map +0 -1
  241. package/dist/cli/commands/setup/SetupSourceLaunch.d.ts +0 -4
  242. package/dist/cli/commands/setup/SetupSourceLaunch.js +0 -65
  243. package/dist/cli/commands/setup/SetupSourceLaunch.js.map +0 -1
  244. package/dist/cli/commands/setup/SetupStarterSource.d.ts +0 -21
  245. package/dist/cli/commands/setup/SetupStarterSource.js +0 -133
  246. package/dist/cli/commands/setup/SetupStarterSource.js.map +0 -1
  247. package/dist/cli/commands/setup/SetupTypes.d.ts +0 -91
  248. package/dist/cli/commands/setup/SetupTypes.js +0 -26
  249. package/dist/cli/commands/setup/SetupTypes.js.map +0 -1
  250. package/dist/compositeProfile/CompositeProfile.d.ts +0 -8
  251. package/dist/compositeProfile/CompositeProfile.js +0 -6
  252. package/dist/compositeProfile/CompositeProfile.js.map +0 -1
  253. package/dist/compositeProfile/CompositeProfileAssembler.d.ts +0 -12
  254. package/dist/compositeProfile/CompositeProfileAssembler.js +0 -32
  255. package/dist/compositeProfile/CompositeProfileAssembler.js.map +0 -1
  256. package/dist/compositeProfile/CompositeProfileCleanup.d.ts +0 -9
  257. package/dist/compositeProfile/CompositeProfileCleanup.js +0 -87
  258. package/dist/compositeProfile/CompositeProfileCleanup.js.map +0 -1
  259. package/dist/compositeProfile/CompositeProfileFile.d.ts +0 -16
  260. package/dist/compositeProfile/CompositeProfileFile.js +0 -16
  261. package/dist/compositeProfile/CompositeProfileFile.js.map +0 -1
  262. package/dist/compositeProfile/CompositeProfileTemplate.d.ts +0 -15
  263. package/dist/compositeProfile/CompositeProfileTemplate.js +0 -65
  264. package/dist/compositeProfile/CompositeProfileTemplate.js.map +0 -1
  265. package/dist/compositeProfile/CompositeProfileWatcher.d.ts +0 -18
  266. package/dist/compositeProfile/CompositeProfileWatcher.js +0 -46
  267. package/dist/compositeProfile/CompositeProfileWatcher.js.map +0 -1
  268. package/dist/compositeProfile/StatePersistence.d.ts +0 -39
  269. package/dist/compositeProfile/StatePersistence.js +0 -249
  270. package/dist/compositeProfile/StatePersistence.js.map +0 -1
  271. package/dist/fs/SafeSymlink.d.ts +0 -13
  272. package/dist/fs/SafeSymlink.js +0 -50
  273. package/dist/fs/SafeSymlink.js.map +0 -1
  274. package/dist/profiles/Profile.d.ts +0 -60
  275. package/dist/profiles/Profile.js +0 -7
  276. package/dist/profiles/Profile.js.map +0 -1
  277. package/dist/profiles/ProfileCache.d.ts +0 -8
  278. package/dist/profiles/ProfileCache.js.map +0 -1
  279. package/dist/profiles/ProfileLoader.d.ts +0 -28
  280. package/dist/profiles/ProfileLoader.js +0 -299
  281. package/dist/profiles/ProfileLoader.js.map +0 -1
  282. package/dist/profiles/ProfileMerger.d.ts +0 -19
  283. package/dist/profiles/ProfileMerger.js +0 -112
  284. package/dist/profiles/ProfileMerger.js.map +0 -1
  285. package/dist/profiles/ProfileSource.d.ts +0 -35
  286. package/dist/profiles/ProfileSource.js +0 -13
  287. package/dist/profiles/ProfileSource.js.map +0 -1
  288. package/dist/profiles/PromptIncludes.d.ts +0 -32
  289. package/dist/profiles/PromptIncludes.js +0 -147
  290. package/dist/profiles/PromptIncludes.js.map +0 -1
  291. package/dist/prompts/SystemPromptExport.d.ts +0 -16
  292. package/dist/prompts/SystemPromptExport.js +0 -81
  293. package/dist/prompts/SystemPromptExport.js.map +0 -1
  294. package/dist/schemas/profile-source.schema.json +0 -29
  295. package/dist/schemas/profile.schema.json +0 -200
  296. package/dist/skills/ProfileSkillResolution.d.ts +0 -21
  297. package/dist/skills/ProfileSkillResolution.js +0 -88
  298. package/dist/skills/ProfileSkillResolution.js.map +0 -1
  299. package/dist/skills/SkillCatalog.d.ts +0 -41
  300. package/dist/skills/SkillCatalog.js +0 -119
  301. package/dist/skills/SkillCatalog.js.map +0 -1
  302. package/dist/skills/SkillResolution.d.ts +0 -34
  303. package/dist/skills/SkillResolution.js +0 -369
  304. package/dist/skills/SkillResolution.js.map +0 -1
  305. package/docs/documentation/profile-repository.md +0 -179
  306. package/src/schemas/SchemaDocument.ts +0 -20
  307. package/src/schemas/profile-source.schema.json +0 -29
  308. package/src/schemas/profile.schema.json +0 -200
@@ -1,22 +1,13 @@
1
- // Validates parsed Outfitter YAML documents against bundled JSON Schemas.
1
+ // Validates parsed Outfitter YAML/JSON documents against bundled JSON Schemas.
2
2
  import { readFileSync } from 'node:fs';
3
3
  import { Ajv2020 } from 'ajv/dist/2020.js';
4
4
  const readSchema = (schemaFileName) => JSON.parse(readFileSync(new URL(`../schemas/${schemaFileName}`, import.meta.url), 'utf8'));
5
5
  const settingsSchema = readSchema('settings.schema.json');
6
- const profileSchema = readSchema('profile.schema.json');
7
- const profileSourceSchema = readSchema('profile-source.schema.json');
8
- const createAjv = () => {
9
- const ajv = new Ajv2020({ allErrors: true });
10
- ajv.addSchema(profileSourceSchema, 'profile-source.schema.json');
11
- ajv.addSchema(profileSchema, 'profile.schema.json');
12
- ajv.addSchema(settingsSchema, 'settings.schema.json');
13
- return ajv;
14
- };
15
- const ajv = createAjv();
6
+ const agentSchema = readSchema('agent.schema.json');
7
+ const ajv = new Ajv2020({ allErrors: true });
16
8
  const validators = {
17
9
  settings: ajv.compile(settingsSchema),
18
- profile: ajv.compile(profileSchema),
19
- 'profile-source': ajv.compile(profileSourceSchema),
10
+ agent: ajv.compile(agentSchema),
20
11
  };
21
12
  export const createValidationResult = (issues) => ({
22
13
  valid: issues.length === 0,
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaValidator.js","sourceRoot":"","sources":["../../src/validation/SchemaValidator.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAc3C,MAAM,UAAU,GAAG,CAAC,cAAsB,EAAW,EAAE,CACrD,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,cAAc,cAAc,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAE7F,MAAM,cAAc,GAAG,UAAU,CAAC,sBAAsB,CAAC,CAAC;AAC1D,MAAM,aAAa,GAAG,UAAU,CAAC,qBAAqB,CAAC,CAAC;AACxD,MAAM,mBAAmB,GAAG,UAAU,CAAC,4BAA4B,CAAC,CAAC;AAErE,MAAM,SAAS,GAAG,GAAY,EAAE;IAC9B,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,GAAG,CAAC,SAAS,CAAC,mBAAgC,EAAE,4BAA4B,CAAC,CAAC;IAC9E,GAAG,CAAC,SAAS,CAAC,aAA0B,EAAE,qBAAqB,CAAC,CAAC;IACjE,GAAG,CAAC,SAAS,CAAC,cAA2B,EAAE,sBAAsB,CAAC,CAAC;IACnE,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;AAExB,MAAM,UAAU,GAAyC;IACvD,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,cAA2B,CAAC;IAClD,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,aAA0B,CAAC;IAChD,gBAAgB,EAAE,GAAG,CAAC,OAAO,CAAC,mBAAgC,CAAC;CAChE,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,MAAkC,EAAoB,EAAE,CAAC,CAAC;IAC/F,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;IAC1B,MAAM;CACP,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,UAAsB,EAAE,QAAiB,EAAoB,EAAE;IAC5F,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAExC,IAAI,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvB,OAAO,sBAAsB,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,sBAAsB,CAAE,QAAQ,CAAC,MAAiC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;AACjG,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,KAAkB,EAAmB,EAAE,CAAC,CAAC;IAC/D,IAAI,EAAE,KAAK,CAAC,YAAY,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY;IAC1D,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;CAC/B,CAAC,CAAC"}
1
+ {"version":3,"file":"SchemaValidator.js","sourceRoot":"","sources":["../../src/validation/SchemaValidator.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAc3C,MAAM,UAAU,GAAG,CAAC,cAAsB,EAAW,EAAE,CACrD,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,cAAc,cAAc,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAE7F,MAAM,cAAc,GAAG,UAAU,CAAC,sBAAsB,CAAC,CAAC;AAC1D,MAAM,WAAW,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC;AAEpD,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAE7C,MAAM,UAAU,GAAyC;IACvD,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,cAA2B,CAAC;IAClD,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,WAAwB,CAAC;CAC7C,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,MAAkC,EAAoB,EAAE,CAAC,CAAC;IAC/F,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;IAC1B,MAAM;CACP,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,UAAsB,EAAE,QAAiB,EAAoB,EAAE;IAC5F,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAExC,IAAI,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvB,OAAO,sBAAsB,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,sBAAsB,CAAE,QAAQ,CAAC,MAAiC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;AACjG,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,KAAkB,EAAmB,EAAE,CAAC,CAAC;IAC/D,IAAI,EAAE,KAAK,CAAC,YAAY,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY;IAC1D,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;CAC/B,CAAC,CAAC"}
@@ -1,82 +1,66 @@
1
1
  # State Writeback Strategy
2
2
 
3
- This document describes Outfitter's current model for handling writes that agent CLIs make inside a composite profile.
3
+ This document describes Outfitter's model for handling writes that agent CLIs make inside a temporary projection — the generated configuration directory an adapter builds from a baked composition.
4
4
 
5
- A composite profile is temporary, but agent CLIs sometimes perform intentionally durable writes, such as logging in, installing plugins, changing settings, or updating MCP configuration.
6
- Outfitter makes those paths explicit: adapter-declared writable paths are materialized with a resolved `state_persistence` strategy before the child CLI starts, and non-persistent or unknown writes are diagnosed after the child exits.
5
+ A projection is temporary, but agent CLIs sometimes perform intentionally durable writes, such as logging in, installing plugins, changing settings, or updating MCP configuration. Outfitter makes those paths explicit: adapter-declared writable paths are materialized with a resolved `state_persistence` strategy before the child CLI starts, and non-persistent or unknown writes are diagnosed after the child exits.
7
6
 
8
7
  ## Functional model
9
8
 
10
- Outfitter separates three kinds of files that may exist in a composite profile:
9
+ Outfitter separates three kinds of files that may exist in a projection:
11
10
 
12
- 1. **Generated runtime files**: files Outfitter assembles from settings, profiles, templates, and adapter rules.
13
- Outfitter may regenerate these while the child agent is running when their source inputs change.
11
+ 1. **Generated runtime files**: files Outfitter assembles from the baked composition and adapter rules.
14
12
  2. **Declared state paths**: adapter-known files or directories the agent CLI may update intentionally, such as auth, settings, MCP config, plugins, caches, and sessions.
15
13
  3. **Unknown writes**: files or directories the agent creates outside the adapter-declared state paths.
16
14
 
17
- Only declared state paths can be made durable automatically.
18
- Unknown writes are never silently persisted because Outfitter does not know their intended owner, merge rules, or durable destination.
19
- Generated runtime files and declared state paths are deliberately handled separately so live profile/template updates do not erase or re-baseline agent state changes made during the same run.
15
+ Only declared state paths can be made durable automatically. Unknown writes are never silently persisted because Outfitter does not know their intended owner, merge rules, or durable destination. Generated runtime files and declared state paths are deliberately handled separately so composition regeneration does not erase or re-baseline agent state changes made during the same run.
20
16
 
21
17
  The user-facing state update lifecycle is:
22
18
 
23
- 1. **Choose a profile**.
24
- Profile resolution determines the effective `state_persistence` map using normal profile precedence.
25
- 2. **Resolve adapter defaults**.
26
- For each path the selected adapter declares, Outfitter uses the profile override when present and otherwise uses the adapter default.
27
- 3. **Prepare the composite profile**.
28
- Durable paths are connected to a profile-managed or native CLI location; non-durable paths are created as normal temporary composite profile paths.
29
- 4. **Run the agent**.
30
- The agent CLI reads and writes the composite profile as if it were its normal configuration directory.
31
- 5. **Classify changes after exit**.
32
- Outfitter checks non-durable declared paths and unknown paths and reports or fails according to their strategies.
33
- 6. **Clean up temporary state**.
34
- Temporary composite profile contents are discarded; durable symlink targets remain in their profile or native CLI location.
19
+ 1. **Resolve settings.** Settings resolution determines the effective `state_persistence` map using normal settings precedence (`settings.local.yml` over `settings.yml`, project over user).
20
+ 2. **Resolve adapter defaults.** For each path the selected adapter declares, Outfitter uses the settings override when present and otherwise uses the adapter default.
21
+ 3. **Prepare the projection.** Durable paths are connected to a native CLI location; non-durable paths are created as normal temporary projection paths.
22
+ 4. **Run the agent.** The agent CLI reads and writes the projection as if it were its normal configuration directory.
23
+ 5. **Classify changes after exit.** Outfitter checks non-durable declared paths and unknown paths and reports, prompts, or fails according to their strategies.
24
+ 6. **Clean up temporary state.** Temporary projection contents are discarded; durable symlink targets remain in their native CLI location.
35
25
 
36
26
  ## Current behavior
37
27
 
38
- - Composite profiles remain temporary and reproducible by default.
28
+ - Projections remain temporary and reproducible by default.
39
29
  - Outfitter does not do generic post-run copy-back or JSON/YAML merge-back.
40
- - Persistent state is represented by symlinking a composite profile path to a profile file/directory or to the native CLI fallback path.
41
- - Adapters may generate a concrete runtime file for a declared state path when they need deterministic launch-time reconciliation.
42
- For example, the Pi adapter can generate a transformed `settings.json` that removes native `packages` entries already supplied by profile-controlled extensions, and then mark that declared path as `discard` for write detection during the run.
43
- - Every adapter-declared state path has a resolved strategy before launch: profile overrides win, otherwise the adapter `default_strategy` is used, except for adapter-generated reconciliation files that are intentionally treated as discarded runtime files.
44
- - Invalid or disallowed profile-requested `state_persistence` strategies fail before launch; adapter-internal reconciliation may still choose a one-run handling strategy for a generated runtime file.
30
+ - Persistent state is represented by symlinking a projection path to the native CLI fallback path.
31
+ - Adapters may generate a concrete runtime file for a declared state path when they need deterministic launch-time reconciliation. For example, the Pi adapter can generate a transformed `settings.json` that removes native `packages` entries already supplied by composition-controlled extensions, and then mark that declared path as `discard` for write detection during the run.
32
+ - Every adapter-declared state path has a resolved strategy before launch: settings overrides win, otherwise the adapter `default_strategy` is used, except for adapter-generated reconciliation files that are intentionally treated as discarded runtime files.
33
+ - Invalid or disallowed requested `state_persistence` strategies fail before launch; adapter-internal reconciliation may still choose a one-run handling strategy for a generated runtime file.
45
34
  - Non-persistent `warn` and `error` strategies are checked after the child CLI exits.
46
35
  - Unknown writes outside adapter-declared paths are checked with the adapter's `unknown` pseudo-path strategy.
47
- - `prompt` is reserved for a future interactive/control-plane workflow.
48
- When accepted by a declaration today, it is treated as a non-persistent diagnostic like `warn`.
36
+ - Baked artifacts and dumps never include declared state paths or their contents; state is runtime, not configuration.
49
37
 
50
38
  ## Non-goals
51
39
 
52
- - Outfitter does not implement generic copy-back from the composite profile to profiles.
40
+ - Outfitter does not implement generic copy-back from the projection to `.agents` trees.
53
41
  - Outfitter does not implement generic structured merge-back.
54
42
  - Outfitter does not silently persist unknown writes.
55
43
 
56
- ## Profile stack and native fallback
44
+ ## Settings resolution and native fallback
57
45
 
58
- State persistence is a normal profile setting.
59
- Its strategy overrides resolve through the same selected-profile stack as other profile data. When the user provides `--profile X`, only definitions of `X` and its explicit inheritance chain participate; the configured `default_profile` is selected only when no explicit profile is provided.
46
+ State persistence is a normal Outfitter setting. Its strategy overrides resolve through the same settings precedence as other settings data:
60
47
 
61
48
  ```text
62
- project-local definition of selected profile
63
- project definition of selected profile
64
- user definition of selected profile
65
- URI/cache definitions of selected profile
66
- explicit inheritance
49
+ <project>/.agents/settings.local.yml
50
+ <project>/.agents/settings.yml
51
+ ~/.agents/settings.local.yml
52
+ ~/.agents/settings.yml
53
+ cached remote settings
67
54
  Outfitter defaults
68
55
  ```
69
56
 
70
- Native CLI state is not represented as an extra profile layer.
71
- For `symlink` paths without a profile-provided source, the selected adapter resolves a native fallback location directly, such as `~/.pi/agent/...` for most Pi state paths, `~/.claude/...` for most Claude Code state paths, or `<cache_directory>/utilities` for Pi `utilities/` and `bin/`.
72
- This native fallback is not a base profile: it does not participate in profile inheritance or merge precedence, and it cannot contribute controls or profile YAML.
73
- Claude Code `projects/` is additionally controlled by `controls.session_directory` or `controls.claude.session_directory` when set.
57
+ Native CLI state is not a configuration layer. For `symlink` paths, the selected adapter resolves a native fallback location directly, such as `~/.pi/agent/...` for most Pi state paths, `~/.claude/...` for most Claude Code state paths, or `<cache_directory>/utilities` for Pi `utilities/` and `bin/`. The native fallback does not participate in resource resolution or merge precedence and cannot contribute resources. Claude Code `projects/` is additionally controlled by the session-directory setting when set.
58
+
59
+ For a [ported Claude Code setup](../documentation/porting-claude.md), configuration entries under `~/.claude` are symlinks into `~/.agents/`, so a durable write through the projection's `skills/` link lands in the protocol tree. The porting arrangement is created by setup; the state machinery just follows the links.
74
60
 
75
61
  ## Path-keyed adapter declarations
76
62
 
77
- Adapters declare writable state paths directly, using relative file paths as keys.
78
- Directory paths use a trailing slash.
79
- The same key is used for adapter coverage, `state_persistence` overrides, profile resource lookup, native fallback lookup, and composite profile materialization.
63
+ Adapters declare writable state paths directly, using relative file paths as keys. Directory paths use a trailing slash. The same key is used for adapter coverage, `state_persistence` overrides, native fallback lookup, and projection materialization.
80
64
 
81
65
  The Pi adapter currently declares:
82
66
 
@@ -90,11 +74,12 @@ state_paths:
90
74
  default_strategy: symlink
91
75
  allowed_strategies: [symlink, warn, error, prompt]
92
76
  note: >-
93
- When profile-controlled Pi extensions duplicate native settings packages,
94
- Outfitter may generate a transformed runtime settings.json and treat this
95
- declared path as discard for that launch. That discard handling is
96
- adapter-internal; users still cannot request settings.json: discard
97
- because discard is not listed in allowed_strategies.
77
+ When composition-controlled Pi extensions duplicate native settings
78
+ packages, Outfitter may generate a transformed runtime settings.json and
79
+ treat this declared path as discard for that launch. That discard
80
+ handling is adapter-internal; users still cannot request
81
+ settings.json: discard because discard is not listed in
82
+ allowed_strategies.
98
83
 
99
84
  keybindings.json:
100
85
  default_strategy: symlink
@@ -190,43 +175,9 @@ state_paths:
190
175
  allowed_strategies: [discard, warn, error, prompt]
191
176
  ```
192
177
 
193
- ## Profile layout for state files
194
-
195
- State files live under the relevant CLI-specific profile folder:
196
-
197
- ```text
198
- profiles/
199
- default/
200
- profile.yml
201
- cli_specific/
202
- pi/
203
- auth.json
204
- settings.json
205
- keybindings.json
206
- plugins/
207
- claude/
208
- settings.json
209
- skills/
210
- commands/
211
- plugins/
212
- ```
213
-
214
- Except for special adapter paths described below, when a selected strategy is `symlink`, Outfitter searches the resolved profile folders from highest to lowest precedence for `cli_specific/<adapter>/<state-path>`.
215
- If a profile contains the file or directory, Outfitter symlinks the composite profile path to that source.
216
-
217
- For most Pi paths, if no profile source exists, Outfitter falls back to the corresponding native Pi agent path under `~/.pi/agent`.
218
- Missing native fallback files/directories are created so the composite profile symlink has a durable destination.
219
-
220
- Pi `utilities/` and `bin/` are special cache-backed paths: both resolve to `<cache_directory>/utilities` instead of profile or native Pi state.
221
- This keeps pi-managed helper binaries reusable across temporary composite profiles without treating them as user-editable profile files.
222
-
223
- For most Claude Code paths, if no profile source exists, Outfitter falls back to the corresponding native Claude Code path under `~/.claude`.
224
- Claude Code `projects/` is special: `controls.claude.session_directory` overrides generic `controls.session_directory`, and the selected session directory becomes the `projects/` symlink source.
225
- If neither session-directory control is present, `projects/` falls back to `~/.claude/projects`.
226
-
227
178
  ## `state_persistence`
228
179
 
229
- Profiles may override persistence by mapping adapter-declared paths to strategy names:
180
+ Settings may override persistence by mapping adapter-declared paths to strategy names:
230
181
 
231
182
  ```yaml
232
183
  state_persistence:
@@ -238,11 +189,9 @@ state_persistence:
238
189
  unknown: warn
239
190
  ```
240
191
 
241
- The values are concrete strategy names.
242
- `state_persistence` only needs overrides; omitted paths use the adapter declaration's `default_strategy`.
192
+ The values are concrete strategy names. `state_persistence` only needs overrides; omitted paths use the adapter declaration's `default_strategy`.
243
193
 
244
- `state_persistence` is validated by the profile JSON Schema at read boundaries.
245
- Outfitter also validates the resolved strategy against the adapter declaration before launch.
194
+ `state_persistence` is validated by the settings JSON Schema at read boundaries. Outfitter also validates the resolved strategy against the adapter declaration before launch.
246
195
 
247
196
  Functional examples:
248
197
 
@@ -256,7 +205,7 @@ state_persistence:
256
205
  ```
257
206
 
258
207
  ```yaml
259
- # CI profile: fail if pi changes settings, MCP config, or unknown files.
208
+ # CI settings: fail if pi changes settings, MCP config, or unknown files.
260
209
  state_persistence:
261
210
  settings.json: error
262
211
  mcp.json: error
@@ -265,25 +214,25 @@ state_persistence:
265
214
  ```
266
215
 
267
216
  ```yaml
268
- # Exploratory profile: allow plugin experiments but report them after exit.
217
+ # Exploratory settings: allow plugin experiments but report them after exit.
269
218
  state_persistence:
270
219
  plugins/: warn
271
220
  unknown: warn
272
221
  ```
273
222
 
274
- ## Composite profile materialization
223
+ ## Projection materialization
275
224
 
276
225
  Before launch, Outfitter processes each adapter-declared state path:
277
226
 
278
- 1. Resolve the path's strategy from profile `state_persistence` overrides, then the adapter `default_strategy`.
227
+ 1. Resolve the path's strategy from `state_persistence` overrides, then the adapter `default_strategy`.
279
228
  2. Validate that the strategy is allowed for that path.
280
- 3. Resolve a source path through the profile hierarchy when the strategy is `symlink`.
281
- 4. Materialize the composite profile path.
229
+ 3. Resolve the native fallback source when the strategy is `symlink`; missing native fallback files/directories are created so the symlink has a durable destination.
230
+ 4. Materialize the projection path.
282
231
  5. Record a baseline fingerprint for non-persistent and unknown write detection.
283
232
 
284
- For `symlink`, Outfitter creates a symlink from the composite profile path to the resolved profile or native CLI source.
233
+ For `symlink`, Outfitter creates a symlink from the projection path to the resolved native CLI source. For `discard`, `warn`, `error`, and `prompt`, Outfitter creates normal temporary projection paths where needed and observes whether they changed.
285
234
 
286
- For `discard`, `warn`, `error`, and `prompt`, Outfitter creates normal temporary composite profile paths where needed and observes whether they changed.
235
+ Pi `utilities/` and `bin/` are special cache-backed paths: both resolve to `<cache_directory>/utilities` instead of native Pi state, keeping pi-managed helper binaries reusable across temporary projections. Claude Code `projects/` uses the configured session directory when set, otherwise `~/.claude/projects`.
287
236
 
288
237
  ## Unknown writes
289
238
 
@@ -294,57 +243,40 @@ state_persistence:
294
243
  unknown: warn
295
244
  ```
296
245
 
297
- Supported `unknown` strategies are non-persistent only:
298
-
299
- - `discard`
300
- - `warn`
301
- - `error`
302
- - `prompt`
303
-
304
- `unknown` does not support `symlink`, because there is no declared durable destination.
246
+ Supported `unknown` strategies are non-persistent only: `discard`, `warn`, `error`, and `prompt`. `unknown` does not support `symlink`, because there is no declared durable destination; `unknown: prompt` reports as a warning with an explanation.
305
247
 
306
248
  ## Strategy selection guide
307
249
 
308
- Use `symlink` when a write is part of durable agent setup, such as logging in, editing native settings, updating MCP config, or installing plugins that should be reused.
309
- Use `discard` when the data is useful only during the current run, such as cache entries or throwaway sessions.
310
- Use `warn` when mutation is acceptable but should be visible to the user.
311
- Use `error` when mutation means the run was not reproducible enough, especially in CI or locked-down project profiles.
312
- Use `prompt` only as a forward-compatible declaration for future interactive handling.
250
+ Use `symlink` when a write is part of durable agent setup, such as logging in, editing native settings, updating MCP config, or installing plugins that should be reused. Use `discard` when the data is useful only during the current run, such as cache entries or throwaway sessions. Use `warn` when mutation is acceptable but should be visible to the user. Use `error` when mutation means the run was not reproducible enough, especially in CI or locked-down projects. Use `prompt` when the user should decide interactively after each run.
313
251
 
314
252
  ## Strategies
315
253
 
316
254
  ### `symlink`
317
255
 
318
- Outfitter resolves the state path through the profile hierarchy, then the native CLI fallback, and symlinks that source into the composite profile.
319
- Persistence happens because the CLI writes through the symlink to an intentional file or directory.
256
+ Outfitter resolves the state path to its native CLI fallback and symlinks that source into the projection. Persistence happens because the CLI writes through the symlink to an intentional file or directory.
320
257
 
321
258
  ### `discard`
322
259
 
323
- Writes are allowed in the composite profile and are thrown away when the composite profile is deleted.
324
- Outfitter does not emit diagnostics for changed `discard` paths.
260
+ Writes are allowed in the projection and are thrown away when the projection is deleted. Outfitter does not emit diagnostics for changed `discard` paths.
325
261
 
326
262
  ### `warn`
327
263
 
328
- Writes are allowed, discarded, and reported after the child exits.
329
- `--strict` makes these warnings fatal.
264
+ Writes are allowed, discarded, and reported after the child exits. `--strict` makes these warnings fatal.
330
265
 
331
266
  ### `error`
332
267
 
333
- Writes are allowed during the child process but cause Outfitter to fail after the child exits if the path changed.
334
- This is useful for CI and strict reproducibility.
268
+ Writes are allowed during the child process but cause Outfitter to fail after the child exits if the path changed. This is useful for CI and strict reproducibility.
335
269
 
336
270
  ### `prompt`
337
271
 
338
- `prompt` is reserved for a future interactive/control-plane workflow.
339
- Current implementations that allow it treat writes as non-persistent diagnostics, equivalent to `warn`, with the strategy name preserved in the message.
272
+ When a `prompt` path changed and both stdin and stdout are interactive terminals, Outfitter asks after the child exits: **persist** (copy the change to the durable destination once), **discard**, or **always** (persist and record a `symlink` override in the editable settings scope). Outfitter never mutates a synced catalog cache; when the active configuration is remote, the change is persisted once with a warning that the choice could not be recorded. In non-interactive sessions, `prompt` falls back to `warn` with an explicit `prompt skipped: non-interactive` notice.
340
273
 
341
274
  ## Rationale
342
275
 
343
276
  Path-keyed state declarations keep the model simple:
344
277
 
345
278
  - the adapter declares the paths it knows the CLI may write and their default strategies;
346
- - profiles may provide files at those same paths;
347
279
  - the native fallback exposes native CLI files at those same paths;
348
280
  - `state_persistence` says what to do with each path.
349
281
 
350
- This avoids ambiguous writeback behavior and gives users a clear rule: if a CLI write should persist, configure that composite profile path as `symlink` and provide or accept the profile/native file that should receive the mutation.
282
+ This avoids ambiguous writeback behavior and gives users a clear rule: if a CLI write should persist, configure that projection path as `symlink` and accept the native file that should receive the mutation. Configuration flows the other direction — from the `.agents` tree into the projection — and never back.
@@ -1,24 +1,45 @@
1
1
  # Outfitter documentation
2
2
 
3
- User-facing Outfitter documentation.
3
+ User-facing Outfitter documentation. These docs describe the [RFC #165](https://github.com/ai-outfitter/outfitter/issues/165) dotagents end state.
4
+
5
+ ## Getting started
4
6
 
5
7
  - [Getting started](./getting-started.md)
6
8
  - [Concepts](./concepts.md)
7
9
  - [CLI reference](./cli.md)
8
10
  - [First-time CLI agent users](./first-time-cli-agent-users.md)
9
- - [Switching to Outfitter](./switching-to-outfitter.md)
10
- - [Profiles](./profiles.md)
11
- - [Skills](./skills.md) — Define project and profile-bundled skills, route to specialized resources, and compose external references.
12
- - [Best practices](./best-practices.md) — Prefer a few stable profiles and many focused, progressively disclosed skills.
13
- - [Profile repositories](./profile-repository.md) — Publish and consume shareable profiles and standalone skills.
14
- - [Iterating on local and worktree profiles](./iterating-on-profiles.md)
15
- - [Running profiles in GitHub Actions](./actions.md)
16
- - [Adapter support matrix](./support-matrix.md)
11
+
12
+ ## Core concepts
13
+
14
+ - [Settings](./settings.md) — Scopes, schema, and the flat `settings.local.yml` override file.
15
+ - [Agents](./agents.md) — The `agents/<id>/agent.md` resource and its loadout what you run.
16
+ - [Agent profiles](./profiles.md) — Why an agent and its loadout _is_ the profile.
17
+ - [Personas](./personas.md) — The base-agent-plus-persona-documents review convention.
18
+ - [Subagents](./subagents.md) — Agents projected as harness delegates; leader-agent delegation.
19
+ - [Skills](./skills.md) — Capability packages with progressive disclosure, references, and routing.
20
+ - [Tasks](./tasks.md) — Placeholder for a separate upcoming RFC.
21
+
22
+ ## Operations
23
+
24
+ - [Catalogs](./catalogs.md) — Publish and consume shareable `.agents` payloads; standalone and colocated layouts.
25
+ - [Dump](./dump-and-bake.md) — Deterministic, self-contained `.agents/` dumps.
26
+ - [Running an agent in GitHub Actions](./actions.md)
27
+ - [Hooks](./hooks.md) — Harness hook wiring and the protocol gap.
17
28
  - [State persistence](./state.md)
29
+ - [Adapter support matrix](./support-matrix.md)
30
+
31
+ ## Adopting Outfitter
32
+
33
+ - [Switching to Outfitter](./switching-to-outfitter.md)
34
+ - [Porting a Claude Code setup](./porting-claude.md) — Port `~/.claude` into `~/.agents/` with a symlink back.
35
+ - [Local dotagents development](./local-development.md) — A personal standalone `.agents` repo that trickles upstream.
36
+ - [Migration from legacy profiles](./migration.md)
37
+ - [Iterating on an agent](./iterating-on-profiles.md)
38
+ - [Best practices](./best-practices.md)
18
39
  - [Philosophy](../philosophy.md)
19
40
 
20
41
  ## Use cases
21
42
 
22
- - [Organization profile catalog](./usecases/organization-profile-catalog.md) — Publish shared team roles so new users can start with organization-approved defaults.
23
- - [Engineering profile catalog](./usecases/engineering.md) — Package coding, platform, and review profiles for repeatable engineering workflows.
24
- - [Persona reviews](./usecases/persona-reviews.md) — Create customer personas to get feedback on ideas, documentation, and designs.
43
+ - [Organization catalog](./usecases/organization-profile-catalog.md) — Publish shared org resources and defaults through an `owner/.outfitter` control repository.
44
+ - [Engineering catalog](./usecases/engineering.md) — Package engineering agents and skills for repeatable workflows.
45
+ - [Persona reviews](./usecases/persona-reviews.md) — A base review agent plus customer-persona documents for feedback on ideas, docs, and designs.
@@ -1,6 +1,6 @@
1
- # Running profiles in GitHub Actions
1
+ # Running an agent in GitHub Actions
2
2
 
3
- [`ai-outfitter/actions`](https://github.com/ai-outfitter/actions) runs an Outfitter profile non-interactively inside a GitHub Actions workflow. Outfitter assembles the profile exactly as it does locally context, prompts, skills, controls and launches the agent CLI in headless print mode (`pi -p`), so the agent does one unit of work per workflow run and exits. Wire it to any trigger and a profile becomes a CI agent: a PR reviewer, a scheduled commit auditor, an issue triager.
3
+ [`ai-outfitter/actions`](https://github.com/ai-outfitter/actions) runs an Outfitter [agent](./agents.md) non-interactively inside a GitHub Actions workflow. The Action asks Outfitter to resolve and compose the selected agent the same loadout it would compose locallythen launches the harness in headless print mode, so the agent does one unit of work per workflow run and exits. Wire it to any trigger and an agent becomes a CI worker: a PR reviewer, a scheduled commit auditor, an issue triager.
4
4
 
5
5
  ```yaml
6
6
  # .github/workflows/issue-triage.yml
@@ -20,78 +20,61 @@ jobs:
20
20
  runs-on: ubuntu-latest
21
21
  steps:
22
22
  - uses: actions/checkout@v4
23
- - uses: ai-outfitter/actions@v1
23
+ - uses: ai-outfitter/actions@v2
24
24
  with:
25
- profile: issue-triage
26
- profile-source: ${{ github.workspace }}/profiles
27
- prompt: >-
28
- Triage issue #${{ github.event.issue.number }} in
29
- ${{ github.repository }} following your process.
25
+ agent: issue-triage
26
+ source: ${{ github.workspace }}/.agents # or owner/.agent + a pinned ref
27
+ inputs: |
28
+ issue_number: ${{ github.event.issue.number }}
29
+ repository: ${{ github.repository }}
30
30
  ```
31
31
 
32
- The action installs `@ai-outfitter/outfitter`, writes a minimal `~/.outfitter/settings.yml` on the runner, syncs remote catalogs if needed, then runs `outfitter run --profile <profile> --agent pi -- -p "<prompt>"`. The runner is discarded afterwards; nothing persists except what the agent pushed through its token.
32
+ The Action consumes an agent ID, a local or pinned remote source, structured inputs, and runtime-only options (harness, credentials, working directory). It does not reproduce composition logic itself it goes through Outfitter's resolver so a CI run and a local run compose identically given the same sources and refs.
33
33
 
34
- Profiles can come from the checked-out repository itself (a path, as above), an `owner/repo` catalog shorthand, or any git URI — the same [profile repository](./profile-repository.md) sources Outfitter supports locally. Pin `profile-source-ref` for catalogs you don't own.
34
+ > **Note:** a dedicated **task**-bake path freezing a named work contract and its typed inputs into an immutable artifact before launch is the subject of a [separate upcoming RFC](./tasks.md). Until then the Action runs an agent with structured inputs; the `inputs:` shape above is forward-compatible with that work.
35
35
 
36
- ## Pass GitHub trigger context
36
+ ## Division of ownership
37
37
 
38
- `trigger_context` is a convention for the initial prompt passed by an
39
- `ai-outfitter/actions` workflow. It is not an Outfitter object and Outfitter does
40
- not create or parse it. GitHub Actions interpolates the selected `github`
41
- expression values before invoking Outfitter, giving the profile metadata that
42
- the workflow — not the event author — chose to pass. That does not make every
43
- value trustworthy: branch and tag names, labels, titles, and logins are
44
- user-influenced, so route on them as opaque identifiers and never treat them
45
- as instructions.
38
+ The workflow YAML owns the GitHub side; the agent owns the work:
46
39
 
47
- ```yaml
48
- - uses: ai-outfitter/actions@v1
49
- with:
50
- profile: platform
51
- prompt: |
52
- Handle this GitHub event according to the profile's skill activation rules.
53
-
54
- trigger_context:
55
- repository: ${{ github.repository }}
56
- event_name: ${{ github.event_name }}
57
- issue_number: ${{ github.event.issue.number || '' }}
58
- ```
40
+ | Workflow YAML owns | Agent owns |
41
+ | ------------------------------------------ | ----------------------------------- |
42
+ | Triggers (`on:`) | The objective and prompt |
43
+ | Checkout | Identity and posture |
44
+ | `permissions:` and credentials | Its loadout: skills, subagents, mcp |
45
+ | Execution identity | How it uses its inputs |
46
+ | Trusted event identifiers passed as inputs | Completion behavior |
47
+ | GitHub-specific result handling | |
59
48
 
60
- Include only the identifiers the profile's routing rules need for the
61
- workflow's declared events (for example `sha`, `issue_labels`, or a
62
- deployment's `environment_url` when those events are in play). Add a
63
- workflow-owned discriminator, such as `report_kind: weekly-kpi`, when GitHub's
64
- event metadata cannot distinguish scheduled behaviors.
49
+ Pass only the identifiers the agent expects (numbers, SHAs, repository names, workflow-owned discriminators). Never interpolate issue bodies, PR bodies, comments, diffs, or fetched page content into inputs — user-influenced values like titles and branch names are opaque identifiers, not instructions. A selected skill retrieves untrusted source material itself with trusted tools.
65
50
 
66
- Keep the profile's mapping from this metadata to skills short and keep task
67
- procedures in the skills themselves. See
68
- [Keep routing concise](./best-practices.md#keep-routing-concise) for that design
69
- boundary.
51
+ ## Setup: the `outfitter-actions` skill
70
52
 
71
- Do not interpolate issue bodies, pull request bodies, comments, diffs,
72
- deployment logs, or fetched page content into `trigger_context`. Pass stable
73
- identifiers, select the relevant skill, and let that skill retrieve only the
74
- untrusted source material it needs with trusted tools.
53
+ The workflow surface is installed and maintained by the `outfitter-actions` setup skill shipped in the `ai-outfitter/actions` catalog, which includes the reusable workflow template (`template/github-action.yml`). Run it in an agent session to create or update your project's workflows.
54
+
55
+ The setup skill consolidates compatible agents into as few workflows as practical: separate workflows are justified only by different triggers, permissions, credentials, isolation, or other GitHub-enforced boundaries. Domain skills such as `reports` or `issue-triage` do not ship their own workflow templates.
75
56
 
76
57
  ## Zero-key inference with GitHub Models
77
58
 
78
- CI agents don't need a paid provider key. [GitHub Models](https://docs.github.com/en/github-models) serves hosted models authenticated by the workflow's own `GITHUB_TOKEN`: grant `models: read` in the `permissions:` block, commit a pi provider config pointing at `https://models.github.ai/inference` with `"apiKey": "$GITHUB_TOKEN"`, install it to `~/.pi/agent/models.json` before the action step, and select the provider in the profile's `controls`. The action's README documents the full recipe, including model-selection gotchas (catalog availability, tool-call wire compatibility, and models too weak to hold an agentic loop).
59
+ CI agents don't need a paid provider key. [GitHub Models](https://docs.github.com/en/github-models) serves hosted models authenticated by the workflow's own `GITHUB_TOKEN`: grant `models: read` in the `permissions:` block and point the tree's `models.json` at `https://models.github.ai/inference` with `"apiKey": "$GITHUB_TOKEN"`. The Action's README documents the full recipe, including model-selection gotchas (catalog availability, tool-call wire compatibility, and models too weak to hold an agentic loop).
79
60
 
80
61
  Mind the rate limits: the included tier is sized for event-driven, one-shot jobs. Concurrent runs of a large model can 429; high-volume review loops need a provider key.
81
62
 
82
- ## Write profiles for headless runs
63
+ ## Write agents for headless runs
83
64
 
84
- A profile that behaves well interactively can still fail silently in CI. Lessons from running triage agents in production:
65
+ A composition that behaves well interactively can still fail silently in CI. Lessons from running triage agents in production:
85
66
 
86
- - **Stdout is invisible.** In print mode nobody reads what the agent says — only its side effects matter. Instruct the profile to _do_ things with `gh` (comment, label, push) and name the exact commands; otherwise models will print the deliverable as their answer and exit green.
67
+ - **Stdout is invisible.** In print mode nobody reads what the agent says — only its side effects matter. Make the agent's completion criteria name the exact `gh` side effects (comment, label, push); otherwise models will print the deliverable as their answer and exit green.
87
68
  - **Quote-safe posting.** When the agent posts text derived from untrusted input (issue bodies, diffs) back through `gh`, require a quoted heredoc plus `--body-file`, never inline `--body "..."` — backticks in a double-quoted body are executed by the shell.
88
- - **Verify side effects, not exit codes.** A green run is not proof of work. Add a post-agent step that asserts the expected side effects landed — the action ships [`scripts/validate-triage.sh`](https://github.com/ai-outfitter/actions/blob/main/scripts/validate-triage.sh) as a reference for triage-style jobs.
89
- - **Hard limits in the profile.** Enumerate exactly what the agent may do (which labels, how many comments, no closing/editing) and treat fetched content as data to classify, never instructions.
69
+ - **Verify side effects, not exit codes.** A green run is not proof of work. Add a post-agent step that asserts the expected side effects landed — the Action ships [`scripts/validate-triage.sh`](https://github.com/ai-outfitter/actions/blob/main/scripts/validate-triage.sh) as a reference for triage-style jobs.
70
+ - **Hard limits in the contract.** Enumerate exactly what the agent may do (which labels, how many comments, no closing/editing) in the agent's own definition, and treat fetched content as data to classify, never instructions.
90
71
 
91
72
  ## Scope the token
92
73
 
93
- The agent runs arbitrary `gh`/`git`/shell with whatever token you hand it, against untrusted input. Prefer the workflow's own `GITHUB_TOKEN` with an explicit least-privilege `permissions:` block; use a fine-grained PAT from a dedicated machine account only when the agent needs its own identity. Never use a human's PAT. The action's [token-permissions](https://github.com/ai-outfitter/actions/blob/main/docs/token-permissions.md) and [bot-account](https://github.com/ai-outfitter/actions/blob/main/docs/bot-account.md) guides cover this in depth, including prompt-injection trust boundaries.
74
+ The agent runs arbitrary `gh`/`git`/shell with whatever token you hand it, against untrusted input. Prefer the workflow's own `GITHUB_TOKEN` with an explicit least-privilege `permissions:` block; use a fine-grained PAT from a dedicated machine account only when the agent needs its own identity. Never use a human's PAT. The Action's [token-permissions](https://github.com/ai-outfitter/actions/blob/main/docs/token-permissions.md) and [bot-account](https://github.com/ai-outfitter/actions/blob/main/docs/bot-account.md) guides cover this in depth, including prompt-injection trust boundaries.
75
+
76
+ Pin remote sources consumed in CI to full commit SHAs — see [Trust and review](./catalogs.md#trust-and-review).
94
77
 
95
78
  ## More examples
96
79
 
97
- The action's [`examples/`](https://github.com/ai-outfitter/actions/tree/main/examples) directory covers scheduled commit review, PR ready-for-review reviews, sensitive-path audits, assigned-task agents, and zero-key issue triage on GitHub Models. A complete live setup — workflow, profile, provider config, and validation — runs in [`ai-outfitter/default-profiles`](https://github.com/ai-outfitter/default-profiles) as its own issue-triage agent.
80
+ The Action's [`examples/`](https://github.com/ai-outfitter/actions/tree/main/examples) directory covers scheduled commit review, PR ready-for-review reviews, sensitive-path audits, assigned-task agents, and zero-key issue triage on GitHub Models. A complete live setup runs in [`ai-outfitter/.outfitter`](https://github.com/ai-outfitter/.outfitter) as the organization's own `weekly-kpis` agent.