@sheepbun/yips 0.1.1 → 0.1.46
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/LICENSE +21 -0
- package/README.md +52 -0
- package/bin/yips.js +15 -0
- package/package.json +21 -128
- package/postinstall.js +50 -0
- package/dist/agent/commands/command-catalog.js +0 -243
- package/dist/agent/commands/commands.js +0 -418
- package/dist/agent/conductor.js +0 -118
- package/dist/agent/context/code-context.js +0 -68
- package/dist/agent/context/memory-store.js +0 -159
- package/dist/agent/context/session-store.js +0 -211
- package/dist/agent/protocol/tool-protocol.js +0 -160
- package/dist/agent/skills/skills.js +0 -327
- package/dist/agent/tools/tool-executor.js +0 -415
- package/dist/agent/tools/tool-safety.js +0 -52
- package/dist/app/index.js +0 -35
- package/dist/app/repl.js +0 -105
- package/dist/app/update-check.js +0 -132
- package/dist/app/version.js +0 -51
- package/dist/code-context.js +0 -68
- package/dist/colors.js +0 -204
- package/dist/command-catalog.js +0 -242
- package/dist/commands.js +0 -350
- package/dist/conductor.js +0 -94
- package/dist/config/config.js +0 -335
- package/dist/config/hooks.js +0 -187
- package/dist/config.js +0 -335
- package/dist/downloader-state.js +0 -302
- package/dist/downloader-ui.js +0 -289
- package/dist/gateway/adapters/discord.js +0 -108
- package/dist/gateway/adapters/formatting.js +0 -96
- package/dist/gateway/adapters/telegram.js +0 -106
- package/dist/gateway/adapters/types.js +0 -2
- package/dist/gateway/adapters/whatsapp.js +0 -124
- package/dist/gateway/auth-policy.js +0 -66
- package/dist/gateway/core.js +0 -87
- package/dist/gateway/headless-conductor.js +0 -328
- package/dist/gateway/message-router.js +0 -23
- package/dist/gateway/rate-limiter.js +0 -48
- package/dist/gateway/runtime/backend-policy.js +0 -18
- package/dist/gateway/runtime/discord-bot.js +0 -104
- package/dist/gateway/runtime/discord-main.js +0 -69
- package/dist/gateway/session-manager.js +0 -77
- package/dist/gateway/types.js +0 -2
- package/dist/hardware.js +0 -92
- package/dist/hooks.js +0 -187
- package/dist/index.js +0 -34
- package/dist/input-engine.js +0 -250
- package/dist/llama-client.js +0 -227
- package/dist/llama-server.js +0 -620
- package/dist/llm/llama-client.js +0 -227
- package/dist/llm/llama-server.js +0 -620
- package/dist/llm/token-counter.js +0 -47
- package/dist/memory-store.js +0 -159
- package/dist/messages.js +0 -59
- package/dist/model-downloader.js +0 -382
- package/dist/model-manager-state.js +0 -118
- package/dist/model-manager-ui.js +0 -194
- package/dist/model-manager.js +0 -190
- package/dist/models/hardware.js +0 -92
- package/dist/models/model-downloader.js +0 -382
- package/dist/models/model-manager.js +0 -190
- package/dist/prompt-box.js +0 -78
- package/dist/prompt-composer.js +0 -498
- package/dist/repl.js +0 -105
- package/dist/session-store.js +0 -211
- package/dist/spinner.js +0 -76
- package/dist/title-box.js +0 -388
- package/dist/token-counter.js +0 -47
- package/dist/tool-executor.js +0 -415
- package/dist/tool-protocol.js +0 -121
- package/dist/tool-safety.js +0 -52
- package/dist/tui/app.js +0 -2553
- package/dist/tui/startup.js +0 -56
- package/dist/tui-input-routing.js +0 -53
- package/dist/tui.js +0 -51
- package/dist/types/app-types.js +0 -2
- package/dist/types.js +0 -2
- package/dist/ui/colors.js +0 -204
- package/dist/ui/downloader/downloader-state.js +0 -302
- package/dist/ui/downloader/downloader-ui.js +0 -289
- package/dist/ui/input/input-engine.js +0 -250
- package/dist/ui/input/tui-input-routing.js +0 -53
- package/dist/ui/input/vt-session.js +0 -168
- package/dist/ui/messages.js +0 -59
- package/dist/ui/model-manager/model-manager-state.js +0 -118
- package/dist/ui/model-manager/model-manager-ui.js +0 -194
- package/dist/ui/prompt/prompt-box.js +0 -78
- package/dist/ui/prompt/prompt-composer.js +0 -498
- package/dist/ui/spinner.js +0 -76
- package/dist/ui/title-box.js +0 -388
- package/dist/ui/tui/app.js +0 -6
- package/dist/ui/tui/autocomplete.js +0 -85
- package/dist/ui/tui/constants.js +0 -18
- package/dist/ui/tui/history.js +0 -29
- package/dist/ui/tui/layout.js +0 -341
- package/dist/ui/tui/runtime-core.js +0 -2584
- package/dist/ui/tui/runtime-utils.js +0 -53
- package/dist/ui/tui/start-tui.js +0 -54
- package/dist/ui/tui/startup.js +0 -56
- package/dist/version.js +0 -51
- package/dist/vt-session.js +0 -168
- package/install.sh +0 -457
package/dist/tui/startup.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.applyHardwareAwareStartupModelSelection = applyHardwareAwareStartupModelSelection;
|
|
4
|
-
exports.ensureFreshLlamaSessionOnStartup = ensureFreshLlamaSessionOnStartup;
|
|
5
|
-
const config_1 = require("../config");
|
|
6
|
-
const hardware_1 = require("../hardware");
|
|
7
|
-
const llama_server_1 = require("../llama-server");
|
|
8
|
-
const model_manager_1 = require("../model-manager");
|
|
9
|
-
function resolveLoadedModel(model) {
|
|
10
|
-
const trimmed = model.trim();
|
|
11
|
-
if (trimmed.length === 0) {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
if (trimmed.toLowerCase() === "default") {
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
return trimmed;
|
|
18
|
-
}
|
|
19
|
-
async function applyHardwareAwareStartupModelSelection(options, deps = {
|
|
20
|
-
getSpecs: hardware_1.getSystemSpecs,
|
|
21
|
-
listModels: model_manager_1.listLocalModels,
|
|
22
|
-
selectModel: model_manager_1.selectBestModelForHardware,
|
|
23
|
-
save: config_1.saveConfig
|
|
24
|
-
}) {
|
|
25
|
-
if (options.config.backend !== "llamacpp") {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
if (resolveLoadedModel(options.config.model)) {
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
const specs = deps.getSpecs();
|
|
32
|
-
const models = await deps.listModels({
|
|
33
|
-
totalMemoryGb: specs.totalMemoryGb,
|
|
34
|
-
nicknames: options.config.nicknames
|
|
35
|
-
});
|
|
36
|
-
const selected = deps.selectModel(models, specs);
|
|
37
|
-
if (!selected) {
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
options.config.model = selected.id;
|
|
41
|
-
await deps.save(options.config);
|
|
42
|
-
return selected.id;
|
|
43
|
-
}
|
|
44
|
-
async function ensureFreshLlamaSessionOnStartup(options, deps = { reset: llama_server_1.resetLlamaForFreshSession }) {
|
|
45
|
-
if (options.config.backend !== "llamacpp") {
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
const configuredModel = options.config.model.trim().toLowerCase();
|
|
49
|
-
if (configuredModel.length === 0 || configuredModel === "default") {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
const resetResult = await deps.reset(options.config);
|
|
53
|
-
if (resetResult.failure) {
|
|
54
|
-
throw new Error((0, llama_server_1.formatLlamaStartupFailure)(resetResult.failure, options.config));
|
|
55
|
-
}
|
|
56
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.decideConfirmationAction = decideConfirmationAction;
|
|
4
|
-
exports.routeVtInput = routeVtInput;
|
|
5
|
-
function decideConfirmationAction(actions) {
|
|
6
|
-
for (const action of actions) {
|
|
7
|
-
if (action.type === "cancel") {
|
|
8
|
-
return "deny";
|
|
9
|
-
}
|
|
10
|
-
if (action.type === "submit") {
|
|
11
|
-
return "approve";
|
|
12
|
-
}
|
|
13
|
-
if (action.type === "insert") {
|
|
14
|
-
const normalized = action.text.trim().toLowerCase();
|
|
15
|
-
if (normalized === "y" || normalized === "yes") {
|
|
16
|
-
return "approve";
|
|
17
|
-
}
|
|
18
|
-
if (normalized === "n" || normalized === "no") {
|
|
19
|
-
return "deny";
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
function routeVtInput(sequence, escapePending) {
|
|
26
|
-
const bytes = Buffer.from(sequence, "latin1");
|
|
27
|
-
if (bytes.includes(0x11)) {
|
|
28
|
-
return {
|
|
29
|
-
exitToChat: true,
|
|
30
|
-
nextEscapePending: false,
|
|
31
|
-
passthrough: null
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
if (sequence === "\u001b") {
|
|
35
|
-
if (escapePending) {
|
|
36
|
-
return {
|
|
37
|
-
exitToChat: true,
|
|
38
|
-
nextEscapePending: false,
|
|
39
|
-
passthrough: null
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
return {
|
|
43
|
-
exitToChat: false,
|
|
44
|
-
nextEscapePending: true,
|
|
45
|
-
passthrough: null
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
return {
|
|
49
|
-
exitToChat: false,
|
|
50
|
-
nextEscapePending: false,
|
|
51
|
-
passthrough: sequence
|
|
52
|
-
};
|
|
53
|
-
}
|
package/dist/tui.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/** Main TUI entrypoint and compatibility exports. */
|
|
3
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
-
};
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.ensureFreshLlamaSessionOnStartup = exports.applyHardwareAwareStartupModelSelection = exports.shouldConsumeSubmitForAutocomplete = exports.runOnceGuarded = exports.resolveModelLoadTarget = exports.renderHistoryLines = exports.formatTokensPerSecond = exports.formatTitleCwd = exports.formatModelLoadingLabel = exports.computeVisibleLayoutSlices = exports.computeTokensPerSecond = exports.computeTitleVisibleScrollCap = exports.composeOutputLines = exports.composeChatRequestMessages = exports.buildPromptStatusText = exports.buildPromptRenderLines = exports.buildModelAutocompleteCandidates = exports.buildAutocompleteOverlayLines = void 0;
|
|
8
|
-
exports.startTui = startTui;
|
|
9
|
-
const react_1 = __importDefault(require("react"));
|
|
10
|
-
const version_1 = require("./version");
|
|
11
|
-
const app_1 = require("./tui/app");
|
|
12
|
-
const startup_1 = require("./tui/startup");
|
|
13
|
-
var app_2 = require("./tui/app");
|
|
14
|
-
Object.defineProperty(exports, "buildAutocompleteOverlayLines", { enumerable: true, get: function () { return app_2.buildAutocompleteOverlayLines; } });
|
|
15
|
-
Object.defineProperty(exports, "buildModelAutocompleteCandidates", { enumerable: true, get: function () { return app_2.buildModelAutocompleteCandidates; } });
|
|
16
|
-
Object.defineProperty(exports, "buildPromptRenderLines", { enumerable: true, get: function () { return app_2.buildPromptRenderLines; } });
|
|
17
|
-
Object.defineProperty(exports, "buildPromptStatusText", { enumerable: true, get: function () { return app_2.buildPromptStatusText; } });
|
|
18
|
-
Object.defineProperty(exports, "composeChatRequestMessages", { enumerable: true, get: function () { return app_2.composeChatRequestMessages; } });
|
|
19
|
-
Object.defineProperty(exports, "composeOutputLines", { enumerable: true, get: function () { return app_2.composeOutputLines; } });
|
|
20
|
-
Object.defineProperty(exports, "computeTitleVisibleScrollCap", { enumerable: true, get: function () { return app_2.computeTitleVisibleScrollCap; } });
|
|
21
|
-
Object.defineProperty(exports, "computeTokensPerSecond", { enumerable: true, get: function () { return app_2.computeTokensPerSecond; } });
|
|
22
|
-
Object.defineProperty(exports, "computeVisibleLayoutSlices", { enumerable: true, get: function () { return app_2.computeVisibleLayoutSlices; } });
|
|
23
|
-
Object.defineProperty(exports, "formatModelLoadingLabel", { enumerable: true, get: function () { return app_2.formatModelLoadingLabel; } });
|
|
24
|
-
Object.defineProperty(exports, "formatTitleCwd", { enumerable: true, get: function () { return app_2.formatTitleCwd; } });
|
|
25
|
-
Object.defineProperty(exports, "formatTokensPerSecond", { enumerable: true, get: function () { return app_2.formatTokensPerSecond; } });
|
|
26
|
-
Object.defineProperty(exports, "renderHistoryLines", { enumerable: true, get: function () { return app_2.renderHistoryLines; } });
|
|
27
|
-
Object.defineProperty(exports, "resolveModelLoadTarget", { enumerable: true, get: function () { return app_2.resolveModelLoadTarget; } });
|
|
28
|
-
Object.defineProperty(exports, "runOnceGuarded", { enumerable: true, get: function () { return app_2.runOnceGuarded; } });
|
|
29
|
-
Object.defineProperty(exports, "shouldConsumeSubmitForAutocomplete", { enumerable: true, get: function () { return app_2.shouldConsumeSubmitForAutocomplete; } });
|
|
30
|
-
var startup_2 = require("./tui/startup");
|
|
31
|
-
Object.defineProperty(exports, "applyHardwareAwareStartupModelSelection", { enumerable: true, get: function () { return startup_2.applyHardwareAwareStartupModelSelection; } });
|
|
32
|
-
Object.defineProperty(exports, "ensureFreshLlamaSessionOnStartup", { enumerable: true, get: function () { return startup_2.ensureFreshLlamaSessionOnStartup; } });
|
|
33
|
-
async function startTui(options) {
|
|
34
|
-
let restartRequested = false;
|
|
35
|
-
await (0, startup_1.applyHardwareAwareStartupModelSelection)(options);
|
|
36
|
-
await (0, startup_1.ensureFreshLlamaSessionOnStartup)(options);
|
|
37
|
-
const version = await (0, version_1.getVersion)();
|
|
38
|
-
const ink = (await import("ink"));
|
|
39
|
-
const App = (0, app_1.createInkApp)(ink);
|
|
40
|
-
const instance = ink.render(react_1.default.createElement(App, {
|
|
41
|
-
options,
|
|
42
|
-
version,
|
|
43
|
-
onRestartRequested: () => {
|
|
44
|
-
restartRequested = true;
|
|
45
|
-
}
|
|
46
|
-
}), {
|
|
47
|
-
exitOnCtrlC: false
|
|
48
|
-
});
|
|
49
|
-
await instance.waitUntilExit();
|
|
50
|
-
return restartRequested ? "restart" : "exit";
|
|
51
|
-
}
|
package/dist/types/app-types.js
DELETED
package/dist/types.js
DELETED
package/dist/ui/colors.js
DELETED
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/** Color palette and gradient utilities for ANSI truecolor output. */
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.DIM_GRAY = exports.SUCCESS_GREEN = exports.WARNING_YELLOW = exports.ERROR_RED = exports.VT_GREEN = exports.INPUT_PINK = exports.DARK_BLUE = exports.GRADIENT_BLUE = exports.GRADIENT_YELLOW = exports.GRADIENT_PINK = void 0;
|
|
5
|
-
exports.parseHex = parseHex;
|
|
6
|
-
exports.toHex = toHex;
|
|
7
|
-
exports.interpolateColor = interpolateColor;
|
|
8
|
-
exports.stripAnsi = stripAnsi;
|
|
9
|
-
exports.colorChar = colorChar;
|
|
10
|
-
exports.colorText = colorText;
|
|
11
|
-
exports.bgColorText = bgColorText;
|
|
12
|
-
exports.horizontalGradient = horizontalGradient;
|
|
13
|
-
exports.horizontalGradientAtOffset = horizontalGradientAtOffset;
|
|
14
|
-
exports.horizontalGradientBackground = horizontalGradientBackground;
|
|
15
|
-
exports.diagonalGradient = diagonalGradient;
|
|
16
|
-
exports.rowMajorGradient = rowMajorGradient;
|
|
17
|
-
// --- Palette constants ---
|
|
18
|
-
exports.GRADIENT_PINK = { r: 0xff, g: 0x14, b: 0x93 };
|
|
19
|
-
exports.GRADIENT_YELLOW = { r: 0xff, g: 0xe1, b: 0x35 };
|
|
20
|
-
exports.GRADIENT_BLUE = { r: 0x89, g: 0xcf, b: 0xf0 };
|
|
21
|
-
exports.DARK_BLUE = { r: 0x00, g: 0x66, b: 0xcc };
|
|
22
|
-
exports.INPUT_PINK = { r: 0xff, g: 0xcc, b: 0xff };
|
|
23
|
-
exports.VT_GREEN = { r: 0x00, g: 0xff, b: 0x00 };
|
|
24
|
-
exports.ERROR_RED = { r: 0xff, g: 0x44, b: 0x44 };
|
|
25
|
-
exports.WARNING_YELLOW = { r: 0xff, g: 0xcc, b: 0x00 };
|
|
26
|
-
exports.SUCCESS_GREEN = { r: 0x44, g: 0xff, b: 0x44 };
|
|
27
|
-
exports.DIM_GRAY = { r: 0x88, g: 0x88, b: 0x88 };
|
|
28
|
-
const ANSI_RESET_FOREGROUND = "\u001b[39m";
|
|
29
|
-
const ANSI_RESET_ALL = "\u001b[0m";
|
|
30
|
-
// --- Color utilities ---
|
|
31
|
-
function parseHex(hex) {
|
|
32
|
-
const cleaned = hex.replace(/^#/, "");
|
|
33
|
-
return {
|
|
34
|
-
r: parseInt(cleaned.slice(0, 2), 16),
|
|
35
|
-
g: parseInt(cleaned.slice(2, 4), 16),
|
|
36
|
-
b: parseInt(cleaned.slice(4, 6), 16)
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
function toHex(color) {
|
|
40
|
-
const r = Math.round(Math.max(0, Math.min(255, color.r)));
|
|
41
|
-
const g = Math.round(Math.max(0, Math.min(255, color.g)));
|
|
42
|
-
const b = Math.round(Math.max(0, Math.min(255, color.b)));
|
|
43
|
-
return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
44
|
-
}
|
|
45
|
-
function interpolateColor(start, end, t) {
|
|
46
|
-
const clamped = Math.max(0, Math.min(1, t));
|
|
47
|
-
return {
|
|
48
|
-
r: start.r + (end.r - start.r) * clamped,
|
|
49
|
-
g: start.g + (end.g - start.g) * clamped,
|
|
50
|
-
b: start.b + (end.b - start.b) * clamped
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
function toAnsiColor(color) {
|
|
54
|
-
const r = Math.round(Math.max(0, Math.min(255, color.r)));
|
|
55
|
-
const g = Math.round(Math.max(0, Math.min(255, color.g)));
|
|
56
|
-
const b = Math.round(Math.max(0, Math.min(255, color.b)));
|
|
57
|
-
return `\u001b[38;2;${r};${g};${b}m`;
|
|
58
|
-
}
|
|
59
|
-
function toAnsiBackground(color) {
|
|
60
|
-
const r = Math.round(Math.max(0, Math.min(255, color.r)));
|
|
61
|
-
const g = Math.round(Math.max(0, Math.min(255, color.g)));
|
|
62
|
-
const b = Math.round(Math.max(0, Math.min(255, color.b)));
|
|
63
|
-
return `\u001b[48;2;${r};${g};${b}m`;
|
|
64
|
-
}
|
|
65
|
-
function stripAnsi(text) {
|
|
66
|
-
let output = "";
|
|
67
|
-
for (let i = 0; i < text.length; i++) {
|
|
68
|
-
if (text[i] === "\u001b" && text[i + 1] === "[") {
|
|
69
|
-
i += 2;
|
|
70
|
-
while (i < text.length && text[i] !== "m") {
|
|
71
|
-
i += 1;
|
|
72
|
-
}
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
output += text[i] ?? "";
|
|
76
|
-
}
|
|
77
|
-
return output;
|
|
78
|
-
}
|
|
79
|
-
/** Wrap a single character with ANSI truecolor sequence. */
|
|
80
|
-
function colorChar(char, color) {
|
|
81
|
-
return `${toAnsiColor(color)}${char}`;
|
|
82
|
-
}
|
|
83
|
-
/** Apply a solid color to an entire string using ANSI truecolor. */
|
|
84
|
-
function colorText(text, color) {
|
|
85
|
-
if (text.length === 0)
|
|
86
|
-
return "";
|
|
87
|
-
return `${toAnsiColor(color)}${text}${ANSI_RESET_FOREGROUND}`;
|
|
88
|
-
}
|
|
89
|
-
/** Apply background (+ optional foreground) color to a string. */
|
|
90
|
-
function bgColorText(text, bgColor, fgColor) {
|
|
91
|
-
if (text.length === 0)
|
|
92
|
-
return "";
|
|
93
|
-
const fg = fgColor ? toAnsiColor(fgColor) : "";
|
|
94
|
-
return `${toAnsiBackground(bgColor)}${fg}${text}${ANSI_RESET_ALL}`;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Apply a horizontal gradient across a string.
|
|
98
|
-
* Each visible character gets its own color interpolated between start and end.
|
|
99
|
-
*/
|
|
100
|
-
function horizontalGradient(text, startColor, endColor) {
|
|
101
|
-
const chars = Array.from(text);
|
|
102
|
-
if (chars.length === 0)
|
|
103
|
-
return "";
|
|
104
|
-
if (chars.length === 1) {
|
|
105
|
-
return `${colorChar(chars[0] ?? "", startColor)}${ANSI_RESET_FOREGROUND}`;
|
|
106
|
-
}
|
|
107
|
-
const gradientChars = [];
|
|
108
|
-
for (let i = 0; i < chars.length; i++) {
|
|
109
|
-
const t = i / (chars.length - 1);
|
|
110
|
-
const color = interpolateColor(startColor, endColor, t);
|
|
111
|
-
gradientChars.push(colorChar(chars[i] ?? "", color));
|
|
112
|
-
}
|
|
113
|
-
gradientChars.push(ANSI_RESET_FOREGROUND);
|
|
114
|
-
return gradientChars.join("");
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Apply a horizontal gradient to a string using an absolute offset in a larger line.
|
|
118
|
-
* Useful when rendering segmented strings that should share one continuous gradient.
|
|
119
|
-
*/
|
|
120
|
-
function horizontalGradientAtOffset(text, startColor, endColor, offset, totalWidth) {
|
|
121
|
-
const chars = Array.from(text);
|
|
122
|
-
if (chars.length === 0)
|
|
123
|
-
return "";
|
|
124
|
-
const safeTotalWidth = Math.max(1, totalWidth);
|
|
125
|
-
const denominator = Math.max(1, safeTotalWidth - 1);
|
|
126
|
-
const baseOffset = Math.max(0, offset);
|
|
127
|
-
const gradientChars = [];
|
|
128
|
-
for (let i = 0; i < chars.length; i++) {
|
|
129
|
-
const t = Math.max(0, Math.min(1, (baseOffset + i) / denominator));
|
|
130
|
-
const color = interpolateColor(startColor, endColor, t);
|
|
131
|
-
gradientChars.push(colorChar(chars[i] ?? "", color));
|
|
132
|
-
}
|
|
133
|
-
gradientChars.push(ANSI_RESET_FOREGROUND);
|
|
134
|
-
return gradientChars.join("");
|
|
135
|
-
}
|
|
136
|
-
/** Apply a left-to-right background gradient across a string. */
|
|
137
|
-
function horizontalGradientBackground(text, startColor, endColor, fgColor) {
|
|
138
|
-
const chars = Array.from(text);
|
|
139
|
-
if (chars.length === 0)
|
|
140
|
-
return "";
|
|
141
|
-
const fg = fgColor ? toAnsiColor(fgColor) : "";
|
|
142
|
-
if (chars.length === 1) {
|
|
143
|
-
return `${toAnsiBackground(startColor)}${fg}${chars[0] ?? ""}${ANSI_RESET_ALL}`;
|
|
144
|
-
}
|
|
145
|
-
const gradientChars = [];
|
|
146
|
-
for (let i = 0; i < chars.length; i++) {
|
|
147
|
-
const t = i / (chars.length - 1);
|
|
148
|
-
const color = interpolateColor(startColor, endColor, t);
|
|
149
|
-
gradientChars.push(`${toAnsiBackground(color)}${fg}${chars[i] ?? ""}`);
|
|
150
|
-
}
|
|
151
|
-
gradientChars.push(ANSI_RESET_ALL);
|
|
152
|
-
return gradientChars.join("");
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Apply a diagonal gradient across multiple lines.
|
|
156
|
-
* Each character's color is based on (row + col) / (totalRows + totalCols).
|
|
157
|
-
*/
|
|
158
|
-
function diagonalGradient(lines, startColor, endColor) {
|
|
159
|
-
if (lines.length === 0)
|
|
160
|
-
return [];
|
|
161
|
-
const splitLines = lines.map((line) => Array.from(line));
|
|
162
|
-
const maxLen = Math.max(...splitLines.map((lineChars) => lineChars.length));
|
|
163
|
-
if (maxLen === 0)
|
|
164
|
-
return lines.map(() => "");
|
|
165
|
-
const totalSteps = lines.length - 1 + maxLen - 1;
|
|
166
|
-
return splitLines.map((lineChars, row) => {
|
|
167
|
-
if (lineChars.length === 0)
|
|
168
|
-
return "";
|
|
169
|
-
const gradientChars = [];
|
|
170
|
-
for (let col = 0; col < lineChars.length; col++) {
|
|
171
|
-
const t = totalSteps > 0 ? (row + col) / totalSteps : 0;
|
|
172
|
-
const color = interpolateColor(startColor, endColor, t);
|
|
173
|
-
gradientChars.push(colorChar(lineChars[col] ?? "", color));
|
|
174
|
-
}
|
|
175
|
-
gradientChars.push(ANSI_RESET_FOREGROUND);
|
|
176
|
-
return gradientChars.join("");
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Apply a multiline gradient by scanning cells row-by-row.
|
|
181
|
-
* Progress advances left-to-right per row, then continues on the next row.
|
|
182
|
-
*/
|
|
183
|
-
function rowMajorGradient(lines, startColor, endColor) {
|
|
184
|
-
if (lines.length === 0)
|
|
185
|
-
return [];
|
|
186
|
-
const splitLines = lines.map((line) => Array.from(line));
|
|
187
|
-
const maxLen = Math.max(...splitLines.map((lineChars) => lineChars.length));
|
|
188
|
-
if (maxLen === 0)
|
|
189
|
-
return lines.map(() => "");
|
|
190
|
-
const totalCells = lines.length * maxLen;
|
|
191
|
-
return splitLines.map((lineChars, row) => {
|
|
192
|
-
if (lineChars.length === 0)
|
|
193
|
-
return "";
|
|
194
|
-
const gradientChars = [];
|
|
195
|
-
for (let col = 0; col < lineChars.length; col++) {
|
|
196
|
-
const cellIndex = row * maxLen + col;
|
|
197
|
-
const t = totalCells > 1 ? cellIndex / (totalCells - 1) : 0;
|
|
198
|
-
const color = interpolateColor(startColor, endColor, t);
|
|
199
|
-
gradientChars.push(colorChar(lineChars[col] ?? "", color));
|
|
200
|
-
}
|
|
201
|
-
gradientChars.push(ANSI_RESET_FOREGROUND);
|
|
202
|
-
return gradientChars.join("");
|
|
203
|
-
});
|
|
204
|
-
}
|
|
@@ -1,302 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DOWNLOADER_TABS = void 0;
|
|
4
|
-
exports.tabToSort = tabToSort;
|
|
5
|
-
exports.createDownloaderState = createDownloaderState;
|
|
6
|
-
exports.cycleTab = cycleTab;
|
|
7
|
-
exports.setModels = setModels;
|
|
8
|
-
exports.setFiles = setFiles;
|
|
9
|
-
exports.setLoading = setLoading;
|
|
10
|
-
exports.setLoadingModels = setLoadingModels;
|
|
11
|
-
exports.setLoadingFiles = setLoadingFiles;
|
|
12
|
-
exports.startDownload = startDownload;
|
|
13
|
-
exports.updateDownloadProgress = updateDownloadProgress;
|
|
14
|
-
exports.finishDownload = finishDownload;
|
|
15
|
-
exports.setPreloadingTabs = setPreloadingTabs;
|
|
16
|
-
exports.setCachedModels = setCachedModels;
|
|
17
|
-
exports.getCachedModels = getCachedModels;
|
|
18
|
-
exports.resetModelCache = resetModelCache;
|
|
19
|
-
exports.setError = setError;
|
|
20
|
-
exports.setDownloaderError = setDownloaderError;
|
|
21
|
-
exports.closeFileView = closeFileView;
|
|
22
|
-
exports.openCancelConfirm = openCancelConfirm;
|
|
23
|
-
exports.closeCancelConfirm = closeCancelConfirm;
|
|
24
|
-
exports.moveModelSelection = moveModelSelection;
|
|
25
|
-
exports.moveFileSelection = moveFileSelection;
|
|
26
|
-
exports.DOWNLOADER_TABS = ["Most Downloaded", "Top Rated", "Newest"];
|
|
27
|
-
function tabToSort(tab) {
|
|
28
|
-
if (tab === "Top Rated") {
|
|
29
|
-
return "trendingScore";
|
|
30
|
-
}
|
|
31
|
-
if (tab === "Newest") {
|
|
32
|
-
return "lastModified";
|
|
33
|
-
}
|
|
34
|
-
return "downloads";
|
|
35
|
-
}
|
|
36
|
-
function createDownloaderState(memory) {
|
|
37
|
-
return {
|
|
38
|
-
isOpen: true,
|
|
39
|
-
view: "models",
|
|
40
|
-
tab: "Most Downloaded",
|
|
41
|
-
searchQuery: "",
|
|
42
|
-
models: [],
|
|
43
|
-
files: [],
|
|
44
|
-
selectedModelIndex: 0,
|
|
45
|
-
selectedFileIndex: 0,
|
|
46
|
-
modelScrollOffset: 0,
|
|
47
|
-
fileScrollOffset: 0,
|
|
48
|
-
phase: "idle",
|
|
49
|
-
loading: false,
|
|
50
|
-
loadingMessage: "Loading models...",
|
|
51
|
-
errorMessage: "",
|
|
52
|
-
download: null,
|
|
53
|
-
selectedRepoId: "",
|
|
54
|
-
ramGb: memory.ramGb,
|
|
55
|
-
vramGb: memory.vramGb,
|
|
56
|
-
totalMemoryGb: memory.totalMemoryGb,
|
|
57
|
-
diskFreeGb: memory.diskFreeGb ?? 0,
|
|
58
|
-
cacheQuery: "",
|
|
59
|
-
modelCacheByTab: {},
|
|
60
|
-
preloadingTabs: false,
|
|
61
|
-
cancelConfirmOpen: false
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
function cycleTab(state, direction) {
|
|
65
|
-
const currentIndex = exports.DOWNLOADER_TABS.indexOf(state.tab);
|
|
66
|
-
const nextIndex = (currentIndex + direction + exports.DOWNLOADER_TABS.length) % exports.DOWNLOADER_TABS.length;
|
|
67
|
-
return {
|
|
68
|
-
...state,
|
|
69
|
-
tab: exports.DOWNLOADER_TABS[nextIndex] ?? "Most Downloaded",
|
|
70
|
-
selectedModelIndex: 0,
|
|
71
|
-
modelScrollOffset: 0
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
function setModels(state, models) {
|
|
75
|
-
return {
|
|
76
|
-
...state,
|
|
77
|
-
models,
|
|
78
|
-
selectedModelIndex: models.length > 0 ? Math.min(state.selectedModelIndex, models.length - 1) : 0,
|
|
79
|
-
modelScrollOffset: 0,
|
|
80
|
-
phase: "idle",
|
|
81
|
-
loading: false,
|
|
82
|
-
errorMessage: "",
|
|
83
|
-
download: null,
|
|
84
|
-
cancelConfirmOpen: false
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
function setFiles(state, repoId, files) {
|
|
88
|
-
return {
|
|
89
|
-
...state,
|
|
90
|
-
selectedRepoId: repoId,
|
|
91
|
-
view: "files",
|
|
92
|
-
files,
|
|
93
|
-
selectedFileIndex: 0,
|
|
94
|
-
fileScrollOffset: 0,
|
|
95
|
-
phase: "idle",
|
|
96
|
-
loading: false,
|
|
97
|
-
errorMessage: "",
|
|
98
|
-
download: null,
|
|
99
|
-
cancelConfirmOpen: false
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
function setLoading(state, message) {
|
|
103
|
-
return {
|
|
104
|
-
...state,
|
|
105
|
-
phase: "loading-models",
|
|
106
|
-
loading: true,
|
|
107
|
-
loadingMessage: message,
|
|
108
|
-
errorMessage: "",
|
|
109
|
-
download: null,
|
|
110
|
-
cancelConfirmOpen: false
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
function setLoadingModels(state, message) {
|
|
114
|
-
return {
|
|
115
|
-
...state,
|
|
116
|
-
phase: "loading-models",
|
|
117
|
-
loading: true,
|
|
118
|
-
loadingMessage: message,
|
|
119
|
-
errorMessage: "",
|
|
120
|
-
download: null,
|
|
121
|
-
cancelConfirmOpen: false
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
function setLoadingFiles(state, message) {
|
|
125
|
-
return {
|
|
126
|
-
...state,
|
|
127
|
-
phase: "loading-files",
|
|
128
|
-
loading: true,
|
|
129
|
-
loadingMessage: message,
|
|
130
|
-
errorMessage: "",
|
|
131
|
-
download: null,
|
|
132
|
-
cancelConfirmOpen: false
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
function startDownload(state, repoId, filename, statusText) {
|
|
136
|
-
const now = Date.now();
|
|
137
|
-
return {
|
|
138
|
-
...state,
|
|
139
|
-
phase: "downloading",
|
|
140
|
-
loading: true,
|
|
141
|
-
loadingMessage: statusText,
|
|
142
|
-
errorMessage: "",
|
|
143
|
-
download: {
|
|
144
|
-
repoId,
|
|
145
|
-
filename,
|
|
146
|
-
bytesDownloaded: 0,
|
|
147
|
-
totalBytes: null,
|
|
148
|
-
startedAtMs: now,
|
|
149
|
-
lastUpdateAtMs: now,
|
|
150
|
-
statusText
|
|
151
|
-
},
|
|
152
|
-
cancelConfirmOpen: false
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
function updateDownloadProgress(state, update) {
|
|
156
|
-
if (state.phase !== "downloading" || !state.download) {
|
|
157
|
-
return state;
|
|
158
|
-
}
|
|
159
|
-
return {
|
|
160
|
-
...state,
|
|
161
|
-
loadingMessage: update.statusText,
|
|
162
|
-
download: {
|
|
163
|
-
...state.download,
|
|
164
|
-
bytesDownloaded: Math.max(0, update.bytesDownloaded),
|
|
165
|
-
totalBytes: update.totalBytes,
|
|
166
|
-
lastUpdateAtMs: Date.now(),
|
|
167
|
-
statusText: update.statusText
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
function finishDownload(state) {
|
|
172
|
-
return {
|
|
173
|
-
...state,
|
|
174
|
-
phase: "idle",
|
|
175
|
-
loading: false,
|
|
176
|
-
loadingMessage: "",
|
|
177
|
-
errorMessage: "",
|
|
178
|
-
download: null,
|
|
179
|
-
cancelConfirmOpen: false
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
function setPreloadingTabs(state, preloadingTabs) {
|
|
183
|
-
return {
|
|
184
|
-
...state,
|
|
185
|
-
preloadingTabs
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
function setCachedModels(state, tab, query, models) {
|
|
189
|
-
const normalizedQuery = query.trim();
|
|
190
|
-
const cache = state.cacheQuery === normalizedQuery ? state.modelCacheByTab : {};
|
|
191
|
-
return {
|
|
192
|
-
...state,
|
|
193
|
-
cacheQuery: normalizedQuery,
|
|
194
|
-
modelCacheByTab: {
|
|
195
|
-
...cache,
|
|
196
|
-
[tab]: models
|
|
197
|
-
}
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
function getCachedModels(state, tab, query) {
|
|
201
|
-
if (state.cacheQuery !== query.trim()) {
|
|
202
|
-
return null;
|
|
203
|
-
}
|
|
204
|
-
return state.modelCacheByTab[tab] ?? null;
|
|
205
|
-
}
|
|
206
|
-
function resetModelCache(state, query) {
|
|
207
|
-
return {
|
|
208
|
-
...state,
|
|
209
|
-
cacheQuery: query.trim(),
|
|
210
|
-
modelCacheByTab: {}
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
function setError(state, message) {
|
|
214
|
-
return {
|
|
215
|
-
...state,
|
|
216
|
-
phase: "error",
|
|
217
|
-
loading: false,
|
|
218
|
-
errorMessage: message,
|
|
219
|
-
download: null,
|
|
220
|
-
cancelConfirmOpen: false
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
function setDownloaderError(state, message) {
|
|
224
|
-
return {
|
|
225
|
-
...state,
|
|
226
|
-
phase: "error",
|
|
227
|
-
loading: false,
|
|
228
|
-
errorMessage: message,
|
|
229
|
-
download: null,
|
|
230
|
-
cancelConfirmOpen: false
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
function closeFileView(state) {
|
|
234
|
-
return {
|
|
235
|
-
...state,
|
|
236
|
-
view: "models",
|
|
237
|
-
files: [],
|
|
238
|
-
selectedFileIndex: 0,
|
|
239
|
-
fileScrollOffset: 0,
|
|
240
|
-
phase: "idle",
|
|
241
|
-
loading: false,
|
|
242
|
-
errorMessage: "",
|
|
243
|
-
download: null,
|
|
244
|
-
cancelConfirmOpen: false
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
function openCancelConfirm(state) {
|
|
248
|
-
if (state.phase !== "downloading" || !state.download) {
|
|
249
|
-
return state;
|
|
250
|
-
}
|
|
251
|
-
return {
|
|
252
|
-
...state,
|
|
253
|
-
cancelConfirmOpen: true
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
function closeCancelConfirm(state) {
|
|
257
|
-
if (!state.cancelConfirmOpen) {
|
|
258
|
-
return state;
|
|
259
|
-
}
|
|
260
|
-
return {
|
|
261
|
-
...state,
|
|
262
|
-
cancelConfirmOpen: false
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
function moveModelSelection(state, delta, windowSize) {
|
|
266
|
-
if (state.models.length === 0) {
|
|
267
|
-
return state;
|
|
268
|
-
}
|
|
269
|
-
const max = state.models.length - 1;
|
|
270
|
-
const nextIndex = Math.max(0, Math.min(max, state.selectedModelIndex + delta));
|
|
271
|
-
let nextOffset = state.modelScrollOffset;
|
|
272
|
-
if (nextIndex < nextOffset) {
|
|
273
|
-
nextOffset = nextIndex;
|
|
274
|
-
}
|
|
275
|
-
if (nextIndex >= nextOffset + windowSize) {
|
|
276
|
-
nextOffset = nextIndex - windowSize + 1;
|
|
277
|
-
}
|
|
278
|
-
return {
|
|
279
|
-
...state,
|
|
280
|
-
selectedModelIndex: nextIndex,
|
|
281
|
-
modelScrollOffset: Math.max(0, nextOffset)
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
function moveFileSelection(state, delta, windowSize) {
|
|
285
|
-
if (state.files.length === 0) {
|
|
286
|
-
return state;
|
|
287
|
-
}
|
|
288
|
-
const max = state.files.length - 1;
|
|
289
|
-
const nextIndex = Math.max(0, Math.min(max, state.selectedFileIndex + delta));
|
|
290
|
-
let nextOffset = state.fileScrollOffset;
|
|
291
|
-
if (nextIndex < nextOffset) {
|
|
292
|
-
nextOffset = nextIndex;
|
|
293
|
-
}
|
|
294
|
-
if (nextIndex >= nextOffset + windowSize) {
|
|
295
|
-
nextOffset = nextIndex - windowSize + 1;
|
|
296
|
-
}
|
|
297
|
-
return {
|
|
298
|
-
...state,
|
|
299
|
-
selectedFileIndex: nextIndex,
|
|
300
|
-
fileScrollOffset: Math.max(0, nextOffset)
|
|
301
|
-
};
|
|
302
|
-
}
|