@caupulican/pi-adaptative 0.81.26 → 0.81.27
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/CHANGELOG.md +31 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +3 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +4 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +19 -2
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +21 -10
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +71 -33
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
- package/dist/core/autonomy/bounded-completion.js +59 -19
- package/dist/core/autonomy/bounded-completion.js.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.d.ts +31 -0
- package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -0
- package/dist/core/autonomy/lane-tool-surface.js +96 -0
- package/dist/core/autonomy/lane-tool-surface.js.map +1 -0
- package/dist/core/background-lane-controller.d.ts +6 -3
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +134 -25
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/billing-failover-controller.d.ts.map +1 -1
- package/dist/core/billing-failover-controller.js +1 -1
- package/dist/core/billing-failover-controller.js.map +1 -1
- package/dist/core/context/current-work-memory.d.ts +9 -0
- package/dist/core/context/current-work-memory.d.ts.map +1 -0
- package/dist/core/context/current-work-memory.js +61 -0
- package/dist/core/context/current-work-memory.js.map +1 -0
- package/dist/core/context/file-store-memory-provider.d.ts +9 -0
- package/dist/core/context/file-store-memory-provider.d.ts.map +1 -0
- package/dist/core/context/file-store-memory-provider.js +106 -0
- package/dist/core/context/file-store-memory-provider.js.map +1 -0
- package/dist/core/context/long-term-memory-trigger.d.ts +15 -0
- package/dist/core/context/long-term-memory-trigger.d.ts.map +1 -0
- package/dist/core/context/long-term-memory-trigger.js +39 -0
- package/dist/core/context/long-term-memory-trigger.js.map +1 -0
- package/dist/core/context/memory-prompt-block.d.ts +3 -1
- package/dist/core/context/memory-prompt-block.d.ts.map +1 -1
- package/dist/core/context/memory-prompt-block.js +20 -3
- package/dist/core/context/memory-prompt-block.js.map +1 -1
- package/dist/core/context/memory-prompt-budget.d.ts +17 -0
- package/dist/core/context/memory-prompt-budget.d.ts.map +1 -0
- package/dist/core/context/memory-prompt-budget.js +64 -0
- package/dist/core/context/memory-prompt-budget.js.map +1 -0
- package/dist/core/context/memory-provider-contract.d.ts.map +1 -1
- package/dist/core/context/memory-provider-contract.js +2 -5
- package/dist/core/context/memory-provider-contract.js.map +1 -1
- package/dist/core/context/memory-tier-composer.d.ts +27 -0
- package/dist/core/context/memory-tier-composer.d.ts.map +1 -0
- package/dist/core/context/memory-tier-composer.js +79 -0
- package/dist/core/context/memory-tier-composer.js.map +1 -0
- package/dist/core/context-gc.d.ts.map +1 -1
- package/dist/core/context-gc.js +1 -0
- package/dist/core/context-gc.js.map +1 -1
- package/dist/core/cost/cost-summary.d.ts +3 -1
- package/dist/core/cost/cost-summary.d.ts.map +1 -1
- package/dist/core/cost/cost-summary.js +3 -3
- package/dist/core/cost/cost-summary.js.map +1 -1
- package/dist/core/cost-guard.d.ts +17 -7
- package/dist/core/cost-guard.d.ts.map +1 -1
- package/dist/core/cost-guard.js +33 -10
- package/dist/core/cost-guard.js.map +1 -1
- package/dist/core/default-tool-surface.d.ts +9 -0
- package/dist/core/default-tool-surface.d.ts.map +1 -0
- package/dist/core/default-tool-surface.js +18 -0
- package/dist/core/default-tool-surface.js.map +1 -0
- package/dist/core/delegation/worker-runner.d.ts +11 -5
- package/dist/core/delegation/worker-runner.d.ts.map +1 -1
- package/dist/core/delegation/worker-runner.js +24 -12
- package/dist/core/delegation/worker-runner.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +15 -0
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +2 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +7 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +9 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/failure-corpus.d.ts.map +1 -1
- package/dist/core/failure-corpus.js +2 -4
- package/dist/core/failure-corpus.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +9 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
- package/dist/core/goals/goal-continuation-prompt.js +4 -3
- package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts +12 -0
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +42 -4
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/memory/memory-manager.d.ts +8 -3
- package/dist/core/memory/memory-manager.d.ts.map +1 -1
- package/dist/core/memory/memory-manager.js +27 -11
- package/dist/core/memory/memory-manager.js.map +1 -1
- package/dist/core/memory/memory-provider.d.ts +5 -1
- package/dist/core/memory/memory-provider.d.ts.map +1 -1
- package/dist/core/memory/memory-provider.js.map +1 -1
- package/dist/core/memory/providers/file-store.d.ts +3 -1
- package/dist/core/memory/providers/file-store.d.ts.map +1 -1
- package/dist/core/memory/providers/file-store.js +7 -2
- package/dist/core/memory/providers/file-store.js.map +1 -1
- package/dist/core/memory/providers/transcript-recall.d.ts +1 -0
- package/dist/core/memory/providers/transcript-recall.d.ts.map +1 -1
- package/dist/core/memory/providers/transcript-recall.js +4 -7
- package/dist/core/memory/providers/transcript-recall.js.map +1 -1
- package/dist/core/memory-controller.d.ts +36 -10
- package/dist/core/memory-controller.d.ts.map +1 -1
- package/dist/core/memory-controller.js +137 -21
- package/dist/core/memory-controller.js.map +1 -1
- package/dist/core/model-registry.d.ts +23 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +87 -8
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +30 -11
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-router-controller.d.ts.map +1 -1
- package/dist/core/model-router-controller.js +33 -29
- package/dist/core/model-router-controller.js.map +1 -1
- package/dist/core/model-selection-controller.d.ts +3 -0
- package/dist/core/model-selection-controller.d.ts.map +1 -1
- package/dist/core/model-selection-controller.js +8 -1
- package/dist/core/model-selection-controller.js.map +1 -1
- package/dist/core/models/perf-profile.d.ts.map +1 -1
- package/dist/core/models/perf-profile.js +95 -33
- package/dist/core/models/perf-profile.js.map +1 -1
- package/dist/core/profile-filter-controller.d.ts +11 -0
- package/dist/core/profile-filter-controller.d.ts.map +1 -1
- package/dist/core/profile-filter-controller.js +56 -11
- package/dist/core/profile-filter-controller.js.map +1 -1
- package/dist/core/profile-registry.d.ts +2 -2
- package/dist/core/profile-registry.d.ts.map +1 -1
- package/dist/core/profile-registry.js +58 -7
- package/dist/core/profile-registry.js.map +1 -1
- package/dist/core/reflection-controller.d.ts +7 -7
- package/dist/core/reflection-controller.d.ts.map +1 -1
- package/dist/core/reflection-controller.js +78 -12
- package/dist/core/reflection-controller.js.map +1 -1
- package/dist/core/research/research-runner.d.ts +2 -2
- package/dist/core/research/research-runner.d.ts.map +1 -1
- package/dist/core/research/research-runner.js +8 -6
- package/dist/core/research/research-runner.js.map +1 -1
- package/dist/core/resource-loader.d.ts +4 -2
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +11 -1
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +13 -1
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +127 -35
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/sdk.d.ts +8 -7
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +35 -5
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/security/secret-text.d.ts +3 -0
- package/dist/core/security/secret-text.d.ts.map +1 -0
- package/dist/core/security/secret-text.js +26 -0
- package/dist/core/security/secret-text.js.map +1 -0
- package/dist/core/settings-manager.d.ts +59 -17
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +300 -51
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +1 -1
- package/dist/core/skills.js.map +1 -1
- package/dist/core/system-prompt-builder.d.ts +7 -0
- package/dist/core/system-prompt-builder.d.ts.map +1 -1
- package/dist/core/system-prompt-builder.js +23 -1
- package/dist/core/system-prompt-builder.js.map +1 -1
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +15 -11
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +2 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +8 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +69 -29
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +2 -0
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/config-backup.d.ts +7 -1
- package/dist/modes/interactive/config-backup.d.ts.map +1 -1
- package/dist/modes/interactive/config-backup.js +196 -32
- package/dist/modes/interactive/config-backup.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +10 -28
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/local-model-commands.d.ts.map +1 -1
- package/dist/modes/interactive/local-model-commands.js +2 -0
- package/dist/modes/interactive/local-model-commands.js.map +1 -1
- package/dist/modes/interactive/profile-menu-controller.d.ts +6 -4
- package/dist/modes/interactive/profile-menu-controller.d.ts.map +1 -1
- package/dist/modes/interactive/profile-menu-controller.js +248 -65
- package/dist/modes/interactive/profile-menu-controller.js.map +1 -1
- package/dist/modes/interactive/report-commands.d.ts.map +1 -1
- package/dist/modes/interactive/report-commands.js +8 -2
- package/dist/modes/interactive/report-commands.js.map +1 -1
- package/dist/modes/interactive/settings-selector-flow.d.ts.map +1 -1
- package/dist/modes/interactive/settings-selector-flow.js +8 -0
- package/dist/modes/interactive/settings-selector-flow.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +3 -1
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/docs/extensions.md +32 -0
- package/docs/resources.md +15 -7
- package/docs/settings.md +54 -5
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/preset.ts +2 -2
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +44 -35
- package/package.json +4 -4
|
@@ -21,7 +21,30 @@ import { ExtensionInputComponent } from "./components/extension-input.js";
|
|
|
21
21
|
import { ProfileResourceEditorComponent, resolveResourceEditPath, } from "./components/profile-resource-editor.js";
|
|
22
22
|
import { ProfileSelectorComponent } from "./components/profile-selector.js";
|
|
23
23
|
import { SelectSubmenu } from "./components/settings-selector.js";
|
|
24
|
+
import { captureProfileFiles, restoreProfileFiles } from "./config-backup.js";
|
|
24
25
|
import { getAvailableThemesWithPaths } from "./theme/theme.js";
|
|
26
|
+
export const NO_ACTIVE_PROFILE_DESCRIPTION = "Baseline resources; inline SDK extensions load, discovered extensions stay withheld";
|
|
27
|
+
function deletionScopeForProfile(profile) {
|
|
28
|
+
switch (profile.source) {
|
|
29
|
+
case "inline":
|
|
30
|
+
return "session";
|
|
31
|
+
case "directory-overlay":
|
|
32
|
+
return "directory";
|
|
33
|
+
case "project-settings":
|
|
34
|
+
return "project";
|
|
35
|
+
case "global-settings":
|
|
36
|
+
return "global";
|
|
37
|
+
case "profile-file": {
|
|
38
|
+
const localProfilePath = path.resolve(getAgentDir(), "profiles", `${profile.name}.json`);
|
|
39
|
+
return profile.sourcePath && path.resolve(profile.sourcePath) === localProfilePath
|
|
40
|
+
? "reusable-file"
|
|
41
|
+
: undefined;
|
|
42
|
+
}
|
|
43
|
+
case "embedded":
|
|
44
|
+
case "external-settings":
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
25
48
|
export class ProfileMenuController {
|
|
26
49
|
deps;
|
|
27
50
|
constructor(deps) {
|
|
@@ -65,7 +88,7 @@ export class ProfileMenuController {
|
|
|
65
88
|
const profiles = registry.listProfiles();
|
|
66
89
|
const activeNames = this.settingsManager.getActiveResourceProfileNames();
|
|
67
90
|
const options = [
|
|
68
|
-
{ value: "(none)", label: "(none)", description:
|
|
91
|
+
{ value: "(none)", label: "(none)", description: NO_ACTIVE_PROFILE_DESCRIPTION },
|
|
69
92
|
...profiles.map((p) => ({
|
|
70
93
|
value: p.name,
|
|
71
94
|
label: p.name,
|
|
@@ -168,8 +191,9 @@ export class ProfileMenuController {
|
|
|
168
191
|
this.ui.showSelector((done) => {
|
|
169
192
|
const selector = new SelectSubmenu("Delete Profile / Situation", "Pick a profile/situation to delete.", editableProfiles, "", (value) => {
|
|
170
193
|
done();
|
|
171
|
-
this.deleteProfileFromSource(value)
|
|
172
|
-
|
|
194
|
+
void this.deleteProfileFromSource(value).then(() => {
|
|
195
|
+
void this.ui.showSettingsSelector();
|
|
196
|
+
});
|
|
173
197
|
}, () => {
|
|
174
198
|
done();
|
|
175
199
|
void this.openManageProfilesFlow();
|
|
@@ -290,9 +314,9 @@ export class ProfileMenuController {
|
|
|
290
314
|
name: trimmed,
|
|
291
315
|
model: profileModel ?? undefined,
|
|
292
316
|
resources: {},
|
|
293
|
-
}, "
|
|
317
|
+
}, "reusable-file");
|
|
294
318
|
await this.applyProfile(trimmed);
|
|
295
|
-
void this.openLibraryEditorForProfile(trimmed, "
|
|
319
|
+
void this.openLibraryEditorForProfile(trimmed, "reusable-file");
|
|
296
320
|
}
|
|
297
321
|
catch (error) {
|
|
298
322
|
this.ui.showError(error instanceof Error ? error.message : String(error));
|
|
@@ -490,31 +514,7 @@ export class ProfileMenuController {
|
|
|
490
514
|
externalResourceRoots: this.settingsManager.getExternalResourceRoots(),
|
|
491
515
|
onSave: (resources) => {
|
|
492
516
|
done();
|
|
493
|
-
|
|
494
|
-
this.settingsManager.setProfileDefinition(profileName, {
|
|
495
|
-
name: profileName,
|
|
496
|
-
description: profile.description,
|
|
497
|
-
model: profile.model,
|
|
498
|
-
thinking: profile.thinking,
|
|
499
|
-
resources,
|
|
500
|
-
}, currentScope);
|
|
501
|
-
this.ui.showStatus(`Saved profile "${profileName}" to ${currentScope}.`);
|
|
502
|
-
if (isActiveProfile) {
|
|
503
|
-
const changedKinds = resourceProfileSettingsChangedKinds(originalResources, resources);
|
|
504
|
-
if (changedKinds.size === 1 && changedKinds.has("extensions")) {
|
|
505
|
-
void this.ui.reconcileExtensionsAndRefreshUI(profileName);
|
|
506
|
-
}
|
|
507
|
-
else if (changedKinds.size > 0) {
|
|
508
|
-
void this.refreshAfterProfileMutation(profileName);
|
|
509
|
-
}
|
|
510
|
-
else {
|
|
511
|
-
this.ui.requestRender();
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
catch (error) {
|
|
516
|
-
this.ui.showError(error instanceof Error ? error.message : String(error));
|
|
517
|
-
}
|
|
517
|
+
void this.saveProfileResources(profile, originalResources, resources, currentScope, isActiveProfile);
|
|
518
518
|
},
|
|
519
519
|
onCancel: () => {
|
|
520
520
|
done();
|
|
@@ -545,6 +545,104 @@ export class ProfileMenuController {
|
|
|
545
545
|
return { component: editor, focus: editor };
|
|
546
546
|
});
|
|
547
547
|
}
|
|
548
|
+
async saveProfileResources(profile, originalResources, resources, scope, isActiveProfile) {
|
|
549
|
+
const definition = {
|
|
550
|
+
name: profile.name,
|
|
551
|
+
description: profile.description,
|
|
552
|
+
model: profile.model,
|
|
553
|
+
thinking: profile.thinking,
|
|
554
|
+
modelRouter: profile.modelRouter,
|
|
555
|
+
soul: profile.soul,
|
|
556
|
+
resources,
|
|
557
|
+
};
|
|
558
|
+
const changedKinds = resourceProfileSettingsChangedKinds(originalResources, resources);
|
|
559
|
+
if (!isActiveProfile || changedKinds.size === 0) {
|
|
560
|
+
try {
|
|
561
|
+
this.settingsManager.setProfileDefinition(profile.name, definition, scope);
|
|
562
|
+
this.ui.showStatus(`Saved profile "${profile.name}" to ${scope}.`);
|
|
563
|
+
this.ui.requestRender();
|
|
564
|
+
}
|
|
565
|
+
catch (error) {
|
|
566
|
+
this.ui.showError(error instanceof Error ? error.message : String(error));
|
|
567
|
+
}
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
const settingsSnapshot = this.settingsManager.createReloadSnapshot();
|
|
571
|
+
const profilesDir = path.join(getAgentDir(), "profiles");
|
|
572
|
+
const profileFilesSnapshot = scope === "reusable-file" ? captureProfileFiles(profilesDir) : undefined;
|
|
573
|
+
let stagedRuntimeApplied = false;
|
|
574
|
+
try {
|
|
575
|
+
// Validate the edited authority surface as a session overlay first. Persistent scopes are
|
|
576
|
+
// written only after the complete runtime generation passes its reload doctor.
|
|
577
|
+
this.settingsManager.setProfileDefinition(profile.name, definition, "session");
|
|
578
|
+
if (!(await this.ui.handleReloadCommand())) {
|
|
579
|
+
this.settingsManager.restoreReloadSnapshot(settingsSnapshot);
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
stagedRuntimeApplied = true;
|
|
583
|
+
if (scope !== "session") {
|
|
584
|
+
this.settingsManager.setProfileDefinition(profile.name, definition, scope);
|
|
585
|
+
await this.settingsManager.flush();
|
|
586
|
+
// Drop the validation-only inline winner, then refresh the registry from the now-validated
|
|
587
|
+
// persistent definition. The live runtime already represents these identical resources.
|
|
588
|
+
this.settingsManager.restoreReloadSnapshot(settingsSnapshot);
|
|
589
|
+
await this.settingsManager.reload();
|
|
590
|
+
}
|
|
591
|
+
const active = this.settingsManager.getActiveResourceProfileNames()[0] ?? "(none)";
|
|
592
|
+
this.ui.footerDataProvider.setExtensionStatus("profile", active);
|
|
593
|
+
this.ui.invalidateFooter();
|
|
594
|
+
this.ui.updateEditorBorderColor();
|
|
595
|
+
this.ui.showStatus(`Saved profile "${profile.name}" to ${scope}.`);
|
|
596
|
+
}
|
|
597
|
+
catch (error) {
|
|
598
|
+
const rollbackError = stagedRuntimeApplied
|
|
599
|
+
? await this.rollbackValidatedProfileMutation(settingsSnapshot, {
|
|
600
|
+
profileName: profile.name,
|
|
601
|
+
scope,
|
|
602
|
+
profileFilesSnapshot,
|
|
603
|
+
})
|
|
604
|
+
: undefined;
|
|
605
|
+
if (!stagedRuntimeApplied)
|
|
606
|
+
this.settingsManager.restoreReloadSnapshot(settingsSnapshot);
|
|
607
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
608
|
+
this.ui.showError(rollbackError
|
|
609
|
+
? `${message}; rollback failed: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`
|
|
610
|
+
: message);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
async rollbackValidatedProfileMutation(settingsSnapshot, definition) {
|
|
614
|
+
const errors = [];
|
|
615
|
+
try {
|
|
616
|
+
if (definition?.scope === "reusable-file") {
|
|
617
|
+
restoreProfileFiles(path.join(getAgentDir(), "profiles"), definition.profileFilesSnapshot);
|
|
618
|
+
}
|
|
619
|
+
else if (definition && definition.scope !== "session") {
|
|
620
|
+
this.settingsManager.restoreProfileDefinitionFromReloadSnapshot(definition.profileName, definition.scope, settingsSnapshot);
|
|
621
|
+
}
|
|
622
|
+
const global = settingsSnapshot.globalSettings;
|
|
623
|
+
this.settingsManager.replaceGlobalResourceProfileConfiguration({
|
|
624
|
+
resourceProfiles: global.resourceProfiles,
|
|
625
|
+
activeResourceProfile: global.activeResourceProfile,
|
|
626
|
+
activeResourceProfiles: global.activeResourceProfiles,
|
|
627
|
+
externalResourceRoots: global.externalResourceRoots,
|
|
628
|
+
trustedResourceRoots: global.trustedResourceRoots,
|
|
629
|
+
});
|
|
630
|
+
await this.settingsManager.flush();
|
|
631
|
+
}
|
|
632
|
+
catch (error) {
|
|
633
|
+
errors.push(`persistence: ${error instanceof Error ? error.message : String(error)}`);
|
|
634
|
+
}
|
|
635
|
+
this.settingsManager.restoreReloadSnapshot(settingsSnapshot);
|
|
636
|
+
try {
|
|
637
|
+
if (!(await this.ui.handleReloadCommand())) {
|
|
638
|
+
errors.push("runtime: the previous profile runtime could not be restored");
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
catch (error) {
|
|
642
|
+
errors.push(`runtime: ${error instanceof Error ? error.message : String(error)}`);
|
|
643
|
+
}
|
|
644
|
+
return errors.length > 0 ? new Error(errors.join("; ")) : undefined;
|
|
645
|
+
}
|
|
548
646
|
async promptScopeChangeForProfile(profileName, currentScope) {
|
|
549
647
|
const scopeOptions = [
|
|
550
648
|
{ value: "session", label: "session", description: "Runtime only (not written to disk)" },
|
|
@@ -593,14 +691,21 @@ export class ProfileMenuController {
|
|
|
593
691
|
const normalizedName = profileName.trim();
|
|
594
692
|
const normalizedLower = normalizedName.toLowerCase();
|
|
595
693
|
if (normalizedName.length === 0 || normalizedLower === "none" || normalizedLower === "(none)") {
|
|
694
|
+
const settingsSnapshot = this.settingsManager.createReloadSnapshot();
|
|
695
|
+
let stagedRuntimeApplied = false;
|
|
596
696
|
try {
|
|
597
697
|
this.settingsManager.setRuntimeResourceProfiles([]);
|
|
598
|
-
|
|
698
|
+
if (!(await this.ui.handleReloadCommand())) {
|
|
699
|
+
this.settingsManager.restoreReloadSnapshot(settingsSnapshot);
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
stagedRuntimeApplied = true;
|
|
703
|
+
// Persist only after the new runtime generation passes its reload doctor.
|
|
599
704
|
this.settingsManager.setActiveProfile(undefined, "global");
|
|
705
|
+
await this.settingsManager.flush();
|
|
600
706
|
this.session.sessionManager.appendCustomEntry("pi.activeResourceProfiles", {
|
|
601
707
|
profiles: [],
|
|
602
708
|
});
|
|
603
|
-
await this.ui.handleReloadCommand();
|
|
604
709
|
const activeProfileName = this.settingsManager.getActiveResourceProfileNames()[0] ?? "(none)";
|
|
605
710
|
this.ui.footerDataProvider.setExtensionStatus("profile", activeProfileName);
|
|
606
711
|
this.ui.invalidateFooter();
|
|
@@ -608,7 +713,15 @@ export class ProfileMenuController {
|
|
|
608
713
|
this.ui.showStatus(`Profile: ${activeProfileName}`);
|
|
609
714
|
}
|
|
610
715
|
catch (error) {
|
|
611
|
-
|
|
716
|
+
const rollbackError = stagedRuntimeApplied
|
|
717
|
+
? await this.rollbackValidatedProfileMutation(settingsSnapshot)
|
|
718
|
+
: undefined;
|
|
719
|
+
if (!stagedRuntimeApplied)
|
|
720
|
+
this.settingsManager.restoreReloadSnapshot(settingsSnapshot);
|
|
721
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
722
|
+
this.ui.showError(rollbackError
|
|
723
|
+
? `${message}; rollback failed: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`
|
|
724
|
+
: message);
|
|
612
725
|
}
|
|
613
726
|
return;
|
|
614
727
|
}
|
|
@@ -620,48 +733,63 @@ export class ProfileMenuController {
|
|
|
620
733
|
this.ui.showError(`Profile not found: ${profileName}`);
|
|
621
734
|
return;
|
|
622
735
|
}
|
|
736
|
+
const settingsSnapshot = this.settingsManager.createReloadSnapshot();
|
|
737
|
+
const modelRegistrySnapshot = profile.model ? this.session.modelRegistry.createReloadSnapshot() : undefined;
|
|
738
|
+
let stagedRuntimeApplied = false;
|
|
623
739
|
try {
|
|
624
|
-
|
|
740
|
+
const activeProfileRef = normalizedName.startsWith("./") || normalizedName.startsWith("../") ? normalizedName : profile.name;
|
|
741
|
+
let requestedModel;
|
|
625
742
|
if (profile.model) {
|
|
626
743
|
this.session.modelRegistry.refresh();
|
|
627
744
|
const resolved = resolveCliModel({ cliModel: profile.model, modelRegistry: this.session.modelRegistry });
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
if (resolved.warning) {
|
|
745
|
+
// The profile may grant an extension that contributes this model. The current generation
|
|
746
|
+
// cannot validate that case; the atomic reload binds new providers before authoritative
|
|
747
|
+
// profile resolution and rolls back if the model is still unresolved.
|
|
748
|
+
if (!resolved.error && resolved.warning) {
|
|
633
749
|
this.ui.showWarning(resolved.warning);
|
|
634
750
|
}
|
|
635
|
-
if (resolved.
|
|
636
|
-
|
|
637
|
-
appliedModel = resolved.model;
|
|
638
|
-
}
|
|
639
|
-
if (resolved.thinkingLevel && !profile.thinking) {
|
|
640
|
-
this.session.setThinkingLevel(resolved.thinkingLevel, { persistSettings: false });
|
|
641
|
-
}
|
|
751
|
+
if (!resolved.error)
|
|
752
|
+
requestedModel = resolved.model;
|
|
642
753
|
}
|
|
643
|
-
|
|
644
|
-
|
|
754
|
+
// Stage the complete situation in memory. Runtime reload applies model/thinking, resource
|
|
755
|
+
// grants, extensions, skills, prompts, and soul together; explicit launch overrides still win.
|
|
756
|
+
this.settingsManager.setRuntimeResourceProfiles([activeProfileRef]);
|
|
757
|
+
if (!(await this.ui.handleReloadCommand())) {
|
|
758
|
+
this.settingsManager.restoreReloadSnapshot(settingsSnapshot);
|
|
759
|
+
if (modelRegistrySnapshot)
|
|
760
|
+
this.session.modelRegistry.restoreReloadSnapshot(modelRegistrySnapshot);
|
|
761
|
+
return;
|
|
645
762
|
}
|
|
646
|
-
|
|
647
|
-
// Selection
|
|
648
|
-
|
|
649
|
-
this.settingsManager.
|
|
763
|
+
stagedRuntimeApplied = true;
|
|
764
|
+
// Selection survives restarts only after the new runtime generation passes its reload doctor.
|
|
765
|
+
this.settingsManager.setActiveProfile(activeProfileRef, "global");
|
|
766
|
+
await this.settingsManager.flush();
|
|
650
767
|
this.session.sessionManager.appendCustomEntry("pi.activeResourceProfiles", {
|
|
651
|
-
profiles: [
|
|
768
|
+
profiles: [activeProfileRef],
|
|
652
769
|
});
|
|
653
|
-
await this.ui.handleReloadCommand();
|
|
654
770
|
this.ui.footerDataProvider.setExtensionStatus("profile", profile.name);
|
|
655
771
|
this.ui.invalidateFooter();
|
|
656
772
|
this.ui.updateEditorBorderColor();
|
|
657
773
|
this.ui.showStatus(`Profile: ${profile.name}`);
|
|
658
|
-
if (
|
|
659
|
-
|
|
660
|
-
this.
|
|
774
|
+
if (requestedModel &&
|
|
775
|
+
this.session.model?.provider === requestedModel.provider &&
|
|
776
|
+
this.session.model.id === requestedModel.id) {
|
|
777
|
+
void this.ui.maybeWarnAboutAnthropicSubscriptionAuth(requestedModel);
|
|
778
|
+
this.ui.checkDaxnutsEasterEgg(requestedModel);
|
|
661
779
|
}
|
|
662
780
|
}
|
|
663
781
|
catch (error) {
|
|
664
|
-
|
|
782
|
+
const rollbackError = stagedRuntimeApplied
|
|
783
|
+
? await this.rollbackValidatedProfileMutation(settingsSnapshot)
|
|
784
|
+
: undefined;
|
|
785
|
+
if (!stagedRuntimeApplied)
|
|
786
|
+
this.settingsManager.restoreReloadSnapshot(settingsSnapshot);
|
|
787
|
+
if (modelRegistrySnapshot)
|
|
788
|
+
this.session.modelRegistry.restoreReloadSnapshot(modelRegistrySnapshot);
|
|
789
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
790
|
+
this.ui.showError(rollbackError
|
|
791
|
+
? `${message}; rollback failed: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`
|
|
792
|
+
: message);
|
|
665
793
|
}
|
|
666
794
|
}
|
|
667
795
|
/** Map where a profile currently lives to the scope we should write it back to. */
|
|
@@ -672,15 +800,18 @@ export class ProfileMenuController {
|
|
|
672
800
|
case "directory-overlay":
|
|
673
801
|
case "embedded":
|
|
674
802
|
return "directory";
|
|
803
|
+
case "project-settings":
|
|
804
|
+
return "project";
|
|
675
805
|
case "inline":
|
|
676
806
|
return "session";
|
|
677
807
|
default:
|
|
678
|
-
return "global";
|
|
808
|
+
return "global";
|
|
679
809
|
}
|
|
680
810
|
}
|
|
681
811
|
async refreshAfterProfileMutation(profileName) {
|
|
682
812
|
if (this.settingsManager.getActiveResourceProfileNames().includes(profileName)) {
|
|
683
|
-
await this.ui.handleReloadCommand()
|
|
813
|
+
if (!(await this.ui.handleReloadCommand()))
|
|
814
|
+
return;
|
|
684
815
|
const active = this.settingsManager.getActiveResourceProfileNames()[0] ?? "(none)";
|
|
685
816
|
this.ui.footerDataProvider.setExtensionStatus("profile", active);
|
|
686
817
|
this.ui.invalidateFooter();
|
|
@@ -822,20 +953,72 @@ export class ProfileMenuController {
|
|
|
822
953
|
this.ui.showError(error instanceof Error ? error.message : String(error));
|
|
823
954
|
}
|
|
824
955
|
}
|
|
825
|
-
deleteProfileFromSource(profileName) {
|
|
826
|
-
const
|
|
956
|
+
async deleteProfileFromSource(profileName) {
|
|
957
|
+
const registry = this.settingsManager.getProfileRegistry();
|
|
958
|
+
const profile = registry.getProfile(profileName);
|
|
827
959
|
if (!profile) {
|
|
828
960
|
this.ui.showError(`Profile not found: ${profileName}`);
|
|
829
961
|
return;
|
|
830
962
|
}
|
|
831
|
-
const scope =
|
|
963
|
+
const scope = deletionScopeForProfile(profile);
|
|
964
|
+
if (!scope) {
|
|
965
|
+
const location = profile.sourcePath ? ` at ${profile.sourcePath}` : "";
|
|
966
|
+
this.ui.showError(`Profile "${profileName}" comes from read-only source ${profile.source}${location}; edit or remove that source definition directly.`);
|
|
967
|
+
return;
|
|
968
|
+
}
|
|
969
|
+
const wasActive = this.settingsManager.getActiveResourceProfileNames().some((profileRef) => {
|
|
970
|
+
if (profileRef === profileName || profileRef === profile.name)
|
|
971
|
+
return true;
|
|
972
|
+
const activeProfile = profileRef.startsWith("./") || profileRef.startsWith("../")
|
|
973
|
+
? registry.resolveProfileRef(profileRef, this.sessionManager.getCwd())
|
|
974
|
+
: registry.getProfile(profileRef);
|
|
975
|
+
return Boolean(activeProfile && activeProfile.name === profile.name && activeProfile.sourcePath === profile.sourcePath);
|
|
976
|
+
});
|
|
977
|
+
const settingsSnapshot = this.settingsManager.createReloadSnapshot();
|
|
978
|
+
const profileFilesSnapshot = scope === "reusable-file" ? captureProfileFiles(path.join(getAgentDir(), "profiles")) : undefined;
|
|
979
|
+
let switchedToNone = false;
|
|
832
980
|
try {
|
|
981
|
+
if (wasActive) {
|
|
982
|
+
// Stage an explicit empty runtime selection while the definition is still intact. The
|
|
983
|
+
// full reload can now remove the profile's extensions, tools, providers, model, and
|
|
984
|
+
// memory generation atomically. Persisting the deletion is deliberately deferred until
|
|
985
|
+
// that generation passes its doctor, so a failed reload has no on-disk deletion to undo.
|
|
986
|
+
this.settingsManager.setRuntimeResourceProfiles([]);
|
|
987
|
+
if (!(await this.ui.handleReloadCommand())) {
|
|
988
|
+
this.settingsManager.restoreReloadSnapshot(settingsSnapshot);
|
|
989
|
+
return;
|
|
990
|
+
}
|
|
991
|
+
switchedToNone = true;
|
|
992
|
+
}
|
|
833
993
|
this.settingsManager.deleteProfile(profileName, scope);
|
|
994
|
+
const remaining = this.settingsManager.getProfileRegistry().getProfile(profileName);
|
|
995
|
+
if (remaining && remaining.source === profile.source && remaining.sourcePath === profile.sourcePath) {
|
|
996
|
+
throw new Error(`Profile "${profileName}" was not removed from ${profile.source}.`);
|
|
997
|
+
}
|
|
998
|
+
if (wasActive) {
|
|
999
|
+
this.settingsManager.setActiveProfile(undefined, "global");
|
|
1000
|
+
await this.settingsManager.flush();
|
|
1001
|
+
this.session.sessionManager.appendCustomEntry("pi.activeResourceProfiles", { profiles: [] });
|
|
1002
|
+
this.ui.footerDataProvider.setExtensionStatus("profile", "(none)");
|
|
1003
|
+
this.ui.invalidateFooter();
|
|
1004
|
+
this.ui.updateEditorBorderColor();
|
|
1005
|
+
}
|
|
834
1006
|
this.ui.showStatus(`Deleted profile "${profileName}" from ${scope}.`);
|
|
835
|
-
void this.refreshAfterProfileMutation(profileName);
|
|
836
1007
|
}
|
|
837
1008
|
catch (error) {
|
|
838
|
-
|
|
1009
|
+
const rollbackError = switchedToNone
|
|
1010
|
+
? await this.rollbackValidatedProfileMutation(settingsSnapshot, {
|
|
1011
|
+
profileName,
|
|
1012
|
+
scope,
|
|
1013
|
+
profileFilesSnapshot,
|
|
1014
|
+
})
|
|
1015
|
+
: undefined;
|
|
1016
|
+
if (!switchedToNone)
|
|
1017
|
+
this.settingsManager.restoreReloadSnapshot(settingsSnapshot);
|
|
1018
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1019
|
+
this.ui.showError(rollbackError
|
|
1020
|
+
? `${message}; rollback failed: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`
|
|
1021
|
+
: message);
|
|
839
1022
|
}
|
|
840
1023
|
}
|
|
841
1024
|
async addExternalResourceRootFlow() {
|