@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.
- package/.outfitter/skills/outfitter/SKILL.md +67 -37
- package/README.md +63 -35
- package/code/enterprise/cli/privateCatalogSettings.cjs +2 -2
- package/code/enterprise/pi-extension/privateCatalogOnboarding.js +5 -8
- package/code/enterprise/shared/privateCatalogPolicy.cjs +5 -5
- package/code/pi-extension/src/outfitter-extension.js +353 -553
- package/code/pi-extension/src/outfitter-runtime-extension.js +160 -0
- package/dist/agents/AgentLaunch.d.ts +9 -1
- package/dist/agents/AgentLaunch.js +19 -0
- package/dist/agents/AgentLaunch.js.map +1 -1
- package/dist/agents/PiCredentialPersistence.d.ts +6 -0
- package/dist/agents/PiCredentialPersistence.js +33 -0
- package/dist/agents/PiCredentialPersistence.js.map +1 -0
- package/dist/cli/OutfitterCli.js +10 -18
- package/dist/cli/OutfitterCli.js.map +1 -1
- package/dist/cli/commands/CommandObject.d.ts +0 -5
- package/dist/cli/commands/CommandObject.js +1 -4
- package/dist/cli/commands/CommandObject.js.map +1 -1
- package/dist/cli/commands/DumpCommand.d.ts +19 -0
- package/dist/cli/commands/DumpCommand.js +54 -0
- package/dist/cli/commands/DumpCommand.js.map +1 -0
- package/dist/cli/commands/ListCommand.d.ts +17 -0
- package/dist/cli/commands/ListCommand.js +77 -0
- package/dist/cli/commands/ListCommand.js.map +1 -0
- package/dist/cli/commands/PiRuntimeLaunch.d.ts +8 -0
- package/dist/cli/commands/PiRuntimeLaunch.js +47 -0
- package/dist/cli/commands/PiRuntimeLaunch.js.map +1 -0
- package/dist/cli/commands/ProcessDefaults.d.ts +2 -0
- package/dist/cli/commands/ProcessDefaults.js +5 -0
- package/dist/cli/commands/ProcessDefaults.js.map +1 -0
- package/dist/cli/commands/RunAgentCommand.d.ts +46 -0
- package/dist/cli/commands/RunAgentCommand.js +176 -0
- package/dist/cli/commands/RunAgentCommand.js.map +1 -0
- package/dist/cli/commands/SetupCommand.d.ts +38 -6
- package/dist/cli/commands/SetupCommand.js +194 -232
- package/dist/cli/commands/SetupCommand.js.map +1 -1
- package/dist/cli/commands/ValidateCommand.d.ts +20 -0
- package/dist/cli/commands/ValidateCommand.js +54 -0
- package/dist/cli/commands/ValidateCommand.js.map +1 -0
- package/dist/composer/Composer.d.ts +11 -0
- package/dist/composer/Composer.js +72 -0
- package/dist/composer/Composer.js.map +1 -0
- package/dist/composer/Composition.d.ts +33 -0
- package/dist/composer/Composition.js +2 -0
- package/dist/composer/Composition.js.map +1 -0
- package/dist/dump/Containment.d.ts +8 -0
- package/dist/dump/Containment.js +22 -0
- package/dist/dump/Containment.js.map +1 -0
- package/dist/dump/Dump.d.ts +8 -0
- package/dist/dump/Dump.js +182 -0
- package/dist/dump/Dump.js.map +1 -0
- package/dist/extensions/PiExtensionCache.d.ts +30 -0
- package/dist/extensions/PiExtensionCache.js +92 -0
- package/dist/extensions/PiExtensionCache.js.map +1 -0
- package/dist/fs/TypeConflict.d.ts +6 -0
- package/dist/fs/TypeConflict.js +21 -0
- package/dist/fs/TypeConflict.js.map +1 -0
- package/dist/paths/OutfitterCache.d.ts +6 -0
- package/dist/paths/OutfitterCache.js +17 -0
- package/dist/paths/OutfitterCache.js.map +1 -0
- package/dist/projection/Materialize.d.ts +24 -0
- package/dist/projection/Materialize.js +83 -0
- package/dist/projection/Materialize.js.map +1 -0
- package/dist/projection/ProjectHarness.d.ts +5 -0
- package/dist/projection/ProjectHarness.js +77 -0
- package/dist/projection/ProjectHarness.js.map +1 -0
- package/dist/projection/Projection.d.ts +23 -0
- package/dist/projection/Projection.js +2 -0
- package/dist/projection/Projection.js.map +1 -0
- package/dist/resolver/AgentDefinition.d.ts +30 -0
- package/dist/resolver/AgentDefinition.js +123 -0
- package/dist/resolver/AgentDefinition.js.map +1 -0
- package/dist/resolver/Layer.d.ts +12 -0
- package/dist/resolver/Layer.js +30 -0
- package/dist/resolver/Layer.js.map +1 -0
- package/dist/resolver/Resolver.d.ts +3 -0
- package/dist/resolver/Resolver.js +163 -0
- package/dist/resolver/Resolver.js.map +1 -0
- package/dist/resolver/ResolverContext.d.ts +15 -0
- package/dist/resolver/ResolverContext.js +11 -0
- package/dist/resolver/ResolverContext.js.map +1 -0
- package/dist/resolver/ResolverValidation.d.ts +11 -0
- package/dist/resolver/ResolverValidation.js +112 -0
- package/dist/resolver/ResolverValidation.js.map +1 -0
- package/dist/resolver/Resource.d.ts +88 -0
- package/dist/resolver/Resource.js +34 -0
- package/dist/resolver/Resource.js.map +1 -0
- package/dist/schemas/agent.schema.json +48 -0
- package/dist/schemas/settings.schema.json +32 -9
- package/dist/settings/Settings.d.ts +34 -5
- package/dist/settings/Settings.js +3 -1
- package/dist/settings/Settings.js.map +1 -1
- package/dist/settings/SettingsLoader.d.ts +1 -1
- package/dist/settings/SettingsLoader.js +23 -22
- package/dist/settings/SettingsLoader.js.map +1 -1
- package/dist/settings/SettingsMerger.js +12 -10
- package/dist/settings/SettingsMerger.js.map +1 -1
- package/dist/setup/DefaultCatalog.d.ts +20 -0
- package/dist/setup/DefaultCatalog.js +89 -0
- package/dist/setup/DefaultCatalog.js.map +1 -0
- package/dist/setup/Setup.d.ts +43 -0
- package/dist/setup/Setup.js +261 -0
- package/dist/setup/Setup.js.map +1 -0
- package/dist/skills/SkillDocument.d.ts +6 -1
- package/dist/skills/SkillDocument.js.map +1 -1
- package/dist/sources/SourceCache.d.ts +19 -0
- package/dist/{profiles/ProfileCache.js → sources/SourceCache.js} +22 -18
- package/dist/sources/SourceCache.js.map +1 -0
- package/dist/validation/SchemaValidator.d.ts +1 -1
- package/dist/validation/SchemaValidator.js +4 -13
- package/dist/validation/SchemaValidator.js.map +1 -1
- package/docs/architecture/state_writeback_strategy.md +54 -122
- package/docs/documentation/README.md +33 -12
- package/docs/documentation/actions.md +35 -52
- package/docs/documentation/agents.md +109 -0
- package/docs/documentation/best-practices.md +25 -63
- package/docs/documentation/catalogs.md +126 -0
- package/docs/documentation/cli.md +39 -41
- package/docs/documentation/concepts.md +66 -23
- package/docs/documentation/dump-and-bake.md +30 -0
- package/docs/documentation/first-time-cli-agent-users.md +8 -8
- package/docs/documentation/getting-started.md +28 -8
- package/docs/documentation/hooks.md +20 -0
- package/docs/documentation/iterating-on-profiles.md +56 -70
- package/docs/documentation/local-development.md +84 -0
- package/docs/documentation/migration.md +39 -0
- package/docs/documentation/personas.md +41 -0
- package/docs/documentation/porting-claude.md +54 -0
- package/docs/documentation/profiles.md +16 -169
- package/docs/documentation/settings.md +61 -0
- package/docs/documentation/skills.md +93 -334
- package/docs/documentation/state.md +24 -62
- package/docs/documentation/subagents.md +37 -0
- package/docs/documentation/support-matrix.md +40 -35
- package/docs/documentation/switching-to-outfitter.md +75 -81
- package/docs/documentation/tasks.md +13 -0
- package/docs/documentation/usecases/engineering.md +67 -84
- package/docs/documentation/usecases/organization-profile-catalog.md +83 -111
- package/docs/documentation/usecases/persona-reviews.md +133 -139
- package/docs/philosophy.md +2 -2
- package/package.json +3 -3
- package/src/schemas/agent.schema.json +48 -0
- package/src/schemas/settings.schema.json +32 -9
- package/dist/agents/AdapterProfileControls.d.ts +0 -21
- package/dist/agents/AdapterProfileControls.js +0 -76
- package/dist/agents/AdapterProfileControls.js.map +0 -1
- package/dist/agents/AdapterStatePaths.d.ts +0 -12
- package/dist/agents/AdapterStatePaths.js +0 -46
- package/dist/agents/AdapterStatePaths.js.map +0 -1
- package/dist/agents/AgentAdapter.d.ts +0 -44
- package/dist/agents/AgentAdapter.js +0 -2
- package/dist/agents/AgentAdapter.js.map +0 -1
- package/dist/agents/AgentRegistry.d.ts +0 -6
- package/dist/agents/AgentRegistry.js +0 -17
- package/dist/agents/AgentRegistry.js.map +0 -1
- package/dist/agents/LaunchResources.d.ts +0 -17
- package/dist/agents/LaunchResources.js +0 -61
- package/dist/agents/LaunchResources.js.map +0 -1
- package/dist/agents/OutfitterSkill.d.ts +0 -11
- package/dist/agents/OutfitterSkill.js +0 -128
- package/dist/agents/OutfitterSkill.js.map +0 -1
- package/dist/agents/ResourceIdentity.d.ts +0 -2
- package/dist/agents/ResourceIdentity.js +0 -51
- package/dist/agents/ResourceIdentity.js.map +0 -1
- package/dist/agents/claude/ClaudeAdapter.d.ts +0 -2
- package/dist/agents/claude/ClaudeAdapter.js +0 -148
- package/dist/agents/claude/ClaudeAdapter.js.map +0 -1
- package/dist/agents/claude/ClaudeCompositeProfileWriter.d.ts +0 -5
- package/dist/agents/claude/ClaudeCompositeProfileWriter.js +0 -7
- package/dist/agents/claude/ClaudeCompositeProfileWriter.js.map +0 -1
- package/dist/agents/pi/PiAdapter.d.ts +0 -2
- package/dist/agents/pi/PiAdapter.js +0 -363
- package/dist/agents/pi/PiAdapter.js.map +0 -1
- package/dist/agents/pi/PiArgs.d.ts +0 -2
- package/dist/agents/pi/PiArgs.js +0 -15
- package/dist/agents/pi/PiArgs.js.map +0 -1
- package/dist/agents/pi/PiCompositeProfileWriter.d.ts +0 -5
- package/dist/agents/pi/PiCompositeProfileWriter.js +0 -7
- package/dist/agents/pi/PiCompositeProfileWriter.js.map +0 -1
- package/dist/agents/pi/PiExtensionCache.d.ts +0 -12
- package/dist/agents/pi/PiExtensionCache.js +0 -195
- package/dist/agents/pi/PiExtensionCache.js.map +0 -1
- package/dist/agents/pi/PiMcpConfig.d.ts +0 -2
- package/dist/agents/pi/PiMcpConfig.js +0 -114
- package/dist/agents/pi/PiMcpConfig.js.map +0 -1
- package/dist/agents/pi/PiSettingsMergePolicy.d.ts +0 -17
- package/dist/agents/pi/PiSettingsMergePolicy.js +0 -59
- package/dist/agents/pi/PiSettingsMergePolicy.js.map +0 -1
- package/dist/agents/pi/PiSkillSources.d.ts +0 -8
- package/dist/agents/pi/PiSkillSources.js +0 -73
- package/dist/agents/pi/PiSkillSources.js.map +0 -1
- package/dist/cli/commands/FirstRunWelcomeProfile.d.ts +0 -11
- package/dist/cli/commands/FirstRunWelcomeProfile.js +0 -110
- package/dist/cli/commands/FirstRunWelcomeProfile.js.map +0 -1
- package/dist/cli/commands/PiLoginLaunch.d.ts +0 -22
- package/dist/cli/commands/PiLoginLaunch.js +0 -170
- package/dist/cli/commands/PiLoginLaunch.js.map +0 -1
- package/dist/cli/commands/RunCommand.d.ts +0 -36
- package/dist/cli/commands/RunCommand.js +0 -345
- package/dist/cli/commands/RunCommand.js.map +0 -1
- package/dist/cli/commands/SyncCommand.d.ts +0 -46
- package/dist/cli/commands/SyncCommand.js +0 -244
- package/dist/cli/commands/SyncCommand.js.map +0 -1
- package/dist/cli/commands/WelcomeCommand.d.ts +0 -56
- package/dist/cli/commands/WelcomeCommand.js +0 -224
- package/dist/cli/commands/WelcomeCommand.js.map +0 -1
- package/dist/cli/commands/assets/outfitter-ascii.txt +0 -5
- package/dist/cli/commands/profile/Command.d.ts +0 -7
- package/dist/cli/commands/profile/Command.js +0 -24
- package/dist/cli/commands/profile/Command.js.map +0 -1
- package/dist/cli/commands/profile/CreateCommand.d.ts +0 -19
- package/dist/cli/commands/profile/CreateCommand.js +0 -115
- package/dist/cli/commands/profile/CreateCommand.js.map +0 -1
- package/dist/cli/commands/profile/LintCommand.d.ts +0 -19
- package/dist/cli/commands/profile/LintCommand.js +0 -155
- package/dist/cli/commands/profile/LintCommand.js.map +0 -1
- package/dist/cli/commands/profile/ListCommand.d.ts +0 -19
- package/dist/cli/commands/profile/ListCommand.js +0 -91
- package/dist/cli/commands/profile/ListCommand.js.map +0 -1
- package/dist/cli/commands/profile/Shared.d.ts +0 -9
- package/dist/cli/commands/profile/Shared.js +0 -10
- package/dist/cli/commands/profile/Shared.js.map +0 -1
- package/dist/cli/commands/run/RunFirstRunOnboarding.d.ts +0 -7
- package/dist/cli/commands/run/RunFirstRunOnboarding.js +0 -52
- package/dist/cli/commands/run/RunFirstRunOnboarding.js.map +0 -1
- package/dist/cli/commands/run/RunLaunchSummary.d.ts +0 -2
- package/dist/cli/commands/run/RunLaunchSummary.js +0 -35
- package/dist/cli/commands/run/RunLaunchSummary.js.map +0 -1
- package/dist/cli/commands/run/RunProfileResolution.d.ts +0 -39
- package/dist/cli/commands/run/RunProfileResolution.js +0 -128
- package/dist/cli/commands/run/RunProfileResolution.js.map +0 -1
- package/dist/cli/commands/run/RunStateWritePrompt.d.ts +0 -2
- package/dist/cli/commands/run/RunStateWritePrompt.js +0 -29
- package/dist/cli/commands/run/RunStateWritePrompt.js.map +0 -1
- package/dist/cli/commands/setup/SetupPrompts.d.ts +0 -14
- package/dist/cli/commands/setup/SetupPrompts.js +0 -296
- package/dist/cli/commands/setup/SetupPrompts.js.map +0 -1
- package/dist/cli/commands/setup/SetupSourceImport.d.ts +0 -5
- package/dist/cli/commands/setup/SetupSourceImport.js +0 -177
- package/dist/cli/commands/setup/SetupSourceImport.js.map +0 -1
- package/dist/cli/commands/setup/SetupSourceLaunch.d.ts +0 -4
- package/dist/cli/commands/setup/SetupSourceLaunch.js +0 -65
- package/dist/cli/commands/setup/SetupSourceLaunch.js.map +0 -1
- package/dist/cli/commands/setup/SetupStarterSource.d.ts +0 -21
- package/dist/cli/commands/setup/SetupStarterSource.js +0 -133
- package/dist/cli/commands/setup/SetupStarterSource.js.map +0 -1
- package/dist/cli/commands/setup/SetupTypes.d.ts +0 -91
- package/dist/cli/commands/setup/SetupTypes.js +0 -26
- package/dist/cli/commands/setup/SetupTypes.js.map +0 -1
- package/dist/compositeProfile/CompositeProfile.d.ts +0 -8
- package/dist/compositeProfile/CompositeProfile.js +0 -6
- package/dist/compositeProfile/CompositeProfile.js.map +0 -1
- package/dist/compositeProfile/CompositeProfileAssembler.d.ts +0 -12
- package/dist/compositeProfile/CompositeProfileAssembler.js +0 -32
- package/dist/compositeProfile/CompositeProfileAssembler.js.map +0 -1
- package/dist/compositeProfile/CompositeProfileCleanup.d.ts +0 -9
- package/dist/compositeProfile/CompositeProfileCleanup.js +0 -87
- package/dist/compositeProfile/CompositeProfileCleanup.js.map +0 -1
- package/dist/compositeProfile/CompositeProfileFile.d.ts +0 -16
- package/dist/compositeProfile/CompositeProfileFile.js +0 -16
- package/dist/compositeProfile/CompositeProfileFile.js.map +0 -1
- package/dist/compositeProfile/CompositeProfileTemplate.d.ts +0 -15
- package/dist/compositeProfile/CompositeProfileTemplate.js +0 -65
- package/dist/compositeProfile/CompositeProfileTemplate.js.map +0 -1
- package/dist/compositeProfile/CompositeProfileWatcher.d.ts +0 -18
- package/dist/compositeProfile/CompositeProfileWatcher.js +0 -46
- package/dist/compositeProfile/CompositeProfileWatcher.js.map +0 -1
- package/dist/compositeProfile/StatePersistence.d.ts +0 -39
- package/dist/compositeProfile/StatePersistence.js +0 -249
- package/dist/compositeProfile/StatePersistence.js.map +0 -1
- package/dist/fs/SafeSymlink.d.ts +0 -13
- package/dist/fs/SafeSymlink.js +0 -50
- package/dist/fs/SafeSymlink.js.map +0 -1
- package/dist/profiles/Profile.d.ts +0 -60
- package/dist/profiles/Profile.js +0 -7
- package/dist/profiles/Profile.js.map +0 -1
- package/dist/profiles/ProfileCache.d.ts +0 -8
- package/dist/profiles/ProfileCache.js.map +0 -1
- package/dist/profiles/ProfileLoader.d.ts +0 -28
- package/dist/profiles/ProfileLoader.js +0 -299
- package/dist/profiles/ProfileLoader.js.map +0 -1
- package/dist/profiles/ProfileMerger.d.ts +0 -19
- package/dist/profiles/ProfileMerger.js +0 -112
- package/dist/profiles/ProfileMerger.js.map +0 -1
- package/dist/profiles/ProfileSource.d.ts +0 -35
- package/dist/profiles/ProfileSource.js +0 -13
- package/dist/profiles/ProfileSource.js.map +0 -1
- package/dist/profiles/PromptIncludes.d.ts +0 -32
- package/dist/profiles/PromptIncludes.js +0 -147
- package/dist/profiles/PromptIncludes.js.map +0 -1
- package/dist/prompts/SystemPromptExport.d.ts +0 -16
- package/dist/prompts/SystemPromptExport.js +0 -81
- package/dist/prompts/SystemPromptExport.js.map +0 -1
- package/dist/schemas/profile-source.schema.json +0 -29
- package/dist/schemas/profile.schema.json +0 -200
- package/dist/skills/ProfileSkillResolution.d.ts +0 -21
- package/dist/skills/ProfileSkillResolution.js +0 -88
- package/dist/skills/ProfileSkillResolution.js.map +0 -1
- package/dist/skills/SkillCatalog.d.ts +0 -41
- package/dist/skills/SkillCatalog.js +0 -119
- package/dist/skills/SkillCatalog.js.map +0 -1
- package/dist/skills/SkillResolution.d.ts +0 -34
- package/dist/skills/SkillResolution.js +0 -369
- package/dist/skills/SkillResolution.js.map +0 -1
- package/docs/documentation/profile-repository.md +0 -179
- package/src/schemas/SchemaDocument.ts +0 -20
- package/src/schemas/profile-source.schema.json +0 -29
- package/src/schemas/profile.schema.json +0 -200
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { Key, matchesKey, truncateToWidth, visibleWidth, wrapTextWithAnsi } from '@earendil-works/pi-tui';
|
|
2
|
+
|
|
3
|
+
// Outfitter runtime extension. Unlike the setup walkthrough extension
|
|
4
|
+
// (outfitter-extension.js), this file is loaded into the real profile pi session. Its only job is
|
|
5
|
+
// to restore Outfitter's original "no provider connected yet" sign-in prompt: when pi starts with
|
|
6
|
+
// no models available, it offers to connect one and delegates to pi's native /login command, which
|
|
7
|
+
// persists credentials in pi's own agent directory and selects a default model in-session.
|
|
8
|
+
//
|
|
9
|
+
// The setup pi stays deliberately model-free and MUST NOT open /login (OFTR-010.1.4); that is why
|
|
10
|
+
// the auto-login lives here instead. This file needs no stamped launch-time values, so the CLI
|
|
11
|
+
// loads it directly by absolute path via --extension.
|
|
12
|
+
|
|
13
|
+
export default function outfitterRuntime(pi) {
|
|
14
|
+
let loginSubmitted = false;
|
|
15
|
+
|
|
16
|
+
const submitSlashCommand = async (ctx, command) => {
|
|
17
|
+
if (ctx.mode !== 'tui') return false;
|
|
18
|
+
ctx.ui.setEditorText(command);
|
|
19
|
+
await ctx.ui.custom(
|
|
20
|
+
(tui, _theme, _keybindings, done) => {
|
|
21
|
+
setTimeout(() => {
|
|
22
|
+
tui.focusedComponent?.handleInput?.('\r');
|
|
23
|
+
done(true);
|
|
24
|
+
}, 25);
|
|
25
|
+
return { render: () => [], invalidate: () => undefined };
|
|
26
|
+
},
|
|
27
|
+
{ overlay: true, overlayOptions: { nonCapturing: true, visible: () => false } },
|
|
28
|
+
);
|
|
29
|
+
return true;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const getAvailableModelCount = async (ctx) => {
|
|
33
|
+
if (ctx.modelRegistry === undefined || typeof ctx.modelRegistry.getAvailable !== 'function') {
|
|
34
|
+
return ctx.model === undefined ? 0 : 1;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const available = await ctx.modelRegistry.getAvailable();
|
|
38
|
+
return Array.isArray(available) ? available.length : 0;
|
|
39
|
+
} catch {
|
|
40
|
+
return ctx.model === undefined ? 0 : 1;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const confirmModelProviderConnection = async (ctx) => {
|
|
45
|
+
if (typeof ctx.ui.custom !== 'function') return true;
|
|
46
|
+
const selected = await selectDescribedOption(
|
|
47
|
+
ctx,
|
|
48
|
+
[
|
|
49
|
+
'Pi does not have a model provider connected yet.',
|
|
50
|
+
'Connect one now so Outfitter can use Pi.',
|
|
51
|
+
'Credentials stay inside Pi.',
|
|
52
|
+
],
|
|
53
|
+
[
|
|
54
|
+
{
|
|
55
|
+
value: 'connect',
|
|
56
|
+
label: 'Connect a model provider',
|
|
57
|
+
description: 'Open Pi /login to sign in via OAuth or an API key.',
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
'connect',
|
|
61
|
+
);
|
|
62
|
+
return selected === 'connect';
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const openLoginIfNoModels = async (ctx) => {
|
|
66
|
+
if (loginSubmitted || ctx.mode !== 'tui') return;
|
|
67
|
+
const availableModelCount = await getAvailableModelCount(ctx);
|
|
68
|
+
if (availableModelCount > 0) return;
|
|
69
|
+
if (!(await confirmModelProviderConnection(ctx))) return;
|
|
70
|
+
loginSubmitted = await submitSlashCommand(ctx, '/login');
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
pi.on('session_start', async (event, ctx) => {
|
|
74
|
+
if (ctx.mode !== 'tui') return;
|
|
75
|
+
if (event.reason === 'startup') await openLoginIfNoModels(ctx);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Renders a described-option picker identical to the setup walkthrough's, so the runtime sign-in
|
|
80
|
+
// prompt matches the rest of the Outfitter UI. Falls back to a plain label list when pi does not
|
|
81
|
+
// support custom UI, then resolves the chosen label back to its item value.
|
|
82
|
+
const selectDescribedOption = (ctx, titleLines, items, initialValue) =>
|
|
83
|
+
ctx.ui.custom((tui, theme, _keybindings, done) => {
|
|
84
|
+
let selectedIndex = Math.max(
|
|
85
|
+
0,
|
|
86
|
+
items.findIndex((item) => item.value === initialValue),
|
|
87
|
+
);
|
|
88
|
+
const labelWidth = Math.max(...items.map((item) => item.label.length));
|
|
89
|
+
let cachedWidth;
|
|
90
|
+
let cachedLines;
|
|
91
|
+
|
|
92
|
+
const finish = (value) => done(value);
|
|
93
|
+
const refresh = () => {
|
|
94
|
+
cachedWidth = undefined;
|
|
95
|
+
cachedLines = undefined;
|
|
96
|
+
tui.requestRender?.();
|
|
97
|
+
};
|
|
98
|
+
const move = (delta) => {
|
|
99
|
+
selectedIndex = Math.max(0, Math.min(items.length - 1, selectedIndex + delta));
|
|
100
|
+
refresh();
|
|
101
|
+
};
|
|
102
|
+
const render = (width) => {
|
|
103
|
+
const maxWidth = typeof width === 'number' && width > 0 ? width : 120;
|
|
104
|
+
if (cachedLines && cachedWidth === maxWidth) return cachedLines;
|
|
105
|
+
const lines = [];
|
|
106
|
+
const add = (line) => lines.push(visibleWidth(line) > maxWidth ? truncateToWidth(line, maxWidth) : line);
|
|
107
|
+
const addWrapped = (line, widthForWrap = maxWidth, prefix = '') => {
|
|
108
|
+
for (const wrappedLine of wrapTextWithAnsi(line, Math.max(1, widthForWrap))) add(prefix + wrappedLine);
|
|
109
|
+
};
|
|
110
|
+
const renderSelectedItem = (prefix, label, description) => {
|
|
111
|
+
const baseLine = prefix + label;
|
|
112
|
+
if (!description) {
|
|
113
|
+
add(baseLine);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const inlineDescriptionWidth = maxWidth - visibleWidth(baseLine) - 2;
|
|
117
|
+
const descriptionText = theme.fg('muted', description);
|
|
118
|
+
if (inlineDescriptionWidth >= 30) {
|
|
119
|
+
const [firstLine = '', ...remainingLines] = wrapTextWithAnsi(descriptionText, inlineDescriptionWidth);
|
|
120
|
+
add(baseLine + ' ' + firstLine);
|
|
121
|
+
const continuationPrefix = ' '.repeat(Math.min(maxWidth, visibleWidth(baseLine) + 2));
|
|
122
|
+
for (const line of remainingLines) add(continuationPrefix + line);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
add(baseLine);
|
|
126
|
+
addWrapped(descriptionText, maxWidth - 2, ' ');
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
add(theme.fg('accent', '─'.repeat(maxWidth)));
|
|
130
|
+
titleLines.forEach((line, index) =>
|
|
131
|
+
addWrapped(index === 0 ? theme.fg('text', ' ' + line) : theme.fg('dim', ' ' + line)),
|
|
132
|
+
);
|
|
133
|
+
lines.push('');
|
|
134
|
+
items.forEach((item, index) => {
|
|
135
|
+
const selected = index === selectedIndex;
|
|
136
|
+
const prefix = selected ? theme.fg('accent', '→ ') : ' ';
|
|
137
|
+
const paddedLabel = item.label.padEnd(labelWidth);
|
|
138
|
+
const label = selected ? theme.fg('accent', paddedLabel) : paddedLabel;
|
|
139
|
+
renderSelectedItem(prefix, label, selected ? item.description : undefined);
|
|
140
|
+
});
|
|
141
|
+
lines.push('');
|
|
142
|
+
add(theme.fg('dim', '↑↓ navigate enter select escape/ctrl+c cancel'));
|
|
143
|
+
add(theme.fg('accent', '─'.repeat(maxWidth)));
|
|
144
|
+
cachedWidth = maxWidth;
|
|
145
|
+
cachedLines = lines;
|
|
146
|
+
return lines;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
outfitterOptions: items.map((item) => item.label),
|
|
151
|
+
render,
|
|
152
|
+
invalidate: refresh,
|
|
153
|
+
handleInput: (data) => {
|
|
154
|
+
if (matchesKey(data, Key.up)) move(-1);
|
|
155
|
+
else if (matchesKey(data, Key.down)) move(1);
|
|
156
|
+
else if (matchesKey(data, Key.enter)) finish(items[selectedIndex]?.value);
|
|
157
|
+
else if (matchesKey(data, Key.escape) || matchesKey(data, Key.ctrl('c'))) finish(undefined);
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
});
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import type { AgentLaunchPlan } from '
|
|
1
|
+
import type { AgentLaunchPlan } from '../projection/Projection.js';
|
|
2
2
|
export interface AgentProcessLauncher {
|
|
3
3
|
launch(plan: AgentLaunchPlan): Promise<number>;
|
|
4
4
|
}
|
|
5
5
|
export declare const launchAgentProcess: (launcher: AgentProcessLauncher, launchPlan: AgentLaunchPlan, agentId: string) => Promise<number>;
|
|
6
6
|
export declare const resolveAgentLaunchExecutable: (launchPlan: AgentLaunchPlan) => AgentLaunchPlan;
|
|
7
|
+
export declare const spawnLauncher: AgentProcessLauncher;
|
|
8
|
+
/**
|
|
9
|
+
* Launches a resolved plan through the given spawn boundary. The install-hint agentId is derived
|
|
10
|
+
* from the logical launch command ('pi' | 'claude') so a missing-CLI failure always names the
|
|
11
|
+
* harness actually being launched, regardless of how the harness was selected (flag, settings
|
|
12
|
+
* default, or built-in fallback).
|
|
13
|
+
*/
|
|
14
|
+
export declare const launchThroughSpawn: (spawn: AgentProcessLauncher, plan: AgentLaunchPlan) => Promise<number>;
|
|
@@ -39,6 +39,25 @@ export const resolveAgentLaunchExecutable = (launchPlan) => {
|
|
|
39
39
|
env: { PI_SKIP_VERSION_CHECK: '1', ...launchPlan.env },
|
|
40
40
|
};
|
|
41
41
|
};
|
|
42
|
+
/* v8 ignore start -- real process spawn is covered by end-to-end smoke usage, not unit tests. */
|
|
43
|
+
export const spawnLauncher = {
|
|
44
|
+
async launch(plan) {
|
|
45
|
+
const { default: spawn } = await import('cross-spawn');
|
|
46
|
+
return await new Promise((resolve, reject) => {
|
|
47
|
+
const child = spawn(plan.command, [...plan.args], { stdio: 'inherit', env: { ...process.env, ...plan.env } });
|
|
48
|
+
child.on('error', reject); // ENOENT surfaces as an actionable install message
|
|
49
|
+
child.on('close', (code, signal) => resolve(code ?? (signal ? 1 : 0)));
|
|
50
|
+
});
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
/* v8 ignore stop */
|
|
54
|
+
/**
|
|
55
|
+
* Launches a resolved plan through the given spawn boundary. The install-hint agentId is derived
|
|
56
|
+
* from the logical launch command ('pi' | 'claude') so a missing-CLI failure always names the
|
|
57
|
+
* harness actually being launched, regardless of how the harness was selected (flag, settings
|
|
58
|
+
* default, or built-in fallback).
|
|
59
|
+
*/
|
|
60
|
+
export const launchThroughSpawn = (spawn, plan) => launchAgentProcess(spawn, resolveAgentLaunchExecutable(plan), plan.command);
|
|
42
61
|
const isCommandNotFoundError = (error) => error !== null && typeof error === 'object' && 'code' in error && error.code === 'ENOENT';
|
|
43
62
|
const agentCliInstallHints = {
|
|
44
63
|
pi: 'Install Pi with `npm install -g @earendil-works/pi-coding-agent` (see https://pi.dev).',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentLaunch.js","sourceRoot":"","sources":["../../src/agents/AgentLaunch.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AgentLaunch.js","sourceRoot":"","sources":["../../src/agents/AgentLaunch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** pi's persistent agent directory (`~/.pi/agent`), the durable home for credentials. */
|
|
2
|
+
export declare const resolvePiUserAgentDirectory: (homeDirectory: string) => string;
|
|
3
|
+
/** Seeds the projection root with the user's existing pi credentials so pi sees them at startup. */
|
|
4
|
+
export declare const seedPiCredentials: (projectionRoot: string, piUserAgentDirectory: string) => void;
|
|
5
|
+
/** Copies credentials created or changed during the pi session back to the durable agent dir. */
|
|
6
|
+
export declare const persistPiCredentials: (projectionRoot: string, piUserAgentDirectory: string) => void;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Persists pi credential/provider state across runs. Outfitter launches pi with PI_CODING_AGENT_DIR
|
|
2
|
+
// pointed at an ephemeral, profile-scoped projection root (OFTR-006.3.1/006.4), which pi also uses
|
|
3
|
+
// as the home for auth.json/models.json (pi-coding-agent config.js: getAgentDir()). Left alone, a
|
|
4
|
+
// /login inside that session would be discarded when the projection root is deleted after the run,
|
|
5
|
+
// so the auto sign-in prompt could never converge. To keep provider credentials durable — matching
|
|
6
|
+
// standalone pi and pre-#165 Outfitter — we seed the projection root from pi's persistent agent dir
|
|
7
|
+
// before launch and copy any changes back afterward.
|
|
8
|
+
import { copyFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
// Files that carry pi credentials and provider/model definitions. Both live in getAgentDir() and
|
|
11
|
+
// must survive across the ephemeral projection root.
|
|
12
|
+
const persistentPiStateFiles = ['auth.json', 'models.json'];
|
|
13
|
+
/** pi's persistent agent directory (`~/.pi/agent`), the durable home for credentials. */
|
|
14
|
+
export const resolvePiUserAgentDirectory = (homeDirectory) => join(homeDirectory, '.pi', 'agent');
|
|
15
|
+
const copyIfPresent = (sourcePath, destinationPath) => {
|
|
16
|
+
if (!existsSync(sourcePath))
|
|
17
|
+
return;
|
|
18
|
+
mkdirSync(join(destinationPath, '..'), { recursive: true });
|
|
19
|
+
copyFileSync(sourcePath, destinationPath);
|
|
20
|
+
};
|
|
21
|
+
/** Seeds the projection root with the user's existing pi credentials so pi sees them at startup. */
|
|
22
|
+
export const seedPiCredentials = (projectionRoot, piUserAgentDirectory) => {
|
|
23
|
+
for (const file of persistentPiStateFiles) {
|
|
24
|
+
copyIfPresent(join(piUserAgentDirectory, file), join(projectionRoot, file));
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
/** Copies credentials created or changed during the pi session back to the durable agent dir. */
|
|
28
|
+
export const persistPiCredentials = (projectionRoot, piUserAgentDirectory) => {
|
|
29
|
+
for (const file of persistentPiStateFiles) {
|
|
30
|
+
copyIfPresent(join(projectionRoot, file), join(piUserAgentDirectory, file));
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=PiCredentialPersistence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PiCredentialPersistence.js","sourceRoot":"","sources":["../../src/agents/PiCredentialPersistence.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,mGAAmG;AACnG,kGAAkG;AAClG,mGAAmG;AACnG,mGAAmG;AACnG,oGAAoG;AACpG,qDAAqD;AACrD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,iGAAiG;AACjG,qDAAqD;AACrD,MAAM,sBAAsB,GAAG,CAAC,WAAW,EAAE,aAAa,CAAU,CAAC;AAErE,yFAAyF;AACzF,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,aAAqB,EAAU,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAElH,MAAM,aAAa,GAAG,CAAC,UAAkB,EAAE,eAAuB,EAAQ,EAAE;IAC1E,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO;IACpC,SAAS,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,YAAY,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;AAC5C,CAAC,CAAC;AAEF,oGAAoG;AACpG,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,cAAsB,EAAE,oBAA4B,EAAQ,EAAE;IAC9F,KAAK,MAAM,IAAI,IAAI,sBAAsB,EAAE,CAAC;QAC1C,aAAa,CAAC,IAAI,CAAC,oBAAoB,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC,CAAC;AAEF,iGAAiG;AACjG,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,cAAsB,EAAE,oBAA4B,EAAQ,EAAE;IACjG,KAAK,MAAM,IAAI,IAAI,sBAAsB,EAAE,CAAC;QAC1C,aAAa,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC,CAAC"}
|
package/dist/cli/OutfitterCli.js
CHANGED
|
@@ -1,31 +1,23 @@
|
|
|
1
1
|
// Assembles the top-level Outfitter Commander program from command objects.
|
|
2
2
|
import { readFileSync } from 'node:fs';
|
|
3
3
|
import { Command } from 'commander';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { createDumpCommand } from './commands/DumpCommand.js';
|
|
5
|
+
import { createListCommand } from './commands/ListCommand.js';
|
|
6
|
+
import { createRunAgentCommand } from './commands/RunAgentCommand.js';
|
|
6
7
|
import { createSetupCommand } from './commands/SetupCommand.js';
|
|
7
|
-
import {
|
|
8
|
-
import { createWelcomeCommand } from './commands/WelcomeCommand.js';
|
|
8
|
+
import { createValidateCommand } from './commands/ValidateCommand.js';
|
|
9
9
|
export const createDefaultCommands = () => [
|
|
10
|
-
|
|
11
|
-
createSetupCommand(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
...input,
|
|
16
|
-
profileId: input.profileId,
|
|
17
|
-
});
|
|
18
|
-
},
|
|
19
|
-
}),
|
|
20
|
-
createSyncCommand(),
|
|
21
|
-
createWelcomeCommand(),
|
|
22
|
-
...createProfileCommands(),
|
|
10
|
+
createRunAgentCommand(),
|
|
11
|
+
createSetupCommand(),
|
|
12
|
+
createListCommand(),
|
|
13
|
+
createValidateCommand(),
|
|
14
|
+
createDumpCommand(),
|
|
23
15
|
];
|
|
24
16
|
export const createOutfitterProgram = (commands = createDefaultCommands()) => {
|
|
25
17
|
const program = new Command();
|
|
26
18
|
program
|
|
27
19
|
.name('outfitter')
|
|
28
|
-
.description('
|
|
20
|
+
.description('Resolve, compose, and launch .agents agents in pi, Claude Code, and future harnesses.')
|
|
29
21
|
.version(readPackageVersion());
|
|
30
22
|
for (const command of commands) {
|
|
31
23
|
command.register(program);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OutfitterCli.js","sourceRoot":"","sources":["../../src/cli/OutfitterCli.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"OutfitterCli.js","sourceRoot":"","sources":["../../src/cli/OutfitterCli.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAoB,EAAE,CAAC;IAC1D,qBAAqB,EAAE;IACvB,kBAAkB,EAAE;IACpB,iBAAiB,EAAE;IACnB,qBAAqB,EAAE;IACvB,iBAAiB,EAAE;CACpB,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,WAAqC,qBAAqB,EAAE,EAAW,EAAE;IAC9G,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,WAAW,CAAC;SACjB,WAAW,CAAC,uFAAuF,CAAC;SACpG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAEjC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,GAAW,EAAE;IACtC,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAwB,CAAC;IAE7F,OAAO,WAAW,CAAC,OAAO,CAAC;AAC7B,CAAC,CAAC"}
|
|
@@ -4,8 +4,3 @@ export interface CommandObject {
|
|
|
4
4
|
readonly description: string;
|
|
5
5
|
register(program: Command): void;
|
|
6
6
|
}
|
|
7
|
-
export interface CommandDescriptor {
|
|
8
|
-
readonly name: string;
|
|
9
|
-
readonly description: string;
|
|
10
|
-
}
|
|
11
|
-
export declare const describeCommandObject: (command: CommandObject) => CommandDescriptor;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommandObject.js","sourceRoot":"","sources":["../../../src/cli/commands/CommandObject.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CommandObject.js","sourceRoot":"","sources":["../../../src/cli/commands/CommandObject.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CommandObject } from './CommandObject.js';
|
|
2
|
+
export interface DumpInput {
|
|
3
|
+
readonly homeDirectory: string;
|
|
4
|
+
readonly projectDirectory: string;
|
|
5
|
+
readonly agent?: string;
|
|
6
|
+
readonly out: string;
|
|
7
|
+
}
|
|
8
|
+
export interface DumpCommandResult {
|
|
9
|
+
readonly writtenPaths: readonly string[];
|
|
10
|
+
readonly messages: readonly string[];
|
|
11
|
+
readonly ok: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface DumpCommandDependencies {
|
|
14
|
+
readonly homeDirectory?: string;
|
|
15
|
+
readonly projectDirectory?: string;
|
|
16
|
+
readonly writeLine?: (message: string) => void;
|
|
17
|
+
}
|
|
18
|
+
export declare const executeDumpCommand: (input: DumpInput) => DumpCommandResult;
|
|
19
|
+
export declare const createDumpCommand: (dependencies?: DumpCommandDependencies) => CommandObject;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Provides `outfitter dump --agent <id> --out <dir>` over the effective resource set.
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { dumpAgent } from '../../dump/Dump.js';
|
|
4
|
+
import { resolveEffectiveSet } from '../../resolver/ResolverContext.js';
|
|
5
|
+
import { resolveHomeDirectory, resolveProjectDirectory } from './ProcessDefaults.js';
|
|
6
|
+
const resolveAgentSlug = (settings, requested) => {
|
|
7
|
+
if (requested !== undefined) {
|
|
8
|
+
return requested;
|
|
9
|
+
}
|
|
10
|
+
if (settings.defaultAgent === undefined) {
|
|
11
|
+
throw new Error("No agent selected and no 'default_agent' in settings. Pass --agent <id>.");
|
|
12
|
+
}
|
|
13
|
+
return settings.defaultAgent;
|
|
14
|
+
};
|
|
15
|
+
export const executeDumpCommand = (input) => {
|
|
16
|
+
const { set, settings, settingsIssues } = resolveEffectiveSet(input);
|
|
17
|
+
if (settingsIssues.length > 0) {
|
|
18
|
+
throw new Error(`Cannot dump with invalid settings: ${settingsIssues.map((issue) => issue.message).join('; ')}`);
|
|
19
|
+
}
|
|
20
|
+
const agentSlug = resolveAgentSlug(settings, input.agent);
|
|
21
|
+
const result = dumpAgent(set, agentSlug, input.out);
|
|
22
|
+
const ok = result.errors.length === 0;
|
|
23
|
+
const messages = ok
|
|
24
|
+
? [`Dumped '${agentSlug}' to ${input.out} (${result.writtenPaths.length} files).`, ...result.warnings]
|
|
25
|
+
: [...result.errors, ...result.warnings];
|
|
26
|
+
return { writtenPaths: result.writtenPaths, messages, ok };
|
|
27
|
+
};
|
|
28
|
+
export const createDumpCommand = (dependencies = {}) => ({
|
|
29
|
+
name: 'dump',
|
|
30
|
+
description: 'Write the composed .agents tree for an agent to a directory.',
|
|
31
|
+
register(program) {
|
|
32
|
+
program.addCommand(new Command('dump')
|
|
33
|
+
.description('Write the composed .agents tree for an agent to a directory.')
|
|
34
|
+
.option('--agent <id>', 'Agent slug to dump (default: settings default_agent).')
|
|
35
|
+
.option('--out <dir>', 'Output directory.', './outfitter-dump')
|
|
36
|
+
.action((options) => {
|
|
37
|
+
const result = executeDumpCommand({
|
|
38
|
+
/* v8 ignore next 2 -- process defaults are exercised by the CLI entrypoint, not unit tests. */
|
|
39
|
+
homeDirectory: resolveHomeDirectory(dependencies.homeDirectory),
|
|
40
|
+
projectDirectory: resolveProjectDirectory(dependencies.projectDirectory),
|
|
41
|
+
agent: options.agent,
|
|
42
|
+
out: options.out,
|
|
43
|
+
});
|
|
44
|
+
for (const message of result.messages) {
|
|
45
|
+
/* v8 ignore next -- console fallback is direct CLI behavior; tests inject a writer. */
|
|
46
|
+
(dependencies.writeLine ?? console.log)(message);
|
|
47
|
+
}
|
|
48
|
+
if (!result.ok) {
|
|
49
|
+
process.exitCode = 1;
|
|
50
|
+
}
|
|
51
|
+
}));
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
//# sourceMappingURL=DumpCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DumpCommand.js","sourceRoot":"","sources":["../../../src/cli/commands/DumpCommand.ts"],"names":[],"mappings":"AAAA,sFAAsF;AAEtF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAGxE,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAqBrF,MAAM,gBAAgB,GAAG,CAAC,QAAkB,EAAE,SAA6B,EAAU,EAAE;IACrF,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,QAAQ,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAC;IAC9F,CAAC;IAED,OAAO,QAAQ,CAAC,YAAY,CAAC;AAC/B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAgB,EAAqB,EAAE;IACxE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAErE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,sCAAsC,cAAc,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnH,CAAC;IAED,MAAM,SAAS,GAAG,gBAAgB,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACpD,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,EAAE;QACjB,CAAC,CAAC,CAAC,WAAW,SAAS,QAAQ,KAAK,CAAC,GAAG,KAAK,MAAM,CAAC,YAAY,CAAC,MAAM,UAAU,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC;QACtG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAE3C,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AAC7D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,eAAwC,EAAE,EAAiB,EAAE,CAAC,CAAC;IAC/F,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,8DAA8D;IAC3E,QAAQ,CAAC,OAAgB;QACvB,OAAO,CAAC,UAAU,CAChB,IAAI,OAAO,CAAC,MAAM,CAAC;aAChB,WAAW,CAAC,8DAA8D,CAAC;aAC3E,MAAM,CAAC,cAAc,EAAE,uDAAuD,CAAC;aAC/E,MAAM,CAAC,aAAa,EAAE,mBAAmB,EAAE,kBAAkB,CAAC;aAC9D,MAAM,CAAC,CAAC,OAAwC,EAAE,EAAE;YACnD,MAAM,MAAM,GAAG,kBAAkB,CAAC;gBAChC,+FAA+F;gBAC/F,aAAa,EAAE,oBAAoB,CAAC,YAAY,CAAC,aAAa,CAAC;gBAC/D,gBAAgB,EAAE,uBAAuB,CAAC,YAAY,CAAC,gBAAgB,CAAC;gBACxE,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,GAAG,EAAE,OAAO,CAAC,GAAG;aACjB,CAAC,CAAC;YAEH,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACtC,uFAAuF;gBACvF,CAAC,YAAY,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;YACnD,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;gBACf,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACvB,CAAC;QACH,CAAC,CAAC,CACL,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CommandObject } from './CommandObject.js';
|
|
2
|
+
export interface ListInput {
|
|
3
|
+
readonly homeDirectory: string;
|
|
4
|
+
readonly projectDirectory: string;
|
|
5
|
+
readonly kind?: string;
|
|
6
|
+
readonly agent?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ListResult {
|
|
9
|
+
readonly messages: readonly string[];
|
|
10
|
+
}
|
|
11
|
+
export interface ListCommandDependencies {
|
|
12
|
+
readonly homeDirectory?: string;
|
|
13
|
+
readonly projectDirectory?: string;
|
|
14
|
+
readonly writeLine?: (message: string) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare const executeListCommand: (input: ListInput) => ListResult;
|
|
17
|
+
export declare const createListCommand: (dependencies?: ListCommandDependencies) => CommandObject;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Provides `outfitter list [kind]` over the effective resource set.
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { agentLocalKinds, compareSlugs, findResource, listAgentResources, listResources, resourceKinds, } from '../../resolver/Resource.js';
|
|
4
|
+
import { resolveEffectiveSet } from '../../resolver/ResolverContext.js';
|
|
5
|
+
import { resolveHomeDirectory, resolveProjectDirectory } from './ProcessDefaults.js';
|
|
6
|
+
const kindByPlural = new Map([
|
|
7
|
+
['agents', 'agent'],
|
|
8
|
+
['skills', 'skill'],
|
|
9
|
+
['knowledge', 'knowledge'],
|
|
10
|
+
['commands', 'command'],
|
|
11
|
+
]);
|
|
12
|
+
const pluralByKind = new Map([
|
|
13
|
+
['agent', 'agents'],
|
|
14
|
+
['skill', 'skills'],
|
|
15
|
+
['knowledge', 'knowledge'],
|
|
16
|
+
['command', 'commands'],
|
|
17
|
+
]);
|
|
18
|
+
const resolveKindFilter = (kind) => {
|
|
19
|
+
if (kind === undefined) {
|
|
20
|
+
return resourceKinds;
|
|
21
|
+
}
|
|
22
|
+
const resolved = kindByPlural.get(kind);
|
|
23
|
+
if (resolved === undefined) {
|
|
24
|
+
throw new Error(`Unknown resource kind '${kind}'. Expected one of: ${[...kindByPlural.keys()].join(', ')}.`);
|
|
25
|
+
}
|
|
26
|
+
return [resolved];
|
|
27
|
+
};
|
|
28
|
+
export const executeListCommand = (input) => {
|
|
29
|
+
const { set, settingsIssues } = resolveEffectiveSet(input);
|
|
30
|
+
if (settingsIssues.length > 0) {
|
|
31
|
+
const detail = settingsIssues.map((issue) => `${issue.filePath}#${issue.path} ${issue.message}`).join('; ');
|
|
32
|
+
throw new Error(`Cannot list resources with invalid settings: ${detail}`);
|
|
33
|
+
}
|
|
34
|
+
const messages = [];
|
|
35
|
+
if (input.agent !== undefined && findResource(set, 'agent', input.agent) === undefined) {
|
|
36
|
+
throw new Error(`Unknown agent '${input.agent}'. Run 'outfitter list agents' to see resolvable agents.`);
|
|
37
|
+
}
|
|
38
|
+
for (const kind of resolveKindFilter(input.kind)) {
|
|
39
|
+
const hasAgentContext = input.agent !== undefined && agentLocalKinds.includes(kind);
|
|
40
|
+
const globalResources = listResources(set, kind);
|
|
41
|
+
const localResources = hasAgentContext ? listAgentResources(set, input.agent, kind) : [];
|
|
42
|
+
const resources = new Map(globalResources.map((resource) => [resource.slug, resource]));
|
|
43
|
+
for (const resource of localResources)
|
|
44
|
+
resources.set(resource.slug, resource);
|
|
45
|
+
messages.push(`${pluralByKind.get(kind)}${hasAgentContext ? ` (agent ${input.agent})` : ''}:`);
|
|
46
|
+
messages.push(...(resources.size === 0
|
|
47
|
+
? [' (none)']
|
|
48
|
+
: [...resources.values()]
|
|
49
|
+
.sort((left, right) => compareSlugs(left.slug, right.slug))
|
|
50
|
+
.map((resource) => ` ${resource.slug} [${resource.winner.layer.label}${resource.winner.ownerAgent === undefined ? '' : '; agent-local'}]`)));
|
|
51
|
+
}
|
|
52
|
+
return { messages };
|
|
53
|
+
};
|
|
54
|
+
export const createListCommand = (dependencies = {}) => ({
|
|
55
|
+
name: 'list',
|
|
56
|
+
description: 'List resolvable resources (agents, skills, knowledge, commands).',
|
|
57
|
+
register(program) {
|
|
58
|
+
program.addCommand(new Command('list')
|
|
59
|
+
.description('List resolvable resources (agents, skills, knowledge, commands).')
|
|
60
|
+
.argument('[kind]', 'Restrict to one kind: agents, skills, knowledge, or commands.')
|
|
61
|
+
.option('--agent <id>', 'Resolve resources in an agent context, including its agent-local skills/knowledge/commands.')
|
|
62
|
+
.action((kind, options) => {
|
|
63
|
+
const result = executeListCommand({
|
|
64
|
+
/* v8 ignore next 2 -- process defaults are exercised by the CLI entrypoint, not unit tests. */
|
|
65
|
+
homeDirectory: resolveHomeDirectory(dependencies.homeDirectory),
|
|
66
|
+
projectDirectory: resolveProjectDirectory(dependencies.projectDirectory),
|
|
67
|
+
kind,
|
|
68
|
+
agent: options.agent,
|
|
69
|
+
});
|
|
70
|
+
for (const message of result.messages) {
|
|
71
|
+
/* v8 ignore next -- console fallback is direct CLI behavior; tests inject a writer. */
|
|
72
|
+
(dependencies.writeLine ?? console.log)(message);
|
|
73
|
+
}
|
|
74
|
+
}));
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=ListCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ListCommand.js","sourceRoot":"","sources":["../../../src/cli/commands/ListCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AgentLaunchPlan } from '../../projection/Projection.js';
|
|
2
|
+
export declare const isNonInteractivePiLaunch: (args: readonly string[]) => boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Prepends `--extension <runtime>` to a pi launch so the auto sign-in prompt loads. The extension is
|
|
5
|
+
* a no-op whenever a model is already available, so it is safe to attach to every interactive pi
|
|
6
|
+
* run. Non-pi and non-interactive launches are returned unchanged.
|
|
7
|
+
*/
|
|
8
|
+
export declare const attachPiRuntimeExtension: (plan: AgentLaunchPlan) => AgentLaunchPlan;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Attaches the Outfitter runtime pi extension to interactive profile launches. The extension
|
|
2
|
+
// restores Outfitter's original "connect a model provider" sign-in prompt: when pi starts with no
|
|
3
|
+
// models available it offers to connect one and opens pi's native /login. Non-interactive pi
|
|
4
|
+
// launches (--print, --export, --mode json|print|rpc, …) are left untouched so scripted runs never
|
|
5
|
+
// prompt, and non-pi harnesses pass through unchanged.
|
|
6
|
+
import { existsSync } from 'node:fs';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
const nonInteractivePiLaunchFlags = new Set(['--print', '-p', '--export', '--list-models']);
|
|
9
|
+
const nonInteractivePiModes = new Set(['json', 'print', 'rpc']);
|
|
10
|
+
const runtimeExtensionAsset = 'pi-extension/src/outfitter-runtime-extension.js';
|
|
11
|
+
export const isNonInteractivePiLaunch = (args) => args.some((arg, index) => {
|
|
12
|
+
if (nonInteractivePiLaunchFlags.has(arg))
|
|
13
|
+
return true;
|
|
14
|
+
if (arg === '--mode')
|
|
15
|
+
return nonInteractivePiModes.has(args[index + 1] ?? '');
|
|
16
|
+
if (arg.startsWith('--mode='))
|
|
17
|
+
return nonInteractivePiModes.has(arg.slice('--mode='.length));
|
|
18
|
+
return false;
|
|
19
|
+
});
|
|
20
|
+
// Resolves the runtime extension in either the repository layout (code/<asset>) or the packaged npm
|
|
21
|
+
// layout (code/cli/code/<asset>), mirroring SetupCommand's asset resolver.
|
|
22
|
+
const resolveRuntimeExtensionPath = () => {
|
|
23
|
+
const sourcePath = fileURLToPath(new URL(`../../../../${runtimeExtensionAsset}`, import.meta.url));
|
|
24
|
+
const packagePath = fileURLToPath(new URL(`../../../code/${runtimeExtensionAsset}`, import.meta.url));
|
|
25
|
+
/* v8 ignore else -- packaged layout is exercised by the npm package smoke test. */
|
|
26
|
+
if (existsSync(sourcePath))
|
|
27
|
+
return sourcePath;
|
|
28
|
+
/* v8 ignore next 2 -- packaged layout is covered by the package smoke test. */
|
|
29
|
+
if (existsSync(packagePath))
|
|
30
|
+
return packagePath;
|
|
31
|
+
return undefined;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Prepends `--extension <runtime>` to a pi launch so the auto sign-in prompt loads. The extension is
|
|
35
|
+
* a no-op whenever a model is already available, so it is safe to attach to every interactive pi
|
|
36
|
+
* run. Non-pi and non-interactive launches are returned unchanged.
|
|
37
|
+
*/
|
|
38
|
+
export const attachPiRuntimeExtension = (plan) => {
|
|
39
|
+
if (plan.command !== 'pi' || isNonInteractivePiLaunch(plan.args))
|
|
40
|
+
return plan;
|
|
41
|
+
const extensionPath = resolveRuntimeExtensionPath();
|
|
42
|
+
/* v8 ignore next -- defensive: the runtime extension ships with the package, so it resolves in practice. */
|
|
43
|
+
if (extensionPath === undefined)
|
|
44
|
+
return plan;
|
|
45
|
+
return { ...plan, args: ['--extension', extensionPath, ...plan.args] };
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=PiRuntimeLaunch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PiRuntimeLaunch.js","sourceRoot":"","sources":["../../../src/cli/commands/PiRuntimeLaunch.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,kGAAkG;AAClG,6FAA6F;AAC7F,mGAAmG;AACnG,uDAAuD;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAIzC,MAAM,2BAA2B,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC;AAC5F,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;AAEhE,MAAM,qBAAqB,GAAG,iDAAiD,CAAC;AAEhF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,IAAuB,EAAW,EAAE,CAC3E,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;IACvB,IAAI,2BAA2B,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACtD,IAAI,GAAG,KAAK,QAAQ;QAAE,OAAO,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9E,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7F,OAAO,KAAK,CAAC;AACf,CAAC,CAAC,CAAC;AAEL,oGAAoG;AACpG,2EAA2E;AAC3E,MAAM,2BAA2B,GAAG,GAAuB,EAAE;IAC3D,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,eAAe,qBAAqB,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACnG,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,iBAAiB,qBAAqB,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACtG,mFAAmF;IACnF,IAAI,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IAC9C,+EAA+E;IAC/E,IAAI,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,WAAW,CAAC;IAChD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,IAAqB,EAAmB,EAAE;IACjF,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAE9E,MAAM,aAAa,GAAG,2BAA2B,EAAE,CAAC;IACpD,4GAA4G;IAC5G,IAAI,aAAa,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAE7C,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC,aAAa,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AACzE,CAAC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Resolves process-derived command defaults (home/project directories) in one tested place.
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
export const resolveHomeDirectory = (provided) => provided ?? homedir();
|
|
4
|
+
export const resolveProjectDirectory = (provided) => provided ?? process.cwd();
|
|
5
|
+
//# sourceMappingURL=ProcessDefaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProcessDefaults.js","sourceRoot":"","sources":["../../../src/cli/commands/ProcessDefaults.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,QAAiB,EAAU,EAAE,CAAC,QAAQ,IAAI,OAAO,EAAE,CAAC;AAEzF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,QAAiB,EAAU,EAAE,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC"}
|