@selesai/code 0.9.14 → 0.10.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/CHANGELOG.md +27 -0
- package/README.md +6 -9
- package/dist/defaults/models.json +79 -29
- package/dist/defaults/settings.json +3 -7
- package/dist/extensions/package.json +3 -4
- package/dist/extensions/pi-zentui/.editorconfig +12 -0
- package/dist/extensions/pi-zentui/.github/CODEOWNERS +1 -0
- package/dist/extensions/pi-zentui/.github/ISSUE_TEMPLATE/bug_report.yml +110 -0
- package/dist/extensions/pi-zentui/.github/ISSUE_TEMPLATE/config.yml +8 -0
- package/dist/extensions/pi-zentui/.github/ISSUE_TEMPLATE/config_question.yml +56 -0
- package/dist/extensions/pi-zentui/.github/ISSUE_TEMPLATE/feature_request.yml +63 -0
- package/dist/extensions/pi-zentui/.github/ISSUE_TEMPLATE/rendering_issue.yml +106 -0
- package/dist/extensions/pi-zentui/.github/ISSUE_TEMPLATE/runtime_detection.yml +103 -0
- package/dist/extensions/pi-zentui/.github/dependabot.yml +47 -0
- package/dist/extensions/pi-zentui/.github/pull_request_template.md +34 -0
- package/dist/extensions/pi-zentui/.github/release.yml +18 -0
- package/dist/extensions/pi-zentui/.github/workflows/ci.yml +79 -0
- package/dist/extensions/pi-zentui/.github/workflows/publish.yml +63 -0
- package/dist/extensions/pi-zentui/AGENTS.md +107 -0
- package/dist/extensions/pi-zentui/CONTRIBUTING.md +68 -0
- package/dist/extensions/pi-zentui/LICENSE +21 -0
- package/dist/extensions/pi-zentui/README.md +188 -0
- package/dist/extensions/pi-zentui/SECURITY.md +18 -0
- package/dist/extensions/pi-zentui/assets/main-cover.png +0 -0
- package/dist/extensions/pi-zentui/assets/screenshots/editor-accent-rail.png +0 -0
- package/dist/extensions/pi-zentui/assets/screenshots/editor-minimalist.png +0 -0
- package/dist/extensions/pi-zentui/assets/screenshots/editor-opencode-copy-friendly.png +0 -0
- package/dist/extensions/pi-zentui/assets/screenshots/editor-opencode.png +0 -0
- package/dist/extensions/pi-zentui/assets/screenshots/user-message-compact.png +0 -0
- package/dist/extensions/pi-zentui/assets/screenshots/user-message-framed-copy-friendly.png +0 -0
- package/dist/extensions/pi-zentui/assets/screenshots/user-message-framed.png +0 -0
- package/dist/extensions/pi-zentui/assets/screenshots/user-message-labeled.png +0 -0
- package/dist/extensions/pi-zentui/assets/zentui.png +0 -0
- package/dist/extensions/pi-zentui/biome.json +31 -0
- package/dist/extensions/pi-zentui/docs/configuration.md +509 -0
- package/dist/extensions/pi-zentui/docs/footer-format.md +162 -0
- package/dist/extensions/pi-zentui/extensions/zentui/accent-rail-editor.ts +99 -0
- package/dist/extensions/pi-zentui/extensions/zentui/accent-rail-layout-patch.ts +457 -0
- package/dist/extensions/pi-zentui/extensions/zentui/completion-menu.ts +157 -0
- package/dist/extensions/pi-zentui/extensions/zentui/config.ts +2100 -0
- package/dist/extensions/pi-zentui/extensions/zentui/editor-metadata-format.ts +321 -0
- package/dist/extensions/pi-zentui/extensions/zentui/editor-transfer.ts +73 -0
- package/dist/extensions/pi-zentui/extensions/zentui/extension-status.ts +89 -0
- package/dist/extensions/pi-zentui/extensions/zentui/footer-format.ts +364 -0
- package/dist/extensions/pi-zentui/extensions/zentui/footer-layout.ts +122 -0
- package/dist/extensions/pi-zentui/extensions/zentui/footer.ts +812 -0
- package/dist/extensions/pi-zentui/extensions/zentui/format.ts +568 -0
- package/dist/extensions/pi-zentui/extensions/zentui/git.ts +384 -0
- package/dist/extensions/pi-zentui/extensions/zentui/icons.ts +252 -0
- package/dist/extensions/pi-zentui/extensions/zentui/index.ts +1406 -0
- package/dist/extensions/pi-zentui/extensions/zentui/interaction-summary.ts +1049 -0
- package/dist/extensions/pi-zentui/extensions/zentui/live-context.ts +75 -0
- package/dist/extensions/pi-zentui/extensions/zentui/minimalist-editor.ts +463 -0
- package/dist/extensions/pi-zentui/extensions/zentui/package-version.ts +651 -0
- package/dist/extensions/pi-zentui/extensions/zentui/project-refresh.ts +120 -0
- package/dist/extensions/pi-zentui/extensions/zentui/project-state.ts +59 -0
- package/dist/extensions/pi-zentui/extensions/zentui/prototype-patch-registry.ts +166 -0
- package/dist/extensions/pi-zentui/extensions/zentui/repository-root.ts +98 -0
- package/dist/extensions/pi-zentui/extensions/zentui/runtime.ts +841 -0
- package/dist/extensions/pi-zentui/extensions/zentui/selector-border.ts +93 -0
- package/dist/extensions/pi-zentui/extensions/zentui/session-lifecycle.ts +60 -0
- package/dist/extensions/pi-zentui/extensions/zentui/settings-command.ts +1796 -0
- package/dist/extensions/pi-zentui/extensions/zentui/settings-previews.ts +128 -0
- package/dist/extensions/pi-zentui/extensions/zentui/state.ts +94 -0
- package/dist/extensions/pi-zentui/extensions/zentui/style.ts +424 -0
- package/dist/extensions/pi-zentui/extensions/zentui/telemetry.ts +82 -0
- package/dist/extensions/pi-zentui/extensions/zentui/ui.ts +1290 -0
- package/dist/extensions/pi-zentui/extensions/zentui/user-message-osc.ts +248 -0
- package/dist/extensions/pi-zentui/extensions/zentui/user-message-styles.ts +215 -0
- package/dist/extensions/pi-zentui/extensions/zentui/user-message.ts +206 -0
- package/dist/extensions/pi-zentui/extensions/zentui/working-line-messages.ts +24 -0
- package/dist/extensions/pi-zentui/extensions/zentui/working-line-spinners.ts +54 -0
- package/dist/extensions/pi-zentui/extensions/zentui/working-line.ts +1433 -0
- package/dist/extensions/pi-zentui/package-lock.json +5311 -0
- package/dist/extensions/pi-zentui/package.json +60 -0
- package/dist/extensions/pi-zentui/test/accent-rail-editor.test.ts +232 -0
- package/dist/extensions/pi-zentui/test/accent-rail-layout-patch.test.ts +669 -0
- package/dist/extensions/pi-zentui/test/completion-menu.test.ts +265 -0
- package/dist/extensions/pi-zentui/test/config.test.ts +3119 -0
- package/dist/extensions/pi-zentui/test/editor-metadata-format.test.ts +405 -0
- package/dist/extensions/pi-zentui/test/editor-transfer.test.ts +260 -0
- package/dist/extensions/pi-zentui/test/editor-viewport-indicators.test.ts +1286 -0
- package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +7196 -0
- package/dist/extensions/pi-zentui/test/extension-status.test.ts +182 -0
- package/dist/extensions/pi-zentui/test/fixtures/starship-nerd-font-symbols.toml +172 -0
- package/dist/extensions/pi-zentui/test/footer-format.test.ts +431 -0
- package/dist/extensions/pi-zentui/test/footer-layout.test.ts +113 -0
- package/dist/extensions/pi-zentui/test/footer-repository-path.test.ts +123 -0
- package/dist/extensions/pi-zentui/test/format.test.ts +865 -0
- package/dist/extensions/pi-zentui/test/git.test.ts +212 -0
- package/dist/extensions/pi-zentui/test/icons.test.ts +69 -0
- package/dist/extensions/pi-zentui/test/interaction-summary.test.ts +1402 -0
- package/dist/extensions/pi-zentui/test/live-context-integration.test.ts +378 -0
- package/dist/extensions/pi-zentui/test/live-context.test.ts +139 -0
- package/dist/extensions/pi-zentui/test/minimalist-editor.test.ts +811 -0
- package/dist/extensions/pi-zentui/test/package-version.test.ts +321 -0
- package/dist/extensions/pi-zentui/test/project-refresh.test.ts +250 -0
- package/dist/extensions/pi-zentui/test/project-state.test.ts +159 -0
- package/dist/extensions/pi-zentui/test/repository-root.test.ts +108 -0
- package/dist/extensions/pi-zentui/test/responsive-dependencies.test.ts +825 -0
- package/dist/extensions/pi-zentui/test/runtime.test.ts +183 -0
- package/dist/extensions/pi-zentui/test/session-lifecycle.test.ts +40 -0
- package/dist/extensions/pi-zentui/test/settings-command.test.ts +1381 -0
- package/dist/extensions/pi-zentui/test/settings-previews.test.ts +347 -0
- package/dist/extensions/pi-zentui/test/state.test.ts +84 -0
- package/dist/extensions/pi-zentui/test/telemetry-lifecycle-integration.test.ts +276 -0
- package/dist/extensions/pi-zentui/test/telemetry.test.ts +105 -0
- package/dist/extensions/pi-zentui/test/turn-summary-lifecycle.integration.test.ts +327 -0
- package/dist/extensions/pi-zentui/test/user-message-osc.test.ts +164 -0
- package/dist/extensions/pi-zentui/test/user-message-styles.test.ts +292 -0
- package/dist/extensions/pi-zentui/test/working-line-lifecycle.integration.test.ts +730 -0
- package/dist/extensions/pi-zentui/test/working-line-messages.test.ts +34 -0
- package/dist/extensions/pi-zentui/test/working-line.test.ts +1990 -0
- package/dist/extensions/pi-zentui/tsconfig.json +16 -0
- package/dist/extensions/tps.test.ts +38 -0
- package/dist/extensions/{pi-powerline-footer/tps.ts → tps.ts} +4 -0
- package/dist/skills/design-references/SKILL.md +31 -0
- package/dist/skills/design-references/references/clickhouse/DESIGN.md +544 -0
- package/dist/themes/adventure.json +84 -0
- package/dist/themes/adwaita-dark.json +84 -0
- package/dist/themes/arcoiris.json +84 -0
- package/dist/themes/arthur.json +84 -0
- package/dist/themes/atom.json +84 -0
- package/dist/themes/aura.json +84 -0
- package/dist/themes/black-metal-bathory.json +84 -0
- package/dist/themes/black-metal-burzum.json +84 -0
- package/dist/themes/black-metal-khold.json +84 -0
- package/dist/themes/box.json +84 -0
- package/dist/themes/brogrammer.json +84 -0
- package/dist/themes/carbonfox.json +84 -0
- package/dist/themes/catppuccin-mocha.json +84 -0
- package/dist/themes/citruszest.json +84 -0
- package/dist/themes/cursor-dark.json +84 -0
- package/dist/themes/cutie-pro.json +84 -0
- package/dist/themes/dark-modern.json +84 -0
- package/dist/themes/dark-pastel.json +84 -0
- package/dist/themes/dimmed-monokai.json +84 -0
- package/dist/themes/doom-peacock.json +84 -0
- package/dist/themes/dracula-plus.json +84 -0
- package/dist/themes/dracula.json +80 -0
- package/dist/themes/earthsong.json +84 -0
- package/dist/themes/everforest-dark-hard.json +84 -0
- package/dist/themes/everforest-dark.json +80 -0
- package/dist/themes/fahrenheit.json +84 -0
- package/dist/themes/flatland.json +84 -0
- package/dist/themes/flexoki-dark.json +84 -0
- package/dist/themes/front-end-delight.json +84 -0
- package/dist/themes/fun-forrest.json +84 -0
- package/dist/themes/galizur.json +84 -0
- package/dist/themes/github-dark-colorblind.json +84 -0
- package/dist/themes/github-dark-high-contrast.json +84 -0
- package/dist/themes/glacier.json +84 -0
- package/dist/themes/gruber-darker.json +84 -0
- package/dist/themes/gruvbox-dark-hard.json +84 -0
- package/dist/themes/gruvbox-dark.json +84 -0
- package/dist/themes/gruvbox-material.json +84 -0
- package/dist/themes/guezwhoz.json +84 -0
- package/dist/themes/hacktober.json +84 -0
- package/dist/themes/hardcore.json +84 -0
- package/dist/themes/havn-skumring.json +84 -0
- package/dist/themes/ic-orange-ppl.json +84 -0
- package/dist/themes/iterm2-smoooooth.json +84 -0
- package/dist/themes/iterm2-tango-dark.json +84 -0
- package/dist/themes/japanesque.json +84 -0
- package/dist/themes/jellybeans.json +84 -0
- package/dist/themes/kanagawa-wave.json +84 -0
- package/dist/themes/kurokula.json +84 -0
- package/dist/themes/later-this-evening.json +84 -0
- package/dist/themes/lovelace.json +84 -0
- package/dist/themes/material-darker.json +84 -0
- package/dist/themes/matte-black.json +84 -0
- package/dist/themes/mellow.json +84 -0
- package/dist/themes/miasma.json +84 -0
- package/dist/themes/nord.json +80 -0
- package/dist/themes/nvim-dark.json +84 -0
- package/dist/themes/one-dark.json +80 -0
- package/dist/themes/popping-and-locking.json +84 -0
- package/dist/themes/rose-pine.json +80 -0
- package/dist/themes/sea-shells.json +84 -0
- package/dist/themes/sleepy-hollow.json +84 -0
- package/dist/themes/smyck.json +84 -0
- package/dist/themes/solarized-dark.json +80 -0
- package/dist/themes/tokyo-night.json +80 -0
- package/dist/themes/tomorrow-night-bright.json +84 -0
- package/dist/themes/tomorrow-night-burns.json +84 -0
- package/dist/themes/tomorrow-night.json +84 -0
- package/dist/themes/twilight.json +84 -0
- package/dist/themes/vague.json +84 -0
- package/dist/themes/vesper.json +84 -0
- package/dist/themes/xcode-dark-hc.json +84 -0
- package/docs/custom-provider.md +0 -1
- package/docs/plans/auto-model-routing-extension.md +490 -0
- package/package.json +3 -3
- package/dist/extensions/pi-powerline-footer/.github/workflows/test.yml +0 -27
- package/dist/extensions/pi-powerline-footer/CHANGELOG.md +0 -687
- package/dist/extensions/pi-powerline-footer/CONTRIBUTING.md +0 -16
- package/dist/extensions/pi-powerline-footer/README.md +0 -513
- package/dist/extensions/pi-powerline-footer/banner.png +0 -0
- package/dist/extensions/pi-powerline-footer/bash-mode/completion.ts +0 -586
- package/dist/extensions/pi-powerline-footer/bash-mode/editor.ts +0 -583
- package/dist/extensions/pi-powerline-footer/bash-mode/history.ts +0 -204
- package/dist/extensions/pi-powerline-footer/bash-mode/shell-session.ts +0 -286
- package/dist/extensions/pi-powerline-footer/bash-mode/transcript.ts +0 -108
- package/dist/extensions/pi-powerline-footer/bash-mode/types.ts +0 -60
- package/dist/extensions/pi-powerline-footer/cd-command.ts +0 -190
- package/dist/extensions/pi-powerline-footer/colors.ts +0 -70
- package/dist/extensions/pi-powerline-footer/context-usage.ts +0 -156
- package/dist/extensions/pi-powerline-footer/currency-rates.ts +0 -142
- package/dist/extensions/pi-powerline-footer/editor-composition.ts +0 -32
- package/dist/extensions/pi-powerline-footer/editor-performance.ts +0 -99
- package/dist/extensions/pi-powerline-footer/git-status.ts +0 -329
- package/dist/extensions/pi-powerline-footer/guide.ts +0 -220
- package/dist/extensions/pi-powerline-footer/icons.ts +0 -190
- package/dist/extensions/pi-powerline-footer/index.ts +0 -3428
- package/dist/extensions/pi-powerline-footer/lifecycle.ts +0 -10
- package/dist/extensions/pi-powerline-footer/package.json +0 -49
- package/dist/extensions/pi-powerline-footer/paths.ts +0 -22
- package/dist/extensions/pi-powerline-footer/powerline-config.ts +0 -446
- package/dist/extensions/pi-powerline-footer/presets.ts +0 -102
- package/dist/extensions/pi-powerline-footer/queue/store.ts +0 -313
- package/dist/extensions/pi-powerline-footer/queue/types.ts +0 -53
- package/dist/extensions/pi-powerline-footer/render-scheduler.ts +0 -29
- package/dist/extensions/pi-powerline-footer/segments.ts +0 -570
- package/dist/extensions/pi-powerline-footer/separators.ts +0 -57
- package/dist/extensions/pi-powerline-footer/session-usage.ts +0 -44
- package/dist/extensions/pi-powerline-footer/shortcuts.ts +0 -61
- package/dist/extensions/pi-powerline-footer/tests/bash-mode.test.ts +0 -1905
- package/dist/extensions/pi-powerline-footer/tests/cd-command.test.ts +0 -144
- package/dist/extensions/pi-powerline-footer/tests/context-usage.test.ts +0 -156
- package/dist/extensions/pi-powerline-footer/tests/custom-items.test.ts +0 -344
- package/dist/extensions/pi-powerline-footer/tests/editor-composition.test.ts +0 -48
- package/dist/extensions/pi-powerline-footer/tests/editor-performance.test.ts +0 -43
- package/dist/extensions/pi-powerline-footer/tests/editor-responsiveness.test.ts +0 -136
- package/dist/extensions/pi-powerline-footer/tests/fixed-editor-border.test.ts +0 -39
- package/dist/extensions/pi-powerline-footer/tests/git-optional-locks.test.ts +0 -64
- package/dist/extensions/pi-powerline-footer/tests/git-status.test.ts +0 -92
- package/dist/extensions/pi-powerline-footer/tests/guide.test.ts +0 -129
- package/dist/extensions/pi-powerline-footer/tests/jump-shortcuts.test.ts +0 -116
- package/dist/extensions/pi-powerline-footer/tests/mode-aware-trigger.test.ts +0 -79
- package/dist/extensions/pi-powerline-footer/tests/paths.test.ts +0 -63
- package/dist/extensions/pi-powerline-footer/tests/queue-store.test.ts +0 -65
- package/dist/extensions/pi-powerline-footer/tests/quit-cursor.test.ts +0 -14
- package/dist/extensions/pi-powerline-footer/tests/remaining-regressions.test.ts +0 -173
- package/dist/extensions/pi-powerline-footer/tests/session-usage.test.ts +0 -47
- package/dist/extensions/pi-powerline-footer/tests/stash-shortcut.test.ts +0 -37
- package/dist/extensions/pi-powerline-footer/tests/thinking-segment.test.ts +0 -76
- package/dist/extensions/pi-powerline-footer/tests/token-stats.test.ts +0 -249
- package/dist/extensions/pi-powerline-footer/tests/tps.test.ts +0 -39
- package/dist/extensions/pi-powerline-footer/tests/usage-display.test.ts +0 -237
- package/dist/extensions/pi-powerline-footer/tests/welcome.test.ts +0 -199
- package/dist/extensions/pi-powerline-footer/tests/working-vibes.test.ts +0 -317
- package/dist/extensions/pi-powerline-footer/theme.example.json +0 -24
- package/dist/extensions/pi-powerline-footer/theme.json +0 -12
- package/dist/extensions/pi-powerline-footer/theme.ts +0 -241
- package/dist/extensions/pi-powerline-footer/token-stats.ts +0 -304
- package/dist/extensions/pi-powerline-footer/tsconfig.json +0 -13
- package/dist/extensions/pi-powerline-footer/types.ts +0 -235
- package/dist/extensions/pi-powerline-footer/welcome-dismiss.ts +0 -34
- package/dist/extensions/pi-powerline-footer/welcome.ts +0 -709
- package/dist/extensions/pi-powerline-footer/working-vibes.ts +0 -721
- package/dist/extensions/preview-tools-disabled.test.ts +0 -37
- package/dist/extensions/preview-tools-disabled.ts +0 -11
- package/dist/themes/powerline-footer/theme.json +0 -33
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Theme system for powerline-footer
|
|
3
|
-
*
|
|
4
|
-
* Colors are resolved in order:
|
|
5
|
-
* 1. User overrides from theme.json (if exists)
|
|
6
|
-
* 2. Preset colors
|
|
7
|
-
* 3. Default colors
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import type { Theme, ThemeColor } from "@selesai/code";
|
|
11
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
12
|
-
import { join, dirname } from "node:path";
|
|
13
|
-
import { fileURLToPath } from "node:url";
|
|
14
|
-
import { getAgentPath } from "./paths.ts";
|
|
15
|
-
import type { ColorScheme, ColorValue, SemanticColor, ThemeLike } from "./types.ts";
|
|
16
|
-
|
|
17
|
-
export interface PowerlineThemeConfig {
|
|
18
|
-
colors?: unknown;
|
|
19
|
-
icons?: unknown;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Default color scheme (uses pi theme colors)
|
|
23
|
-
const DEFAULT_COLORS: Required<ColorScheme> = {
|
|
24
|
-
model: "#d787af", // Pink/mauve (matching original colors.ts)
|
|
25
|
-
shellMode: "accent",
|
|
26
|
-
path: "#00afaf", // Teal/cyan (matching original colors.ts)
|
|
27
|
-
gitDirty: "warning",
|
|
28
|
-
gitClean: "success",
|
|
29
|
-
thinking: "thinkingOff",
|
|
30
|
-
thinkingMinimal: "thinkingMinimal",
|
|
31
|
-
thinkingLow: "thinkingLow",
|
|
32
|
-
thinkingMedium: "thinkingMedium",
|
|
33
|
-
context: "dim",
|
|
34
|
-
contextWarn: "warning",
|
|
35
|
-
contextError: "error",
|
|
36
|
-
cost: "text",
|
|
37
|
-
tokens: "muted",
|
|
38
|
-
queue: "accent",
|
|
39
|
-
separator: "dim",
|
|
40
|
-
border: "borderMuted",
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// Rainbow colors for high thinking levels
|
|
44
|
-
const RAINBOW_COLORS = [
|
|
45
|
-
"#b281d6", "#d787af", "#febc38", "#e4c00f",
|
|
46
|
-
"#89d281", "#00afaf", "#178fb9", "#b281d6",
|
|
47
|
-
];
|
|
48
|
-
|
|
49
|
-
// Cache for user theme overrides
|
|
50
|
-
let userThemeCache: ColorScheme | null = null;
|
|
51
|
-
let userThemeCacheTime = 0;
|
|
52
|
-
let userThemeCacheKey = "";
|
|
53
|
-
let themeConfigCache: PowerlineThemeConfig | null = null;
|
|
54
|
-
let themeConfigCacheTime = 0;
|
|
55
|
-
let themeConfigCacheKey = "";
|
|
56
|
-
const CACHE_TTL = 5000; // 5 seconds
|
|
57
|
-
const warnedInvalidThemeColors = new Set<string>();
|
|
58
|
-
|
|
59
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
60
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function sanitizeUserThemeOverrides(value: unknown): ColorScheme {
|
|
64
|
-
if (!isRecord(value)) {
|
|
65
|
-
return {};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const sanitized: ColorScheme = {};
|
|
69
|
-
for (const [key, rawColor] of Object.entries(value)) {
|
|
70
|
-
if (!Object.prototype.hasOwnProperty.call(DEFAULT_COLORS, key)) {
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
if (typeof rawColor !== "string") {
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const color = rawColor.trim();
|
|
78
|
-
if (!color) {
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
sanitized[key as SemanticColor] = color as ColorValue;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return sanitized;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Get theme.json lookup paths.
|
|
90
|
-
*/
|
|
91
|
-
function getThemePaths(): string[] {
|
|
92
|
-
const extDir = dirname(fileURLToPath(import.meta.url));
|
|
93
|
-
return Array.from(new Set([
|
|
94
|
-
getAgentPath("extensions", "powerline-footer", "theme.json"),
|
|
95
|
-
join(extDir, "theme.json"),
|
|
96
|
-
]));
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Load user theme config from theme.json.
|
|
101
|
-
*/
|
|
102
|
-
export function loadThemeConfig(): PowerlineThemeConfig {
|
|
103
|
-
const now = Date.now();
|
|
104
|
-
const themePaths = getThemePaths();
|
|
105
|
-
const cacheKey = themePaths.join("\0");
|
|
106
|
-
if (themeConfigCache && themeConfigCacheKey === cacheKey && now - themeConfigCacheTime < CACHE_TTL) {
|
|
107
|
-
return themeConfigCache;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
for (const themePath of themePaths) {
|
|
111
|
-
try {
|
|
112
|
-
if (existsSync(themePath)) {
|
|
113
|
-
const content = readFileSync(themePath, "utf-8");
|
|
114
|
-
const parsed = JSON.parse(content);
|
|
115
|
-
themeConfigCache = isRecord(parsed) ? parsed : {};
|
|
116
|
-
themeConfigCacheTime = now;
|
|
117
|
-
themeConfigCacheKey = cacheKey;
|
|
118
|
-
return themeConfigCache;
|
|
119
|
-
}
|
|
120
|
-
} catch (error) {
|
|
121
|
-
// Theme overrides are optional. If the file is unreadable or malformed,
|
|
122
|
-
// keep rendering with built-in defaults instead of breaking the footer.
|
|
123
|
-
console.debug(`[powerline-theme] Failed to load ${themePath}:`, error);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
themeConfigCache = {};
|
|
128
|
-
themeConfigCacheTime = now;
|
|
129
|
-
themeConfigCacheKey = cacheKey;
|
|
130
|
-
return themeConfigCache;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function loadUserTheme(): ColorScheme {
|
|
134
|
-
const now = Date.now();
|
|
135
|
-
const cacheKey = getThemePaths().join("\0");
|
|
136
|
-
if (userThemeCache && userThemeCacheKey === cacheKey && now - userThemeCacheTime < CACHE_TTL) {
|
|
137
|
-
return userThemeCache;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
userThemeCache = sanitizeUserThemeOverrides(loadThemeConfig().colors);
|
|
141
|
-
userThemeCacheTime = now;
|
|
142
|
-
userThemeCacheKey = cacheKey;
|
|
143
|
-
return userThemeCache;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Resolve a semantic color to an actual color value
|
|
148
|
-
*/
|
|
149
|
-
export function resolveColor(
|
|
150
|
-
semantic: SemanticColor,
|
|
151
|
-
presetColors?: ColorScheme
|
|
152
|
-
): ColorValue {
|
|
153
|
-
const userTheme = loadUserTheme();
|
|
154
|
-
|
|
155
|
-
// Priority: user overrides > preset colors > defaults
|
|
156
|
-
return userTheme[semantic]
|
|
157
|
-
?? presetColors?.[semantic]
|
|
158
|
-
?? DEFAULT_COLORS[semantic];
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Check if a color value is a hex color
|
|
163
|
-
*/
|
|
164
|
-
function isHexColor(color: ColorValue): color is `#${string}` {
|
|
165
|
-
return typeof color === "string" && /^#[0-9a-fA-F]{6}$/.test(color);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Convert hex color to ANSI escape code
|
|
170
|
-
*/
|
|
171
|
-
function hexToAnsi(hex: string): string {
|
|
172
|
-
const h = hex.replace("#", "");
|
|
173
|
-
const r = parseInt(h.slice(0, 2), 16);
|
|
174
|
-
const g = parseInt(h.slice(2, 4), 16);
|
|
175
|
-
const b = parseInt(h.slice(4, 6), 16);
|
|
176
|
-
return `\x1b[38;2;${r};${g};${b}m`;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Apply a color to text using the pi theme or custom hex
|
|
181
|
-
*/
|
|
182
|
-
export function applyColor(
|
|
183
|
-
theme: ThemeLike,
|
|
184
|
-
color: ColorValue,
|
|
185
|
-
text: string
|
|
186
|
-
): string {
|
|
187
|
-
if (isHexColor(color)) {
|
|
188
|
-
return `${hexToAnsi(color)}${text}\x1b[0m`;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
try {
|
|
192
|
-
return theme.fg(color as ThemeColor, text);
|
|
193
|
-
} catch (error) {
|
|
194
|
-
const key = String(color);
|
|
195
|
-
if (!warnedInvalidThemeColors.has(key)) {
|
|
196
|
-
warnedInvalidThemeColors.add(key);
|
|
197
|
-
if (warnedInvalidThemeColors.size > 200) {
|
|
198
|
-
warnedInvalidThemeColors.clear();
|
|
199
|
-
}
|
|
200
|
-
console.debug(`[powerline-theme] Invalid theme color "${key}"; falling back to "text".`, error);
|
|
201
|
-
}
|
|
202
|
-
return theme.fg("text", text);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Apply a semantic color to text
|
|
208
|
-
*/
|
|
209
|
-
export function fg(
|
|
210
|
-
theme: ThemeLike,
|
|
211
|
-
semantic: SemanticColor,
|
|
212
|
-
text: string,
|
|
213
|
-
presetColors?: ColorScheme
|
|
214
|
-
): string {
|
|
215
|
-
const color = resolveColor(semantic, presetColors);
|
|
216
|
-
return applyColor(theme, color, text);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Apply rainbow gradient to text (for high thinking levels)
|
|
221
|
-
*/
|
|
222
|
-
export function rainbow(text: string): string {
|
|
223
|
-
let result = "";
|
|
224
|
-
let colorIndex = 0;
|
|
225
|
-
for (const char of text) {
|
|
226
|
-
if (char === " " || char === ":") {
|
|
227
|
-
result += char;
|
|
228
|
-
} else {
|
|
229
|
-
result += hexToAnsi(RAINBOW_COLORS[colorIndex % RAINBOW_COLORS.length]) + char;
|
|
230
|
-
colorIndex++;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
return result + "\x1b[0m";
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Get the default color scheme
|
|
238
|
-
*/
|
|
239
|
-
export function getDefaultColors(): Required<ColorScheme> {
|
|
240
|
-
return { ...DEFAULT_COLORS };
|
|
241
|
-
}
|
|
@@ -1,304 +0,0 @@
|
|
|
1
|
-
import type { AssistantMessage } from "@earendil-works/pi-ai";
|
|
2
|
-
|
|
3
|
-
type SessionAssistantUsage = AssistantMessage["usage"];
|
|
4
|
-
|
|
5
|
-
export interface SessionTokenStats {
|
|
6
|
-
input: number;
|
|
7
|
-
output: number;
|
|
8
|
-
cacheRead: number;
|
|
9
|
-
cacheWrite: number;
|
|
10
|
-
cost: number;
|
|
11
|
-
subagentCost: number;
|
|
12
|
-
lastAssistant: AssistantMessage | undefined;
|
|
13
|
-
thinkingLevelFromSession: string | null;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
17
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function hasSessionAssistantUsage(value: unknown): value is SessionAssistantUsage {
|
|
21
|
-
if (!isRecord(value)) {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (
|
|
26
|
-
typeof value.input !== "number" ||
|
|
27
|
-
typeof value.output !== "number" ||
|
|
28
|
-
typeof value.cacheRead !== "number" ||
|
|
29
|
-
typeof value.cacheWrite !== "number"
|
|
30
|
-
) {
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return isRecord(value.cost) && typeof value.cost.total === "number";
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function isSessionAssistantMessage(value: unknown): value is AssistantMessage {
|
|
38
|
-
return isRecord(value)
|
|
39
|
-
&& value.role === "assistant"
|
|
40
|
-
&& hasSessionAssistantUsage(value.usage)
|
|
41
|
-
&& (value.stopReason === undefined || typeof value.stopReason === "string");
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function getUsageTokenTotal(usage: SessionAssistantUsage): number {
|
|
45
|
-
const totalTokens = "totalTokens" in usage && typeof usage.totalTokens === "number" ? usage.totalTokens : 0;
|
|
46
|
-
return totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Matches pi-subagents' internal SLASH_RESULT_TYPE custom_message marker.
|
|
50
|
-
const SUBAGENT_SLASH_RESULT_TYPE = "subagent-slash-result";
|
|
51
|
-
|
|
52
|
-
function subagentDetailsFromSessionEntry(e: Record<string, unknown>): { results: unknown[] } | undefined {
|
|
53
|
-
if (e.type === "custom_message" && e.customType === SUBAGENT_SLASH_RESULT_TYPE) {
|
|
54
|
-
const details = isRecord(e.details) ? e.details : undefined;
|
|
55
|
-
const result = isRecord(details?.result) ? details.result : undefined;
|
|
56
|
-
const inner = isRecord(result?.details) ? result.details : undefined;
|
|
57
|
-
return Array.isArray(inner?.results) ? { results: inner.results } : undefined;
|
|
58
|
-
}
|
|
59
|
-
if (e.type === "message" && isRecord(e.message)) {
|
|
60
|
-
const message = e.message as { role?: unknown; toolName?: unknown; details?: unknown };
|
|
61
|
-
if (message.role === "toolResult" && message.toolName === "subagent" && isRecord(message.details) && Array.isArray(message.details.results)) {
|
|
62
|
-
return { results: message.details.results };
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return undefined;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Sums subagent child usage cost recorded on a single session entry (parallel/chain/single runs
|
|
69
|
-
// launched via the subagent tool or /parallel, /worker etc. slash commands), so the footer can
|
|
70
|
-
// show total spend rather than only the interactive parent session's cost.
|
|
71
|
-
function extractSubagentResultCost(e: Record<string, unknown>): number {
|
|
72
|
-
const details = subagentDetailsFromSessionEntry(e);
|
|
73
|
-
if (!details) return 0;
|
|
74
|
-
let total = 0;
|
|
75
|
-
for (const result of details.results) {
|
|
76
|
-
if (!isRecord(result)) continue;
|
|
77
|
-
const usage = isRecord(result.usage) ? result.usage : undefined;
|
|
78
|
-
if (typeof usage?.cost === "number") total += usage.cost;
|
|
79
|
-
}
|
|
80
|
-
return total;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Fingerprint of the fields on a session event that influence the aggregated
|
|
85
|
-
* stats. Comparing only the event count is not enough: while streaming, pi
|
|
86
|
-
* may update the trailing assistant message in place (usage grows, stopReason
|
|
87
|
-
* flips), so the same event reference can carry fresh numbers.
|
|
88
|
-
*/
|
|
89
|
-
function eventStatsSignature(event: unknown): string {
|
|
90
|
-
if (!isRecord(event)) {
|
|
91
|
-
return "?";
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (event.type === "thinking_level_change") {
|
|
95
|
-
return `t:${typeof event.thinkingLevel === "string" ? event.thinkingLevel : ""}`;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const subagentDetails = subagentDetailsFromSessionEntry(event);
|
|
99
|
-
if (subagentDetails) {
|
|
100
|
-
return `s:${subagentDetails.results.length}:${extractSubagentResultCost(event)}`;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (event.type === "message" && isRecord(event.message)) {
|
|
104
|
-
const message = event.message;
|
|
105
|
-
const role = typeof message.role === "string" ? message.role : "";
|
|
106
|
-
const stopReason = typeof message.stopReason === "string" ? message.stopReason : "";
|
|
107
|
-
if (role === "assistant" && hasSessionAssistantUsage(message.usage)) {
|
|
108
|
-
const usage = message.usage;
|
|
109
|
-
return `a:${stopReason}:${usage.input}/${usage.output}/${usage.cacheRead}/${usage.cacheWrite}/${usage.cost.total}`;
|
|
110
|
-
}
|
|
111
|
-
return `m:${role}:${stopReason}`;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return `e:${typeof event.type === "string" ? event.type : "?"}`;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function emptySessionTokenStats(): SessionTokenStats {
|
|
118
|
-
return {
|
|
119
|
-
input: 0,
|
|
120
|
-
output: 0,
|
|
121
|
-
cacheRead: 0,
|
|
122
|
-
cacheWrite: 0,
|
|
123
|
-
cost: 0,
|
|
124
|
-
subagentCost: 0,
|
|
125
|
-
lastAssistant: undefined,
|
|
126
|
-
thinkingLevelFromSession: null,
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function copySessionTokenStats(stats: SessionTokenStats): SessionTokenStats {
|
|
131
|
-
return { ...stats };
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function accumulateSessionEvent(stats: SessionTokenStats, event: unknown): void {
|
|
135
|
-
if (!isRecord(event)) return;
|
|
136
|
-
|
|
137
|
-
if (event.type === "thinking_level_change" && typeof event.thinkingLevel === "string") {
|
|
138
|
-
stats.thinkingLevelFromSession = event.thinkingLevel;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
stats.subagentCost += extractSubagentResultCost(event);
|
|
142
|
-
|
|
143
|
-
if (event.type !== "message" || !isSessionAssistantMessage(event.message)) return;
|
|
144
|
-
|
|
145
|
-
const message = event.message;
|
|
146
|
-
if (message.stopReason === "error" || message.stopReason === "aborted") return;
|
|
147
|
-
|
|
148
|
-
stats.input += message.usage.input;
|
|
149
|
-
stats.output += message.usage.output;
|
|
150
|
-
stats.cacheRead += message.usage.cacheRead;
|
|
151
|
-
stats.cacheWrite += message.usage.cacheWrite;
|
|
152
|
-
stats.cost += message.usage.cost.total;
|
|
153
|
-
if (getUsageTokenTotal(message.usage) > 0) {
|
|
154
|
-
stats.lastAssistant = message;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
export interface SessionBranchProvider {
|
|
159
|
-
getLeafId(): string | null;
|
|
160
|
-
getBranch(): readonly unknown[];
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
function isSessionBranchProvider(value: unknown): value is SessionBranchProvider {
|
|
164
|
-
return isRecord(value) && typeof value.getLeafId === "function" && typeof value.getBranch === "function";
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Session branches are immutable for a given leaf. Keep the already-built path
|
|
169
|
-
* while streaming updates mutate only its trailing message in place.
|
|
170
|
-
*/
|
|
171
|
-
export class SessionBranchCache {
|
|
172
|
-
private provider: SessionBranchProvider | null = null;
|
|
173
|
-
private leafId: string | null = null;
|
|
174
|
-
private branch: readonly unknown[] = [];
|
|
175
|
-
|
|
176
|
-
get(source: unknown): readonly unknown[] {
|
|
177
|
-
if (!isSessionBranchProvider(source)) return [];
|
|
178
|
-
|
|
179
|
-
const provider = source;
|
|
180
|
-
const leafId = provider.getLeafId();
|
|
181
|
-
// A reset cache holds provider === null, which never matches a live provider.
|
|
182
|
-
if (this.provider !== provider || this.leafId !== leafId) {
|
|
183
|
-
this.provider = provider;
|
|
184
|
-
this.leafId = leafId;
|
|
185
|
-
this.branch = provider.getBranch();
|
|
186
|
-
}
|
|
187
|
-
return this.branch;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
reset(): void {
|
|
191
|
-
this.provider = null;
|
|
192
|
-
this.leafId = null;
|
|
193
|
-
this.branch = [];
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
export function computeSessionTokenStats(sessionEvents: readonly unknown[]): SessionTokenStats {
|
|
198
|
-
let input = 0, output = 0, cacheRead = 0, cacheWrite = 0, cost = 0, subagentCost = 0;
|
|
199
|
-
let lastAssistant: AssistantMessage | undefined;
|
|
200
|
-
let thinkingLevelFromSession: string | null = null;
|
|
201
|
-
|
|
202
|
-
for (const e of sessionEvents) {
|
|
203
|
-
if (!isRecord(e)) continue;
|
|
204
|
-
|
|
205
|
-
if (e.type === "thinking_level_change" && typeof e.thinkingLevel === "string") {
|
|
206
|
-
thinkingLevelFromSession = e.thinkingLevel;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
subagentCost += extractSubagentResultCost(e);
|
|
210
|
-
|
|
211
|
-
if (e.type !== "message" || !isSessionAssistantMessage(e.message)) continue;
|
|
212
|
-
|
|
213
|
-
const m = e.message;
|
|
214
|
-
if (m.stopReason === "error" || m.stopReason === "aborted") continue;
|
|
215
|
-
|
|
216
|
-
input += m.usage.input;
|
|
217
|
-
output += m.usage.output;
|
|
218
|
-
cacheRead += m.usage.cacheRead;
|
|
219
|
-
cacheWrite += m.usage.cacheWrite;
|
|
220
|
-
cost += m.usage.cost.total;
|
|
221
|
-
if (getUsageTokenTotal(m.usage) > 0) {
|
|
222
|
-
lastAssistant = m;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
return { input, output, cacheRead, cacheWrite, cost, subagentCost, lastAssistant, thinkingLevelFromSession };
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Cache for token counting: avoid re-scanning the full session event list on
|
|
231
|
-
* every render (250ms-1s cadence while streaming). Historical session entries
|
|
232
|
-
* are append-only, so appended entries are accumulated and an in-place update
|
|
233
|
-
* to the trailing streaming entry only recomputes that entry.
|
|
234
|
-
*/
|
|
235
|
-
export class SessionTokenStatsCache {
|
|
236
|
-
private eventCount = -1;
|
|
237
|
-
private lastEvent: unknown;
|
|
238
|
-
private lastSignature = "";
|
|
239
|
-
private prefixStats: SessionTokenStats | null = null;
|
|
240
|
-
private stats: SessionTokenStats | null = null;
|
|
241
|
-
|
|
242
|
-
get(sessionEvents: readonly unknown[]): SessionTokenStats {
|
|
243
|
-
const eventCount = sessionEvents.length;
|
|
244
|
-
const lastEvent = eventCount > 0 ? sessionEvents[eventCount - 1] : undefined;
|
|
245
|
-
const lastSignature = eventStatsSignature(lastEvent);
|
|
246
|
-
|
|
247
|
-
if (
|
|
248
|
-
this.stats !== null
|
|
249
|
-
&& this.eventCount === eventCount
|
|
250
|
-
&& this.lastEvent === lastEvent
|
|
251
|
-
&& this.lastSignature === lastSignature
|
|
252
|
-
) {
|
|
253
|
-
return this.stats;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// getBranch() walks unique parent links, so an identical trailing event at
|
|
257
|
-
// the previous count proves the whole previous array is an unchanged prefix.
|
|
258
|
-
const previousStats = this.stats;
|
|
259
|
-
const canExtendPreviousStats = previousStats !== null
|
|
260
|
-
&& eventCount > this.eventCount
|
|
261
|
-
&& (this.eventCount === 0 || (
|
|
262
|
-
sessionEvents[this.eventCount - 1] === this.lastEvent
|
|
263
|
-
&& eventStatsSignature(sessionEvents[this.eventCount - 1]) === this.lastSignature
|
|
264
|
-
));
|
|
265
|
-
|
|
266
|
-
let prefixStats: SessionTokenStats;
|
|
267
|
-
if (canExtendPreviousStats && previousStats !== null) {
|
|
268
|
-
prefixStats = copySessionTokenStats(previousStats);
|
|
269
|
-
for (let index = this.eventCount; index < eventCount - 1; index += 1) {
|
|
270
|
-
accumulateSessionEvent(prefixStats, sessionEvents[index]);
|
|
271
|
-
}
|
|
272
|
-
} else if (
|
|
273
|
-
this.prefixStats !== null
|
|
274
|
-
&& this.eventCount === eventCount
|
|
275
|
-
&& this.lastEvent === lastEvent
|
|
276
|
-
) {
|
|
277
|
-
// Same array with an in-place tail mutation: reuse the cached prefix.
|
|
278
|
-
prefixStats = this.prefixStats;
|
|
279
|
-
} else {
|
|
280
|
-
prefixStats = emptySessionTokenStats();
|
|
281
|
-
for (let index = 0; index < eventCount - 1; index += 1) {
|
|
282
|
-
accumulateSessionEvent(prefixStats, sessionEvents[index]);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
const stats = copySessionTokenStats(prefixStats);
|
|
287
|
-
if (eventCount > 0) accumulateSessionEvent(stats, lastEvent);
|
|
288
|
-
|
|
289
|
-
this.eventCount = eventCount;
|
|
290
|
-
this.lastEvent = lastEvent;
|
|
291
|
-
this.lastSignature = lastSignature;
|
|
292
|
-
this.prefixStats = prefixStats;
|
|
293
|
-
this.stats = stats;
|
|
294
|
-
return stats;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
reset(): void {
|
|
298
|
-
this.eventCount = -1;
|
|
299
|
-
this.lastEvent = undefined;
|
|
300
|
-
this.lastSignature = "";
|
|
301
|
-
this.prefixStats = null;
|
|
302
|
-
this.stats = null;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "NodeNext",
|
|
5
|
-
"moduleResolution": "NodeNext",
|
|
6
|
-
"strict": true,
|
|
7
|
-
"noEmit": true,
|
|
8
|
-
"skipLibCheck": true,
|
|
9
|
-
"types": ["node"],
|
|
10
|
-
"allowImportingTsExtensions": true
|
|
11
|
-
},
|
|
12
|
-
"include": ["*.ts", "bash-mode/**/*.ts", "queue/**/*.ts"]
|
|
13
|
-
}
|