auq-mcp-server 2.3.0 → 2.4.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 +82 -0
- package/dist/bin/auq.js +47 -93
- package/dist/bin/tui-app.js +69 -6
- package/dist/package.json +1 -1
- package/dist/src/__tests__/server.abort.test.js +214 -0
- package/dist/src/cli/commands/__tests__/answer.test.js +199 -0
- package/dist/src/cli/commands/__tests__/config.test.js +218 -0
- package/dist/src/cli/commands/__tests__/sessions.test.js +282 -0
- package/dist/src/cli/commands/answer.js +128 -0
- package/dist/src/cli/commands/config.js +263 -0
- package/dist/src/cli/commands/sessions.js +164 -0
- package/dist/src/cli/utils.js +95 -0
- package/dist/src/config/__tests__/ConfigLoader.test.js +41 -0
- package/dist/src/config/defaults.js +3 -0
- package/dist/src/config/types.js +4 -0
- package/dist/src/core/ask-user-questions.js +3 -2
- package/dist/src/i18n/locales/en.js +7 -0
- package/dist/src/i18n/locales/ko.js +7 -0
- package/dist/src/server.js +64 -11
- package/dist/src/session/SessionManager.js +69 -4
- package/dist/src/session/__tests__/SessionManager.test.js +65 -0
- package/dist/src/tui/__tests__/session-watcher.test.js +109 -0
- package/dist/src/tui/components/SessionDots.js +33 -4
- package/dist/src/tui/components/SessionPicker.js +25 -17
- package/dist/src/tui/components/Spinner.js +19 -0
- package/dist/src/tui/components/StepperView.js +68 -5
- package/dist/src/tui/components/__tests__/SessionDots.test.js +160 -1
- package/dist/src/tui/components/__tests__/SessionPicker.test.js +43 -1
- package/dist/src/tui/components/__tests__/StepperView.abandoned.test.js +160 -0
- package/dist/src/tui/components/__tests__/StepperView.state.test.js +1 -0
- package/dist/src/tui/session-watcher.js +50 -0
- package/dist/src/tui/themes/catppuccin-latte.js +7 -0
- package/dist/src/tui/themes/catppuccin-mocha.js +7 -0
- package/dist/src/tui/themes/dark.js +7 -0
- package/dist/src/tui/themes/dracula.js +7 -0
- package/dist/src/tui/themes/github-dark.js +7 -0
- package/dist/src/tui/themes/github-light.js +7 -0
- package/dist/src/tui/themes/gruvbox-dark.js +7 -0
- package/dist/src/tui/themes/gruvbox-light.js +7 -0
- package/dist/src/tui/themes/light.js +7 -0
- package/dist/src/tui/themes/monokai.js +7 -0
- package/dist/src/tui/themes/nord.js +7 -0
- package/dist/src/tui/themes/one-dark.js +7 -0
- package/dist/src/tui/themes/rose-pine.js +7 -0
- package/dist/src/tui/themes/solarized-dark.js +7 -0
- package/dist/src/tui/themes/solarized-light.js +7 -0
- package/dist/src/tui/themes/tokyo-night.js +7 -0
- package/dist/src/tui/utils/__tests__/detectTheme.test.js +78 -0
- package/dist/src/tui/utils/__tests__/staleDetection.test.js +118 -0
- package/dist/src/tui/utils/staleDetection.js +51 -0
- package/package.json +1 -1
|
@@ -29,7 +29,7 @@ function renderWithTheme(ui) {
|
|
|
29
29
|
function getOutput(frame) {
|
|
30
30
|
return (frame ?? "").replace(/\x1b\[[0-9;]*m/g, "").replace(/\r/g, "");
|
|
31
31
|
}
|
|
32
|
-
function createSession(id) {
|
|
32
|
+
function createSession(id, overrides) {
|
|
33
33
|
return {
|
|
34
34
|
sessionId: `picker-id-${id}`,
|
|
35
35
|
sessionRequest: {
|
|
@@ -47,6 +47,7 @@ function createSession(id) {
|
|
|
47
47
|
],
|
|
48
48
|
},
|
|
49
49
|
timestamp: new Date("2026-01-01T00:00:00.000Z"),
|
|
50
|
+
...overrides,
|
|
50
51
|
};
|
|
51
52
|
}
|
|
52
53
|
afterEach(() => {
|
|
@@ -122,4 +123,45 @@ describe("SessionPicker", () => {
|
|
|
122
123
|
expect(onClose).toHaveBeenCalledTimes(1);
|
|
123
124
|
expect(onSelectIndex).not.toHaveBeenCalled();
|
|
124
125
|
});
|
|
126
|
+
describe("stale/abandoned session indicators", () => {
|
|
127
|
+
it("shows ⚠ icon for stale sessions", () => {
|
|
128
|
+
const sessions = [createSession(1), createSession(2, { isStale: true })];
|
|
129
|
+
const instance = renderWithTheme(React.createElement(SessionPicker, { isOpen: true, sessions: sessions, activeIndex: 0, sessionUIStates: {}, onSelectIndex: () => { }, onClose: () => { } }));
|
|
130
|
+
const output = getOutput(instance.lastFrame());
|
|
131
|
+
expect(output).toContain("⚠");
|
|
132
|
+
expect(output).toContain("Title 2");
|
|
133
|
+
});
|
|
134
|
+
it("shows 'may be orphaned' subtitle for stale sessions", () => {
|
|
135
|
+
const sessions = [createSession(1, { isStale: true })];
|
|
136
|
+
const instance = renderWithTheme(React.createElement(SessionPicker, { isOpen: true, sessions: sessions, activeIndex: 0, sessionUIStates: {}, onSelectIndex: () => { }, onClose: () => { } }));
|
|
137
|
+
const output = getOutput(instance.lastFrame());
|
|
138
|
+
expect(output).toContain("may be orphaned");
|
|
139
|
+
});
|
|
140
|
+
it("shows 'session abandoned' subtitle for abandoned sessions", () => {
|
|
141
|
+
const sessions = [createSession(1, { isAbandoned: true })];
|
|
142
|
+
const instance = renderWithTheme(React.createElement(SessionPicker, { isOpen: true, sessions: sessions, activeIndex: 0, sessionUIStates: {}, onSelectIndex: () => { }, onClose: () => { } }));
|
|
143
|
+
const output = getOutput(instance.lastFrame());
|
|
144
|
+
expect(output).toContain("⚠");
|
|
145
|
+
expect(output).toContain("session abandoned");
|
|
146
|
+
});
|
|
147
|
+
it("stale sessions remain selectable via Enter", async () => {
|
|
148
|
+
const sessions = [createSession(1, { isStale: true }), createSession(2)];
|
|
149
|
+
const onSelectIndex = vi.fn();
|
|
150
|
+
const onClose = vi.fn();
|
|
151
|
+
renderWithTheme(React.createElement(SessionPicker, { isOpen: true, sessions: sessions, activeIndex: 0, sessionUIStates: {}, onSelectIndex: onSelectIndex, onClose: onClose }));
|
|
152
|
+
expect(inputState.handler).not.toBeNull();
|
|
153
|
+
inputState.handler("", { return: true });
|
|
154
|
+
await Promise.resolve();
|
|
155
|
+
expect(onSelectIndex).toHaveBeenCalledWith(0);
|
|
156
|
+
expect(onClose).toHaveBeenCalled();
|
|
157
|
+
});
|
|
158
|
+
it("non-stale sessions render normally without ⚠ or subtitles", () => {
|
|
159
|
+
const sessions = [createSession(1), createSession(2)];
|
|
160
|
+
const instance = renderWithTheme(React.createElement(SessionPicker, { isOpen: true, sessions: sessions, activeIndex: 0, sessionUIStates: {}, onSelectIndex: () => { }, onClose: () => { } }));
|
|
161
|
+
const output = getOutput(instance.lastFrame());
|
|
162
|
+
expect(output).not.toContain("⚠");
|
|
163
|
+
expect(output).not.toContain("may be orphaned");
|
|
164
|
+
expect(output).not.toContain("session abandoned");
|
|
165
|
+
});
|
|
166
|
+
});
|
|
125
167
|
});
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { cleanup, render } from "ink-testing-library";
|
|
3
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
4
|
+
import { ConfigProvider } from "../../ConfigContext.js";
|
|
5
|
+
import { ThemeContext } from "../../ThemeContext.js";
|
|
6
|
+
import { darkTheme } from "../../themes/dark.js";
|
|
7
|
+
import { StepperView } from "../StepperView.js";
|
|
8
|
+
const mockThemeValue = {
|
|
9
|
+
theme: darkTheme,
|
|
10
|
+
themeName: "AUQ dark",
|
|
11
|
+
cycleTheme: () => { },
|
|
12
|
+
};
|
|
13
|
+
const sessionRequest = {
|
|
14
|
+
sessionId: "abandoned-test-session",
|
|
15
|
+
status: "pending",
|
|
16
|
+
timestamp: new Date().toISOString(),
|
|
17
|
+
callId: "call-abandoned-1",
|
|
18
|
+
questions: [
|
|
19
|
+
{
|
|
20
|
+
title: "Language",
|
|
21
|
+
prompt: "Pick a language",
|
|
22
|
+
options: [{ label: "TypeScript" }, { label: "Python" }],
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
title: "Framework",
|
|
26
|
+
prompt: "Pick a framework",
|
|
27
|
+
options: [{ label: "React" }, { label: "Vue" }],
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
};
|
|
31
|
+
function renderStepper(props = {}) {
|
|
32
|
+
return render(React.createElement(ThemeContext.Provider, { value: mockThemeValue },
|
|
33
|
+
React.createElement(ConfigProvider, null,
|
|
34
|
+
React.createElement(StepperView, { sessionId: sessionRequest.sessionId, sessionRequest: sessionRequest, ...props }))));
|
|
35
|
+
}
|
|
36
|
+
function getOutput(frame) {
|
|
37
|
+
return (frame ?? "").replace(/\x1b\[[0-9;]*m/g, "").replace(/\r/g, "");
|
|
38
|
+
}
|
|
39
|
+
afterEach(() => {
|
|
40
|
+
cleanup();
|
|
41
|
+
vi.restoreAllMocks();
|
|
42
|
+
});
|
|
43
|
+
describe("StepperView abandoned session confirmation", () => {
|
|
44
|
+
it("shows abandoned confirmation dialog when isAbandoned is true", async () => {
|
|
45
|
+
const instance = renderStepper({ isAbandoned: true });
|
|
46
|
+
await vi.waitFor(() => {
|
|
47
|
+
const output = getOutput(instance.lastFrame());
|
|
48
|
+
expect(output).toContain("AI Disconnected");
|
|
49
|
+
});
|
|
50
|
+
const output = getOutput(instance.lastFrame());
|
|
51
|
+
expect(output).toContain("Answer anyway");
|
|
52
|
+
expect(output).toContain("Cancel");
|
|
53
|
+
// Should NOT show question content behind the dialog
|
|
54
|
+
expect(output).not.toContain("Pick a language");
|
|
55
|
+
});
|
|
56
|
+
it("does not show abandoned dialog when isAbandoned is false", () => {
|
|
57
|
+
const instance = renderStepper({ isAbandoned: false });
|
|
58
|
+
const output = getOutput(instance.lastFrame());
|
|
59
|
+
expect(output).not.toContain("AI Disconnected");
|
|
60
|
+
expect(output).toContain("Pick a language");
|
|
61
|
+
});
|
|
62
|
+
it("does not show abandoned dialog when isAbandoned is undefined", () => {
|
|
63
|
+
const instance = renderStepper();
|
|
64
|
+
const output = getOutput(instance.lastFrame());
|
|
65
|
+
expect(output).not.toContain("AI Disconnected");
|
|
66
|
+
expect(output).toContain("Pick a language");
|
|
67
|
+
});
|
|
68
|
+
it("selecting 'Answer anyway' dismisses dialog and shows questions", async () => {
|
|
69
|
+
const instance = renderStepper({ isAbandoned: true });
|
|
70
|
+
await vi.waitFor(() => {
|
|
71
|
+
const output = getOutput(instance.lastFrame());
|
|
72
|
+
expect(output).toContain("AI Disconnected");
|
|
73
|
+
});
|
|
74
|
+
// Press Enter to select the first option ("Answer anyway")
|
|
75
|
+
instance.stdin.write("\r");
|
|
76
|
+
await vi.waitFor(() => {
|
|
77
|
+
const output = getOutput(instance.lastFrame());
|
|
78
|
+
expect(output).toContain("Pick a language");
|
|
79
|
+
});
|
|
80
|
+
const output = getOutput(instance.lastFrame());
|
|
81
|
+
expect(output).not.toContain("AI Disconnected");
|
|
82
|
+
});
|
|
83
|
+
it("selecting 'Cancel' calls onAbandonedCancel", async () => {
|
|
84
|
+
const onAbandonedCancel = vi.fn();
|
|
85
|
+
const instance = renderStepper({
|
|
86
|
+
isAbandoned: true,
|
|
87
|
+
onAbandonedCancel,
|
|
88
|
+
});
|
|
89
|
+
await vi.waitFor(() => {
|
|
90
|
+
const output = getOutput(instance.lastFrame());
|
|
91
|
+
expect(output).toContain("AI Disconnected");
|
|
92
|
+
});
|
|
93
|
+
// Navigate down to "Cancel" then press Enter
|
|
94
|
+
// Use OA/OB sequences which ink reliably parses as arrows
|
|
95
|
+
instance.stdin.write("\x1bOB"); // Down arrow (application mode)
|
|
96
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
97
|
+
// Press Enter to select "Cancel"
|
|
98
|
+
instance.stdin.write("\r");
|
|
99
|
+
await vi.waitFor(() => {
|
|
100
|
+
expect(onAbandonedCancel).toHaveBeenCalledOnce();
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
it("pressing Escape calls onAbandonedCancel", async () => {
|
|
104
|
+
const onAbandonedCancel = vi.fn();
|
|
105
|
+
const instance = renderStepper({
|
|
106
|
+
isAbandoned: true,
|
|
107
|
+
onAbandonedCancel,
|
|
108
|
+
});
|
|
109
|
+
await vi.waitFor(() => {
|
|
110
|
+
const output = getOutput(instance.lastFrame());
|
|
111
|
+
expect(output).toContain("AI Disconnected");
|
|
112
|
+
});
|
|
113
|
+
// Press Escape
|
|
114
|
+
instance.stdin.write("\x1b");
|
|
115
|
+
await vi.waitFor(() => {
|
|
116
|
+
expect(onAbandonedCancel).toHaveBeenCalledOnce();
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
it("after confirming, dialog does not reappear for the same session", async () => {
|
|
120
|
+
const instance = renderStepper({ isAbandoned: true });
|
|
121
|
+
// Wait for dialog
|
|
122
|
+
await vi.waitFor(() => {
|
|
123
|
+
expect(getOutput(instance.lastFrame())).toContain("AI Disconnected");
|
|
124
|
+
});
|
|
125
|
+
// Confirm ("Answer anyway")
|
|
126
|
+
instance.stdin.write("\r");
|
|
127
|
+
// Wait for questions to appear
|
|
128
|
+
await vi.waitFor(() => {
|
|
129
|
+
expect(getOutput(instance.lastFrame())).toContain("Pick a language");
|
|
130
|
+
});
|
|
131
|
+
// The dialog should stay dismissed - verify questions are still shown
|
|
132
|
+
const output = getOutput(instance.lastFrame());
|
|
133
|
+
expect(output).toContain("Pick a language");
|
|
134
|
+
expect(output).not.toContain("AI Disconnected");
|
|
135
|
+
});
|
|
136
|
+
it("emits showAbandonedConfirm in onFlowStateChange", async () => {
|
|
137
|
+
const onFlowStateChange = vi.fn();
|
|
138
|
+
renderStepper({
|
|
139
|
+
isAbandoned: true,
|
|
140
|
+
onFlowStateChange,
|
|
141
|
+
});
|
|
142
|
+
await vi.waitFor(() => {
|
|
143
|
+
expect(onFlowStateChange).toHaveBeenCalledWith(expect.objectContaining({ showAbandonedConfirm: true }));
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
it("blocks keyboard navigation while dialog is shown", async () => {
|
|
147
|
+
const instance = renderStepper({ isAbandoned: true });
|
|
148
|
+
await vi.waitFor(() => {
|
|
149
|
+
expect(getOutput(instance.lastFrame())).toContain("AI Disconnected");
|
|
150
|
+
});
|
|
151
|
+
// Try Tab to navigate questions - should do nothing
|
|
152
|
+
instance.stdin.write("\t");
|
|
153
|
+
// Dialog should still be shown
|
|
154
|
+
await vi.waitFor(() => {
|
|
155
|
+
const output = getOutput(instance.lastFrame());
|
|
156
|
+
expect(output).toContain("AI Disconnected");
|
|
157
|
+
expect(output).not.toContain("Pick a language");
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
});
|
|
@@ -72,6 +72,56 @@ export class EnhancedTUISessionWatcher extends TUISessionWatcher {
|
|
|
72
72
|
return [];
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Get pending and abandoned sessions with full status metadata.
|
|
77
|
+
* Unlike getPendingSessions(), this includes abandoned sessions
|
|
78
|
+
* and returns status + createdAt for stale detection.
|
|
79
|
+
*/
|
|
80
|
+
async getPendingSessionsWithStatus() {
|
|
81
|
+
const fs = await import("fs/promises");
|
|
82
|
+
const { join } = await import("path");
|
|
83
|
+
try {
|
|
84
|
+
const sessionDir = this.watchedPath;
|
|
85
|
+
const entries = await fs.readdir(sessionDir, { withFileTypes: true });
|
|
86
|
+
const results = [];
|
|
87
|
+
for (const entry of entries) {
|
|
88
|
+
if (!entry.isDirectory())
|
|
89
|
+
continue;
|
|
90
|
+
const sessionPath = join(sessionDir, entry.name);
|
|
91
|
+
const answersPath = join(sessionPath, SESSION_FILES.ANSWERS);
|
|
92
|
+
const statusPath = join(sessionPath, SESSION_FILES.STATUS);
|
|
93
|
+
try {
|
|
94
|
+
// Skip sessions that already have answers
|
|
95
|
+
await fs.access(answersPath);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// No answers file — read status.json
|
|
99
|
+
try {
|
|
100
|
+
const statusContent = await fs.readFile(statusPath, "utf-8");
|
|
101
|
+
const status = JSON.parse(statusContent);
|
|
102
|
+
// Include pending, in-progress, AND abandoned sessions
|
|
103
|
+
if (status.status === "pending" ||
|
|
104
|
+
status.status === "in-progress" ||
|
|
105
|
+
status.status === "abandoned") {
|
|
106
|
+
results.push({
|
|
107
|
+
createdAt: status.createdAt,
|
|
108
|
+
sessionId: entry.name,
|
|
109
|
+
status: status.status,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// No valid status file — skip
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return results.sort((a, b) => a.sessionId.localeCompare(b.sessionId));
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
console.warn("Failed to scan for pending sessions with status:", error);
|
|
122
|
+
return [];
|
|
123
|
+
}
|
|
124
|
+
}
|
|
75
125
|
/**
|
|
76
126
|
* Get session request data for a specific session
|
|
77
127
|
*/
|
|
@@ -91,6 +91,7 @@ export const catppuccinLatteTheme = {
|
|
|
91
91
|
successPillBg: "#dce0e8",
|
|
92
92
|
error: "#d20f39",
|
|
93
93
|
info: "#1e66f5",
|
|
94
|
+
warning: "#df8e1d",
|
|
94
95
|
border: "#ccd0da",
|
|
95
96
|
},
|
|
96
97
|
markdown: {
|
|
@@ -105,6 +106,8 @@ export const catppuccinLatteTheme = {
|
|
|
105
106
|
untouched: "#acb0c0",
|
|
106
107
|
number: "#4c4f69",
|
|
107
108
|
activeNumber: "#1e66f5",
|
|
109
|
+
stale: "#df8e1d",
|
|
110
|
+
abandoned: "#d20f39",
|
|
108
111
|
},
|
|
109
112
|
sessionPicker: {
|
|
110
113
|
border: "#1e66f5",
|
|
@@ -115,6 +118,10 @@ export const catppuccinLatteTheme = {
|
|
|
115
118
|
highlightFg: "#40a02b",
|
|
116
119
|
activeMark: "#1e66f5",
|
|
117
120
|
progress: "#04a5e5",
|
|
121
|
+
staleIcon: "#df8e1d",
|
|
122
|
+
staleText: "#df8e1d",
|
|
123
|
+
staleAge: "#df8e1d",
|
|
124
|
+
staleSubtitle: "#acb0c0",
|
|
118
125
|
},
|
|
119
126
|
},
|
|
120
127
|
};
|
|
@@ -91,6 +91,7 @@ export const catppuccinMochaTheme = {
|
|
|
91
91
|
successPillBg: "#313244",
|
|
92
92
|
error: "#f38ba8",
|
|
93
93
|
info: "#89b4fa",
|
|
94
|
+
warning: "#f9e2af",
|
|
94
95
|
border: "#313244",
|
|
95
96
|
},
|
|
96
97
|
markdown: {
|
|
@@ -105,6 +106,8 @@ export const catppuccinMochaTheme = {
|
|
|
105
106
|
untouched: "#8688a0",
|
|
106
107
|
number: "#cdd6f4",
|
|
107
108
|
activeNumber: "#89b4fa",
|
|
109
|
+
stale: "#f9e2af",
|
|
110
|
+
abandoned: "#f38ba8",
|
|
108
111
|
},
|
|
109
112
|
sessionPicker: {
|
|
110
113
|
border: "#89b4fa",
|
|
@@ -115,6 +118,10 @@ export const catppuccinMochaTheme = {
|
|
|
115
118
|
highlightFg: "#a6e3a1",
|
|
116
119
|
activeMark: "#89b4fa",
|
|
117
120
|
progress: "#89dceb",
|
|
121
|
+
staleIcon: "#f9e2af",
|
|
122
|
+
staleText: "#f9e2af",
|
|
123
|
+
staleAge: "#f9e2af",
|
|
124
|
+
staleSubtitle: "#8688a0",
|
|
118
125
|
},
|
|
119
126
|
},
|
|
120
127
|
};
|
|
@@ -92,6 +92,7 @@ export const darkTheme = {
|
|
|
92
92
|
successPillBg: "#0F2417",
|
|
93
93
|
error: "#FF5C57",
|
|
94
94
|
info: "#46D9FF",
|
|
95
|
+
warning: "#FFD36A",
|
|
95
96
|
border: "#2A3238",
|
|
96
97
|
},
|
|
97
98
|
markdown: {
|
|
@@ -106,6 +107,8 @@ export const darkTheme = {
|
|
|
106
107
|
untouched: "#A0AAB4",
|
|
107
108
|
number: "#E7EEF5",
|
|
108
109
|
activeNumber: "#46D9FF",
|
|
110
|
+
stale: "#FFD36A",
|
|
111
|
+
abandoned: "#FF5C57",
|
|
109
112
|
},
|
|
110
113
|
sessionPicker: {
|
|
111
114
|
border: "#46D9FF",
|
|
@@ -116,6 +119,10 @@ export const darkTheme = {
|
|
|
116
119
|
highlightFg: "#5AF78E",
|
|
117
120
|
activeMark: "#46D9FF",
|
|
118
121
|
progress: "#46D9FF",
|
|
122
|
+
staleIcon: "#FFD36A",
|
|
123
|
+
staleText: "#FFD36A",
|
|
124
|
+
staleAge: "#FFD36A",
|
|
125
|
+
staleSubtitle: "#A0AAB4",
|
|
119
126
|
},
|
|
120
127
|
},
|
|
121
128
|
};
|
|
@@ -91,6 +91,7 @@ export const draculaTheme = {
|
|
|
91
91
|
successPillBg: "#44475a", // current line
|
|
92
92
|
error: "#ff5555",
|
|
93
93
|
info: "#bd93f9",
|
|
94
|
+
warning: "#f1fa8c",
|
|
94
95
|
border: "#44475a",
|
|
95
96
|
},
|
|
96
97
|
markdown: {
|
|
@@ -105,6 +106,8 @@ export const draculaTheme = {
|
|
|
105
106
|
untouched: "#7C8BBE",
|
|
106
107
|
number: "#f8f8f2",
|
|
107
108
|
activeNumber: "#bd93f9",
|
|
109
|
+
stale: "#f1fa8c",
|
|
110
|
+
abandoned: "#ff5555",
|
|
108
111
|
},
|
|
109
112
|
sessionPicker: {
|
|
110
113
|
border: "#bd93f9",
|
|
@@ -115,6 +118,10 @@ export const draculaTheme = {
|
|
|
115
118
|
highlightFg: "#50fa7b",
|
|
116
119
|
activeMark: "#bd93f9",
|
|
117
120
|
progress: "#8be9fd",
|
|
121
|
+
staleIcon: "#f1fa8c",
|
|
122
|
+
staleText: "#f1fa8c",
|
|
123
|
+
staleAge: "#f1fa8c",
|
|
124
|
+
staleSubtitle: "#7C8BBE",
|
|
118
125
|
},
|
|
119
126
|
},
|
|
120
127
|
};
|
|
@@ -90,6 +90,7 @@ export const githubDarkTheme = {
|
|
|
90
90
|
successPillBg: "#161b22",
|
|
91
91
|
error: "#f85149",
|
|
92
92
|
info: "#58a6ff",
|
|
93
|
+
warning: "#d29922",
|
|
93
94
|
border: "#30363d",
|
|
94
95
|
},
|
|
95
96
|
markdown: {
|
|
@@ -104,6 +105,8 @@ export const githubDarkTheme = {
|
|
|
104
105
|
untouched: "#a0a8b4",
|
|
105
106
|
number: "#c9d1d9",
|
|
106
107
|
activeNumber: "#58a6ff",
|
|
108
|
+
stale: "#d29922",
|
|
109
|
+
abandoned: "#f85149",
|
|
107
110
|
},
|
|
108
111
|
sessionPicker: {
|
|
109
112
|
border: "#58a6ff",
|
|
@@ -114,6 +117,10 @@ export const githubDarkTheme = {
|
|
|
114
117
|
highlightFg: "#3fb950",
|
|
115
118
|
activeMark: "#58a6ff",
|
|
116
119
|
progress: "#58a6ff",
|
|
120
|
+
staleIcon: "#d29922",
|
|
121
|
+
staleText: "#d29922",
|
|
122
|
+
staleAge: "#d29922",
|
|
123
|
+
staleSubtitle: "#a0a8b4",
|
|
117
124
|
},
|
|
118
125
|
},
|
|
119
126
|
};
|
|
@@ -90,6 +90,7 @@ export const githubLightTheme = {
|
|
|
90
90
|
successPillBg: "#f6f8fa",
|
|
91
91
|
error: "#CF222E",
|
|
92
92
|
info: "#0969DA",
|
|
93
|
+
warning: "#9A6700",
|
|
93
94
|
border: "#D0D7DE",
|
|
94
95
|
},
|
|
95
96
|
markdown: {
|
|
@@ -104,6 +105,8 @@ export const githubLightTheme = {
|
|
|
104
105
|
untouched: "#6E7781",
|
|
105
106
|
number: "#24292F",
|
|
106
107
|
activeNumber: "#0969DA",
|
|
108
|
+
stale: "#9A6700",
|
|
109
|
+
abandoned: "#CF222E",
|
|
107
110
|
},
|
|
108
111
|
sessionPicker: {
|
|
109
112
|
border: "#0969DA",
|
|
@@ -114,6 +117,10 @@ export const githubLightTheme = {
|
|
|
114
117
|
highlightFg: "#1A7F37",
|
|
115
118
|
activeMark: "#0969DA",
|
|
116
119
|
progress: "#0969DA",
|
|
120
|
+
staleIcon: "#9A6700",
|
|
121
|
+
staleText: "#9A6700",
|
|
122
|
+
staleAge: "#9A6700",
|
|
123
|
+
staleSubtitle: "#6E7781",
|
|
117
124
|
},
|
|
118
125
|
},
|
|
119
126
|
};
|
|
@@ -91,6 +91,7 @@ export const gruvboxDarkTheme = {
|
|
|
91
91
|
successPillBg: "#3c3836", // dark1
|
|
92
92
|
error: "#cc241d",
|
|
93
93
|
info: "#458588",
|
|
94
|
+
warning: "#d79921",
|
|
94
95
|
border: "#3c3836",
|
|
95
96
|
},
|
|
96
97
|
markdown: {
|
|
@@ -105,6 +106,8 @@ export const gruvboxDarkTheme = {
|
|
|
105
106
|
untouched: "#a89984",
|
|
106
107
|
number: "#ebdbb2",
|
|
107
108
|
activeNumber: "#458588",
|
|
109
|
+
stale: "#d79921",
|
|
110
|
+
abandoned: "#cc241d",
|
|
108
111
|
},
|
|
109
112
|
sessionPicker: {
|
|
110
113
|
border: "#458588",
|
|
@@ -115,6 +118,10 @@ export const gruvboxDarkTheme = {
|
|
|
115
118
|
highlightFg: "#98971a",
|
|
116
119
|
activeMark: "#458588",
|
|
117
120
|
progress: "#458588",
|
|
121
|
+
staleIcon: "#d79921",
|
|
122
|
+
staleText: "#d79921",
|
|
123
|
+
staleAge: "#d79921",
|
|
124
|
+
staleSubtitle: "#a89984",
|
|
118
125
|
},
|
|
119
126
|
},
|
|
120
127
|
};
|
|
@@ -91,6 +91,7 @@ export const gruvboxLightTheme = {
|
|
|
91
91
|
successPillBg: "#ebdbb2", // light1 - light bg
|
|
92
92
|
error: "#9d0006",
|
|
93
93
|
info: "#076678",
|
|
94
|
+
warning: "#b57614",
|
|
94
95
|
border: "#d5c4a1",
|
|
95
96
|
},
|
|
96
97
|
markdown: {
|
|
@@ -105,6 +106,8 @@ export const gruvboxLightTheme = {
|
|
|
105
106
|
untouched: "#a89984",
|
|
106
107
|
number: "#3c3836",
|
|
107
108
|
activeNumber: "#076678",
|
|
109
|
+
stale: "#b57614",
|
|
110
|
+
abandoned: "#9d0006",
|
|
108
111
|
},
|
|
109
112
|
sessionPicker: {
|
|
110
113
|
border: "#076678",
|
|
@@ -115,6 +118,10 @@ export const gruvboxLightTheme = {
|
|
|
115
118
|
highlightFg: "#79740e",
|
|
116
119
|
activeMark: "#076678",
|
|
117
120
|
progress: "#076678",
|
|
121
|
+
staleIcon: "#b57614",
|
|
122
|
+
staleText: "#b57614",
|
|
123
|
+
staleAge: "#b57614",
|
|
124
|
+
staleSubtitle: "#a89984",
|
|
118
125
|
},
|
|
119
126
|
},
|
|
120
127
|
};
|
|
@@ -91,6 +91,7 @@ export const lightTheme = {
|
|
|
91
91
|
successPillBg: "#E6F9EE",
|
|
92
92
|
error: "#CF222E",
|
|
93
93
|
info: "#007EA7",
|
|
94
|
+
warning: "#B07D00",
|
|
94
95
|
border: "#D0D7DE",
|
|
95
96
|
},
|
|
96
97
|
markdown: {
|
|
@@ -105,6 +106,8 @@ export const lightTheme = {
|
|
|
105
106
|
untouched: "#6E7781",
|
|
106
107
|
number: "#24292F",
|
|
107
108
|
activeNumber: "#007EA7",
|
|
109
|
+
stale: "#B07D00",
|
|
110
|
+
abandoned: "#CF222E",
|
|
108
111
|
},
|
|
109
112
|
sessionPicker: {
|
|
110
113
|
border: "#007EA7",
|
|
@@ -115,6 +118,10 @@ export const lightTheme = {
|
|
|
115
118
|
highlightFg: "#2DA44E",
|
|
116
119
|
activeMark: "#007EA7",
|
|
117
120
|
progress: "#007EA7",
|
|
121
|
+
staleIcon: "#B07D00",
|
|
122
|
+
staleText: "#B07D00",
|
|
123
|
+
staleAge: "#B07D00",
|
|
124
|
+
staleSubtitle: "#6E7781",
|
|
118
125
|
},
|
|
119
126
|
},
|
|
120
127
|
};
|
|
@@ -92,6 +92,7 @@ export const monokaiTheme = {
|
|
|
92
92
|
successPillBg: "#272822",
|
|
93
93
|
error: "#F92672",
|
|
94
94
|
info: "#66D9EF",
|
|
95
|
+
warning: "#E6DB74",
|
|
95
96
|
border: "#49483E",
|
|
96
97
|
},
|
|
97
98
|
markdown: {
|
|
@@ -106,6 +107,8 @@ export const monokaiTheme = {
|
|
|
106
107
|
untouched: "#908B78",
|
|
107
108
|
number: "#F8F8F2",
|
|
108
109
|
activeNumber: "#66D9EF",
|
|
110
|
+
stale: "#E6DB74",
|
|
111
|
+
abandoned: "#F92672",
|
|
109
112
|
},
|
|
110
113
|
sessionPicker: {
|
|
111
114
|
border: "#66D9EF",
|
|
@@ -116,6 +119,10 @@ export const monokaiTheme = {
|
|
|
116
119
|
highlightFg: "#A6E22E",
|
|
117
120
|
activeMark: "#66D9EF",
|
|
118
121
|
progress: "#66D9EF",
|
|
122
|
+
staleIcon: "#E6DB74",
|
|
123
|
+
staleText: "#E6DB74",
|
|
124
|
+
staleAge: "#E6DB74",
|
|
125
|
+
staleSubtitle: "#908B78",
|
|
119
126
|
},
|
|
120
127
|
},
|
|
121
128
|
};
|
|
@@ -91,6 +91,7 @@ export const nordTheme = {
|
|
|
91
91
|
successPillBg: "#3b4252", // nord1
|
|
92
92
|
error: "#bf616a", // nord11
|
|
93
93
|
info: "#88c0d0", // nord8
|
|
94
|
+
warning: "#ebcb8b",
|
|
94
95
|
border: "#3b4252", // nord1
|
|
95
96
|
},
|
|
96
97
|
markdown: {
|
|
@@ -105,6 +106,8 @@ export const nordTheme = {
|
|
|
105
106
|
untouched: "#616E88",
|
|
106
107
|
number: "#eceff4",
|
|
107
108
|
activeNumber: "#88c0d0",
|
|
109
|
+
stale: "#ebcb8b",
|
|
110
|
+
abandoned: "#bf616a",
|
|
108
111
|
},
|
|
109
112
|
sessionPicker: {
|
|
110
113
|
border: "#88c0d0",
|
|
@@ -115,6 +118,10 @@ export const nordTheme = {
|
|
|
115
118
|
highlightFg: "#a3be8c",
|
|
116
119
|
activeMark: "#88c0d0",
|
|
117
120
|
progress: "#81a1c1",
|
|
121
|
+
staleIcon: "#ebcb8b",
|
|
122
|
+
staleText: "#ebcb8b",
|
|
123
|
+
staleAge: "#ebcb8b",
|
|
124
|
+
staleSubtitle: "#616E88",
|
|
118
125
|
},
|
|
119
126
|
},
|
|
120
127
|
};
|
|
@@ -91,6 +91,7 @@ export const oneDarkTheme = {
|
|
|
91
91
|
successPillBg: "#282c34",
|
|
92
92
|
error: "#e06c75",
|
|
93
93
|
info: "#61afef",
|
|
94
|
+
warning: "#d19a66",
|
|
94
95
|
border: "#3e4451",
|
|
95
96
|
},
|
|
96
97
|
markdown: {
|
|
@@ -105,6 +106,8 @@ export const oneDarkTheme = {
|
|
|
105
106
|
untouched: "#767D8A",
|
|
106
107
|
number: "#abb2bf",
|
|
107
108
|
activeNumber: "#61afef",
|
|
109
|
+
stale: "#d19a66",
|
|
110
|
+
abandoned: "#e06c75",
|
|
108
111
|
},
|
|
109
112
|
sessionPicker: {
|
|
110
113
|
border: "#61afef",
|
|
@@ -115,6 +118,10 @@ export const oneDarkTheme = {
|
|
|
115
118
|
highlightFg: "#98c379",
|
|
116
119
|
activeMark: "#61afef",
|
|
117
120
|
progress: "#56b6c2",
|
|
121
|
+
staleIcon: "#d19a66",
|
|
122
|
+
staleText: "#d19a66",
|
|
123
|
+
staleAge: "#d19a66",
|
|
124
|
+
staleSubtitle: "#767D8A",
|
|
118
125
|
},
|
|
119
126
|
},
|
|
120
127
|
};
|
|
@@ -92,6 +92,7 @@ export const rosePineTheme = {
|
|
|
92
92
|
successPillBg: "#191724",
|
|
93
93
|
error: "#eb6f92",
|
|
94
94
|
info: "#9ccfd8",
|
|
95
|
+
warning: "#f6c177",
|
|
95
96
|
border: "#26233a",
|
|
96
97
|
},
|
|
97
98
|
markdown: {
|
|
@@ -106,6 +107,8 @@ export const rosePineTheme = {
|
|
|
106
107
|
untouched: "#8884a0",
|
|
107
108
|
number: "#e0def4",
|
|
108
109
|
activeNumber: "#ebbcba",
|
|
110
|
+
stale: "#f6c177",
|
|
111
|
+
abandoned: "#eb6f92",
|
|
109
112
|
},
|
|
110
113
|
sessionPicker: {
|
|
111
114
|
border: "#ebbcba",
|
|
@@ -116,6 +119,10 @@ export const rosePineTheme = {
|
|
|
116
119
|
highlightFg: "#31748f",
|
|
117
120
|
activeMark: "#ebbcba",
|
|
118
121
|
progress: "#9ccfd8",
|
|
122
|
+
staleIcon: "#f6c177",
|
|
123
|
+
staleText: "#f6c177",
|
|
124
|
+
staleAge: "#f6c177",
|
|
125
|
+
staleSubtitle: "#8884a0",
|
|
119
126
|
},
|
|
120
127
|
},
|
|
121
128
|
};
|