@mrquake/quakecode-cli 0.64.4 → 0.64.6
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/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +1 -0
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/session-tabs.d.ts +9 -0
- package/dist/modes/interactive/components/session-tabs.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-tabs.js +43 -0
- package/dist/modes/interactive/components/session-tabs.js.map +1 -0
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +3 -2
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -3
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +46 -10
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/package.json +2 -2
|
@@ -42,6 +42,7 @@ import { ModelSelectorComponent } from "./components/model-selector.js";
|
|
|
42
42
|
import { OAuthSelectorComponent } from "./components/oauth-selector.js";
|
|
43
43
|
import { ScopedModelsSelectorComponent } from "./components/scoped-models-selector.js";
|
|
44
44
|
import { SessionSelectorComponent } from "./components/session-selector.js";
|
|
45
|
+
import { SessionTabsComponent } from "./components/session-tabs.js";
|
|
45
46
|
import { SettingsSelectorComponent } from "./components/settings-selector.js";
|
|
46
47
|
import { SkillInvocationMessageComponent } from "./components/skill-invocation-message.js";
|
|
47
48
|
import { ToolExecutionComponent } from "./components/tool-execution.js";
|
|
@@ -161,6 +162,8 @@ export class InteractiveMode {
|
|
|
161
162
|
this.defaultEditor = new CustomEditor(this.ui, getEditorTheme(), this.keybindings, {
|
|
162
163
|
paddingX: editorPaddingX,
|
|
163
164
|
autocompleteMaxVisible,
|
|
165
|
+
noBorders: true,
|
|
166
|
+
prompt: theme.bold(theme.fg("accent", "› ")),
|
|
164
167
|
});
|
|
165
168
|
this.editor = this.defaultEditor;
|
|
166
169
|
this.editorContainer = new Container();
|
|
@@ -291,14 +294,16 @@ export class InteractiveMode {
|
|
|
291
294
|
this.fdPath = fdPath;
|
|
292
295
|
// Add header container as first child
|
|
293
296
|
this.ui.addChild(this.headerContainer);
|
|
297
|
+
this.headerContainer.addChild(new SessionTabsComponent(() => this.getSessionTabLabel(), () => DISPLAY_NAME));
|
|
298
|
+
this.headerContainer.addChild(new Spacer(1));
|
|
294
299
|
// Add header with keybindings from config (unless silenced)
|
|
295
300
|
if (this.options.verbose || !this.settingsManager.getQuietStartup()) {
|
|
296
301
|
const currentModel = this.session.model?.id ?? "no model";
|
|
297
302
|
const cwd = this.sessionManager.getCwd();
|
|
298
303
|
const owner = os.userInfo().username;
|
|
299
304
|
const title = `${DISPLAY_NAME} v${this.version}`;
|
|
300
|
-
const leftInner =
|
|
301
|
-
const maxTotalWidth = Math.max(
|
|
305
|
+
const leftInner = 44;
|
|
306
|
+
const maxTotalWidth = Math.max(128, Math.min(this.ui.terminal.columns - 6, 172));
|
|
302
307
|
const rightInner = maxTotalWidth - leftInner - 7;
|
|
303
308
|
const totalWidth = leftInner + rightInner + 7;
|
|
304
309
|
const border = (s) => theme.fg("borderAccent", s);
|
|
@@ -412,17 +417,21 @@ export class InteractiveMode {
|
|
|
412
417
|
// Initialize available provider count for footer display
|
|
413
418
|
await this.updateAvailableProviderCount();
|
|
414
419
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
420
|
+
getSessionTabLabel() {
|
|
421
|
+
return this.sessionManager.getSessionName() || path.basename(this.sessionManager.getCwd()) || "new session";
|
|
422
|
+
}
|
|
418
423
|
updateTerminalTitle() {
|
|
419
|
-
const cwdBasename = path.basename(this.sessionManager.getCwd());
|
|
420
424
|
const sessionName = this.sessionManager.getSessionName();
|
|
421
|
-
|
|
422
|
-
|
|
425
|
+
const title = sessionName ? `${DISPLAY_NAME} - ${sessionName}` : DISPLAY_NAME;
|
|
426
|
+
// Add spinner if agent is thinking or working
|
|
427
|
+
const isActive = this.session.agent.state.isStreaming || this.session.agent.state.pendingToolCalls.size > 0;
|
|
428
|
+
if (isActive) {
|
|
429
|
+
const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
430
|
+
const frame = frames[Math.floor(Date.now() / 100) % frames.length];
|
|
431
|
+
this.ui.terminal.setTitle(`${frame} ${title}`);
|
|
423
432
|
}
|
|
424
433
|
else {
|
|
425
|
-
this.ui.terminal.setTitle(
|
|
434
|
+
this.ui.terminal.setTitle(title);
|
|
426
435
|
}
|
|
427
436
|
}
|
|
428
437
|
/**
|
|
@@ -449,6 +458,13 @@ export class InteractiveMode {
|
|
|
449
458
|
this.showWarning(warning);
|
|
450
459
|
}
|
|
451
460
|
});
|
|
461
|
+
// Start thinking/working animation loop for terminal title
|
|
462
|
+
setInterval(() => {
|
|
463
|
+
const state = this.session.agent.state;
|
|
464
|
+
if (state.isStreaming || state.pendingToolCalls.size > 0) {
|
|
465
|
+
this.updateTerminalTitle();
|
|
466
|
+
}
|
|
467
|
+
}, 100);
|
|
452
468
|
// Show startup warnings
|
|
453
469
|
const { migratedProviders, modelFallbackMessage, initialMessage, initialImages, initialMessages } = this.options;
|
|
454
470
|
if (migratedProviders && migratedProviders.length > 0) {
|
|
@@ -1895,7 +1911,27 @@ export class InteractiveMode {
|
|
|
1895
1911
|
this.loadingAnimation.stop();
|
|
1896
1912
|
}
|
|
1897
1913
|
this.statusContainer.clear();
|
|
1898
|
-
|
|
1914
|
+
// Create loading animation with "shimmer" effect support
|
|
1915
|
+
this.loadingAnimation = new Loader(this.ui, (spinner) => theme.fg("accent", spinner), (text) => {
|
|
1916
|
+
// Custom "shimmer" effect for the working message text
|
|
1917
|
+
const chars = text.split("");
|
|
1918
|
+
if (chars.length === 0)
|
|
1919
|
+
return "";
|
|
1920
|
+
const sweepSeconds = 2.0;
|
|
1921
|
+
const padding = 10;
|
|
1922
|
+
const period = chars.length + padding * 2;
|
|
1923
|
+
const posF = ((Date.now() / 1000) % sweepSeconds) / sweepSeconds * period;
|
|
1924
|
+
const pos = Math.floor(posF);
|
|
1925
|
+
const bandHalfWidth = 5;
|
|
1926
|
+
return chars.map((ch, i) => {
|
|
1927
|
+
const dist = Math.abs(i + padding - pos);
|
|
1928
|
+
if (dist <= bandHalfWidth) {
|
|
1929
|
+
// Glow effect: Bold + Accent color
|
|
1930
|
+
return theme.bold(theme.fg("accent", ch));
|
|
1931
|
+
}
|
|
1932
|
+
return theme.fg("muted", ch);
|
|
1933
|
+
}).join("");
|
|
1934
|
+
}, this.defaultWorkingMessage);
|
|
1899
1935
|
this.statusContainer.addChild(this.loadingAnimation);
|
|
1900
1936
|
// Apply any pending working message queued before loader existed
|
|
1901
1937
|
if (this.pendingWorkingMessage !== undefined) {
|