@mariozechner/pi-coding-agent 0.27.9 → 0.28.0

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 (88) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +16 -17
  3. package/dist/cli/list-models.d.ts +2 -2
  4. package/dist/cli/list-models.d.ts.map +1 -1
  5. package/dist/cli/list-models.js +2 -7
  6. package/dist/cli/list-models.js.map +1 -1
  7. package/dist/config.d.ts +2 -2
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +3 -3
  10. package/dist/config.js.map +1 -1
  11. package/dist/core/agent-session.d.ts +6 -3
  12. package/dist/core/agent-session.d.ts.map +1 -1
  13. package/dist/core/agent-session.js +18 -20
  14. package/dist/core/agent-session.js.map +1 -1
  15. package/dist/core/auth-storage.d.ts +104 -0
  16. package/dist/core/auth-storage.d.ts.map +1 -0
  17. package/dist/core/auth-storage.js +232 -0
  18. package/dist/core/auth-storage.js.map +1 -0
  19. package/dist/core/model-registry.d.ts +50 -0
  20. package/dist/core/model-registry.d.ts.map +1 -0
  21. package/dist/core/model-registry.js +268 -0
  22. package/dist/core/model-registry.js.map +1 -0
  23. package/dist/core/model-resolver.d.ts +7 -7
  24. package/dist/core/model-resolver.d.ts.map +1 -1
  25. package/dist/core/model-resolver.js +12 -44
  26. package/dist/core/model-resolver.js.map +1 -1
  27. package/dist/core/sdk.d.ts +13 -26
  28. package/dist/core/sdk.d.ts.map +1 -1
  29. package/dist/core/sdk.js +24 -101
  30. package/dist/core/sdk.js.map +1 -1
  31. package/dist/core/settings-manager.d.ts +0 -5
  32. package/dist/core/settings-manager.d.ts.map +1 -1
  33. package/dist/core/settings-manager.js +0 -19
  34. package/dist/core/settings-manager.js.map +1 -1
  35. package/dist/core/skills.d.ts.map +1 -1
  36. package/dist/core/skills.js +15 -1
  37. package/dist/core/skills.js.map +1 -1
  38. package/dist/index.d.ts +3 -3
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +4 -8
  41. package/dist/index.js.map +1 -1
  42. package/dist/main.d.ts.map +1 -1
  43. package/dist/main.js +37 -22
  44. package/dist/main.js.map +1 -1
  45. package/dist/modes/interactive/components/footer.d.ts +3 -1
  46. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  47. package/dist/modes/interactive/components/footer.js +4 -3
  48. package/dist/modes/interactive/components/footer.js.map +1 -1
  49. package/dist/modes/interactive/components/model-selector.d.ts +3 -1
  50. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  51. package/dist/modes/interactive/components/model-selector.js +21 -14
  52. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  53. package/dist/modes/interactive/components/oauth-selector.d.ts +3 -1
  54. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  55. package/dist/modes/interactive/components/oauth-selector.js +6 -6
  56. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  57. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  58. package/dist/modes/interactive/interactive-mode.js +53 -48
  59. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  60. package/docs/sdk.md +86 -61
  61. package/examples/custom-tools/hello/index.ts +15 -15
  62. package/examples/custom-tools/question/index.ts +3 -3
  63. package/examples/custom-tools/subagent/agents.ts +1 -2
  64. package/examples/custom-tools/subagent/index.ts +332 -125
  65. package/examples/custom-tools/todo/index.ts +30 -12
  66. package/examples/hooks/confirm-destructive.ts +5 -7
  67. package/examples/hooks/custom-compaction.ts +7 -7
  68. package/examples/hooks/dirty-repo-guard.ts +5 -9
  69. package/examples/hooks/permission-gate.ts +1 -5
  70. package/examples/sdk/02-custom-model.ts +20 -7
  71. package/examples/sdk/04-skills.ts +1 -1
  72. package/examples/sdk/05-tools.ts +11 -14
  73. package/examples/sdk/06-hooks.ts +1 -1
  74. package/examples/sdk/07-context-files.ts +1 -1
  75. package/examples/sdk/08-slash-commands.ts +3 -3
  76. package/examples/sdk/09-api-keys-and-oauth.ts +36 -26
  77. package/examples/sdk/10-settings.ts +2 -2
  78. package/examples/sdk/12-full-control.ts +19 -20
  79. package/examples/sdk/README.md +26 -13
  80. package/package.json +4 -5
  81. package/dist/core/model-config.d.ts +0 -58
  82. package/dist/core/model-config.d.ts.map +0 -1
  83. package/dist/core/model-config.js +0 -384
  84. package/dist/core/model-config.js.map +0 -1
  85. package/dist/core/oauth/index.d.ts +0 -41
  86. package/dist/core/oauth/index.d.ts.map +0 -1
  87. package/dist/core/oauth/index.js +0 -84
  88. package/dist/core/oauth/index.js.map +0 -1
