drexler 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/package.json +1 -1
- package/src/commands.ts +65 -1
- package/src/ui/App.tsx +2 -9
- package/src/ui/CommandPalette.tsx +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.3
|
|
4
|
+
|
|
5
|
+
- Restored full-terminal-width interactive chrome, including the chat input bar.
|
|
6
|
+
|
|
7
|
+
## 0.2.2
|
|
8
|
+
|
|
9
|
+
- Added argument suggestions in the slash command palette for `/theme`, `/startup`, `/retry`, `/export`, and `/model`.
|
|
10
|
+
- Kept argument suggestion rows concise by avoiding duplicated hint copy.
|
|
11
|
+
|
|
3
12
|
## 0.2.1
|
|
4
13
|
|
|
5
14
|
- Fixed slash command help and palette coverage so every implemented command is discoverable.
|
package/package.json
CHANGED
package/src/commands.ts
CHANGED
|
@@ -76,10 +76,74 @@ export const COMMAND_PALETTE: ReadonlyArray<SlashCommand> = [
|
|
|
76
76
|
{ name: "/copy-last", description: "Copy last response" },
|
|
77
77
|
];
|
|
78
78
|
|
|
79
|
+
const ARGUMENT_PALETTE: ReadonlyArray<{
|
|
80
|
+
readonly command: string;
|
|
81
|
+
readonly values: ReadonlyArray<SlashCommand>;
|
|
82
|
+
}> = [
|
|
83
|
+
{
|
|
84
|
+
command: "/theme",
|
|
85
|
+
values: [
|
|
86
|
+
...THEME_NAMES.map((name) => ({
|
|
87
|
+
name: `/theme ${name}`,
|
|
88
|
+
description: `Switch to ${name} theme`,
|
|
89
|
+
})),
|
|
90
|
+
{ name: "/theme save", description: "Save current theme as default" },
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
command: "/startup",
|
|
95
|
+
values: [
|
|
96
|
+
{ name: "/startup fast", description: "Persist fast startup" },
|
|
97
|
+
{ name: "/startup no-intro", description: "Skip intro on launch" },
|
|
98
|
+
{ name: "/startup normal", description: "Restore full intro" },
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
command: "/retry",
|
|
103
|
+
values: [
|
|
104
|
+
{ name: "/retry terse", description: "Retry in two sentences" },
|
|
105
|
+
{ name: "/retry brutal", description: "Retry more forcefully" },
|
|
106
|
+
],
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
command: "/export",
|
|
110
|
+
values: [
|
|
111
|
+
{ name: "/export md", description: "Export markdown transcript" },
|
|
112
|
+
{ name: "/export txt", description: "Export plain text transcript" },
|
|
113
|
+
{ name: "/export json", description: "Export structured JSON" },
|
|
114
|
+
{ name: "/export html", description: "Export printable HTML" },
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
command: "/model",
|
|
119
|
+
values: [
|
|
120
|
+
{ name: "/model 31b", description: "Use primary 31b model" },
|
|
121
|
+
{ name: "/model 26b", description: "Use fallback 26b model" },
|
|
122
|
+
],
|
|
123
|
+
},
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
function filterArgumentPalette(input: string): ReadonlyArray<SlashCommand> {
|
|
127
|
+
const lower = input.toLowerCase();
|
|
128
|
+
for (const group of ARGUMENT_PALETTE) {
|
|
129
|
+
const prefix = `${group.command} `;
|
|
130
|
+
if (!lower.startsWith(prefix)) continue;
|
|
131
|
+
const argPrefix = lower.slice(prefix.length);
|
|
132
|
+
return group.values.filter((item) =>
|
|
133
|
+
item.name.toLowerCase().startsWith(lower),
|
|
134
|
+
).filter((item) => {
|
|
135
|
+
if (argPrefix.trim() === "") return true;
|
|
136
|
+
return item.name.toLowerCase().slice(prefix.length).startsWith(argPrefix);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return [];
|
|
140
|
+
}
|
|
141
|
+
|
|
79
142
|
export function filterPaletteByPrefix(
|
|
80
143
|
input: string,
|
|
81
144
|
): ReadonlyArray<SlashCommand> {
|
|
82
|
-
if (!input.startsWith("/")
|
|
145
|
+
if (!input.startsWith("/")) return [];
|
|
146
|
+
if (input.includes(" ")) return filterArgumentPalette(input);
|
|
83
147
|
const prefix = input.toLowerCase();
|
|
84
148
|
return COMMAND_PALETTE.filter((c) =>
|
|
85
149
|
c.name.toLowerCase().startsWith(prefix),
|
package/src/ui/App.tsx
CHANGED
|
@@ -41,7 +41,6 @@ import { ThemeProvider } from "./ThemeContext.tsx";
|
|
|
41
41
|
import { TranscriptViewport } from "./TranscriptViewport.tsx";
|
|
42
42
|
import { getActiveTheme, THEMES } from "./themes.ts";
|
|
43
43
|
|
|
44
|
-
const MAX_INPUT_WIDTH = 80;
|
|
45
44
|
const TRANSCRIPT_CHROME_ROWS = 12;
|
|
46
45
|
|
|
47
46
|
export function transcriptRowsForTerminalRows(rows: number): number {
|
|
@@ -111,14 +110,8 @@ export function App({ conversation, config, mood = "neutral", fetchFn }: AppProp
|
|
|
111
110
|
};
|
|
112
111
|
}, [stdout]);
|
|
113
112
|
const mode = useMemo(() => pickLayout(cols), [cols]);
|
|
114
|
-
const inputWidth = useMemo(
|
|
115
|
-
|
|
116
|
-
[cols],
|
|
117
|
-
);
|
|
118
|
-
const chromeWidth = useMemo(
|
|
119
|
-
() => Math.max(1, Math.min(cols, MAX_INPUT_WIDTH)),
|
|
120
|
-
[cols],
|
|
121
|
-
);
|
|
113
|
+
const inputWidth = useMemo(() => Math.max(1, cols), [cols]);
|
|
114
|
+
const chromeWidth = useMemo(() => Math.max(1, cols), [cols]);
|
|
122
115
|
const statusBarWidth = useMemo(() => Math.max(1, inputWidth - 2), [inputWidth]);
|
|
123
116
|
const isCompact = mode === "very-narrow";
|
|
124
117
|
const maxTranscriptRows = useMemo(
|
|
@@ -90,7 +90,10 @@ function CommandPaletteInner({ items, selectedIdx, width = 80 }: Props) {
|
|
|
90
90
|
</Box>
|
|
91
91
|
{items.map((item, idx) => {
|
|
92
92
|
const sel = idx === selectedIdx;
|
|
93
|
-
const
|
|
93
|
+
const isArgumentSuggestion = item.name.includes(" ");
|
|
94
|
+
const hint = isArgumentSuggestion
|
|
95
|
+
? ""
|
|
96
|
+
: COMMAND_HINTS[item.name] ?? item.description;
|
|
94
97
|
const name = item.name.padEnd(maxNameW + 1);
|
|
95
98
|
const desc = fitDisplayText(item.description, descBudget);
|
|
96
99
|
const clippedHint =
|