pi-ui-extend 0.1.13 → 0.1.17
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 +1 -1
- package/dist/app/app.d.ts +7 -0
- package/dist/app/app.js +102 -17
- package/dist/app/commands/command-controller.js +2 -0
- package/dist/app/commands/command-host.d.ts +5 -0
- package/dist/app/commands/command-model-actions.d.ts +2 -0
- package/dist/app/commands/command-model-actions.js +40 -4
- package/dist/app/commands/command-navigation-actions.d.ts +9 -0
- package/dist/app/commands/command-navigation-actions.js +62 -0
- package/dist/app/commands/command-registry.d.ts +2 -0
- package/dist/app/commands/command-registry.js +16 -0
- package/dist/app/constants.d.ts +0 -1
- package/dist/app/constants.js +0 -1
- package/dist/app/extensions/extension-ui-controller.d.ts +16 -5
- package/dist/app/extensions/extension-ui-controller.js +99 -61
- package/dist/app/icons.d.ts +1 -0
- package/dist/app/icons.js +2 -0
- package/dist/app/input/input-action-controller.d.ts +2 -0
- package/dist/app/input/input-action-controller.js +8 -1
- package/dist/app/logger.d.ts +25 -0
- package/dist/app/logger.js +90 -0
- package/dist/app/model/model-usage-status.js +30 -15
- package/dist/app/popup/menu-items-controller.d.ts +4 -0
- package/dist/app/popup/menu-items-controller.js +68 -6
- package/dist/app/popup/popup-action-controller.d.ts +2 -1
- package/dist/app/popup/popup-action-controller.js +7 -4
- package/dist/app/popup/popup-menu-controller.d.ts +36 -23
- package/dist/app/popup/popup-menu-controller.js +97 -326
- package/dist/app/rendering/conversation-entry-renderer.js +3 -3
- package/dist/app/rendering/conversation-viewport.d.ts +10 -2
- package/dist/app/rendering/conversation-viewport.js +157 -16
- package/dist/app/rendering/editor-panels.js +22 -9
- package/dist/app/rendering/popup-menu-renderer.d.ts +62 -0
- package/dist/app/rendering/popup-menu-renderer.js +405 -0
- package/dist/app/rendering/render-controller.js +30 -28
- package/dist/app/rendering/render-text.js +5 -2
- package/dist/app/rendering/status-line-renderer.d.ts +8 -1
- package/dist/app/rendering/status-line-renderer.js +217 -117
- package/dist/app/rendering/toast-controller.d.ts +12 -3
- package/dist/app/rendering/toast-controller.js +70 -12
- package/dist/app/runtime.d.ts +2 -1
- package/dist/app/runtime.js +20 -10
- package/dist/app/screen/mouse-controller.d.ts +2 -2
- package/dist/app/screen/mouse-controller.js +27 -48
- package/dist/app/screen/screen-styler.d.ts +1 -1
- package/dist/app/screen/screen-styler.js +9 -7
- package/dist/app/screen/scroll-controller.d.ts +12 -9
- package/dist/app/screen/scroll-controller.js +56 -45
- package/dist/app/screen/status-controller.js +2 -1
- package/dist/app/session/lazy-session-manager.d.ts +11 -0
- package/dist/app/session/lazy-session-manager.js +539 -0
- package/dist/app/session/pix-system-message.d.ts +16 -0
- package/dist/app/session/pix-system-message.js +64 -0
- package/dist/app/session/request-history.d.ts +4 -0
- package/dist/app/session/request-history.js +11 -0
- package/dist/app/session/session-event-controller.d.ts +11 -0
- package/dist/app/session/session-event-controller.js +58 -2
- package/dist/app/session/session-history.d.ts +18 -0
- package/dist/app/session/session-history.js +72 -3
- package/dist/app/session/session-lifecycle-controller.d.ts +6 -2
- package/dist/app/session/session-lifecycle-controller.js +7 -2
- package/dist/app/session/session-search.js +10 -0
- package/dist/app/session/tabs-controller.d.ts +17 -5
- package/dist/app/session/tabs-controller.js +308 -29
- package/dist/app/todo/todo-model.d.ts +4 -2
- package/dist/app/todo/todo-model.js +23 -13
- package/dist/app/types.d.ts +17 -6
- package/dist/app/workspace/workspace-actions-controller.d.ts +2 -0
- package/dist/app/workspace/workspace-actions-controller.js +12 -0
- package/dist/config.d.ts +6 -1
- package/dist/config.js +82 -25
- package/dist/default-pix-config.js +4 -0
- package/dist/fuzzy.d.ts +2 -0
- package/dist/fuzzy.js +27 -7
- package/dist/input-editor.d.ts +9 -0
- package/dist/input-editor.js +52 -0
- package/dist/schemas/pi-tools-suite-schema.d.ts +1 -0
- package/dist/schemas/pi-tools-suite-schema.js +1 -0
- package/dist/schemas/pix-schema.d.ts +3 -1
- package/dist/schemas/pix-schema.js +6 -4
- package/dist/terminal-width.d.ts +2 -0
- package/dist/terminal-width.js +64 -3
- package/dist/theme.js +6 -6
- package/dist/ui.d.ts +8 -0
- package/external/pi-tools-suite/README.md +3 -2
- package/external/pi-tools-suite/src/antigravity-auth/auth-store.ts +52 -8
- package/external/pi-tools-suite/src/antigravity-auth/commands.ts +3 -41
- package/external/pi-tools-suite/src/antigravity-auth/constants.ts +0 -2
- package/external/pi-tools-suite/src/antigravity-auth/index.ts +11 -18
- package/external/pi-tools-suite/src/antigravity-auth/oauth.ts +129 -61
- package/external/pi-tools-suite/src/antigravity-auth/status.ts +82 -3
- package/external/pi-tools-suite/src/antigravity-auth/stream.ts +20 -7
- package/external/pi-tools-suite/src/antigravity-auth/types.ts +21 -0
- package/external/pi-tools-suite/src/config.ts +8 -0
- package/external/pi-tools-suite/src/dcp/index.ts +16 -1
- package/external/pi-tools-suite/src/dcp/state.ts +35 -0
- package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +3 -0
- package/external/pi-tools-suite/src/todo/index.ts +123 -14
- package/external/pi-tools-suite/src/todo/state/persistence.ts +0 -1
- package/external/pi-tools-suite/src/todo/state/state-reducer.ts +26 -43
- package/external/pi-tools-suite/src/todo/todo.ts +12 -23
- package/external/pi-tools-suite/src/todo/tool/response-envelope.ts +34 -16
- package/external/pi-tools-suite/src/todo/tool/types.ts +7 -28
- package/external/pi-tools-suite/src/todo/view/format.ts +2 -3
- package/external/pi-tools-suite/src/tool-descriptions.ts +6 -4
- package/external/pi-tools-suite/src/usage/index.ts +5 -2
- package/external/pi-tools-suite/src/usage/lib/google.ts +53 -40
- package/external/pi-tools-suite/src/usage/lib/types.ts +12 -2
- package/package.json +1 -1
- package/schemas/pi-tools-suite.json +4 -0
- package/schemas/pix.json +11 -2
package/dist/app/types.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { ThemeName } from "../theme.js";
|
|
|
5
5
|
import type { ToastKind, ToastNotifier } from "../ui.js";
|
|
6
6
|
import type { RenderedLink } from "./screen/file-links.js";
|
|
7
7
|
import type { WorkspaceMutation } from "./workspace/workspace-undo.js";
|
|
8
|
-
import type { SUBAGENT_ACTIVE_STATUSES, SUBAGENT_RENDER_MODES, SUBAGENT_STATUSES, SUBAGENT_TERMINAL_STATUSES, THINKING_LEVELS, TODO_ACTIONS,
|
|
8
|
+
import type { SUBAGENT_ACTIVE_STATUSES, SUBAGENT_RENDER_MODES, SUBAGENT_STATUSES, SUBAGENT_TERMINAL_STATUSES, THINKING_LEVELS, TODO_ACTIONS, TODO_STATUSES } from "./constants.js";
|
|
9
9
|
export type ThinkingLevel = (typeof THINKING_LEVELS)[number];
|
|
10
10
|
export type NativeModifierKey = "shift" | "command" | "control" | "option";
|
|
11
11
|
export type SessionActivity = "idle" | "running" | "thinking";
|
|
@@ -92,23 +92,22 @@ export type Entry = {
|
|
|
92
92
|
};
|
|
93
93
|
export type TodoAction = (typeof TODO_ACTIONS)[number];
|
|
94
94
|
export type TodoStatus = (typeof TODO_STATUSES)[number];
|
|
95
|
-
export type TodoPriority = (typeof TODO_PRIORITIES)[number];
|
|
96
95
|
export type TodoTask = {
|
|
97
96
|
id: number;
|
|
98
97
|
subject: string;
|
|
99
98
|
status: TodoStatus;
|
|
100
99
|
description?: string;
|
|
101
100
|
activeForm?: string;
|
|
102
|
-
|
|
101
|
+
thinking?: ThinkingLevel;
|
|
103
102
|
parentId?: number;
|
|
104
103
|
blockedBy?: number[];
|
|
105
|
-
tags?: string[];
|
|
106
104
|
owner?: string;
|
|
107
105
|
metadata?: Record<string, unknown>;
|
|
108
106
|
};
|
|
109
107
|
export type TodoTaskLinePart = {
|
|
110
108
|
text: string;
|
|
111
109
|
muted?: boolean;
|
|
110
|
+
thinking?: ThinkingLevel;
|
|
112
111
|
};
|
|
113
112
|
export type TodoTaskRow = {
|
|
114
113
|
task: TodoTask;
|
|
@@ -261,6 +260,7 @@ export type StatusLineLayout = {
|
|
|
261
260
|
text: string;
|
|
262
261
|
sessionLabel: string;
|
|
263
262
|
workspaceLabel: string;
|
|
263
|
+
inputBorderWidgetStartColumn?: number;
|
|
264
264
|
modelUsageLabel?: string;
|
|
265
265
|
contextBarLabel?: string;
|
|
266
266
|
userJumpWidget?: StatusUserJumpWidgetLayout;
|
|
@@ -379,6 +379,14 @@ export type PixMenuItem<T = string> = {
|
|
|
379
379
|
label: string;
|
|
380
380
|
description?: string;
|
|
381
381
|
keywords?: readonly string[];
|
|
382
|
+
labelHighlightRanges?: readonly {
|
|
383
|
+
start: number;
|
|
384
|
+
end: number;
|
|
385
|
+
}[];
|
|
386
|
+
descriptionHighlightRanges?: readonly {
|
|
387
|
+
start: number;
|
|
388
|
+
end: number;
|
|
389
|
+
}[];
|
|
382
390
|
variant?: PixMenuVariant;
|
|
383
391
|
};
|
|
384
392
|
export type PixMenuOptions = {
|
|
@@ -386,6 +394,8 @@ export type PixMenuOptions = {
|
|
|
386
394
|
placeholder?: string;
|
|
387
395
|
emptyText?: string;
|
|
388
396
|
searchable?: boolean;
|
|
397
|
+
minScorePerCharacter?: number;
|
|
398
|
+
preferKeyboardLayoutMatches?: boolean;
|
|
389
399
|
preserveStatus?: boolean;
|
|
390
400
|
};
|
|
391
401
|
export type PixMenuSelectOptions = Omit<PixMenuOptions, "title">;
|
|
@@ -498,9 +508,10 @@ export type ThinkingMenuValue = {
|
|
|
498
508
|
level: ThinkingLevel;
|
|
499
509
|
current: boolean;
|
|
500
510
|
};
|
|
501
|
-
export type UserMessageMenuValue = "copy" | "fork" | "undo";
|
|
511
|
+
export type UserMessageMenuValue = "copy" | "fork" | "fork-new-tab" | "undo";
|
|
502
512
|
export type UserMessageJumpMenuValue = {
|
|
503
|
-
entryId
|
|
513
|
+
entryId?: string;
|
|
514
|
+
sessionEntryId?: string;
|
|
504
515
|
};
|
|
505
516
|
export type QueueMessageMenuValue = "cancel" | "edit" | "send-now";
|
|
506
517
|
export type ResumeMenuValue = {
|
|
@@ -18,6 +18,7 @@ export type AppWorkspaceActionsControllerHost = {
|
|
|
18
18
|
showToast(message: string, kind: "success" | "error" | "warning" | "info"): void;
|
|
19
19
|
render(): void;
|
|
20
20
|
isRunning(): boolean;
|
|
21
|
+
forkSessionEntryInNewTab(sessionEntryId: string): Promise<boolean>;
|
|
21
22
|
};
|
|
22
23
|
export declare class AppWorkspaceActionsController {
|
|
23
24
|
private readonly host;
|
|
@@ -30,6 +31,7 @@ export declare class AppWorkspaceActionsController {
|
|
|
30
31
|
syncUserSessionEntryMetadata(): void;
|
|
31
32
|
copyUserMessage(entryId: string): Promise<void>;
|
|
32
33
|
forkFromUserMessage(entryId: string): Promise<void>;
|
|
34
|
+
forkFromUserMessageInNewTab(entryId: string): Promise<void>;
|
|
33
35
|
undoChangesFromUserMessage(entryId: string): Promise<void>;
|
|
34
36
|
private resolveUserSessionEntryId;
|
|
35
37
|
private getIdleRuntimeForAction;
|
|
@@ -108,6 +108,18 @@ export class AppWorkspaceActionsController {
|
|
|
108
108
|
this.host.setSessionStatus(runtime.session);
|
|
109
109
|
this.host.showToast("Session forked", "success");
|
|
110
110
|
}
|
|
111
|
+
async forkFromUserMessageInNewTab(entryId) {
|
|
112
|
+
const runtime = this.getIdleRuntimeForAction("fork in new tab");
|
|
113
|
+
if (!runtime)
|
|
114
|
+
return;
|
|
115
|
+
const entry = this.host.findUserEntry(entryId);
|
|
116
|
+
if (!entry)
|
|
117
|
+
throw new Error("User message is no longer available");
|
|
118
|
+
const sessionEntryId = this.resolveUserSessionEntryId(entry);
|
|
119
|
+
if (!sessionEntryId)
|
|
120
|
+
throw new Error("Session entry for this message is not available yet");
|
|
121
|
+
await this.host.forkSessionEntryInNewTab(sessionEntryId);
|
|
122
|
+
}
|
|
111
123
|
async undoChangesFromUserMessage(entryId) {
|
|
112
124
|
const runtime = this.getIdleRuntimeForAction("undo changes");
|
|
113
125
|
if (!runtime)
|
package/dist/config.d.ts
CHANGED
|
@@ -67,16 +67,21 @@ export type PixConfig = {
|
|
|
67
67
|
modelColors: ModelColorsConfig;
|
|
68
68
|
iconTheme: IconThemeConfig;
|
|
69
69
|
dictation: DictationConfig;
|
|
70
|
+
ignoreContextFiles: boolean;
|
|
71
|
+
maxProjectSessions: number;
|
|
70
72
|
};
|
|
71
73
|
export declare function getPixConfigPath(homeDir?: string): string;
|
|
74
|
+
export declare function getProjectPixConfigPath(cwd: string): string;
|
|
72
75
|
export declare function resolveDefaultModelRef(config: PixConfig): string | undefined;
|
|
73
76
|
export declare function savePixDefaultModel(modelRef: string): DefaultModelConfig | undefined;
|
|
74
77
|
export declare function savePixDefaultThinking(thinking: string, fallbackModelRef?: string): DefaultModelConfig | undefined;
|
|
75
78
|
export declare function savePixAutocompleteModel(modelRef: string): AutocompleteConfig;
|
|
79
|
+
export declare function saveProjectPixIgnoreContextFiles(cwd: string, ignoreContextFiles: boolean): boolean;
|
|
80
|
+
export declare function upsertPixIgnoreContextFilesInJsonc(source: string, ignoreContextFiles: boolean): string;
|
|
76
81
|
export declare function upsertPixDefaultModelInJsonc(source: string, modelRef: string): string;
|
|
77
82
|
export declare function upsertPixDefaultThinkingInJsonc(source: string, thinking: string, fallbackModelRef?: string): string;
|
|
78
83
|
export declare function upsertPixAutocompleteModelInJsonc(source: string, modelRef: string): string;
|
|
79
|
-
export declare function loadPixConfig(): PixConfig;
|
|
84
|
+
export declare function loadPixConfig(cwd?: string): PixConfig;
|
|
80
85
|
export declare function savePixDictationLanguage(language: string): void;
|
|
81
86
|
export declare function upsertPixDictationLanguageInJsonc(source: string, language: string): string;
|
|
82
87
|
export declare function resolveModelColor(modelRef: string, config: ModelColorsConfig): string | undefined;
|
package/dist/config.js
CHANGED
|
@@ -4,9 +4,13 @@ import { homedir } from "node:os";
|
|
|
4
4
|
import { applyEdits, modify, parse } from "jsonc-parser";
|
|
5
5
|
import { appIconThemeFromFallbackFlag, appIconThemeOverrideFromEnv, parseAppIconThemeName, resolveAppIconThemeNameFromEnv, } from "./app/icons.js";
|
|
6
6
|
import { DEFAULT_PIX_CONFIG_JSONC } from "./default-pix-config.js";
|
|
7
|
+
const PIX_SCHEMA_URL = "https://unpkg.com/pi-ui-extend/schemas/pix.json";
|
|
7
8
|
export function getPixConfigPath(homeDir = homedir()) {
|
|
8
9
|
return join(homeDir, ".config", "pi", "pix.jsonc");
|
|
9
10
|
}
|
|
11
|
+
export function getProjectPixConfigPath(cwd) {
|
|
12
|
+
return join(cwd, ".pi", "pix.jsonc");
|
|
13
|
+
}
|
|
10
14
|
const PIX_CONFIG_PATH = getPixConfigPath();
|
|
11
15
|
const DEFAULT_TOOL_RENDERER = {
|
|
12
16
|
default: {
|
|
@@ -68,9 +72,6 @@ const DEFAULT_MODEL_COLORS = {
|
|
|
68
72
|
"antigravity/antigravity-claude-*": "error",
|
|
69
73
|
},
|
|
70
74
|
};
|
|
71
|
-
const DEFAULT_ICON_THEME = {
|
|
72
|
-
name: "nerdFont",
|
|
73
|
-
};
|
|
74
75
|
const DEFAULT_DICTATION = {
|
|
75
76
|
language: "en",
|
|
76
77
|
languages: {
|
|
@@ -164,17 +165,21 @@ function extractDefaultModelConfig(raw) {
|
|
|
164
165
|
return undefined;
|
|
165
166
|
const configured = raw.defaultModel ?? raw.modelDefault;
|
|
166
167
|
if (typeof configured === "string") {
|
|
167
|
-
|
|
168
|
-
return modelRef ? { modelRef } : undefined;
|
|
168
|
+
return normalizeDefaultModelRef(configured);
|
|
169
169
|
}
|
|
170
170
|
if (!isPlainObject(configured))
|
|
171
171
|
return undefined;
|
|
172
172
|
const modelRef = nonEmptyString(configured.modelRef) ?? nonEmptyString(configured.model);
|
|
173
173
|
if (!modelRef)
|
|
174
174
|
return undefined;
|
|
175
|
-
const
|
|
175
|
+
const normalizedModel = normalizeDefaultModelRef(modelRef);
|
|
176
|
+
if (!normalizedModel)
|
|
177
|
+
return undefined;
|
|
178
|
+
const thinking = normalizeDefaultThinking(configured.thinking)
|
|
179
|
+
?? normalizeDefaultThinking(configured.thinkingLevel)
|
|
180
|
+
?? normalizedModel.thinking;
|
|
176
181
|
return {
|
|
177
|
-
modelRef,
|
|
182
|
+
modelRef: normalizedModel.modelRef,
|
|
178
183
|
...(thinking === undefined ? {} : { thinking }),
|
|
179
184
|
};
|
|
180
185
|
}
|
|
@@ -241,6 +246,18 @@ function extractDictationConfig(raw) {
|
|
|
241
246
|
languages,
|
|
242
247
|
} : undefined;
|
|
243
248
|
}
|
|
249
|
+
function extractIgnoreContextFiles(raw) {
|
|
250
|
+
if (!isPlainObject(raw))
|
|
251
|
+
return undefined;
|
|
252
|
+
return typeof raw.ignoreContextFiles === "boolean" ? raw.ignoreContextFiles : undefined;
|
|
253
|
+
}
|
|
254
|
+
function extractMaxProjectSessions(raw) {
|
|
255
|
+
if (!isPlainObject(raw))
|
|
256
|
+
return undefined;
|
|
257
|
+
if (typeof raw.maxProjectSessions !== "number" || !Number.isFinite(raw.maxProjectSessions))
|
|
258
|
+
return undefined;
|
|
259
|
+
return Math.max(0, Math.floor(raw.maxProjectSessions));
|
|
260
|
+
}
|
|
244
261
|
function normalizeDictationLanguage(value) {
|
|
245
262
|
if (typeof value !== "string")
|
|
246
263
|
return undefined;
|
|
@@ -253,6 +270,9 @@ function normalizeThinkingLevel(value) {
|
|
|
253
270
|
const normalized = value.trim().toLowerCase();
|
|
254
271
|
return THINKING_LEVELS.includes(normalized) ? normalized : undefined;
|
|
255
272
|
}
|
|
273
|
+
function normalizeDefaultThinking(value) {
|
|
274
|
+
return normalizeThinkingLevel(value);
|
|
275
|
+
}
|
|
256
276
|
function nonEmptyString(value) {
|
|
257
277
|
if (typeof value !== "string")
|
|
258
278
|
return undefined;
|
|
@@ -274,15 +294,31 @@ function defaultPixConfig() {
|
|
|
274
294
|
modelColors: DEFAULT_MODEL_COLORS,
|
|
275
295
|
iconTheme: { name: resolveAppIconThemeNameFromEnv() },
|
|
276
296
|
dictation: DEFAULT_DICTATION,
|
|
297
|
+
ignoreContextFiles: false,
|
|
298
|
+
maxProjectSessions: 0,
|
|
277
299
|
};
|
|
278
300
|
}
|
|
301
|
+
function pixConfigFromParsed(parsed, fallback = defaultPixConfig()) {
|
|
302
|
+
const toolRenderer = extractToolRendererConfig(parsed) ?? fallback.toolRenderer;
|
|
303
|
+
const outputFilters = extractOutputFiltersConfig(parsed) ?? fallback.outputFilters;
|
|
304
|
+
const defaultModel = extractDefaultModelConfig(parsed) ?? fallback.defaultModel;
|
|
305
|
+
const promptEnhancer = extractPromptEnhancerConfig(parsed) ?? fallback.promptEnhancer;
|
|
306
|
+
const autocomplete = extractAutocompleteConfig(parsed) ?? fallback.autocomplete;
|
|
307
|
+
const modelColors = extractModelColorsConfig(parsed) ?? fallback.modelColors;
|
|
308
|
+
const configuredIconTheme = extractIconThemeConfig(parsed) ?? fallback.iconTheme;
|
|
309
|
+
const iconTheme = { name: appIconThemeOverrideFromEnv() ?? configuredIconTheme.name };
|
|
310
|
+
const dictation = extractDictationConfig(parsed) ?? fallback.dictation;
|
|
311
|
+
const ignoreContextFiles = extractIgnoreContextFiles(parsed) ?? fallback.ignoreContextFiles;
|
|
312
|
+
const maxProjectSessions = extractMaxProjectSessions(parsed) ?? fallback.maxProjectSessions;
|
|
313
|
+
return { toolRenderer, outputFilters, ...(defaultModel === undefined ? {} : { defaultModel }), promptEnhancer, autocomplete, modelColors, iconTheme, dictation, ignoreContextFiles, maxProjectSessions };
|
|
314
|
+
}
|
|
279
315
|
export function resolveDefaultModelRef(config) {
|
|
280
316
|
const modelRef = config.defaultModel?.modelRef.trim();
|
|
281
317
|
if (!modelRef)
|
|
282
318
|
return undefined;
|
|
283
319
|
const thinking = config.defaultModel?.thinking;
|
|
284
320
|
if (!thinking)
|
|
285
|
-
return modelRef;
|
|
321
|
+
return stripThinkingSuffix(modelRef);
|
|
286
322
|
return `${stripThinkingSuffix(modelRef)}:${thinking}`;
|
|
287
323
|
}
|
|
288
324
|
export function savePixDefaultModel(modelRef) {
|
|
@@ -297,7 +333,7 @@ export function savePixDefaultModel(modelRef) {
|
|
|
297
333
|
return extractDefaultModelConfig(parseJsonc(updated));
|
|
298
334
|
}
|
|
299
335
|
export function savePixDefaultThinking(thinking, fallbackModelRef) {
|
|
300
|
-
const normalizedThinking =
|
|
336
|
+
const normalizedThinking = normalizeDefaultThinking(thinking);
|
|
301
337
|
if (!normalizedThinking)
|
|
302
338
|
return undefined;
|
|
303
339
|
const configPath = PIX_CONFIG_PATH;
|
|
@@ -318,6 +354,21 @@ export function savePixAutocompleteModel(modelRef) {
|
|
|
318
354
|
writeFileSync(configPath, updated);
|
|
319
355
|
return extractAutocompleteConfig(parseJsonc(updated)) ?? { ...DEFAULT_AUTOCOMPLETE, modelRef: modelRef.trim() };
|
|
320
356
|
}
|
|
357
|
+
export function saveProjectPixIgnoreContextFiles(cwd, ignoreContextFiles) {
|
|
358
|
+
const configPath = getProjectPixConfigPath(cwd);
|
|
359
|
+
const source = existsSync(configPath) ? readFileSync(configPath, "utf8") : `{
|
|
360
|
+
"$schema": "${PIX_SCHEMA_URL}"
|
|
361
|
+
}
|
|
362
|
+
`;
|
|
363
|
+
const updated = upsertPixIgnoreContextFilesInJsonc(source, ignoreContextFiles);
|
|
364
|
+
mkdirSync(dirname(configPath), { recursive: true });
|
|
365
|
+
writeFileSync(configPath, updated);
|
|
366
|
+
return extractIgnoreContextFiles(parseJsonc(updated)) ?? ignoreContextFiles;
|
|
367
|
+
}
|
|
368
|
+
export function upsertPixIgnoreContextFilesInJsonc(source, ignoreContextFiles) {
|
|
369
|
+
const formattingOptions = { insertSpaces: true, tabSize: 2 };
|
|
370
|
+
return applyEdits(source, modify(source, ["ignoreContextFiles"], ignoreContextFiles, { formattingOptions }));
|
|
371
|
+
}
|
|
321
372
|
export function upsertPixDefaultModelInJsonc(source, modelRef) {
|
|
322
373
|
const normalized = normalizeDefaultModelRef(modelRef);
|
|
323
374
|
if (!normalized)
|
|
@@ -332,7 +383,7 @@ export function upsertPixDefaultModelInJsonc(source, modelRef) {
|
|
|
332
383
|
return upsertPixDefaultModelObjectInJsonc(source, parsed, next);
|
|
333
384
|
}
|
|
334
385
|
export function upsertPixDefaultThinkingInJsonc(source, thinking, fallbackModelRef) {
|
|
335
|
-
const normalizedThinking =
|
|
386
|
+
const normalizedThinking = normalizeDefaultThinking(thinking);
|
|
336
387
|
if (!normalizedThinking)
|
|
337
388
|
return source;
|
|
338
389
|
const parsed = parseJsonc(source);
|
|
@@ -370,7 +421,7 @@ function normalizeDefaultModelRef(modelRef) {
|
|
|
370
421
|
if (colonIndex <= 0)
|
|
371
422
|
return { modelRef: trimmed };
|
|
372
423
|
const suffix = trimmed.slice(colonIndex + 1);
|
|
373
|
-
const thinking =
|
|
424
|
+
const thinking = normalizeDefaultThinking(suffix);
|
|
374
425
|
return thinking ? { modelRef: trimmed.slice(0, colonIndex), thinking } : { modelRef: trimmed };
|
|
375
426
|
}
|
|
376
427
|
function stripThinkingSuffix(modelRef) {
|
|
@@ -378,7 +429,7 @@ function stripThinkingSuffix(modelRef) {
|
|
|
378
429
|
if (colonIndex <= 0)
|
|
379
430
|
return modelRef;
|
|
380
431
|
const suffix = modelRef.slice(colonIndex + 1);
|
|
381
|
-
return
|
|
432
|
+
return normalizeDefaultThinking(suffix) ? modelRef.slice(0, colonIndex) : modelRef;
|
|
382
433
|
}
|
|
383
434
|
function extractToolRendererRule(value) {
|
|
384
435
|
if (!isPlainObject(value))
|
|
@@ -415,32 +466,38 @@ function ensurePixConfigExists(configPath) {
|
|
|
415
466
|
throw error;
|
|
416
467
|
}
|
|
417
468
|
}
|
|
418
|
-
export function loadPixConfig() {
|
|
469
|
+
export function loadPixConfig(cwd) {
|
|
419
470
|
const configPath = PIX_CONFIG_PATH;
|
|
420
471
|
try {
|
|
421
472
|
ensurePixConfigExists(configPath);
|
|
422
473
|
}
|
|
423
474
|
catch (error) {
|
|
424
475
|
process.stderr.write(`[pix] Failed to create ${configPath}: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
425
|
-
return defaultPixConfig();
|
|
476
|
+
return loadProjectPixConfig(cwd, defaultPixConfig());
|
|
426
477
|
}
|
|
427
478
|
try {
|
|
428
479
|
const raw = readFileSync(configPath, "utf8");
|
|
429
480
|
const parsed = parseJsonc(raw);
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
return
|
|
481
|
+
return loadProjectPixConfig(cwd, pixConfigFromParsed(parsed));
|
|
482
|
+
}
|
|
483
|
+
catch (error) {
|
|
484
|
+
process.stderr.write(`[pix] Failed to load ${configPath}: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
485
|
+
return loadProjectPixConfig(cwd, defaultPixConfig());
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
function loadProjectPixConfig(cwd, fallback) {
|
|
489
|
+
if (!cwd)
|
|
490
|
+
return fallback;
|
|
491
|
+
const configPath = getProjectPixConfigPath(cwd);
|
|
492
|
+
if (!existsSync(configPath))
|
|
493
|
+
return fallback;
|
|
494
|
+
try {
|
|
495
|
+
const raw = readFileSync(configPath, "utf8");
|
|
496
|
+
return pixConfigFromParsed(parseJsonc(raw), fallback);
|
|
440
497
|
}
|
|
441
498
|
catch (error) {
|
|
442
499
|
process.stderr.write(`[pix] Failed to load ${configPath}: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
443
|
-
return
|
|
500
|
+
return fallback;
|
|
444
501
|
}
|
|
445
502
|
}
|
|
446
503
|
export function savePixDictationLanguage(language) {
|
|
@@ -2,6 +2,10 @@ export const DEFAULT_PIX_CONFIG_JSONC = String.raw `{
|
|
|
2
2
|
"$schema": "https://unpkg.com/pi-ui-extend/schemas/pix.json",
|
|
3
3
|
// pix renderer configuration
|
|
4
4
|
"defaultModel": { "modelRef": "openai-codex/gpt-5.5", "thinking": "medium" },
|
|
5
|
+
// Disable AGENTS.md / CLAUDE.md discovery for this project when set in <cwd>/.pi/pix.jsonc.
|
|
6
|
+
"ignoreContextFiles": false,
|
|
7
|
+
// Maximum pi session JSONL files to retain per project. 0 disables automatic deletion.
|
|
8
|
+
"maxProjectSessions": 0,
|
|
5
9
|
|
|
6
10
|
"toolRenderer": {
|
|
7
11
|
"default": { "previewLines": 0, "direction": "head", "color": "toolTitle" },
|
package/dist/fuzzy.d.ts
CHANGED
|
@@ -19,5 +19,7 @@ export type FuzzyMatch<T> = {
|
|
|
19
19
|
export type FuzzySearchOptions = {
|
|
20
20
|
limit?: number;
|
|
21
21
|
includeEmptyQuery?: boolean;
|
|
22
|
+
minScorePerCharacter?: number;
|
|
23
|
+
preferKeyboardLayoutMatches?: boolean;
|
|
22
24
|
};
|
|
23
25
|
export declare function fuzzySearch<T>(items: readonly FuzzySearchItem<T>[], query: string, options?: FuzzySearchOptions): FuzzyMatch<T>[];
|
package/dist/fuzzy.js
CHANGED
|
@@ -41,7 +41,7 @@ export function fuzzySearch(items, query, options = {}) {
|
|
|
41
41
|
const includeEmptyQuery = options.includeEmptyQuery ?? true;
|
|
42
42
|
if (!includeEmptyQuery && normalizedQuery.length === 0)
|
|
43
43
|
return [];
|
|
44
|
-
const
|
|
44
|
+
const candidateMatches = [];
|
|
45
45
|
items.forEach((item, rank) => {
|
|
46
46
|
const texts = [item.label, ...(item.aliases ?? []), ...(item.keywords ?? [])];
|
|
47
47
|
let best;
|
|
@@ -51,21 +51,28 @@ export function fuzzySearch(items, query, options = {}) {
|
|
|
51
51
|
if (!score)
|
|
52
52
|
continue;
|
|
53
53
|
const adjustedScore = score.score - queryVariant.penalty;
|
|
54
|
-
if (!best || adjustedScore > best.score)
|
|
55
|
-
best = { ...score, score: adjustedScore, text };
|
|
54
|
+
if (!best || adjustedScore > best.score) {
|
|
55
|
+
best = { ...score, score: adjustedScore, text, keyboardLayout: queryVariant.keyboardLayout };
|
|
56
|
+
}
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
if (!best)
|
|
59
60
|
return;
|
|
60
|
-
|
|
61
|
+
if (isBelowMinimumScore(best.score, normalizedQuery, options.minScorePerCharacter))
|
|
62
|
+
return;
|
|
63
|
+
candidateMatches.push({
|
|
61
64
|
value: item.value,
|
|
62
65
|
label: item.label,
|
|
63
66
|
matchedText: best.text,
|
|
64
67
|
matchedRanges: best.ranges,
|
|
65
68
|
score: best.score,
|
|
66
69
|
rank,
|
|
70
|
+
keyboardLayout: best.keyboardLayout,
|
|
67
71
|
});
|
|
68
72
|
});
|
|
73
|
+
const matches = options.preferKeyboardLayoutMatches && shouldPreferKeyboardLayoutMatches(query) && candidateMatches.some((match) => match.keyboardLayout)
|
|
74
|
+
? candidateMatches.filter((match) => match.keyboardLayout)
|
|
75
|
+
: candidateMatches;
|
|
69
76
|
matches.sort((left, right) => {
|
|
70
77
|
const scoreDelta = right.score - left.score;
|
|
71
78
|
if (scoreDelta !== 0)
|
|
@@ -75,7 +82,12 @@ export function fuzzySearch(items, query, options = {}) {
|
|
|
75
82
|
return rankDelta;
|
|
76
83
|
return left.label.localeCompare(right.label);
|
|
77
84
|
});
|
|
78
|
-
return options.limit === undefined ? matches : matches.slice(0, options.limit);
|
|
85
|
+
return (options.limit === undefined ? matches : matches.slice(0, options.limit)).map(({ keyboardLayout: _keyboardLayout, ...match }) => match);
|
|
86
|
+
}
|
|
87
|
+
function isBelowMinimumScore(score, normalizedQuery, minScorePerCharacter) {
|
|
88
|
+
if (minScorePerCharacter === undefined || normalizedQuery.length === 0)
|
|
89
|
+
return false;
|
|
90
|
+
return score < normalizedQuery.length * minScorePerCharacter;
|
|
79
91
|
}
|
|
80
92
|
function scoreFuzzyMatch(normalizedQuery, text) {
|
|
81
93
|
if (normalizedQuery.length === 0) {
|
|
@@ -149,7 +161,7 @@ function normalizeText(value) {
|
|
|
149
161
|
return value.toLowerCase();
|
|
150
162
|
}
|
|
151
163
|
function getQueryVariants(normalizedQuery) {
|
|
152
|
-
const variants = [{ query: normalizedQuery, penalty: 0 }];
|
|
164
|
+
const variants = [{ query: normalizedQuery, penalty: 0, keyboardLayout: false }];
|
|
153
165
|
addKeyboardLayoutVariant(variants, normalizedQuery, RUSSIAN_TO_ENGLISH_KEYBOARD_LAYOUT);
|
|
154
166
|
addKeyboardLayoutVariant(variants, normalizedQuery, ENGLISH_TO_RUSSIAN_KEYBOARD_LAYOUT);
|
|
155
167
|
return variants;
|
|
@@ -158,7 +170,15 @@ function addKeyboardLayoutVariant(variants, normalizedQuery, layout) {
|
|
|
158
170
|
const variant = remapKeyboardLayout(normalizedQuery, layout);
|
|
159
171
|
if (variant === normalizedQuery || variants.some((existing) => existing.query === variant))
|
|
160
172
|
return;
|
|
161
|
-
variants.push({ query: variant, penalty: KEYBOARD_LAYOUT_VARIANT_PENALTY });
|
|
173
|
+
variants.push({ query: variant, penalty: KEYBOARD_LAYOUT_VARIANT_PENALTY, keyboardLayout: true });
|
|
174
|
+
}
|
|
175
|
+
function shouldPreferKeyboardLayoutMatches(query) {
|
|
176
|
+
const trimmed = query.trim();
|
|
177
|
+
if (!trimmed)
|
|
178
|
+
return false;
|
|
179
|
+
if (/^[А-ЯЁ][а-яё]+$/u.test(trimmed))
|
|
180
|
+
return false;
|
|
181
|
+
return /[А-ЯЁ]/u.test(trimmed);
|
|
162
182
|
}
|
|
163
183
|
function remapKeyboardLayout(value, layout) {
|
|
164
184
|
return Array.from(value, (char) => layout[char] ?? char).join("");
|
package/dist/input-editor.d.ts
CHANGED
|
@@ -49,6 +49,11 @@ export interface VisualLine {
|
|
|
49
49
|
end: number;
|
|
50
50
|
}>;
|
|
51
51
|
}
|
|
52
|
+
export interface InputEditorDraftState {
|
|
53
|
+
text: string;
|
|
54
|
+
cursor: number;
|
|
55
|
+
attachments?: readonly Attachment[];
|
|
56
|
+
}
|
|
52
57
|
/** Full render-ready snapshot of the editor state. */
|
|
53
58
|
export interface RenderedEditor {
|
|
54
59
|
visualLines: VisualLine[];
|
|
@@ -70,6 +75,7 @@ export declare class InputEditor {
|
|
|
70
75
|
private readonly _redoStack;
|
|
71
76
|
private _historyMutationDepth;
|
|
72
77
|
private _restoringHistory;
|
|
78
|
+
private _contentVersion;
|
|
73
79
|
get text(): string;
|
|
74
80
|
get cursor(): number;
|
|
75
81
|
get selection(): Selection | undefined;
|
|
@@ -78,6 +84,8 @@ export declare class InputEditor {
|
|
|
78
84
|
get hasAttachments(): boolean;
|
|
79
85
|
get canUndo(): boolean;
|
|
80
86
|
get canRedo(): boolean;
|
|
87
|
+
get contentVersion(): number;
|
|
88
|
+
get draftState(): InputEditorDraftState;
|
|
81
89
|
/** Get only image attachments. */
|
|
82
90
|
get images(): ImageContent[];
|
|
83
91
|
/** Get the text to submit — virtual attachment tags are expanded or removed. */
|
|
@@ -91,6 +99,7 @@ export declare class InputEditor {
|
|
|
91
99
|
*/
|
|
92
100
|
get promptText(): string;
|
|
93
101
|
setText(text: string, cursor?: number): void;
|
|
102
|
+
setDraftState(state: InputEditorDraftState): void;
|
|
94
103
|
clear(): void;
|
|
95
104
|
undo(): boolean;
|
|
96
105
|
redo(): boolean;
|
package/dist/input-editor.js
CHANGED
|
@@ -27,6 +27,7 @@ export class InputEditor {
|
|
|
27
27
|
_redoStack = [];
|
|
28
28
|
_historyMutationDepth = 0;
|
|
29
29
|
_restoringHistory = false;
|
|
30
|
+
_contentVersion = 0;
|
|
30
31
|
// ── public getters ──────────────────────────────────────────────
|
|
31
32
|
get text() { return this._text; }
|
|
32
33
|
get cursor() { return this._cursor; }
|
|
@@ -38,6 +39,14 @@ export class InputEditor {
|
|
|
38
39
|
get hasAttachments() { return this._attachments.length > 0; }
|
|
39
40
|
get canUndo() { return this._undoStack.length > 0; }
|
|
40
41
|
get canRedo() { return this._redoStack.length > 0; }
|
|
42
|
+
get contentVersion() { return this._contentVersion; }
|
|
43
|
+
get draftState() {
|
|
44
|
+
return {
|
|
45
|
+
text: this._text,
|
|
46
|
+
cursor: this._cursor,
|
|
47
|
+
...(this._attachments.length > 0 ? { attachments: this._attachments.map(cloneAttachment) } : {}),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
41
50
|
/** Get only image attachments. */
|
|
42
51
|
get images() {
|
|
43
52
|
const images = [];
|
|
@@ -93,7 +102,20 @@ export class InputEditor {
|
|
|
93
102
|
this.clearSelection();
|
|
94
103
|
});
|
|
95
104
|
}
|
|
105
|
+
setDraftState(state) {
|
|
106
|
+
this.recordEdit(() => {
|
|
107
|
+
this._text = state.text;
|
|
108
|
+
this._cursor = state.cursor;
|
|
109
|
+
this._attachments.length = 0;
|
|
110
|
+
this._attachments.push(...Array.from(state.attachments ?? [], cloneAttachment));
|
|
111
|
+
this._imageCounter = Math.max(this._imageCounter, maxTagCounter(this._attachments, /^\[Image (\d+)/u));
|
|
112
|
+
this._pasteCounter = Math.max(this._pasteCounter, maxTagCounter(this._attachments, /^\[Pasted ~?(\d+)/u));
|
|
113
|
+
this.clampCursor();
|
|
114
|
+
this.clearSelection();
|
|
115
|
+
});
|
|
116
|
+
}
|
|
96
117
|
clear() {
|
|
118
|
+
const hadContent = this._text.length > 0 || this._attachments.length > 0;
|
|
97
119
|
this._text = "";
|
|
98
120
|
this._cursor = 0;
|
|
99
121
|
this.clearSelection();
|
|
@@ -102,6 +124,8 @@ export class InputEditor {
|
|
|
102
124
|
this._imageCounter = 0;
|
|
103
125
|
this._pasteCounter = 0;
|
|
104
126
|
this.clearHistory();
|
|
127
|
+
if (hadContent)
|
|
128
|
+
this._contentVersion += 1;
|
|
105
129
|
}
|
|
106
130
|
undo() {
|
|
107
131
|
const previous = this._undoStack.pop();
|
|
@@ -115,6 +139,7 @@ export class InputEditor {
|
|
|
115
139
|
this._redoStack.length = 0;
|
|
116
140
|
}
|
|
117
141
|
this.restoreHistorySnapshot(previous);
|
|
142
|
+
this._contentVersion += 1;
|
|
118
143
|
this.trimHistory();
|
|
119
144
|
return true;
|
|
120
145
|
}
|
|
@@ -130,6 +155,7 @@ export class InputEditor {
|
|
|
130
155
|
this._undoStack.length = 0;
|
|
131
156
|
}
|
|
132
157
|
this.restoreHistorySnapshot(next);
|
|
158
|
+
this._contentVersion += 1;
|
|
133
159
|
this.trimHistory();
|
|
134
160
|
return true;
|
|
135
161
|
}
|
|
@@ -545,6 +571,7 @@ export class InputEditor {
|
|
|
545
571
|
}
|
|
546
572
|
if (!this.didContentChangeFrom(before))
|
|
547
573
|
return;
|
|
574
|
+
this._contentVersion += 1;
|
|
548
575
|
this.clearScrollOffset();
|
|
549
576
|
if (!this.isRecordableHistorySnapshot(before)) {
|
|
550
577
|
this.clearHistory();
|
|
@@ -867,6 +894,31 @@ function removeVirtualAttachmentTag(text, tag) {
|
|
|
867
894
|
return text.replace(withTrailingSpace, "");
|
|
868
895
|
return text.replace(tag, "");
|
|
869
896
|
}
|
|
897
|
+
function cloneAttachment(attachment) {
|
|
898
|
+
if (attachment.kind === "image") {
|
|
899
|
+
return { kind: "image", tag: attachment.tag, image: { ...attachment.image } };
|
|
900
|
+
}
|
|
901
|
+
if (attachment.kind === "pasted-text") {
|
|
902
|
+
return { kind: "pasted-text", tag: attachment.tag, text: attachment.text, lineCount: attachment.lineCount };
|
|
903
|
+
}
|
|
904
|
+
return {
|
|
905
|
+
kind: "file",
|
|
906
|
+
tag: attachment.tag,
|
|
907
|
+
path: attachment.path,
|
|
908
|
+
...(attachment.content === undefined ? {} : { content: attachment.content }),
|
|
909
|
+
...(attachment.image === undefined ? {} : { image: { ...attachment.image } }),
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
function maxTagCounter(attachments, pattern) {
|
|
913
|
+
let max = 0;
|
|
914
|
+
for (const attachment of attachments) {
|
|
915
|
+
const match = pattern.exec(attachment.tag);
|
|
916
|
+
const value = match ? Number.parseInt(match[1] ?? "", 10) : NaN;
|
|
917
|
+
if (Number.isFinite(value))
|
|
918
|
+
max = Math.max(max, value);
|
|
919
|
+
}
|
|
920
|
+
return max;
|
|
921
|
+
}
|
|
870
922
|
function suggestionSpansForChunk(chunkStart, chunkEnd, suggestionStart, suggestionEnd, prefixLength) {
|
|
871
923
|
const start = Math.max(chunkStart, suggestionStart);
|
|
872
924
|
const end = Math.min(chunkEnd, suggestionEnd);
|
|
@@ -9,6 +9,7 @@ export declare const PiToolsSuiteConfigSchema: Type.TObject<{
|
|
|
9
9
|
$schema: Type.TOptional<Type.TString>;
|
|
10
10
|
enabled: Type.TOptional<Type.TBoolean>;
|
|
11
11
|
disabledModules: Type.TOptional<Type.TArray<Type.TString>>;
|
|
12
|
+
todoThinking: Type.TOptional<Type.TBoolean>;
|
|
12
13
|
terminalBell: Type.TOptional<Type.TObject<{
|
|
13
14
|
sound: Type.TOptional<Type.TBoolean>;
|
|
14
15
|
}>>;
|
|
@@ -203,6 +203,7 @@ export const PiToolsSuiteConfigSchema = Type.Object({
|
|
|
203
203
|
$schema: Type.Optional(Type.String({ description: "JSON Schema URL used by editors for validation and autocomplete." })),
|
|
204
204
|
enabled: Type.Optional(Type.Boolean({ description: "Enable or disable the entire pi-tools-suite extension." })),
|
|
205
205
|
disabledModules: Type.Optional(Type.Array(Type.String(), { description: "List of disabled module names (e.g. ['lsp', 'prompt-commands'])." })),
|
|
206
|
+
todoThinking: Type.Optional(Type.Boolean({ description: "Enable per-todo thinking levels and automatic thinking switch/restore when tasks become in-progress/completed." })),
|
|
206
207
|
terminalBell: Type.Optional(TerminalBellConfig),
|
|
207
208
|
dcp: Type.Optional(DcpConfig),
|
|
208
209
|
asyncSubagents: Type.Optional(AsyncSubagentsConfig),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* TypeBox JSON Schema definitions for pix.jsonc (~/.config/pi/pix.jsonc).
|
|
2
|
+
* TypeBox JSON Schema definitions for pix.jsonc (~/.config/pi/pix.jsonc or <cwd>/.pi/pix.jsonc).
|
|
3
3
|
*
|
|
4
4
|
* These schemas describe the _user-facing_ config shape — all fields are optional
|
|
5
5
|
* because the runtime applies generous defaults. The generated JSON Schema files
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
import { Type, Static } from "typebox";
|
|
9
9
|
export declare const PixConfigSchema: Type.TObject<{
|
|
10
10
|
$schema: Type.TOptional<Type.TString>;
|
|
11
|
+
ignoreContextFiles: Type.TOptional<Type.TBoolean>;
|
|
12
|
+
maxProjectSessions: Type.TOptional<Type.TNumber>;
|
|
11
13
|
defaultModel: Type.TOptional<Type.TObject<{
|
|
12
14
|
modelRef: Type.TOptional<Type.TString>;
|
|
13
15
|
thinking: Type.TOptional<Type.TUnion<Type.TLiteral<string>[]>>;
|