@@ -7,10 +7,8 @@ import * as os from "node:os";
7
7
  import * as path from "node:path";
8
8
  import { CombinedAutocompleteProvider, Container, getCapabilities, Input, Loader, Markdown, ProcessTerminal, Spacer, Text, TruncatedText, TUI, visibleWidth, } from "@mariozechner/pi-tui";
9
9
  import { exec, spawnSync } from "child_process";
10
- import { APP_NAME, getDebugLogPath, getOAuthPath } from "../../config.js";
10
+ import { APP_NAME, getAuthPath, getDebugLogPath } from "../../config.js";
11
11
  import { isBashExecutionMessage } from "../../core/messages.js";
12
- import { invalidateOAuthCache } from "../../core/model-config.js";
13
- import { listOAuthProviders, login, logout } from "../../core/oauth/index.js";
14
12
  import { getLatestCompactionEntry, SessionManager, SUMMARY_PREFIX, SUMMARY_SUFFIX, } from "../../core/session-manager.js";
15
13
  import { loadSkills } from "../../core/skills.js";
16
14
  import { loadProjectContextFiles } from "../../core/system-prompt.js";
@@ -105,7 +103,7 @@ export class InteractiveMode {
105
103
  this.editor = new CustomEditor(getEditorTheme());
106
104
  this.editorContainer = new Container();
107
105
  this.editorContainer.addChild(this.editor);
108
- this.footer = new FooterComponent(session.state);
106
+ this.footer = new FooterComponent(session.state, session.modelRegistry);
109
107
  this.footer.setAutoCompactEnabled(session.autoCompactionEnabled);
110
108
  // Define slash commands for autocomplete
111
109
  const slashCommands = [
@@ -1261,7 +1259,7 @@ export class InteractiveMode {
1261
1259
  }
1262
1260
  showModelSelector() {
1263
1261
  this.showSelector((done) => {
1264
- const selector = new ModelSelectorComponent(this.ui, this.session.model, this.settingsManager, this.session.scopedModels, async (model) => {
1262
+ const selector = new ModelSelectorComponent(this.ui, this.session.model, this.settingsManager, this.session.modelRegistry, this.session.scopedModels, async (model) => {
1265
1263
  try {
1266
1264
  await this.session.setModel(model);
1267
1265
  this.footer.updateState(this.session.state);
@@ -1344,62 +1342,68 @@ export class InteractiveMode {
1344
1342
  }
1345
1343
  async showOAuthSelector(mode) {
1346
1344
  if (mode === "logout") {
1347
- const loggedInProviders = listOAuthProviders();
1345
+ const providers = this.session.modelRegistry.authStorage.list();
1346
+ const loggedInProviders = providers.filter((p) => this.session.modelRegistry.authStorage.get(p)?.type === "oauth");
1348
1347
  if (loggedInProviders.length === 0) {
1349
1348
  this.showStatus("No OAuth providers logged in. Use /login first.");
1350
1349
  return;
1351
1350
  }
1352
1351
  }
1353
1352
  this.showSelector((done) => {
1354
- const selector = new OAuthSelectorComponent(mode, async (providerId) => {
1353
+ const selector = new OAuthSelectorComponent(mode, this.session.modelRegistry.authStorage, async (providerId) => {
1355
1354
  done();
1356
1355
  if (mode === "login") {
1357
1356
  this.showStatus(`Logging in to ${providerId}...`);
1358
1357
  try {
1359
- await login(providerId, (info) => {
1360
- this.chatContainer.addChild(new Spacer(1));
1361
- this.chatContainer.addChild(new Text(theme.fg("accent", "Opening browser to:"), 1, 0));
1362
- this.chatContainer.addChild(new Text(theme.fg("accent", info.url), 1, 0));
1363
- if (info.instructions) {
1358
+ await this.session.modelRegistry.authStorage.login(providerId, {
1359
+ onAuth: (info) => {
1364
1360
  this.chatContainer.addChild(new Spacer(1));
1365
- this.chatContainer.addChild(new Text(theme.fg("warning", info.instructions), 1, 0));
1366
- }
1367
- this.ui.requestRender();
1368
- const openCmd = process.platform === "darwin"
1369
- ? "open"
1370
- : process.platform === "win32"
1371
- ? "start"
1372
- : "xdg-open";
1373
- exec(`${openCmd} "${info.url}"`);
1374
- }, async (prompt) => {
1375
- this.chatContainer.addChild(new Spacer(1));
1376
- this.chatContainer.addChild(new Text(theme.fg("warning", prompt.message), 1, 0));
1377
- if (prompt.placeholder) {
1378
- this.chatContainer.addChild(new Text(theme.fg("dim", prompt.placeholder), 1, 0));
1379
- }
1380
- this.ui.requestRender();
1381
- return new Promise((resolve) => {
1382
- const codeInput = new Input();
1383
- codeInput.onSubmit = () => {
1384
- const code = codeInput.getValue();
1361
+ this.chatContainer.addChild(new Text(theme.fg("accent", "Opening browser to:"), 1, 0));
1362
+ this.chatContainer.addChild(new Text(theme.fg("accent", info.url), 1, 0));
1363
+ if (info.instructions) {
1364
+ this.chatContainer.addChild(new Spacer(1));
1365
+ this.chatContainer.addChild(new Text(theme.fg("warning", info.instructions), 1, 0));
1366
+ }
1367
+ this.ui.requestRender();
1368
+ const openCmd = process.platform === "darwin"
1369
+ ? "open"
1370
+ : process.platform === "win32"
1371
+ ? "start"
1372
+ : "xdg-open";
1373
+ exec(`${openCmd} "${info.url}"`);
1374
+ },
1375
+ onPrompt: async (prompt) => {
1376
+ this.chatContainer.addChild(new Spacer(1));
1377
+ this.chatContainer.addChild(new Text(theme.fg("warning", prompt.message), 1, 0));
1378
+ if (prompt.placeholder) {
1379
+ this.chatContainer.addChild(new Text(theme.fg("dim", prompt.placeholder), 1, 0));
1380
+ }
1381
+ this.ui.requestRender();
1382
+ return new Promise((resolve) => {
1383
+ const codeInput = new Input();
1384
+ codeInput.onSubmit = () => {
1385
+ const code = codeInput.getValue();
1386
+ this.editorContainer.clear();
1387
+ this.editorContainer.addChild(this.editor);
1388
+ this.ui.setFocus(this.editor);
1389
+ resolve(code);
1390
+ };
1385
1391
  this.editorContainer.clear();
1386
- this.editorContainer.addChild(this.editor);
1387
- this.ui.setFocus(this.editor);
1388
- resolve(code);
1389
- };
1390
- this.editorContainer.clear();
1391
- this.editorContainer.addChild(codeInput);
1392
- this.ui.setFocus(codeInput);
1392
+ this.editorContainer.addChild(codeInput);
1393
+ this.ui.setFocus(codeInput);
1394
+ this.ui.requestRender();
1395
+ });
1396
+ },
1397
+ onProgress: (message) => {
1398
+ this.chatContainer.addChild(new Text(theme.fg("dim", message), 1, 0));
1393
1399
  this.ui.requestRender();
1394
- });
1395
- }, (message) => {
1396
- this.chatContainer.addChild(new Text(theme.fg("dim", message), 1, 0));
1397
- this.ui.requestRender();
1400
+ },
1398
1401
  });
1399
- invalidateOAuthCache();
1402
+ // Refresh models to pick up new baseUrl (e.g., github-copilot)
1403
+ this.session.modelRegistry.refresh();
1400
1404
  this.chatContainer.addChild(new Spacer(1));
1401
1405
  this.chatContainer.addChild(new Text(theme.fg("success", `✓ Successfully logged in to ${providerId}`), 1, 0));
1402
- this.chatContainer.addChild(new Text(theme.fg("dim", `Tokens saved to ${getOAuthPath()}`), 1, 0));
1406
+ this.chatContainer.addChild(new Text(theme.fg("dim", `Credentials saved to ${getAuthPath()}`), 1, 0));
1403
1407
  this.ui.requestRender();
1404
1408
  }
1405
1409
  catch (error) {
@@ -1408,11 +1412,12 @@ export class InteractiveMode {
1408
1412
  }
1409
1413
  else {
1410
1414
  try {
1411
- await logout(providerId);
1412
- invalidateOAuthCache();
1415
+ this.session.modelRegistry.authStorage.logout(providerId);
1416
+ // Refresh models to reset baseUrl
1417
+ this.session.modelRegistry.refresh();
1413
1418
  this.chatContainer.addChild(new Spacer(1));
1414
1419
  this.chatContainer.addChild(new Text(theme.fg("success", `✓ Successfully logged out of ${providerId}`), 1, 0));
1415
- this.chatContainer.addChild(new Text(theme.fg("dim", `Credentials removed from ${getOAuthPath()}`), 1, 0));
1420
+ this.chatContainer.addChild(new Text(theme.fg("dim", `Credentials removed from ${getAuthPath()}`), 1, 0));
1416
1421
  this.ui.requestRender();
1417
1422
  }
1418
1423
  catch (error) {