gsd-pi 2.8.2 → 2.9.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.
- package/README.md +2 -1
- package/dist/cli.js +5 -0
- package/dist/loader.js +1 -1
- package/dist/update-check.d.ts +24 -0
- package/dist/update-check.js +93 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/extensions/types.d.ts +4 -2
- package/node_modules/@gsd/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/client.d.ts +46 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/client.js +758 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/client.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/config.d.ts +23 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/config.js +267 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/config.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/edits.d.ts +17 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/edits.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/edits.js +101 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/edits.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/helpers.d.ts +15 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/helpers.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/helpers.js +46 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/helpers.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/index.d.ts +35 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/index.js +709 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/index.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lsp-integration.test.d.ts +2 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lsp-integration.test.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +308 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lspmux.d.ts +34 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lspmux.js +136 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/types.d.ts +262 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/types.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/types.js +64 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/types.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/utils.d.ts +50 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/utils.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/utils.js +574 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/utils.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/core/slash-commands.js +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/core/tools/index.d.ts +13 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/core/tools/index.js +4 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/tools/index.js.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +10 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +2 -2
- package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/interactive-mode.js +80 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +5 -0
- package/node_modules/@gsd/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/src/core/extensions/types.ts +4 -2
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/client.ts +880 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/config.ts +325 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/defaults.json +456 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/edits.ts +109 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/helpers.ts +54 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/index.ts +943 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +407 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/lsp.md +33 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/lspmux.ts +199 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/types.ts +421 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/utils.ts +682 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/slash-commands.ts +1 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/tools/index.ts +10 -0
- package/node_modules/@gsd/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +2 -2
- package/node_modules/@gsd/pi-coding-agent/src/modes/interactive/interactive-mode.ts +94 -2
- package/node_modules/@gsd/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -2
- package/node_modules/@gsd/pi-coding-agent/src/modes/rpc/rpc-types.ts +2 -1
- package/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +4 -2
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/client.d.ts +46 -0
- package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/client.js +758 -0
- package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/config.d.ts +23 -0
- package/packages/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/config.js +267 -0
- package/packages/pi-coding-agent/dist/core/lsp/config.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/edits.d.ts +17 -0
- package/packages/pi-coding-agent/dist/core/lsp/edits.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/edits.js +101 -0
- package/packages/pi-coding-agent/dist/core/lsp/edits.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/helpers.d.ts +15 -0
- package/packages/pi-coding-agent/dist/core/lsp/helpers.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/helpers.js +46 -0
- package/packages/pi-coding-agent/dist/core/lsp/helpers.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/index.d.ts +35 -0
- package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/index.js +709 -0
- package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +308 -0
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts +34 -0
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +136 -0
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/types.d.ts +262 -0
- package/packages/pi-coding-agent/dist/core/lsp/types.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/types.js +64 -0
- package/packages/pi-coding-agent/dist/core/lsp/types.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts +50 -0
- package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/utils.js +574 -0
- package/packages/pi-coding-agent/dist/core/lsp/utils.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
- package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts +13 -0
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.js +4 -0
- package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +10 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +80 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +5 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
- package/packages/pi-coding-agent/src/core/extensions/types.ts +4 -2
- package/packages/pi-coding-agent/src/core/lsp/client.ts +880 -0
- package/packages/pi-coding-agent/src/core/lsp/config.ts +325 -0
- package/packages/pi-coding-agent/src/core/lsp/defaults.json +456 -0
- package/packages/pi-coding-agent/src/core/lsp/edits.ts +109 -0
- package/packages/pi-coding-agent/src/core/lsp/helpers.ts +54 -0
- package/packages/pi-coding-agent/src/core/lsp/index.ts +943 -0
- package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +407 -0
- package/packages/pi-coding-agent/src/core/lsp/lsp.md +33 -0
- package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +199 -0
- package/packages/pi-coding-agent/src/core/lsp/types.ts +421 -0
- package/packages/pi-coding-agent/src/core/lsp/utils.ts +682 -0
- package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
- package/packages/pi-coding-agent/src/core/tools/index.ts +10 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +2 -2
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +94 -2
- package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -2
- package/packages/pi-coding-agent/src/modes/rpc/rpc-types.ts +2 -1
- package/src/resources/extensions/ask-user-questions.ts +42 -2
- package/src/resources/extensions/bg-shell/index.ts +34 -37
- package/src/resources/extensions/browser-tools/core.d.ts +205 -0
- package/src/resources/extensions/browser-tools/index.ts +2 -2
- package/src/resources/extensions/browser-tools/refs.ts +1 -1
- package/src/resources/extensions/browser-tools/tools/session.ts +1 -1
- package/src/resources/extensions/context7/index.ts +2 -2
- package/src/resources/extensions/get-secrets-from-user.ts +3 -2
- package/src/resources/extensions/google-search/index.ts +1 -1
- package/src/resources/extensions/gsd/auto.ts +126 -12
- package/src/resources/extensions/gsd/commands.ts +218 -3
- package/src/resources/extensions/gsd/doctor.ts +1 -1
- package/src/resources/extensions/gsd/git-service.ts +163 -13
- package/src/resources/extensions/gsd/guided-flow.ts +19 -9
- package/src/resources/extensions/gsd/index.ts +17 -7
- package/src/resources/extensions/gsd/preferences.ts +1 -1
- package/src/resources/extensions/gsd/tests/git-service.test.ts +226 -0
- package/src/resources/extensions/gsd/tests/migrate-command.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +10 -10
- package/src/resources/extensions/gsd/tests/next-milestone-id.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/worktree.test.ts +352 -0
- package/src/resources/extensions/gsd/types.ts +1 -0
- package/src/resources/extensions/gsd/worktree.ts +20 -1
- package/src/resources/extensions/mac-tools/index.ts +1 -1
- package/src/resources/extensions/search-the-web/command-search-provider.ts +1 -1
- package/src/resources/extensions/search-the-web/format.ts +1 -1
- package/src/resources/extensions/search-the-web/index.ts +5 -5
- package/src/resources/extensions/search-the-web/native-search.ts +5 -6
- package/src/resources/extensions/search-the-web/tool-fetch-page.ts +7 -7
- package/src/resources/extensions/search-the-web/tool-llm-context.ts +11 -11
- package/src/resources/extensions/search-the-web/tool-search.ts +10 -10
- package/src/resources/extensions/shared/interview-ui.ts +2 -2
|
@@ -65,6 +65,13 @@ export {
|
|
|
65
65
|
type WriteToolOptions,
|
|
66
66
|
writeTool,
|
|
67
67
|
} from "./write.js";
|
|
68
|
+
export {
|
|
69
|
+
createLspTool,
|
|
70
|
+
type LspToolDetails,
|
|
71
|
+
lspSchema,
|
|
72
|
+
lspTool,
|
|
73
|
+
} from "../lsp/index.js";
|
|
74
|
+
export type { LspServerStatus } from "../lsp/client.js";
|
|
68
75
|
|
|
69
76
|
import type { AgentTool } from "@gsd/pi-agent-core";
|
|
70
77
|
import { type BashToolOptions, bashTool, createBashTool } from "./bash.js";
|
|
@@ -74,6 +81,7 @@ import { createGrepTool, grepTool } from "./grep.js";
|
|
|
74
81
|
import { createLsTool, lsTool } from "./ls.js";
|
|
75
82
|
import { createReadTool, type ReadToolOptions, readTool } from "./read.js";
|
|
76
83
|
import { createWriteTool, writeTool } from "./write.js";
|
|
84
|
+
import { createLspTool, lspTool } from "../lsp/index.js";
|
|
77
85
|
|
|
78
86
|
/** Tool type (AgentTool from pi-ai) */
|
|
79
87
|
export type Tool = AgentTool<any>;
|
|
@@ -93,6 +101,7 @@ export const allTools = {
|
|
|
93
101
|
grep: grepTool,
|
|
94
102
|
find: findTool,
|
|
95
103
|
ls: lsTool,
|
|
104
|
+
lsp: lspTool,
|
|
96
105
|
};
|
|
97
106
|
|
|
98
107
|
export type ToolName = keyof typeof allTools;
|
|
@@ -135,5 +144,6 @@ export function createAllTools(cwd: string, options?: ToolsOptions): Record<Tool
|
|
|
135
144
|
grep: createGrepTool(cwd),
|
|
136
145
|
find: createFindTool(cwd),
|
|
137
146
|
ls: createLsTool(cwd),
|
|
147
|
+
lsp: createLspTool(cwd),
|
|
138
148
|
};
|
|
139
149
|
}
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import { getSelectListTheme, getSettingsListTheme, theme } from "../theme/theme.js";
|
|
14
14
|
import { DynamicBorder } from "./dynamic-border.js";
|
|
15
15
|
|
|
16
|
-
const THINKING_DESCRIPTIONS: Record<ThinkingLevel, string> = {
|
|
16
|
+
export const THINKING_DESCRIPTIONS: Record<ThinkingLevel, string> = {
|
|
17
17
|
off: "No reasoning",
|
|
18
18
|
minimal: "Very brief reasoning (~1k tokens)",
|
|
19
19
|
low: "Light reasoning (~2k tokens)",
|
|
@@ -73,7 +73,7 @@ export interface SettingsCallbacks {
|
|
|
73
73
|
/**
|
|
74
74
|
* A submenu component for selecting from a list of options.
|
|
75
75
|
*/
|
|
76
|
-
class SelectSubmenu extends Container {
|
|
76
|
+
export class SelectSubmenu extends Container {
|
|
77
77
|
private selectList: SelectList;
|
|
78
78
|
|
|
79
79
|
constructor(
|
|
@@ -7,7 +7,7 @@ import * as crypto from "node:crypto";
|
|
|
7
7
|
import * as fs from "node:fs";
|
|
8
8
|
import * as os from "node:os";
|
|
9
9
|
import * as path from "node:path";
|
|
10
|
-
import type { AgentMessage } from "@gsd/pi-agent-core";
|
|
10
|
+
import type { AgentMessage, ThinkingLevel } from "@gsd/pi-agent-core";
|
|
11
11
|
import type { AssistantMessage, ImageContent, Message, Model, OAuthProviderId } from "@gsd/pi-ai";
|
|
12
12
|
import type {
|
|
13
13
|
AutocompleteItem,
|
|
@@ -85,7 +85,7 @@ import { ModelSelectorComponent } from "./components/model-selector.js";
|
|
|
85
85
|
import { OAuthSelectorComponent } from "./components/oauth-selector.js";
|
|
86
86
|
import { ScopedModelsSelectorComponent } from "./components/scoped-models-selector.js";
|
|
87
87
|
import { SessionSelectorComponent } from "./components/session-selector.js";
|
|
88
|
-
import { SettingsSelectorComponent } from "./components/settings-selector.js";
|
|
88
|
+
import { SelectSubmenu, SettingsSelectorComponent, THINKING_DESCRIPTIONS } from "./components/settings-selector.js";
|
|
89
89
|
import { SkillInvocationMessageComponent } from "./components/skill-invocation-message.js";
|
|
90
90
|
import { ToolExecutionComponent } from "./components/tool-execution.js";
|
|
91
91
|
import { TreeSelectorComponent } from "./components/tree-selector.js";
|
|
@@ -2015,6 +2015,12 @@ export class InteractiveMode {
|
|
|
2015
2015
|
await this.handleReloadCommand();
|
|
2016
2016
|
return;
|
|
2017
2017
|
}
|
|
2018
|
+
if (text === "/thinking" || text.startsWith("/thinking ")) {
|
|
2019
|
+
const arg = text.startsWith("/thinking ") ? text.slice(10).trim() : undefined;
|
|
2020
|
+
this.editor.setText("");
|
|
2021
|
+
this.handleThinkingCommand(arg);
|
|
2022
|
+
return;
|
|
2023
|
+
}
|
|
2018
2024
|
if (text === "/debug") {
|
|
2019
2025
|
this.handleDebugCommand();
|
|
2020
2026
|
this.editor.setText("");
|
|
@@ -2745,6 +2751,57 @@ export class InteractiveMode {
|
|
|
2745
2751
|
}
|
|
2746
2752
|
}
|
|
2747
2753
|
|
|
2754
|
+
private handleThinkingCommand(arg?: string): void {
|
|
2755
|
+
if (!this.session.supportsThinking()) {
|
|
2756
|
+
this.showStatus("Current model does not support thinking");
|
|
2757
|
+
return;
|
|
2758
|
+
}
|
|
2759
|
+
|
|
2760
|
+
const availableLevels = this.session.getAvailableThinkingLevels();
|
|
2761
|
+
|
|
2762
|
+
if (arg) {
|
|
2763
|
+
const level = arg.toLowerCase();
|
|
2764
|
+
if (!availableLevels.includes(level as ThinkingLevel)) {
|
|
2765
|
+
this.showStatus(`Invalid thinking level "${arg}". Available: ${availableLevels.join(", ")}`);
|
|
2766
|
+
return;
|
|
2767
|
+
}
|
|
2768
|
+
this.session.setThinkingLevel(level as ThinkingLevel);
|
|
2769
|
+
this.footer.invalidate();
|
|
2770
|
+
this.updateEditorBorderColor();
|
|
2771
|
+
this.showStatus(`Thinking level: ${level}`);
|
|
2772
|
+
return;
|
|
2773
|
+
}
|
|
2774
|
+
|
|
2775
|
+
this.showThinkingSelector();
|
|
2776
|
+
}
|
|
2777
|
+
|
|
2778
|
+
private showThinkingSelector(): void {
|
|
2779
|
+
const availableLevels = this.session.getAvailableThinkingLevels();
|
|
2780
|
+
this.showSelector((done) => {
|
|
2781
|
+
const selector = new SelectSubmenu(
|
|
2782
|
+
"Thinking Level",
|
|
2783
|
+
"Select reasoning depth for thinking-capable models",
|
|
2784
|
+
availableLevels.map((level) => ({
|
|
2785
|
+
value: level,
|
|
2786
|
+
label: level,
|
|
2787
|
+
description: THINKING_DESCRIPTIONS[level],
|
|
2788
|
+
})),
|
|
2789
|
+
this.session.thinkingLevel,
|
|
2790
|
+
(value) => {
|
|
2791
|
+
this.session.setThinkingLevel(value as ThinkingLevel);
|
|
2792
|
+
this.footer.invalidate();
|
|
2793
|
+
this.updateEditorBorderColor();
|
|
2794
|
+
done();
|
|
2795
|
+
this.showStatus(`Thinking level: ${value}`);
|
|
2796
|
+
},
|
|
2797
|
+
() => {
|
|
2798
|
+
done();
|
|
2799
|
+
},
|
|
2800
|
+
);
|
|
2801
|
+
return { component: selector, focus: selector };
|
|
2802
|
+
});
|
|
2803
|
+
}
|
|
2804
|
+
|
|
2748
2805
|
private async cycleModel(direction: "forward" | "backward"): Promise<void> {
|
|
2749
2806
|
try {
|
|
2750
2807
|
const result = await this.session.cycleModel(direction);
|
|
@@ -3695,6 +3752,21 @@ export class InteractiveMode {
|
|
|
3695
3752
|
this.session.modelRegistry.authStorage.logout(providerId);
|
|
3696
3753
|
this.session.modelRegistry.refresh();
|
|
3697
3754
|
await this.updateAvailableProviderCount();
|
|
3755
|
+
|
|
3756
|
+
// Auto-switch model if current model belongs to the logged-out provider
|
|
3757
|
+
const currentModel = this.session.model;
|
|
3758
|
+
if (currentModel?.provider === providerId) {
|
|
3759
|
+
try {
|
|
3760
|
+
const available = this.session.modelRegistry.getAvailable();
|
|
3761
|
+
const fallback = available.find((m) => m.provider !== providerId);
|
|
3762
|
+
if (fallback) {
|
|
3763
|
+
await this.session.setModel(fallback);
|
|
3764
|
+
}
|
|
3765
|
+
} catch {
|
|
3766
|
+
// Model switch failed — user can manually switch via /model
|
|
3767
|
+
}
|
|
3768
|
+
}
|
|
3769
|
+
|
|
3698
3770
|
this.showStatus(`Logged out of ${providerName}`);
|
|
3699
3771
|
} catch (error: unknown) {
|
|
3700
3772
|
this.showError(`Logout failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -3789,6 +3861,26 @@ export class InteractiveMode {
|
|
|
3789
3861
|
restoreEditor();
|
|
3790
3862
|
this.session.modelRegistry.refresh();
|
|
3791
3863
|
await this.updateAvailableProviderCount();
|
|
3864
|
+
|
|
3865
|
+
// Auto-switch model if current model has no valid API key
|
|
3866
|
+
try {
|
|
3867
|
+
const currentModel = this.session.model;
|
|
3868
|
+
if (currentModel) {
|
|
3869
|
+
const currentKey = await this.session.modelRegistry.getApiKey(currentModel);
|
|
3870
|
+
if (!currentKey) {
|
|
3871
|
+
const available = this.session.modelRegistry.getAvailable();
|
|
3872
|
+
const newProviderModel = available.find((m) => m.provider === providerId);
|
|
3873
|
+
if (newProviderModel) {
|
|
3874
|
+
await this.session.setModel(newProviderModel);
|
|
3875
|
+
} else if (available.length > 0) {
|
|
3876
|
+
await this.session.setModel(available[0]);
|
|
3877
|
+
}
|
|
3878
|
+
}
|
|
3879
|
+
}
|
|
3880
|
+
} catch (error: unknown) {
|
|
3881
|
+
// Model switch failed — user can manually switch via /model
|
|
3882
|
+
}
|
|
3883
|
+
|
|
3792
3884
|
this.showStatus(`Logged in to ${providerName}. Credentials saved to ${getAuthPath()}`);
|
|
3793
3885
|
} catch (error: unknown) {
|
|
3794
3886
|
restoreEditor();
|
|
@@ -119,8 +119,8 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
|
|
|
119
119
|
*/
|
|
120
120
|
const createExtensionUIContext = (): ExtensionUIContext => ({
|
|
121
121
|
select: (title, options, opts) =>
|
|
122
|
-
createDialogPromise(opts, undefined, { method: "select", title, options, timeout: opts?.timeout }, (r) =>
|
|
123
|
-
"cancelled" in r && r.cancelled ? undefined : "value" in r ? r.value : undefined,
|
|
122
|
+
createDialogPromise(opts, undefined, { method: "select", title, options, timeout: opts?.timeout, allowMultiple: opts?.allowMultiple }, (r) =>
|
|
123
|
+
"cancelled" in r && r.cancelled ? undefined : "values" in r ? r.values : "value" in r ? r.value : undefined,
|
|
124
124
|
),
|
|
125
125
|
|
|
126
126
|
confirm: (title, message, opts) =>
|
|
@@ -210,7 +210,7 @@ export type RpcResponse =
|
|
|
210
210
|
|
|
211
211
|
/** Emitted when an extension needs user input */
|
|
212
212
|
export type RpcExtensionUIRequest =
|
|
213
|
-
| { type: "extension_ui_request"; id: string; method: "select"; title: string; options: string[]; timeout?: number }
|
|
213
|
+
| { type: "extension_ui_request"; id: string; method: "select"; title: string; options: string[]; timeout?: number; allowMultiple?: boolean }
|
|
214
214
|
| { type: "extension_ui_request"; id: string; method: "confirm"; title: string; message: string; timeout?: number }
|
|
215
215
|
| {
|
|
216
216
|
type: "extension_ui_request";
|
|
@@ -253,6 +253,7 @@ export type RpcExtensionUIRequest =
|
|
|
253
253
|
/** Response to an extension UI request */
|
|
254
254
|
export type RpcExtensionUIResponse =
|
|
255
255
|
| { type: "extension_ui_response"; id: string; value: string }
|
|
256
|
+
| { type: "extension_ui_response"; id: string; values: string[] }
|
|
256
257
|
| { type: "extension_ui_response"; id: string; confirmed: boolean }
|
|
257
258
|
| { type: "extension_ui_response"; id: string; cancelled: true };
|
|
258
259
|
|
|
@@ -137,12 +137,52 @@ export default function AskUserQuestions(pi: ExtensionAPI) {
|
|
|
137
137
|
if (!ctx.hasUI) {
|
|
138
138
|
const { tryRemoteQuestions } = await import("./remote-questions/manager.js");
|
|
139
139
|
const remoteResult = await tryRemoteQuestions(params.questions, signal);
|
|
140
|
-
if (remoteResult) return remoteResult;
|
|
140
|
+
if (remoteResult) return { ...remoteResult, details: remoteResult.details as unknown };
|
|
141
141
|
return errorResult("Error: UI not available (non-interactive mode)", params.questions);
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
// Delegate to shared interview UI
|
|
145
|
-
const result = await showInterviewRound(params.questions, {}, ctx);
|
|
145
|
+
const result = await showInterviewRound(params.questions, {}, ctx as any);
|
|
146
|
+
|
|
147
|
+
// RPC mode fallback: custom() returns undefined, so showInterviewRound
|
|
148
|
+
// may return undefined. Fall back to sequential ctx.ui.select() calls.
|
|
149
|
+
if (!result) {
|
|
150
|
+
const answers: Record<string, { answers: string[] }> = {};
|
|
151
|
+
for (const q of params.questions) {
|
|
152
|
+
const options = q.options.map((o) => o.label);
|
|
153
|
+
if (!q.allowMultiple) {
|
|
154
|
+
options.push(OTHER_OPTION_LABEL);
|
|
155
|
+
}
|
|
156
|
+
const selected = await ctx.ui.select(
|
|
157
|
+
`${q.header}: ${q.question}`,
|
|
158
|
+
options,
|
|
159
|
+
{ signal, ...(q.allowMultiple ? { allowMultiple: true } : {}) },
|
|
160
|
+
);
|
|
161
|
+
if (selected === undefined) {
|
|
162
|
+
return errorResult("ask_user_questions was cancelled", params.questions);
|
|
163
|
+
}
|
|
164
|
+
answers[q.id] = {
|
|
165
|
+
answers: Array.isArray(selected) ? selected : [selected],
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
const roundResult: RoundResult = {
|
|
169
|
+
endInterview: false,
|
|
170
|
+
answers: Object.fromEntries(
|
|
171
|
+
Object.entries(answers).map(([id, a]) => [
|
|
172
|
+
id,
|
|
173
|
+
{ selected: a.answers.length === 1 ? a.answers[0] : a.answers, notes: "" },
|
|
174
|
+
]),
|
|
175
|
+
),
|
|
176
|
+
};
|
|
177
|
+
return {
|
|
178
|
+
content: [{ type: "text" as const, text: JSON.stringify({ answers }) }],
|
|
179
|
+
details: {
|
|
180
|
+
questions: params.questions,
|
|
181
|
+
response: roundResult,
|
|
182
|
+
cancelled: false,
|
|
183
|
+
} satisfies LocalResultDetails,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
146
186
|
|
|
147
187
|
// Check if cancelled (empty answers = user exited)
|
|
148
188
|
const hasAnswers = Object.keys(result.answers).length > 0;
|
|
@@ -1261,7 +1261,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1261
1261
|
if (!params.command) {
|
|
1262
1262
|
return {
|
|
1263
1263
|
content: [{ type: "text" as const, text: "Error: 'command' is required for start" }],
|
|
1264
|
-
isError: true,
|
|
1264
|
+
isError: true, details: undefined as unknown,
|
|
1265
1265
|
};
|
|
1266
1266
|
}
|
|
1267
1267
|
|
|
@@ -1316,7 +1316,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1316
1316
|
if (!bg) {
|
|
1317
1317
|
return {
|
|
1318
1318
|
content: [{ type: "text" as const, text: `Error: No process found with id '${params.id}'` }],
|
|
1319
|
-
isError: true,
|
|
1319
|
+
isError: true, details: undefined as unknown,
|
|
1320
1320
|
};
|
|
1321
1321
|
}
|
|
1322
1322
|
const digest = generateDigest(bg, true);
|
|
@@ -1356,7 +1356,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1356
1356
|
if (!params.id) {
|
|
1357
1357
|
return {
|
|
1358
1358
|
content: [{ type: "text" as const, text: "Error: 'id' is required for highlights" }],
|
|
1359
|
-
isError: true,
|
|
1359
|
+
isError: true, details: undefined as unknown,
|
|
1360
1360
|
};
|
|
1361
1361
|
}
|
|
1362
1362
|
|
|
@@ -1364,7 +1364,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1364
1364
|
if (!bg) {
|
|
1365
1365
|
return {
|
|
1366
1366
|
content: [{ type: "text" as const, text: `Error: No process found with id '${params.id}'` }],
|
|
1367
|
-
isError: true,
|
|
1367
|
+
isError: true, details: undefined as unknown,
|
|
1368
1368
|
};
|
|
1369
1369
|
}
|
|
1370
1370
|
|
|
@@ -1388,7 +1388,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1388
1388
|
if (!params.id) {
|
|
1389
1389
|
return {
|
|
1390
1390
|
content: [{ type: "text" as const, text: "Error: 'id' is required for output" }],
|
|
1391
|
-
isError: true,
|
|
1391
|
+
isError: true, details: undefined as unknown,
|
|
1392
1392
|
};
|
|
1393
1393
|
}
|
|
1394
1394
|
|
|
@@ -1396,7 +1396,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1396
1396
|
if (!bg) {
|
|
1397
1397
|
return {
|
|
1398
1398
|
content: [{ type: "text" as const, text: `Error: No process found with id '${params.id}'` }],
|
|
1399
|
-
isError: true,
|
|
1399
|
+
isError: true, details: undefined as unknown,
|
|
1400
1400
|
};
|
|
1401
1401
|
}
|
|
1402
1402
|
|
|
@@ -1429,7 +1429,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1429
1429
|
if (!params.id) {
|
|
1430
1430
|
return {
|
|
1431
1431
|
content: [{ type: "text" as const, text: "Error: 'id' is required for wait_for_ready" }],
|
|
1432
|
-
isError: true,
|
|
1432
|
+
isError: true, details: undefined as unknown,
|
|
1433
1433
|
};
|
|
1434
1434
|
}
|
|
1435
1435
|
|
|
@@ -1437,7 +1437,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1437
1437
|
if (!bg) {
|
|
1438
1438
|
return {
|
|
1439
1439
|
content: [{ type: "text" as const, text: `Error: No process found with id '${params.id}'` }],
|
|
1440
|
-
isError: true,
|
|
1440
|
+
isError: true, details: undefined as unknown,
|
|
1441
1441
|
};
|
|
1442
1442
|
}
|
|
1443
1443
|
|
|
@@ -1472,13 +1472,13 @@ export default function (pi: ExtensionAPI) {
|
|
|
1472
1472
|
if (!params.id) {
|
|
1473
1473
|
return {
|
|
1474
1474
|
content: [{ type: "text" as const, text: "Error: 'id' is required for send" }],
|
|
1475
|
-
isError: true,
|
|
1475
|
+
isError: true, details: undefined as unknown,
|
|
1476
1476
|
};
|
|
1477
1477
|
}
|
|
1478
1478
|
if (params.input === undefined) {
|
|
1479
1479
|
return {
|
|
1480
1480
|
content: [{ type: "text" as const, text: "Error: 'input' is required for send" }],
|
|
1481
|
-
isError: true,
|
|
1481
|
+
isError: true, details: undefined as unknown,
|
|
1482
1482
|
};
|
|
1483
1483
|
}
|
|
1484
1484
|
|
|
@@ -1486,14 +1486,14 @@ export default function (pi: ExtensionAPI) {
|
|
|
1486
1486
|
if (!bg) {
|
|
1487
1487
|
return {
|
|
1488
1488
|
content: [{ type: "text" as const, text: `Error: No process found with id '${params.id}'` }],
|
|
1489
|
-
isError: true,
|
|
1489
|
+
isError: true, details: undefined as unknown,
|
|
1490
1490
|
};
|
|
1491
1491
|
}
|
|
1492
1492
|
|
|
1493
1493
|
if (!bg.alive) {
|
|
1494
1494
|
return {
|
|
1495
1495
|
content: [{ type: "text" as const, text: `Error: Process ${params.id} has already exited` }],
|
|
1496
|
-
isError: true,
|
|
1496
|
+
isError: true, details: undefined as unknown,
|
|
1497
1497
|
};
|
|
1498
1498
|
}
|
|
1499
1499
|
|
|
@@ -1506,7 +1506,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1506
1506
|
} catch (err) {
|
|
1507
1507
|
return {
|
|
1508
1508
|
content: [{ type: "text" as const, text: `Error writing to stdin: ${err instanceof Error ? err.message : String(err)}` }],
|
|
1509
|
-
isError: true,
|
|
1509
|
+
isError: true, details: undefined as unknown,
|
|
1510
1510
|
};
|
|
1511
1511
|
}
|
|
1512
1512
|
}
|
|
@@ -1516,19 +1516,19 @@ export default function (pi: ExtensionAPI) {
|
|
|
1516
1516
|
if (!params.id) {
|
|
1517
1517
|
return {
|
|
1518
1518
|
content: [{ type: "text" as const, text: "Error: 'id' is required for send_and_wait" }],
|
|
1519
|
-
isError: true,
|
|
1519
|
+
isError: true, details: undefined as unknown,
|
|
1520
1520
|
};
|
|
1521
1521
|
}
|
|
1522
1522
|
if (params.input === undefined) {
|
|
1523
1523
|
return {
|
|
1524
1524
|
content: [{ type: "text" as const, text: "Error: 'input' is required for send_and_wait" }],
|
|
1525
|
-
isError: true,
|
|
1525
|
+
isError: true, details: undefined as unknown,
|
|
1526
1526
|
};
|
|
1527
1527
|
}
|
|
1528
1528
|
if (!params.wait_pattern) {
|
|
1529
1529
|
return {
|
|
1530
1530
|
content: [{ type: "text" as const, text: "Error: 'wait_pattern' is required for send_and_wait" }],
|
|
1531
|
-
isError: true,
|
|
1531
|
+
isError: true, details: undefined as unknown,
|
|
1532
1532
|
};
|
|
1533
1533
|
}
|
|
1534
1534
|
|
|
@@ -1536,14 +1536,14 @@ export default function (pi: ExtensionAPI) {
|
|
|
1536
1536
|
if (!bg) {
|
|
1537
1537
|
return {
|
|
1538
1538
|
content: [{ type: "text" as const, text: `Error: No process found with id '${params.id}'` }],
|
|
1539
|
-
isError: true,
|
|
1539
|
+
isError: true, details: undefined as unknown,
|
|
1540
1540
|
};
|
|
1541
1541
|
}
|
|
1542
1542
|
|
|
1543
1543
|
if (!bg.alive) {
|
|
1544
1544
|
return {
|
|
1545
1545
|
content: [{ type: "text" as const, text: `Error: Process ${params.id} has already exited` }],
|
|
1546
|
-
isError: true,
|
|
1546
|
+
isError: true, details: undefined as unknown,
|
|
1547
1547
|
};
|
|
1548
1548
|
}
|
|
1549
1549
|
|
|
@@ -1568,7 +1568,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1568
1568
|
if (!params.id) {
|
|
1569
1569
|
return {
|
|
1570
1570
|
content: [{ type: "text" as const, text: "Error: 'id' is required for signal" }],
|
|
1571
|
-
isError: true,
|
|
1571
|
+
isError: true, details: undefined as unknown,
|
|
1572
1572
|
};
|
|
1573
1573
|
}
|
|
1574
1574
|
|
|
@@ -1576,7 +1576,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1576
1576
|
if (!bg) {
|
|
1577
1577
|
return {
|
|
1578
1578
|
content: [{ type: "text" as const, text: `Error: No process found with id '${params.id}'` }],
|
|
1579
|
-
isError: true,
|
|
1579
|
+
isError: true, details: undefined as unknown,
|
|
1580
1580
|
};
|
|
1581
1581
|
}
|
|
1582
1582
|
|
|
@@ -1621,7 +1621,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1621
1621
|
if (!params.id) {
|
|
1622
1622
|
return {
|
|
1623
1623
|
content: [{ type: "text" as const, text: "Error: 'id' is required for kill" }],
|
|
1624
|
-
isError: true,
|
|
1624
|
+
isError: true, details: undefined as unknown,
|
|
1625
1625
|
};
|
|
1626
1626
|
}
|
|
1627
1627
|
|
|
@@ -1629,7 +1629,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1629
1629
|
if (!bg) {
|
|
1630
1630
|
return {
|
|
1631
1631
|
content: [{ type: "text" as const, text: `Error: No process found with id '${params.id}'` }],
|
|
1632
|
-
isError: true,
|
|
1632
|
+
isError: true, details: undefined as unknown,
|
|
1633
1633
|
};
|
|
1634
1634
|
}
|
|
1635
1635
|
|
|
@@ -1657,7 +1657,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1657
1657
|
if (!params.id) {
|
|
1658
1658
|
return {
|
|
1659
1659
|
content: [{ type: "text" as const, text: "Error: 'id' is required for restart" }],
|
|
1660
|
-
isError: true,
|
|
1660
|
+
isError: true, details: undefined as unknown,
|
|
1661
1661
|
};
|
|
1662
1662
|
}
|
|
1663
1663
|
|
|
@@ -1665,7 +1665,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1665
1665
|
if (!newBg) {
|
|
1666
1666
|
return {
|
|
1667
1667
|
content: [{ type: "text" as const, text: `Error: No process found with id '${params.id}'` }],
|
|
1668
|
-
isError: true,
|
|
1668
|
+
isError: true, details: undefined as unknown,
|
|
1669
1669
|
};
|
|
1670
1670
|
}
|
|
1671
1671
|
|
|
@@ -1732,7 +1732,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1732
1732
|
default:
|
|
1733
1733
|
return {
|
|
1734
1734
|
content: [{ type: "text" as const, text: `Unknown action: ${params.action}` }],
|
|
1735
|
-
isError: true,
|
|
1735
|
+
isError: true, details: undefined as unknown,
|
|
1736
1736
|
};
|
|
1737
1737
|
}
|
|
1738
1738
|
},
|
|
@@ -1760,7 +1760,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1760
1760
|
|
|
1761
1761
|
const action = details.action as string;
|
|
1762
1762
|
|
|
1763
|
-
if (result.isError) {
|
|
1763
|
+
if ((result as any).isError) {
|
|
1764
1764
|
const text = result.content[0];
|
|
1765
1765
|
return new Text(
|
|
1766
1766
|
theme.fg("error", text?.type === "text" ? text.text : "Error"),
|
|
@@ -2338,17 +2338,14 @@ export default function (pi: ExtensionAPI) {
|
|
|
2338
2338
|
}, 2000);
|
|
2339
2339
|
|
|
2340
2340
|
// Refresh widget after agent actions and session events
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
refreshWidget();
|
|
2350
|
-
});
|
|
2351
|
-
}
|
|
2341
|
+
const refreshHandler = async (_event: unknown, ctx: ExtensionContext) => {
|
|
2342
|
+
latestCtx = ctx;
|
|
2343
|
+
refreshWidget();
|
|
2344
|
+
};
|
|
2345
|
+
pi.on("turn_end", refreshHandler as any);
|
|
2346
|
+
pi.on("agent_end", refreshHandler as any);
|
|
2347
|
+
pi.on("session_start", refreshHandler as any);
|
|
2348
|
+
pi.on("session_switch", refreshHandler as any);
|
|
2352
2349
|
|
|
2353
2350
|
pi.on("tool_execution_end", async (_event, ctx) => {
|
|
2354
2351
|
latestCtx = ctx;
|