@dexto/tui 1.6.11 → 1.6.13

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.
Files changed (66) hide show
  1. package/dist/InkCLIRefactored.cjs +39 -29
  2. package/dist/InkCLIRefactored.d.ts.map +1 -1
  3. package/dist/InkCLIRefactored.js +39 -29
  4. package/dist/components/Footer.cjs +9 -2
  5. package/dist/components/Footer.d.ts +3 -2
  6. package/dist/components/Footer.d.ts.map +1 -1
  7. package/dist/components/Footer.js +17 -3
  8. package/dist/components/modes/AlternateBufferCLI.cjs +2 -1
  9. package/dist/components/modes/AlternateBufferCLI.d.ts.map +1 -1
  10. package/dist/components/modes/AlternateBufferCLI.js +2 -1
  11. package/dist/components/modes/StaticCLI.cjs +2 -1
  12. package/dist/components/modes/StaticCLI.d.ts.map +1 -1
  13. package/dist/components/modes/StaticCLI.js +2 -1
  14. package/dist/components/overlays/ChatGPTUsageCapOverlay.cjs +90 -0
  15. package/dist/components/overlays/ChatGPTUsageCapOverlay.d.ts +19 -0
  16. package/dist/components/overlays/ChatGPTUsageCapOverlay.d.ts.map +1 -0
  17. package/dist/components/overlays/ChatGPTUsageCapOverlay.js +70 -0
  18. package/dist/components/overlays/ModelSelectorRefactored.cjs +263 -38
  19. package/dist/components/overlays/ModelSelectorRefactored.d.ts.map +1 -1
  20. package/dist/components/overlays/ModelSelectorRefactored.js +267 -38
  21. package/dist/components/overlays/ReasoningOverlay.cjs +1 -1
  22. package/dist/components/overlays/ReasoningOverlay.js +1 -1
  23. package/dist/containers/OverlayContainer.cjs +104 -13
  24. package/dist/containers/OverlayContainer.d.ts.map +1 -1
  25. package/dist/containers/OverlayContainer.js +104 -13
  26. package/dist/hooks/useAgentEvents.cjs +33 -2
  27. package/dist/hooks/useAgentEvents.d.ts.map +1 -1
  28. package/dist/hooks/useAgentEvents.js +35 -3
  29. package/dist/hooks/useCLIState.cjs +1 -0
  30. package/dist/hooks/useCLIState.d.ts.map +1 -1
  31. package/dist/hooks/useCLIState.js +1 -0
  32. package/dist/interactive-commands/exit-stats.cjs +16 -0
  33. package/dist/interactive-commands/exit-stats.d.ts +4 -0
  34. package/dist/interactive-commands/exit-stats.d.ts.map +1 -1
  35. package/dist/interactive-commands/exit-stats.js +15 -0
  36. package/dist/interactive-commands/general-commands.cjs +13 -2
  37. package/dist/interactive-commands/general-commands.d.ts.map +1 -1
  38. package/dist/interactive-commands/general-commands.js +14 -3
  39. package/dist/interactive-commands/general-commands.test.cjs +152 -0
  40. package/dist/interactive-commands/general-commands.test.d.ts +2 -0
  41. package/dist/interactive-commands/general-commands.test.d.ts.map +1 -0
  42. package/dist/interactive-commands/general-commands.test.js +151 -0
  43. package/dist/services/processStream.test.cjs +1 -0
  44. package/dist/services/processStream.test.js +1 -0
  45. package/dist/state/initialState.cjs +1 -0
  46. package/dist/state/initialState.d.ts.map +1 -1
  47. package/dist/state/initialState.js +1 -0
  48. package/dist/state/types.d.ts +4 -2
  49. package/dist/state/types.d.ts.map +1 -1
  50. package/dist/utils/chatgpt-rate-limit.cjs +72 -0
  51. package/dist/utils/chatgpt-rate-limit.d.ts +11 -0
  52. package/dist/utils/chatgpt-rate-limit.d.ts.map +1 -0
  53. package/dist/utils/chatgpt-rate-limit.js +49 -0
  54. package/dist/utils/chatgpt-rate-limit.test.cjs +46 -0
  55. package/dist/utils/chatgpt-rate-limit.test.d.ts +2 -0
  56. package/dist/utils/chatgpt-rate-limit.test.d.ts.map +1 -0
  57. package/dist/utils/chatgpt-rate-limit.test.js +49 -0
  58. package/dist/utils/llm-provider-display.cjs +11 -1
  59. package/dist/utils/llm-provider-display.d.ts +2 -2
  60. package/dist/utils/llm-provider-display.d.ts.map +1 -1
  61. package/dist/utils/llm-provider-display.js +11 -1
  62. package/dist/utils/llm-provider-display.test.cjs +15 -0
  63. package/dist/utils/llm-provider-display.test.d.ts +2 -0
  64. package/dist/utils/llm-provider-display.test.d.ts.map +1 -0
  65. package/dist/utils/llm-provider-display.test.js +14 -0
  66. package/package.json +4 -4
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var chatgpt_rate_limit_exports = {};
20
+ __export(chatgpt_rate_limit_exports, {
21
+ CHATGPT_RATE_LIMIT_WARNING_THRESHOLD: () => CHATGPT_RATE_LIMIT_WARNING_THRESHOLD,
22
+ getChatGPTRateLimitHint: () => getChatGPTRateLimitHint,
23
+ resolveChatGPTFallbackModel: () => resolveChatGPTFallbackModel,
24
+ shouldShowChatGPTRateLimitHint: () => shouldShowChatGPTRateLimitHint
25
+ });
26
+ module.exports = __toCommonJS(chatgpt_rate_limit_exports);
27
+ var import_core = require("@dexto/core");
28
+ const CHATGPT_RATE_LIMIT_WARNING_THRESHOLD = 80;
29
+ function shouldShowChatGPTRateLimitHint(status) {
30
+ if (!status) {
31
+ return false;
32
+ }
33
+ return status.exceeded || status.usedPercent >= CHATGPT_RATE_LIMIT_WARNING_THRESHOLD;
34
+ }
35
+ function formatResetTime(resetsAt) {
36
+ if (!resetsAt) {
37
+ return null;
38
+ }
39
+ const date = new Date(resetsAt);
40
+ if (Number.isNaN(date.getTime())) {
41
+ return null;
42
+ }
43
+ return new Intl.DateTimeFormat("en-US", {
44
+ hour: "numeric",
45
+ minute: "2-digit"
46
+ }).format(date);
47
+ }
48
+ function getChatGPTRateLimitHint(status) {
49
+ const resetTime = formatResetTime(status.resetsAt);
50
+ if (status.exceeded) {
51
+ return resetTime ? `ChatGPT cap reached \xB7 resets ${resetTime}` : "ChatGPT cap reached";
52
+ }
53
+ const usedPercent = Math.max(0, Math.min(100, Math.round(status.usedPercent)));
54
+ return resetTime ? `ChatGPT cap ${usedPercent}% used \xB7 resets ${resetTime}` : `ChatGPT cap ${usedPercent}% used`;
55
+ }
56
+ function resolveChatGPTFallbackModel(currentModel) {
57
+ const currentModelIsValid = (0, import_core.isModelValidForProvider)("openai", currentModel);
58
+ const fallbackModel = currentModelIsValid ? currentModel : (0, import_core.getDefaultModelForProvider)("openai") ?? currentModel;
59
+ return {
60
+ provider: "openai",
61
+ model: fallbackModel,
62
+ displayName: (0, import_core.getModelDisplayName)(fallbackModel, "openai"),
63
+ usedDefaultFallback: !currentModelIsValid && fallbackModel !== currentModel
64
+ };
65
+ }
66
+ // Annotate the CommonJS export names for ESM import in node:
67
+ 0 && (module.exports = {
68
+ CHATGPT_RATE_LIMIT_WARNING_THRESHOLD,
69
+ getChatGPTRateLimitHint,
70
+ resolveChatGPTFallbackModel,
71
+ shouldShowChatGPTRateLimitHint
72
+ });
@@ -0,0 +1,11 @@
1
+ import { type CodexRateLimitSnapshot } from '@dexto/core';
2
+ export declare const CHATGPT_RATE_LIMIT_WARNING_THRESHOLD = 80;
3
+ export declare function shouldShowChatGPTRateLimitHint(status: CodexRateLimitSnapshot | null | undefined): boolean;
4
+ export declare function getChatGPTRateLimitHint(status: CodexRateLimitSnapshot): string;
5
+ export declare function resolveChatGPTFallbackModel(currentModel: string): {
6
+ provider: 'openai';
7
+ model: string;
8
+ displayName: string;
9
+ usedDefaultFallback: boolean;
10
+ };
11
+ //# sourceMappingURL=chatgpt-rate-limit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatgpt-rate-limit.d.ts","sourceRoot":"","sources":["../../src/utils/chatgpt-rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,KAAK,sBAAsB,EAC9B,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,oCAAoC,KAAK,CAAC;AAEvD,wBAAgB,8BAA8B,CAC1C,MAAM,EAAE,sBAAsB,GAAG,IAAI,GAAG,SAAS,GAClD,OAAO,CAMT;AAkBD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAW9E;AAED,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM,GAAG;IAC/D,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,OAAO,CAAC;CAChC,CAYA"}
@@ -0,0 +1,49 @@
1
+ import {
2
+ getDefaultModelForProvider,
3
+ getModelDisplayName,
4
+ isModelValidForProvider
5
+ } from "@dexto/core";
6
+ const CHATGPT_RATE_LIMIT_WARNING_THRESHOLD = 80;
7
+ function shouldShowChatGPTRateLimitHint(status) {
8
+ if (!status) {
9
+ return false;
10
+ }
11
+ return status.exceeded || status.usedPercent >= CHATGPT_RATE_LIMIT_WARNING_THRESHOLD;
12
+ }
13
+ function formatResetTime(resetsAt) {
14
+ if (!resetsAt) {
15
+ return null;
16
+ }
17
+ const date = new Date(resetsAt);
18
+ if (Number.isNaN(date.getTime())) {
19
+ return null;
20
+ }
21
+ return new Intl.DateTimeFormat("en-US", {
22
+ hour: "numeric",
23
+ minute: "2-digit"
24
+ }).format(date);
25
+ }
26
+ function getChatGPTRateLimitHint(status) {
27
+ const resetTime = formatResetTime(status.resetsAt);
28
+ if (status.exceeded) {
29
+ return resetTime ? `ChatGPT cap reached \xB7 resets ${resetTime}` : "ChatGPT cap reached";
30
+ }
31
+ const usedPercent = Math.max(0, Math.min(100, Math.round(status.usedPercent)));
32
+ return resetTime ? `ChatGPT cap ${usedPercent}% used \xB7 resets ${resetTime}` : `ChatGPT cap ${usedPercent}% used`;
33
+ }
34
+ function resolveChatGPTFallbackModel(currentModel) {
35
+ const currentModelIsValid = isModelValidForProvider("openai", currentModel);
36
+ const fallbackModel = currentModelIsValid ? currentModel : getDefaultModelForProvider("openai") ?? currentModel;
37
+ return {
38
+ provider: "openai",
39
+ model: fallbackModel,
40
+ displayName: getModelDisplayName(fallbackModel, "openai"),
41
+ usedDefaultFallback: !currentModelIsValid && fallbackModel !== currentModel
42
+ };
43
+ }
44
+ export {
45
+ CHATGPT_RATE_LIMIT_WARNING_THRESHOLD,
46
+ getChatGPTRateLimitHint,
47
+ resolveChatGPTFallbackModel,
48
+ shouldShowChatGPTRateLimitHint
49
+ };
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var import_vitest = require("vitest");
3
+ var import_chatgpt_rate_limit = require("./chatgpt-rate-limit.js");
4
+ (0, import_vitest.describe)("chatgpt-rate-limit utils", () => {
5
+ (0, import_vitest.it)("shows footer hints when ChatGPT usage is approaching the cap", () => {
6
+ (0, import_vitest.expect)(
7
+ (0, import_chatgpt_rate_limit.shouldShowChatGPTRateLimitHint)({
8
+ source: "chatgpt-login",
9
+ usedPercent: 82,
10
+ exceeded: false
11
+ })
12
+ ).toBe(true);
13
+ (0, import_vitest.expect)(
14
+ (0, import_chatgpt_rate_limit.getChatGPTRateLimitHint)({
15
+ source: "chatgpt-login",
16
+ usedPercent: 82,
17
+ exceeded: false
18
+ })
19
+ ).toBe("ChatGPT cap 82% used");
20
+ });
21
+ (0, import_vitest.it)("formats a hard cap state without showing fake reset data", () => {
22
+ (0, import_vitest.expect)(
23
+ (0, import_chatgpt_rate_limit.getChatGPTRateLimitHint)({
24
+ source: "chatgpt-login",
25
+ usedPercent: 100,
26
+ exceeded: true
27
+ })
28
+ ).toBe("ChatGPT cap reached");
29
+ });
30
+ (0, import_vitest.it)("keeps the same model when it is available via the OpenAI API", () => {
31
+ (0, import_vitest.expect)((0, import_chatgpt_rate_limit.resolveChatGPTFallbackModel)("gpt-5")).toEqual({
32
+ provider: "openai",
33
+ model: "gpt-5",
34
+ displayName: "GPT-5",
35
+ usedDefaultFallback: false
36
+ });
37
+ });
38
+ (0, import_vitest.it)("falls back to the default OpenAI model when the ChatGPT model is not available", () => {
39
+ (0, import_vitest.expect)((0, import_chatgpt_rate_limit.resolveChatGPTFallbackModel)("nonexistent-chatgpt-model")).toEqual({
40
+ provider: "openai",
41
+ model: "gpt-5-mini",
42
+ displayName: "GPT-5 Mini",
43
+ usedDefaultFallback: true
44
+ });
45
+ });
46
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=chatgpt-rate-limit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatgpt-rate-limit.test.d.ts","sourceRoot":"","sources":["../../src/utils/chatgpt-rate-limit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,49 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import {
3
+ getChatGPTRateLimitHint,
4
+ resolveChatGPTFallbackModel,
5
+ shouldShowChatGPTRateLimitHint
6
+ } from "./chatgpt-rate-limit.js";
7
+ describe("chatgpt-rate-limit utils", () => {
8
+ it("shows footer hints when ChatGPT usage is approaching the cap", () => {
9
+ expect(
10
+ shouldShowChatGPTRateLimitHint({
11
+ source: "chatgpt-login",
12
+ usedPercent: 82,
13
+ exceeded: false
14
+ })
15
+ ).toBe(true);
16
+ expect(
17
+ getChatGPTRateLimitHint({
18
+ source: "chatgpt-login",
19
+ usedPercent: 82,
20
+ exceeded: false
21
+ })
22
+ ).toBe("ChatGPT cap 82% used");
23
+ });
24
+ it("formats a hard cap state without showing fake reset data", () => {
25
+ expect(
26
+ getChatGPTRateLimitHint({
27
+ source: "chatgpt-login",
28
+ usedPercent: 100,
29
+ exceeded: true
30
+ })
31
+ ).toBe("ChatGPT cap reached");
32
+ });
33
+ it("keeps the same model when it is available via the OpenAI API", () => {
34
+ expect(resolveChatGPTFallbackModel("gpt-5")).toEqual({
35
+ provider: "openai",
36
+ model: "gpt-5",
37
+ displayName: "GPT-5",
38
+ usedDefaultFallback: false
39
+ });
40
+ });
41
+ it("falls back to the default OpenAI model when the ChatGPT model is not available", () => {
42
+ expect(resolveChatGPTFallbackModel("nonexistent-chatgpt-model")).toEqual({
43
+ provider: "openai",
44
+ model: "gpt-5-mini",
45
+ displayName: "GPT-5 Mini",
46
+ usedDefaultFallback: true
47
+ });
48
+ });
49
+ });
@@ -21,6 +21,7 @@ __export(llm_provider_display_exports, {
21
21
  getLLMProviderDisplayName: () => getLLMProviderDisplayName
22
22
  });
23
23
  module.exports = __toCommonJS(llm_provider_display_exports);
24
+ var import_core = require("@dexto/core");
24
25
  const LLM_PROVIDER_DISPLAY_NAMES = {
25
26
  openai: "OpenAI",
26
27
  "openai-compatible": "OpenAI-Compatible",
@@ -40,7 +41,16 @@ const LLM_PROVIDER_DISPLAY_NAMES = {
40
41
  ollama: "Ollama",
41
42
  "dexto-nova": "Dexto Nova"
42
43
  };
43
- function getLLMProviderDisplayName(provider) {
44
+ function getLLMProviderDisplayName(provider, baseURL) {
45
+ if (provider === "openai-compatible") {
46
+ const codex = (0, import_core.parseCodexBaseURL)(baseURL);
47
+ if (codex?.authMode === "chatgpt") {
48
+ return "via ChatGPT";
49
+ }
50
+ if (codex) {
51
+ return "via Codex";
52
+ }
53
+ }
44
54
  return LLM_PROVIDER_DISPLAY_NAMES[provider] ?? provider;
45
55
  }
46
56
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,3 +1,3 @@
1
- import type { LLMProvider } from '@dexto/core';
2
- export declare function getLLMProviderDisplayName(provider: LLMProvider): string;
1
+ import { type LLMProvider } from '@dexto/core';
2
+ export declare function getLLMProviderDisplayName(provider: LLMProvider, baseURL?: string): string;
3
3
  //# sourceMappingURL=llm-provider-display.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"llm-provider-display.d.ts","sourceRoot":"","sources":["../../src/utils/llm-provider-display.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAsB/C,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAEvE"}
1
+ {"version":3,"file":"llm-provider-display.d.ts","sourceRoot":"","sources":["../../src/utils/llm-provider-display.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAsBlE,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAYzF"}
@@ -1,3 +1,4 @@
1
+ import { parseCodexBaseURL } from "@dexto/core";
1
2
  const LLM_PROVIDER_DISPLAY_NAMES = {
2
3
  openai: "OpenAI",
3
4
  "openai-compatible": "OpenAI-Compatible",
@@ -17,7 +18,16 @@ const LLM_PROVIDER_DISPLAY_NAMES = {
17
18
  ollama: "Ollama",
18
19
  "dexto-nova": "Dexto Nova"
19
20
  };
20
- function getLLMProviderDisplayName(provider) {
21
+ function getLLMProviderDisplayName(provider, baseURL) {
22
+ if (provider === "openai-compatible") {
23
+ const codex = parseCodexBaseURL(baseURL);
24
+ if (codex?.authMode === "chatgpt") {
25
+ return "via ChatGPT";
26
+ }
27
+ if (codex) {
28
+ return "via Codex";
29
+ }
30
+ }
21
31
  return LLM_PROVIDER_DISPLAY_NAMES[provider] ?? provider;
22
32
  }
23
33
  export {
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ var import_vitest = require("vitest");
3
+ var import_llm_provider_display = require("./llm-provider-display.js");
4
+ (0, import_vitest.describe)("getLLMProviderDisplayName", () => {
5
+ (0, import_vitest.it)("shows ChatGPT-backed Codex configs distinctly", () => {
6
+ (0, import_vitest.expect)((0, import_llm_provider_display.getLLMProviderDisplayName)("openai-compatible", "codex://chatgpt")).toBe(
7
+ "via ChatGPT"
8
+ );
9
+ });
10
+ (0, import_vitest.it)("falls back to generic openai-compatible labeling for standard endpoints", () => {
11
+ (0, import_vitest.expect)((0, import_llm_provider_display.getLLMProviderDisplayName)("openai-compatible", "https://example.com/v1")).toBe(
12
+ "OpenAI-Compatible"
13
+ );
14
+ });
15
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=llm-provider-display.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-provider-display.test.d.ts","sourceRoot":"","sources":["../../src/utils/llm-provider-display.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { getLLMProviderDisplayName } from "./llm-provider-display.js";
3
+ describe("getLLMProviderDisplayName", () => {
4
+ it("shows ChatGPT-backed Codex configs distinctly", () => {
5
+ expect(getLLMProviderDisplayName("openai-compatible", "codex://chatgpt")).toBe(
6
+ "via ChatGPT"
7
+ );
8
+ });
9
+ it("falls back to generic openai-compatible labeling for standard endpoints", () => {
10
+ expect(getLLMProviderDisplayName("openai-compatible", "https://example.com/v1")).toBe(
11
+ "OpenAI-Compatible"
12
+ );
13
+ });
14
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dexto/tui",
3
- "version": "1.6.11",
3
+ "version": "1.6.13",
4
4
  "description": "Interactive terminal UI for Dexto CLI",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -28,9 +28,9 @@
28
28
  "string-width": "^8.1.0",
29
29
  "strip-ansi": "^7.1.2",
30
30
  "wrap-ansi": "^9.0.2",
31
- "@dexto/agent-management": "1.6.11",
32
- "@dexto/registry": "1.6.11",
33
- "@dexto/core": "1.6.11"
31
+ "@dexto/agent-management": "1.6.13",
32
+ "@dexto/core": "1.6.13",
33
+ "@dexto/registry": "1.6.13"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/react": "^19.0.0",