@caupulican/pi-adaptative 0.80.48 → 0.80.50
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 +15 -0
- package/dist/core/model-resolver.d.ts +13 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +44 -0
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +20 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +28 -3
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/profile-resource-editor.d.ts +3 -0
- package/dist/modes/interactive/components/profile-resource-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/profile-resource-editor.js +78 -1
- package/dist/modes/interactive/components/profile-resource-editor.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +4 -4
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +111 -25
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- 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/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 +12 -12
- package/package.json +4 -4
|
@@ -59,7 +59,7 @@ import { formatKeyText, keyDisplayText, keyHint, keyText, rawKeyHint } from "./c
|
|
|
59
59
|
import { LoginDialogComponent } from "./components/login-dialog.js";
|
|
60
60
|
import { ModelSelectorComponent } from "./components/model-selector.js";
|
|
61
61
|
import { OAuthSelectorComponent } from "./components/oauth-selector.js";
|
|
62
|
-
import { ProfileResourceEditorComponent, } from "./components/profile-resource-editor.js";
|
|
62
|
+
import { ProfileResourceEditorComponent, resolveResourceEditPath, } from "./components/profile-resource-editor.js";
|
|
63
63
|
import { ProfileSelectorComponent } from "./components/profile-selector.js";
|
|
64
64
|
import { ScopedModelsSelectorComponent } from "./components/scoped-models-selector.js";
|
|
65
65
|
import { SessionSelectorComponent } from "./components/session-selector.js";
|
|
@@ -3718,6 +3718,50 @@ export class InteractiveMode {
|
|
|
3718
3718
|
this.ui.requestRender(true);
|
|
3719
3719
|
}
|
|
3720
3720
|
}
|
|
3721
|
+
async openEditorForPath(filePath) {
|
|
3722
|
+
let editorCmd = process.env.EDITOR || process.env.VISUAL;
|
|
3723
|
+
let isFallback = false;
|
|
3724
|
+
if (!editorCmd) {
|
|
3725
|
+
editorCmd = "vi";
|
|
3726
|
+
isFallback = true;
|
|
3727
|
+
}
|
|
3728
|
+
try {
|
|
3729
|
+
// Stop TUI to release terminal
|
|
3730
|
+
this.ui.stop();
|
|
3731
|
+
// Split by space to support editor arguments (e.g., "code --wait")
|
|
3732
|
+
const [editor, ...editorArgs] = editorCmd.split(" ");
|
|
3733
|
+
process.stdout.write(`Launching external editor: ${editorCmd} ${filePath}\nPi will resume when the editor exits.\n`);
|
|
3734
|
+
const status = await new Promise((resolve) => {
|
|
3735
|
+
const child = spawn(editor, [...editorArgs, filePath], {
|
|
3736
|
+
stdio: "inherit",
|
|
3737
|
+
shell: process.platform === "win32",
|
|
3738
|
+
});
|
|
3739
|
+
child.on("error", () => resolve(null));
|
|
3740
|
+
child.on("close", (code) => resolve(code));
|
|
3741
|
+
});
|
|
3742
|
+
if (status === null) {
|
|
3743
|
+
if (isFallback) {
|
|
3744
|
+
process.stdout.write(`\nError: Failed to launch fallback editor "vi".\n`);
|
|
3745
|
+
}
|
|
3746
|
+
else {
|
|
3747
|
+
process.stdout.write(`\nError: Failed to launch editor "${editorCmd}".\n`);
|
|
3748
|
+
}
|
|
3749
|
+
process.stdout.write(`Please set the $EDITOR or $VISUAL environment variable to edit inline.\n`);
|
|
3750
|
+
process.stdout.write(`Absolute file path: ${filePath}\n\nPress Enter to return to Pi...`);
|
|
3751
|
+
// Wait for enter key
|
|
3752
|
+
await new Promise((resolve) => {
|
|
3753
|
+
process.stdin.once("data", () => resolve());
|
|
3754
|
+
});
|
|
3755
|
+
}
|
|
3756
|
+
return status === 0;
|
|
3757
|
+
}
|
|
3758
|
+
finally {
|
|
3759
|
+
// Restart TUI
|
|
3760
|
+
this.ui.start();
|
|
3761
|
+
// Force full re-render since external editor uses alternate screen
|
|
3762
|
+
this.ui.requestRender(true);
|
|
3763
|
+
}
|
|
3764
|
+
}
|
|
3721
3765
|
// =========================================================================
|
|
3722
3766
|
// UI helpers
|
|
3723
3767
|
// =========================================================================
|
|
@@ -5127,7 +5171,7 @@ export class InteractiveMode {
|
|
|
5127
5171
|
const profiles = registry.listProfiles();
|
|
5128
5172
|
const activeNames = this.settingsManager.getActiveResourceProfileNames();
|
|
5129
5173
|
const options = [
|
|
5130
|
-
{ value: "(none)", label: "(none)", description: "No active profile (all resources enabled)" },
|
|
5174
|
+
{ value: "(none)", label: "(none)", description: "No active profile/situation (all resources enabled)" },
|
|
5131
5175
|
...profiles.map((p) => ({
|
|
5132
5176
|
value: p.name,
|
|
5133
5177
|
label: p.name,
|
|
@@ -5135,7 +5179,7 @@ export class InteractiveMode {
|
|
|
5135
5179
|
})),
|
|
5136
5180
|
];
|
|
5137
5181
|
this.showSelector((done) => {
|
|
5138
|
-
const selector = new SelectSubmenu("Profile / Situation", "Select the active runtime profile for this session. This is session-only unless saved elsewhere.", options, activeNames[0] || "(none)", (value) => {
|
|
5182
|
+
const selector = new SelectSubmenu("Profile / Situation", "Select the active runtime profile/situation for this session. This is session-only unless saved elsewhere.", options, activeNames[0] || "(none)", (value) => {
|
|
5139
5183
|
done();
|
|
5140
5184
|
void this.applyProfile(value === "(none)" ? "" : value).then(() => {
|
|
5141
5185
|
void this.showSettingsSelector();
|
|
@@ -5156,24 +5200,28 @@ export class InteractiveMode {
|
|
|
5156
5200
|
description: p.description || p.source,
|
|
5157
5201
|
}));
|
|
5158
5202
|
const options = [
|
|
5159
|
-
{
|
|
5203
|
+
{
|
|
5204
|
+
value: "create",
|
|
5205
|
+
label: "+ Create profile / situation...",
|
|
5206
|
+
description: "Create a new resource profile/situation definition.",
|
|
5207
|
+
},
|
|
5160
5208
|
];
|
|
5161
5209
|
if (this.settingsManager.getActiveResourceProfileNames().length > 0) {
|
|
5162
5210
|
options.push({
|
|
5163
5211
|
value: "persist",
|
|
5164
|
-
label: "Persist active profile to...",
|
|
5165
|
-
description: "Save the current active
|
|
5212
|
+
label: "Persist active profile / situation to...",
|
|
5213
|
+
description: "Save the current active profile/situation selection so it survives restart.",
|
|
5166
5214
|
});
|
|
5167
5215
|
}
|
|
5168
5216
|
if (editableProfiles.length > 0) {
|
|
5169
5217
|
options.push({
|
|
5170
5218
|
value: "delete",
|
|
5171
|
-
label: "Delete profile...",
|
|
5172
|
-
description: "Remove a profile definition from where it is stored.",
|
|
5219
|
+
label: "Delete profile / situation...",
|
|
5220
|
+
description: "Remove a profile/situation definition from where it is stored.",
|
|
5173
5221
|
});
|
|
5174
5222
|
}
|
|
5175
5223
|
this.showSelector((done) => {
|
|
5176
|
-
const selector = new SelectSubmenu("Manage Profiles", "Create, delete, or persist profile definitions.", options, "", (value) => {
|
|
5224
|
+
const selector = new SelectSubmenu("Manage Profiles / Situations", "Create, delete, or persist profile/situation definitions.", options, "", (value) => {
|
|
5177
5225
|
done();
|
|
5178
5226
|
if (value === "create") {
|
|
5179
5227
|
void this.createProfileFlow().then(() => {
|
|
@@ -5205,7 +5253,7 @@ export class InteractiveMode {
|
|
|
5205
5253
|
{ value: "global", label: "global", description: "~/.pi/agent/settings.json" },
|
|
5206
5254
|
];
|
|
5207
5255
|
this.showSelector((done) => {
|
|
5208
|
-
const selector = new SelectSubmenu("Persist Active Profile", "Choose where to write the active
|
|
5256
|
+
const selector = new SelectSubmenu("Persist Active Profile / Situation", "Choose where to write the active profile/situation selection.", scopeOptions, "directory", (value) => {
|
|
5209
5257
|
done();
|
|
5210
5258
|
this.persistActiveProfile(value);
|
|
5211
5259
|
void this.showSettingsSelector();
|
|
@@ -5224,7 +5272,7 @@ export class InteractiveMode {
|
|
|
5224
5272
|
description: p.description || p.source,
|
|
5225
5273
|
}));
|
|
5226
5274
|
this.showSelector((done) => {
|
|
5227
|
-
const selector = new SelectSubmenu("Delete Profile", "Pick a profile to delete.", editableProfiles, "", (value) => {
|
|
5275
|
+
const selector = new SelectSubmenu("Delete Profile / Situation", "Pick a profile/situation to delete.", editableProfiles, "", (value) => {
|
|
5228
5276
|
done();
|
|
5229
5277
|
this.deleteProfileFromSource(value);
|
|
5230
5278
|
void this.showSettingsSelector();
|
|
@@ -5279,13 +5327,17 @@ export class InteractiveMode {
|
|
|
5279
5327
|
const activeName = activeNames[0];
|
|
5280
5328
|
if (!activeName || activeName === "(none)") {
|
|
5281
5329
|
this.showSelector((done) => {
|
|
5282
|
-
const selector = new SelectSubmenu("No Active Profile", "Select or create a profile to manage the library.", [
|
|
5330
|
+
const selector = new SelectSubmenu("No Active Profile / Situation", "Select or create a profile/situation to manage the library.", [
|
|
5283
5331
|
{
|
|
5284
5332
|
value: "select",
|
|
5285
|
-
label: "Select existing profile...",
|
|
5286
|
-
description: "Choose an existing profile to activate.",
|
|
5333
|
+
label: "Select existing profile / situation...",
|
|
5334
|
+
description: "Choose an existing profile/situation to activate.",
|
|
5335
|
+
},
|
|
5336
|
+
{
|
|
5337
|
+
value: "create",
|
|
5338
|
+
label: "Create new profile / situation...",
|
|
5339
|
+
description: "Create a new profile/situation definition.",
|
|
5287
5340
|
},
|
|
5288
|
-
{ value: "create", label: "Create new profile...", description: "Create a new profile definition." },
|
|
5289
5341
|
], "select", (value) => {
|
|
5290
5342
|
done();
|
|
5291
5343
|
if (value === "create") {
|
|
@@ -5305,7 +5357,7 @@ export class InteractiveMode {
|
|
|
5305
5357
|
const registry = this.settingsManager.getProfileRegistry();
|
|
5306
5358
|
const profile = registry.getProfile(activeName);
|
|
5307
5359
|
if (!profile) {
|
|
5308
|
-
this.showError(`Active profile "${activeName}" not found in registry.`);
|
|
5360
|
+
this.showError(`Active profile/situation "${activeName}" not found in registry.`);
|
|
5309
5361
|
return;
|
|
5310
5362
|
}
|
|
5311
5363
|
const scope = this.scopeForProfileSource(profile.source);
|
|
@@ -5314,7 +5366,7 @@ export class InteractiveMode {
|
|
|
5314
5366
|
async createProfileAndOpenLibraryFlow() {
|
|
5315
5367
|
const name = await new Promise((resolve) => {
|
|
5316
5368
|
this.showSelector((done) => {
|
|
5317
|
-
const input = new ExtensionInputComponent("Create Profile", "Enter profile name", (value) => {
|
|
5369
|
+
const input = new ExtensionInputComponent("Create Profile / Situation", "Enter profile/situation name", (value) => {
|
|
5318
5370
|
done();
|
|
5319
5371
|
resolve(value);
|
|
5320
5372
|
}, () => {
|
|
@@ -5330,7 +5382,7 @@ export class InteractiveMode {
|
|
|
5330
5382
|
}
|
|
5331
5383
|
const trimmed = name.trim();
|
|
5332
5384
|
if (!trimmed) {
|
|
5333
|
-
this.showWarning("Profile name cannot be empty.");
|
|
5385
|
+
this.showWarning("Profile/situation name cannot be empty.");
|
|
5334
5386
|
void this.openLibraryManagerFlow();
|
|
5335
5387
|
return;
|
|
5336
5388
|
}
|
|
@@ -5356,12 +5408,12 @@ export class InteractiveMode {
|
|
|
5356
5408
|
description: p.description || p.source,
|
|
5357
5409
|
}));
|
|
5358
5410
|
if (editableProfiles.length === 0) {
|
|
5359
|
-
this.showWarning("No existing profiles to select. Please create one.");
|
|
5411
|
+
this.showWarning("No existing profiles/situations to select. Please create one.");
|
|
5360
5412
|
void this.createProfileAndOpenLibraryFlow();
|
|
5361
5413
|
return;
|
|
5362
5414
|
}
|
|
5363
5415
|
this.showSelector((done) => {
|
|
5364
|
-
const selector = new SelectSubmenu("Select Profile", "Pick a profile to activate and edit.", editableProfiles, "", (value) => {
|
|
5416
|
+
const selector = new SelectSubmenu("Select Profile / Situation", "Pick a profile/situation to activate and edit.", editableProfiles, "", (value) => {
|
|
5365
5417
|
done();
|
|
5366
5418
|
void this.applyProfile(value).then(() => {
|
|
5367
5419
|
const profile = registry.getProfile(value);
|
|
@@ -5521,6 +5573,23 @@ export class InteractiveMode {
|
|
|
5521
5573
|
done();
|
|
5522
5574
|
void this.promptScopeChangeForProfile(profileName, currentScope);
|
|
5523
5575
|
},
|
|
5576
|
+
onEdit: async (id, pathValue, kind) => {
|
|
5577
|
+
done();
|
|
5578
|
+
const resolvedEditPath = resolveResourceEditPath(id, pathValue, kind);
|
|
5579
|
+
if (!resolvedEditPath) {
|
|
5580
|
+
this.showWarning(`Resource "${id}" of kind "${kind}" has no editable file path.`);
|
|
5581
|
+
void this.openLibraryEditorForProfile(profileName, currentScope);
|
|
5582
|
+
return;
|
|
5583
|
+
}
|
|
5584
|
+
if (!fs.existsSync(resolvedEditPath)) {
|
|
5585
|
+
this.showError(`Resolved path for "${id}" does not exist: ${resolvedEditPath}`);
|
|
5586
|
+
void this.openLibraryEditorForProfile(profileName, currentScope);
|
|
5587
|
+
return;
|
|
5588
|
+
}
|
|
5589
|
+
await this.openEditorForPath(resolvedEditPath);
|
|
5590
|
+
await this.handleReloadCommand();
|
|
5591
|
+
void this.openLibraryEditorForProfile(profileName, currentScope);
|
|
5592
|
+
},
|
|
5524
5593
|
});
|
|
5525
5594
|
return { component: editor, focus: editor };
|
|
5526
5595
|
});
|
|
@@ -5537,7 +5606,7 @@ export class InteractiveMode {
|
|
|
5537
5606
|
{ value: "global", label: "global", description: "~/.pi/agent/settings.json" },
|
|
5538
5607
|
];
|
|
5539
5608
|
this.showSelector((done) => {
|
|
5540
|
-
const selector = new SelectSubmenu("Change Profile Scope", `Select new scope for profile "${profileName}".`, scopeOptions, currentScope, (value) => {
|
|
5609
|
+
const selector = new SelectSubmenu("Change Profile / Situation Scope", `Select new scope for profile/situation "${profileName}".`, scopeOptions, currentScope, (value) => {
|
|
5541
5610
|
done();
|
|
5542
5611
|
void this.openLibraryEditorForProfile(profileName, value);
|
|
5543
5612
|
}, () => {
|
|
@@ -5665,7 +5734,7 @@ export class InteractiveMode {
|
|
|
5665
5734
|
async createProfileFlow() {
|
|
5666
5735
|
const name = await new Promise((resolve) => {
|
|
5667
5736
|
this.showSelector((done) => {
|
|
5668
|
-
const input = new ExtensionInputComponent("Create Profile", "Enter profile name", (value) => {
|
|
5737
|
+
const input = new ExtensionInputComponent("Create Profile / Situation", "Enter profile/situation name", (value) => {
|
|
5669
5738
|
done();
|
|
5670
5739
|
resolve(value);
|
|
5671
5740
|
}, () => {
|
|
@@ -5681,19 +5750,19 @@ export class InteractiveMode {
|
|
|
5681
5750
|
}
|
|
5682
5751
|
const trimmed = name.trim();
|
|
5683
5752
|
if (!trimmed) {
|
|
5684
|
-
this.showError("Profile name cannot be empty");
|
|
5753
|
+
this.showError("Profile/situation name cannot be empty");
|
|
5685
5754
|
return this.createProfileFlow();
|
|
5686
5755
|
}
|
|
5687
5756
|
// Validate name rules using validateSkillName
|
|
5688
5757
|
const errors = validateSkillName(trimmed);
|
|
5689
5758
|
if (errors.length > 0) {
|
|
5690
|
-
this.showError(`Invalid profile name: ${errors.join(", ")}`);
|
|
5759
|
+
this.showError(`Invalid profile/situation name: ${errors.join(", ")}`);
|
|
5691
5760
|
return this.createProfileFlow();
|
|
5692
5761
|
}
|
|
5693
5762
|
// Collision check
|
|
5694
5763
|
const existing = this.settingsManager.getProfileRegistry().getProfile(trimmed);
|
|
5695
5764
|
if (existing) {
|
|
5696
|
-
this.showError(`Profile "${trimmed}" already exists`);
|
|
5765
|
+
this.showError(`Profile/situation "${trimmed}" already exists`);
|
|
5697
5766
|
return this.createProfileFlow();
|
|
5698
5767
|
}
|
|
5699
5768
|
// Open the resource editor on the NEW profile
|
|
@@ -5729,6 +5798,23 @@ export class InteractiveMode {
|
|
|
5729
5798
|
done();
|
|
5730
5799
|
this.ui.requestRender();
|
|
5731
5800
|
},
|
|
5801
|
+
onEdit: async (id, pathValue, kind) => {
|
|
5802
|
+
done();
|
|
5803
|
+
const resolvedEditPath = resolveResourceEditPath(id, pathValue, kind);
|
|
5804
|
+
if (!resolvedEditPath) {
|
|
5805
|
+
this.showWarning(`Resource "${id}" of kind "${kind}" has no editable file path.`);
|
|
5806
|
+
void this.openNewProfileEditor(profileName);
|
|
5807
|
+
return;
|
|
5808
|
+
}
|
|
5809
|
+
if (!fs.existsSync(resolvedEditPath)) {
|
|
5810
|
+
this.showError(`Resolved path for "${id}" does not exist: ${resolvedEditPath}`);
|
|
5811
|
+
void this.openNewProfileEditor(profileName);
|
|
5812
|
+
return;
|
|
5813
|
+
}
|
|
5814
|
+
await this.openEditorForPath(resolvedEditPath);
|
|
5815
|
+
await this.handleReloadCommand();
|
|
5816
|
+
void this.openNewProfileEditor(profileName);
|
|
5817
|
+
},
|
|
5732
5818
|
});
|
|
5733
5819
|
return { component: editor, focus: editor };
|
|
5734
5820
|
});
|