@caupulican/pi-adaptative 0.80.44 → 0.80.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/core/profile-registry.d.ts +1 -0
  3. package/dist/core/profile-registry.d.ts.map +1 -1
  4. package/dist/core/profile-registry.js +40 -20
  5. package/dist/core/profile-registry.js.map +1 -1
  6. package/dist/core/resource-loader.d.ts.map +1 -1
  7. package/dist/core/resource-loader.js +133 -4
  8. package/dist/core/resource-loader.js.map +1 -1
  9. package/dist/core/settings-manager.d.ts +9 -0
  10. package/dist/core/settings-manager.d.ts.map +1 -1
  11. package/dist/core/settings-manager.js +67 -1
  12. package/dist/core/settings-manager.js.map +1 -1
  13. package/dist/modes/interactive/components/settings-selector.d.ts +12 -1
  14. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  15. package/dist/modes/interactive/components/settings-selector.js +52 -1
  16. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  17. package/dist/modes/interactive/interactive-mode.d.ts +4 -0
  18. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  19. package/dist/modes/interactive/interactive-mode.js +158 -1
  20. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  21. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  22. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  23. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  24. package/examples/extensions/sandbox/package-lock.json +2 -2
  25. package/examples/extensions/sandbox/package.json +1 -1
  26. package/examples/extensions/with-deps/package-lock.json +2 -2
  27. package/examples/extensions/with-deps/package.json +1 -1
  28. package/npm-shrinkwrap.json +12 -12
  29. package/package.json +4 -4
@@ -24,6 +24,7 @@ import { BUILT_IN_PROVIDER_DISPLAY_NAMES } from "../../core/provider-display-nam
24
24
  import { getPendingReloadBlockers } from "../../core/reload-blockers.js";
25
25
  import { formatMissingSessionCwdPrompt, MissingSessionCwdError } from "../../core/session-cwd.js";
26
26
  import { isAutoLearnSessionId, SessionManager } from "../../core/session-manager.js";
27
+ import { validateSkillName } from "../../core/skills.js";
27
28
  import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
28
29
  import { isInstallTelemetryEnabled } from "../../core/telemetry.js";
29
30
  import { allToolNames } from "../../core/tools/index.js";
@@ -61,7 +62,7 @@ import { ProfileResourceEditorComponent, } from "./components/profile-resource-e
61
62
  import { ProfileSelectorComponent } from "./components/profile-selector.js";
62
63
  import { ScopedModelsSelectorComponent } from "./components/scoped-models-selector.js";
63
64
  import { SessionSelectorComponent } from "./components/session-selector.js";
64
- import { SettingsSelectorComponent } from "./components/settings-selector.js";
65
+ import { SelectSubmenu, SettingsSelectorComponent } from "./components/settings-selector.js";
65
66
  import { SkillInvocationMessageComponent } from "./components/skill-invocation-message.js";
66
67
  import { ToolExecutionComponent } from "./components/tool-execution.js";
67
68
  import { ToolGroupComponent } from "./components/tool-group.js";
@@ -4925,6 +4926,8 @@ export class InteractiveMode {
4925
4926
  : undefined,
4926
4927
  activeProfileName: this.settingsManager.getActiveResourceProfileNames()[0],
4927
4928
  profileOptions,
4929
+ externalResourceRoots: this.settingsManager.getExternalResourceRoots(),
4930
+ trustedResourceRoots: this.settingsManager.getTrustedResourceRoots(),
4928
4931
  }, {
4929
4932
  onAutoCompactChange: (enabled) => {
4930
4933
  this.session.setAutoCompactionEnabled(enabled);
@@ -5071,6 +5074,10 @@ export class InteractiveMode {
5071
5074
  done();
5072
5075
  void this.applyProfile(profile);
5073
5076
  },
5077
+ onProfileCreate: () => {
5078
+ done();
5079
+ void this.createProfileFlow();
5080
+ },
5074
5081
  onProfileEdit: (profileName) => {
5075
5082
  done();
5076
5083
  void this.openProfileResourceEditor(profileName);
@@ -5083,6 +5090,14 @@ export class InteractiveMode {
5083
5090
  done();
5084
5091
  this.deleteProfileFromSource(profileName);
5085
5092
  },
5093
+ onAddExternalResourceRoot: () => {
5094
+ done();
5095
+ void this.addExternalResourceRootFlow();
5096
+ },
5097
+ onRemoveExternalResourceRoot: (root) => {
5098
+ done();
5099
+ void this.removeExternalResourceRootFlow(root);
5100
+ },
5086
5101
  onCancel: () => {
5087
5102
  done();
5088
5103
  this.ui.requestRender();
@@ -5224,6 +5239,73 @@ export class InteractiveMode {
5224
5239
  this.updateEditorBorderColor();
5225
5240
  }
5226
5241
  }
5242
+ async createProfileFlow() {
5243
+ const name = await new Promise((resolve) => {
5244
+ this.showSelector((done) => {
5245
+ const input = new ExtensionInputComponent("Create Profile", "Enter profile name", (value) => {
5246
+ done();
5247
+ resolve(value);
5248
+ }, () => {
5249
+ done();
5250
+ resolve(undefined);
5251
+ }, { tui: this.ui });
5252
+ return { component: input, focus: input };
5253
+ });
5254
+ });
5255
+ if (name === undefined) {
5256
+ this.ui.requestRender();
5257
+ return;
5258
+ }
5259
+ const trimmed = name.trim();
5260
+ if (!trimmed) {
5261
+ this.showError("Profile name cannot be empty");
5262
+ return this.createProfileFlow();
5263
+ }
5264
+ // Validate name rules using validateSkillName
5265
+ const errors = validateSkillName(trimmed);
5266
+ if (errors.length > 0) {
5267
+ this.showError(`Invalid profile name: ${errors.join(", ")}`);
5268
+ return this.createProfileFlow();
5269
+ }
5270
+ // Collision check
5271
+ const existing = this.settingsManager.getProfileRegistry().getProfile(trimmed);
5272
+ if (existing) {
5273
+ this.showError(`Profile "${trimmed}" already exists`);
5274
+ return this.createProfileFlow();
5275
+ }
5276
+ // Open the resource editor on the NEW profile
5277
+ void this.openNewProfileEditor(trimmed);
5278
+ }
5279
+ async openNewProfileEditor(profileName) {
5280
+ const scope = "reusable-file";
5281
+ const kinds = await this.getProfileResourceKinds();
5282
+ this.showSelector((done) => {
5283
+ const editor = new ProfileResourceEditorComponent({
5284
+ profileName,
5285
+ initialResources: {},
5286
+ kinds,
5287
+ onSave: (resources) => {
5288
+ done();
5289
+ try {
5290
+ this.settingsManager.setProfileDefinition(profileName, {
5291
+ name: profileName,
5292
+ resources,
5293
+ }, scope);
5294
+ this.showStatus(`Saved profile "${profileName}" to ${scope}.`);
5295
+ this.ui.requestRender();
5296
+ }
5297
+ catch (error) {
5298
+ this.showError(error instanceof Error ? error.message : String(error));
5299
+ }
5300
+ },
5301
+ onCancel: () => {
5302
+ done();
5303
+ this.ui.requestRender();
5304
+ },
5305
+ });
5306
+ return { component: editor, focus: editor };
5307
+ });
5308
+ }
5227
5309
  async openProfileResourceEditor(profileName) {
5228
5310
  const profile = this.settingsManager.getProfileRegistry().getProfile(profileName);
5229
5311
  if (!profile) {
@@ -5316,6 +5398,81 @@ export class InteractiveMode {
5316
5398
  this.showError(error instanceof Error ? error.message : String(error));
5317
5399
  }
5318
5400
  }
5401
+ async addExternalResourceRootFlow() {
5402
+ const rootPath = await new Promise((resolve) => {
5403
+ this.showSelector((done) => {
5404
+ const input = new ExtensionInputComponent("Add External Root", "Enter external root directory path", (value) => {
5405
+ done();
5406
+ resolve(value);
5407
+ }, () => {
5408
+ done();
5409
+ resolve(undefined);
5410
+ }, { tui: this.ui });
5411
+ return { component: input, focus: input };
5412
+ });
5413
+ });
5414
+ if (rootPath === undefined) {
5415
+ this.ui.requestRender();
5416
+ return;
5417
+ }
5418
+ const trimmed = rootPath.trim();
5419
+ if (!trimmed) {
5420
+ this.showError("Directory path cannot be empty");
5421
+ return;
5422
+ }
5423
+ const canonical = this.settingsManager.canonicalizePath(trimmed);
5424
+ if (!canonical) {
5425
+ this.showError(`Invalid path: ${trimmed}`);
5426
+ return;
5427
+ }
5428
+ // Prompt for trust confirmation (Yes/No)
5429
+ const trust = await new Promise((resolve) => {
5430
+ this.showSelector((done) => {
5431
+ const submenu = new SelectSubmenu("Trust external source?", "This directory can load custom extensions that execute arbitrary code on your machine.", [
5432
+ { value: "yes", label: "Yes", description: "Trust this directory and enable loading resources." },
5433
+ { value: "no", label: "No", description: "Do not trust this directory. Skip loading resources." },
5434
+ ], "no", (value) => {
5435
+ done();
5436
+ resolve(value === "yes");
5437
+ }, () => {
5438
+ done();
5439
+ resolve(false);
5440
+ });
5441
+ return { component: submenu, focus: submenu.getSelectList() };
5442
+ });
5443
+ });
5444
+ if (!trust) {
5445
+ this.showStatus("Aborted. External root was not trusted.");
5446
+ return;
5447
+ }
5448
+ try {
5449
+ const currentRoots = this.settingsManager.getExternalResourceRoots();
5450
+ if (!currentRoots.includes(canonical)) {
5451
+ this.settingsManager.setExternalResourceRoots([...currentRoots, canonical], "global");
5452
+ }
5453
+ this.settingsManager.addTrustedResourceRoot(canonical, "global");
5454
+ this.showStatus(`Added trusted external root: ${canonical}`);
5455
+ await this.handleReloadCommand();
5456
+ }
5457
+ catch (error) {
5458
+ this.showError(error instanceof Error ? error.message : String(error));
5459
+ }
5460
+ }
5461
+ async removeExternalResourceRootFlow(root) {
5462
+ try {
5463
+ const currentRoots = this.settingsManager.getExternalResourceRoots();
5464
+ const currentTrusted = this.settingsManager.getTrustedResourceRoots();
5465
+ const newRoots = currentRoots.filter((r) => r !== root);
5466
+ const newTrusted = currentTrusted.filter((r) => r !== root);
5467
+ this.settingsManager.setExternalResourceRoots(newRoots, "global");
5468
+ this.settingsManager.setTrustedResourceRoots(newTrusted, "global");
5469
+ this.showStatus(`Removed external root: ${root}`);
5470
+ await this.handleReloadCommand();
5471
+ }
5472
+ catch (error) {
5473
+ this.showError(error instanceof Error ? error.message : String(error));
5474
+ }
5475
+ }
5319
5476
  async handleModelCommand(searchTerm) {
5320
5477
  if (!searchTerm) {
5321
5478
  await this.showModelSelector();