@ashx-j/lunr 0.2.13 → 0.2.14
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 +10 -1
- package/README.md +6 -3
- package/dist/builtin-extensions/ashxj-tui.d.ts +16 -1
- package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
- package/dist/builtin-extensions/ashxj-tui.js +44 -20
- package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +2 -0
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js +27 -22
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js +5 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js +12 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.js +3 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-append.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-append.js +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-append.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.js +3 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/fleet-view.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/fleet-view.js +3 -3
- package/dist/builtin-extensions/pi-subagents/src/runs/background/fleet-view.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/run-status.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/run-status.js +2 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/run-status.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +3 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +7 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +19 -3
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +10 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +19 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts +2 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js +17 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts +3 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js +14 -3
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +14 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/fleet.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/fleet.js +2 -2
- package/dist/builtin-extensions/pi-subagents/src/tui/fleet.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js +12 -10
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
- package/dist/catalog/models.json +1 -1
- package/dist/catalog/providers/amazon-bedrock.json +1 -1
- package/dist/catalog/providers/anthropic.json +1 -1
- package/dist/catalog/providers/azure-openai-responses.json +1 -1
- package/dist/catalog/providers/cloudflare-ai-gateway.json +1 -1
- package/dist/catalog/providers/fireworks.json +1 -1
- package/dist/catalog/providers/github-copilot.json +1 -1
- package/dist/catalog/providers/google-vertex.json +1 -1
- package/dist/catalog/providers/google.json +1 -1
- package/dist/catalog/providers/groq.json +1 -1
- package/dist/catalog/providers/huggingface.json +1 -1
- package/dist/catalog/providers/nvidia.json +1 -1
- package/dist/catalog/providers/openai-codex.json +1 -1
- package/dist/catalog/providers/openai.json +1 -1
- package/dist/catalog/providers/opencode-go.json +1 -1
- package/dist/catalog/providers/opencode.json +1 -1
- package/dist/catalog/providers/openrouter.json +1 -1
- package/dist/catalog/providers/vercel-ai-gateway.json +1 -1
- package/dist/catalog/publication.json +131 -3
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js +1 -0
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +52 -27
- package/dist/cli.js.map +1 -1
- package/dist/core/catalog-cache-scope.d.ts +3 -0
- package/dist/core/catalog-cache-scope.d.ts.map +1 -0
- package/dist/core/catalog-cache-scope.js +12 -0
- package/dist/core/catalog-cache-scope.js.map +1 -0
- package/dist/core/catalog-merge.d.ts +2 -0
- package/dist/core/catalog-merge.d.ts.map +1 -1
- package/dist/core/catalog-merge.js +29 -2
- package/dist/core/catalog-merge.js.map +1 -1
- package/dist/core/catalog-refresh-polling.d.ts +8 -0
- package/dist/core/catalog-refresh-polling.d.ts.map +1 -0
- package/dist/core/catalog-refresh-polling.js +30 -0
- package/dist/core/catalog-refresh-polling.js.map +1 -0
- package/dist/core/codex-catalog.d.ts +3 -0
- package/dist/core/codex-catalog.d.ts.map +1 -0
- package/dist/core/codex-catalog.js +15 -0
- package/dist/core/codex-catalog.js.map +1 -0
- package/dist/core/customize.d.ts +2 -4
- package/dist/core/customize.d.ts.map +1 -1
- package/dist/core/customize.js +2 -8
- package/dist/core/customize.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +3 -4
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +54 -82
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/live-catalog.d.ts +5 -2
- package/dist/core/live-catalog.d.ts.map +1 -1
- package/dist/core/live-catalog.js +108 -27
- package/dist/core/live-catalog.js.map +1 -1
- package/dist/core/model-runtime.d.ts +8 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +64 -12
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/official-catalog.d.ts +4 -0
- package/dist/core/official-catalog.d.ts.map +1 -1
- package/dist/core/official-catalog.js +86 -21
- package/dist/core/official-catalog.js.map +1 -1
- package/dist/core/settings-manager.d.ts +0 -6
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +0 -17
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/main.d.ts +2 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +106 -50
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts +2 -0
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +14 -4
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +1 -3
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +4 -32
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +2 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +4 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/plan-message.d.ts +1 -3
- package/dist/modes/interactive/components/plan-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/plan-message.js +1 -16
- package/dist/modes/interactive/components/plan-message.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +0 -4
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +10 -30
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts +1 -3
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +2 -19
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +12 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +137 -127
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/moon.json +0 -1
- package/dist/modes/interactive/theme/theme-schema.json +3 -3
- package/dist/modes/interactive/theme/theme.d.ts +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +95 -90
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/startup/interactive-view.d.ts +55 -0
- package/dist/startup/interactive-view.d.ts.map +1 -0
- package/dist/startup/interactive-view.js +332 -0
- package/dist/startup/interactive-view.js.map +1 -0
- package/dist/startup/launch-routing.d.ts +8 -0
- package/dist/startup/launch-routing.d.ts.map +1 -0
- package/dist/startup/launch-routing.js +29 -0
- package/dist/startup/launch-routing.js.map +1 -0
- package/dist/startup/startup-milestones.d.ts +4 -0
- package/dist/startup/startup-milestones.d.ts.map +1 -0
- package/dist/startup/startup-milestones.js +14 -0
- package/dist/startup/startup-milestones.js.map +1 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +10 -4
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/docs/features.md +2 -2
- package/docs/interactive-startup.md +58 -0
- package/docs/keybindings.md +1 -1
- package/docs/model-catalog.md +29 -0
- package/docs/quickstart.md +1 -1
- package/docs/settings.md +1 -3
- package/docs/terminal-setup.md +2 -2
- package/docs/usage.md +2 -1
- package/docs/windows.md +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +16 -16
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import * as crypto from "node:crypto";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as os from "node:os";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import { Container, isFocusable, ProcessTerminal, Spacer, setKeybindings, Text, TUI, } from "@ashx-j/lunr-tui";
|
|
6
|
+
import { getChatboxEditor, renderStatsLine, thinkingThemeToken } from "../builtin-extensions/ashxj-tui.js";
|
|
7
|
+
import { APP_NAME, getAgentDir, VERSION } from "../config.js";
|
|
8
|
+
import { KeybindingsManager } from "../core/keybindings.js";
|
|
9
|
+
import { registerPermissionModeBridge } from "../core/permission-mode.js";
|
|
10
|
+
import { BootScreenComponent } from "../modes/interactive/components/boot-screen.js";
|
|
11
|
+
import { getEditorTheme, getThemeName, initTheme, theme } from "../modes/interactive/theme/theme.js";
|
|
12
|
+
import { markStartupMilestone } from "./startup-milestones.js";
|
|
13
|
+
// Read display preferences only: no auth, models, resources, migrations, or writes.
|
|
14
|
+
function readDisplaySettings() {
|
|
15
|
+
try {
|
|
16
|
+
const value = JSON.parse(fs.readFileSync(path.join(getAgentDir(), "settings.json"), "utf8"));
|
|
17
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
class StartupProcessTerminal extends ProcessTerminal {
|
|
24
|
+
watchForFirstFrame = false;
|
|
25
|
+
firstFrameCallback;
|
|
26
|
+
setFirstFrameCallback(callback) {
|
|
27
|
+
this.firstFrameCallback = callback;
|
|
28
|
+
this.watchForFirstFrame = true;
|
|
29
|
+
}
|
|
30
|
+
start(onInput, onResize) {
|
|
31
|
+
super.start(onInput, onResize);
|
|
32
|
+
markStartupMilestone("input_handler_armed");
|
|
33
|
+
if (process.stdin.isTTY)
|
|
34
|
+
markStartupMilestone("raw_mode_active");
|
|
35
|
+
}
|
|
36
|
+
write(data) {
|
|
37
|
+
super.write(data);
|
|
38
|
+
// TUI ends each content frame with synchronized-output end. Setup writes do not count.
|
|
39
|
+
if (this.watchForFirstFrame && data.includes("\x1b[?2026l")) {
|
|
40
|
+
this.watchForFirstFrame = false;
|
|
41
|
+
markStartupMilestone("first_frame_committed");
|
|
42
|
+
this.firstFrameCallback?.();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export class InteractiveView {
|
|
47
|
+
ui;
|
|
48
|
+
editor;
|
|
49
|
+
keybindings;
|
|
50
|
+
submitRequested = false;
|
|
51
|
+
inputUnsubscribe;
|
|
52
|
+
modalActive = false;
|
|
53
|
+
terminal;
|
|
54
|
+
status = new Text("", 1, 0);
|
|
55
|
+
header;
|
|
56
|
+
footer;
|
|
57
|
+
statusContainer = new Container();
|
|
58
|
+
editorContainer = new Container();
|
|
59
|
+
firstFramePromise;
|
|
60
|
+
resolveFirstFrame;
|
|
61
|
+
exitPromise;
|
|
62
|
+
resolveExit;
|
|
63
|
+
started = false;
|
|
64
|
+
handedOff = false;
|
|
65
|
+
exitRequested = false;
|
|
66
|
+
lastClearAt = 0;
|
|
67
|
+
currentEditor = () => this.editor;
|
|
68
|
+
constructor() {
|
|
69
|
+
const settings = readDisplaySettings();
|
|
70
|
+
const permission = settings.defaultPermissionMode;
|
|
71
|
+
registerPermissionModeBridge(() => permission === "auto" || permission === "yolo" || permission === "plan" ? permission : "manual");
|
|
72
|
+
initTheme(typeof settings.theme === "string" ? settings.theme : undefined);
|
|
73
|
+
this.terminal = new StartupProcessTerminal();
|
|
74
|
+
this.ui = new TUI(this.terminal, settings.showHardwareCursor);
|
|
75
|
+
this.ui.setClearOnShrink(settings.terminal?.clearOnShrink ?? false);
|
|
76
|
+
this.keybindings = KeybindingsManager.create();
|
|
77
|
+
setKeybindings(this.keybindings);
|
|
78
|
+
const ctx = {
|
|
79
|
+
mode: "tui",
|
|
80
|
+
hasUI: true,
|
|
81
|
+
model: settings.defaultModel ? { id: settings.defaultModel, provider: settings.defaultProvider } : undefined,
|
|
82
|
+
sessionManager: { getEntries: () => [] },
|
|
83
|
+
getContextUsage: () => undefined,
|
|
84
|
+
ui: { theme, setEditorComponent() { }, setFooter() { } },
|
|
85
|
+
};
|
|
86
|
+
const effort = settings.defaultThinkingLevel ?? "off";
|
|
87
|
+
this.editor = getChatboxEditor(this.ui, getEditorTheme(), this.keybindings, ctx, {
|
|
88
|
+
getThinkingLevel: () => effort,
|
|
89
|
+
on() { },
|
|
90
|
+
});
|
|
91
|
+
this.editor.borderColor = (text) => theme.fg(thinkingThemeToken(effort), text);
|
|
92
|
+
this.editor.disableSubmit = true;
|
|
93
|
+
this.header = settings.quietStartup
|
|
94
|
+
? new Text("", 0, 0)
|
|
95
|
+
: new BootScreenComponent(theme.bold(theme.fg("accent", APP_NAME)) + theme.fg("dim", ` v${VERSION}`), [
|
|
96
|
+
{ label: "directory", value: process.cwd() },
|
|
97
|
+
{ label: "config", value: getAgentDir() },
|
|
98
|
+
{ label: "theme", value: getThemeName() },
|
|
99
|
+
]);
|
|
100
|
+
this.footer = {
|
|
101
|
+
invalidate() { },
|
|
102
|
+
render: (width) => renderStatsLine(width, ctx, theme, {
|
|
103
|
+
getGitBranch: () => null,
|
|
104
|
+
getExtensionStatuses: () => new Map(),
|
|
105
|
+
getAvailableProviderCount: () => 0,
|
|
106
|
+
onBranchChange: () => () => { },
|
|
107
|
+
}),
|
|
108
|
+
};
|
|
109
|
+
this.editorContainer.addChild(this.editor);
|
|
110
|
+
this.statusContainer.addChild(this.status);
|
|
111
|
+
this.firstFramePromise = new Promise((resolve) => {
|
|
112
|
+
this.resolveFirstFrame = resolve;
|
|
113
|
+
});
|
|
114
|
+
this.exitPromise = new Promise((resolve) => {
|
|
115
|
+
this.resolveExit = resolve;
|
|
116
|
+
});
|
|
117
|
+
this.terminal.setFirstFrameCallback(this.resolveFirstFrame);
|
|
118
|
+
this.installInputHandlers();
|
|
119
|
+
}
|
|
120
|
+
get isExitRequested() {
|
|
121
|
+
return this.exitRequested;
|
|
122
|
+
}
|
|
123
|
+
start() {
|
|
124
|
+
if (this.started)
|
|
125
|
+
return;
|
|
126
|
+
this.restoreLayout();
|
|
127
|
+
this.ui.setAlternateScreen(true);
|
|
128
|
+
this.ui.start();
|
|
129
|
+
this.started = true;
|
|
130
|
+
}
|
|
131
|
+
pause() {
|
|
132
|
+
if (!this.started || this.handedOff)
|
|
133
|
+
return;
|
|
134
|
+
this.ui.stop();
|
|
135
|
+
this.started = false;
|
|
136
|
+
}
|
|
137
|
+
resume() {
|
|
138
|
+
if (this.started || this.handedOff || this.exitRequested)
|
|
139
|
+
return;
|
|
140
|
+
this.restoreLayout();
|
|
141
|
+
this.ui.start();
|
|
142
|
+
this.started = true;
|
|
143
|
+
}
|
|
144
|
+
waitForFirstFrame() {
|
|
145
|
+
return this.firstFramePromise;
|
|
146
|
+
}
|
|
147
|
+
waitForExit() {
|
|
148
|
+
return this.exitPromise;
|
|
149
|
+
}
|
|
150
|
+
binding() {
|
|
151
|
+
this.handedOff = true;
|
|
152
|
+
return this;
|
|
153
|
+
}
|
|
154
|
+
setCurrentEditor(getEditor) {
|
|
155
|
+
this.currentEditor = getEditor;
|
|
156
|
+
}
|
|
157
|
+
/** Called only after the normal submit handler and all extensions are ready. */
|
|
158
|
+
activate() {
|
|
159
|
+
if (this.exitRequested)
|
|
160
|
+
return;
|
|
161
|
+
this.inputUnsubscribe?.();
|
|
162
|
+
this.inputUnsubscribe = undefined;
|
|
163
|
+
this.editor.onPasteImage = undefined;
|
|
164
|
+
this.editor.disableSubmit = false;
|
|
165
|
+
this.status.setText("");
|
|
166
|
+
if (this.submitRequested) {
|
|
167
|
+
this.submitRequested = false;
|
|
168
|
+
this.currentEditor().handleInput("\r");
|
|
169
|
+
}
|
|
170
|
+
this.ui.requestRender();
|
|
171
|
+
}
|
|
172
|
+
showError(error) {
|
|
173
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
174
|
+
this.status.setText(`Startup failed: ${message}\nYour draft is intact. Press Ctrl+C twice or Ctrl+D on an empty draft to exit.`);
|
|
175
|
+
this.editor.disableSubmit = true;
|
|
176
|
+
this.statusContainer.clear();
|
|
177
|
+
this.statusContainer.addChild(this.status);
|
|
178
|
+
this.ui.requestRender();
|
|
179
|
+
}
|
|
180
|
+
async fail(error) {
|
|
181
|
+
this.showError(error);
|
|
182
|
+
if (process.env.PI_STARTUP_BENCHMARK === "1") {
|
|
183
|
+
this.stop();
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
await this.exitPromise;
|
|
187
|
+
}
|
|
188
|
+
stop() {
|
|
189
|
+
if (this.exitRequested)
|
|
190
|
+
return;
|
|
191
|
+
this.exitRequested = true;
|
|
192
|
+
if (this.started) {
|
|
193
|
+
this.ui.stop();
|
|
194
|
+
this.started = false;
|
|
195
|
+
}
|
|
196
|
+
this.inputUnsubscribe?.();
|
|
197
|
+
this.resolveFirstFrame();
|
|
198
|
+
this.resolveExit();
|
|
199
|
+
}
|
|
200
|
+
async select(title, options) {
|
|
201
|
+
const { ExtensionSelectorComponent } = await import("../modes/interactive/components/extension-selector.js");
|
|
202
|
+
return new Promise((resolve) => {
|
|
203
|
+
let settled = false;
|
|
204
|
+
const finish = (value) => {
|
|
205
|
+
if (settled)
|
|
206
|
+
return;
|
|
207
|
+
settled = true;
|
|
208
|
+
this.restoreLayout();
|
|
209
|
+
resolve(value);
|
|
210
|
+
};
|
|
211
|
+
const selector = new ExtensionSelectorComponent(title, options.map((option) => option.label), (label) => finish(options.find((option) => option.label === label)?.value), () => finish(undefined), { tui: this.ui });
|
|
212
|
+
this.showModal(selector, selector);
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
async confirm(title, message) {
|
|
216
|
+
return ((await this.select(`${title}\n${message}`, [
|
|
217
|
+
{ label: "Yes", value: true },
|
|
218
|
+
{ label: "No", value: false },
|
|
219
|
+
])) ?? false);
|
|
220
|
+
}
|
|
221
|
+
async input(title, placeholder) {
|
|
222
|
+
const { ExtensionInputComponent } = await import("../modes/interactive/components/extension-input.js");
|
|
223
|
+
return new Promise((resolve) => {
|
|
224
|
+
let settled = false;
|
|
225
|
+
const finish = (value) => {
|
|
226
|
+
if (settled)
|
|
227
|
+
return;
|
|
228
|
+
settled = true;
|
|
229
|
+
input.dispose();
|
|
230
|
+
this.restoreLayout();
|
|
231
|
+
resolve(value);
|
|
232
|
+
};
|
|
233
|
+
const input = new ExtensionInputComponent(title, placeholder, finish, () => finish(undefined), {
|
|
234
|
+
tui: this.ui,
|
|
235
|
+
});
|
|
236
|
+
this.showModal(input, input);
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
async selectSession(currentSessionsLoader, allSessionsLoader) {
|
|
240
|
+
const { SessionSelectorComponent } = await import("../modes/interactive/components/session-selector.js");
|
|
241
|
+
return new Promise((resolve) => {
|
|
242
|
+
let settled = false;
|
|
243
|
+
const finish = (path) => {
|
|
244
|
+
if (settled)
|
|
245
|
+
return;
|
|
246
|
+
settled = true;
|
|
247
|
+
this.restoreLayout();
|
|
248
|
+
resolve(path);
|
|
249
|
+
};
|
|
250
|
+
const selector = new SessionSelectorComponent(currentSessionsLoader, allSessionsLoader, (path) => finish(path), () => finish(null), () => this.stop(), () => this.ui.requestRender(), { showRenameHint: false, keybindings: this.keybindings });
|
|
251
|
+
this.showModal(selector, selector.getSessionList());
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
showModal(component, focus) {
|
|
255
|
+
this.modalActive = true;
|
|
256
|
+
this.ui.pinFrom(null);
|
|
257
|
+
this.ui.clear();
|
|
258
|
+
this.ui.addChild(component);
|
|
259
|
+
this.ui.setFocus(focus);
|
|
260
|
+
this.ui.requestRender(true);
|
|
261
|
+
}
|
|
262
|
+
restoreLayout() {
|
|
263
|
+
this.modalActive = false;
|
|
264
|
+
this.ui.pinFrom(null);
|
|
265
|
+
this.ui.clear();
|
|
266
|
+
this.ui.addChild(new Spacer(1));
|
|
267
|
+
this.ui.addChild(this.header);
|
|
268
|
+
this.ui.addChild(new Spacer(1));
|
|
269
|
+
this.ui.addChild(this.statusContainer);
|
|
270
|
+
this.ui.addChild(this.editorContainer);
|
|
271
|
+
this.ui.addChild(this.footer);
|
|
272
|
+
this.ui.pinFrom(this.editorContainer);
|
|
273
|
+
this.ui.setFocus(this.editor);
|
|
274
|
+
this.ui.requestRender(true);
|
|
275
|
+
}
|
|
276
|
+
installInputHandlers() {
|
|
277
|
+
this.editor.onAction("app.clear", () => {
|
|
278
|
+
const now = Date.now();
|
|
279
|
+
if (this.editor.getText().length === 0 && now - this.lastClearAt < 500) {
|
|
280
|
+
this.stop();
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
this.editor.setText("");
|
|
284
|
+
this.lastClearAt = now;
|
|
285
|
+
});
|
|
286
|
+
this.editor.onCtrlD = () => this.stop();
|
|
287
|
+
this.editor.onPasteImage = () => void this.pasteClipboard();
|
|
288
|
+
this.inputUnsubscribe = this.ui.addInputListener((data) => {
|
|
289
|
+
const editor = this.currentEditor();
|
|
290
|
+
if (this.modalActive || !isFocusable(editor) || !editor.focused)
|
|
291
|
+
return;
|
|
292
|
+
if (this.keybindings.matches(data, "tui.input.submit")) {
|
|
293
|
+
this.submitRequested = editor.getText().trim().length > 0;
|
|
294
|
+
return { consume: true };
|
|
295
|
+
}
|
|
296
|
+
if (this.keybindings.matches(data, "app.interrupt") || this.keybindings.matches(data, "app.clear")) {
|
|
297
|
+
this.submitRequested = false;
|
|
298
|
+
}
|
|
299
|
+
return undefined;
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
async pasteClipboard() {
|
|
303
|
+
try {
|
|
304
|
+
const [{ readClipboardText }, { extensionForImageMimeType, readClipboardImage }] = await Promise.all([
|
|
305
|
+
import("../utils/clipboard.js"),
|
|
306
|
+
import("../utils/clipboard-image.js"),
|
|
307
|
+
]);
|
|
308
|
+
const image = await readClipboardImage();
|
|
309
|
+
if (image) {
|
|
310
|
+
const extension = extensionForImageMimeType(image.mimeType) ?? "png";
|
|
311
|
+
const filePath = path.join(os.tmpdir(), `lunr-clipboard-${crypto.randomUUID()}.${extension}`);
|
|
312
|
+
fs.writeFileSync(filePath, Buffer.from(image.bytes));
|
|
313
|
+
const id = this.editor.insertImageMarker({ path: filePath, mimeType: image.mimeType });
|
|
314
|
+
this.status.setText(`Pasted [image_${id}] while startup continues.`);
|
|
315
|
+
this.ui.requestRender();
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const text = await readClipboardText();
|
|
319
|
+
if (text) {
|
|
320
|
+
this.editor.insertTextAtCursor(text);
|
|
321
|
+
this.ui.requestRender();
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
this.status.setText("Clipboard contains no image or text.");
|
|
325
|
+
}
|
|
326
|
+
catch (error) {
|
|
327
|
+
this.status.setText(`Clipboard paste failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
328
|
+
}
|
|
329
|
+
this.ui.requestRender();
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
//# sourceMappingURL=interactive-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-view.js","sourceRoot":"","sources":["../../src/startup/interactive-view.ts"],"names":[],"mappings":"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","sourcesContent":["import * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport {\n\ttype Component,\n\tContainer,\n\ttype EditorComponent,\n\tisFocusable,\n\tProcessTerminal,\n\tSpacer,\n\tsetKeybindings,\n\tText,\n\tTUI,\n} from \"@ashx-j/lunr-tui\";\nimport { getChatboxEditor, renderStatsLine, thinkingThemeToken } from \"../builtin-extensions/ashxj-tui.ts\";\nimport { APP_NAME, getAgentDir, VERSION } from \"../config.ts\";\nimport { KeybindingsManager } from \"../core/keybindings.ts\";\nimport { registerPermissionModeBridge } from \"../core/permission-mode.ts\";\nimport type { SessionInfo, SessionListProgress } from \"../core/session-manager.ts\";\nimport type { Settings } from \"../core/settings-manager.ts\";\nimport { BootScreenComponent } from \"../modes/interactive/components/boot-screen.ts\";\nimport { getEditorTheme, getThemeName, initTheme, theme } from \"../modes/interactive/theme/theme.ts\";\nimport { markStartupMilestone } from \"./startup-milestones.ts\";\n\ntype SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionInfo[]>;\n\n// Read display preferences only: no auth, models, resources, migrations, or writes.\nfunction readDisplaySettings(): Partial<Settings> {\n\ttry {\n\t\tconst value = JSON.parse(fs.readFileSync(path.join(getAgentDir(), \"settings.json\"), \"utf8\"));\n\t\treturn value && typeof value === \"object\" && !Array.isArray(value) ? value : {};\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nclass StartupProcessTerminal extends ProcessTerminal {\n\tprivate watchForFirstFrame = false;\n\tprivate firstFrameCallback: (() => void) | undefined;\n\n\tsetFirstFrameCallback(callback: () => void): void {\n\t\tthis.firstFrameCallback = callback;\n\t\tthis.watchForFirstFrame = true;\n\t}\n\n\toverride start(onInput: (data: string) => void, onResize: () => void): void {\n\t\tsuper.start(onInput, onResize);\n\t\tmarkStartupMilestone(\"input_handler_armed\");\n\t\tif (process.stdin.isTTY) markStartupMilestone(\"raw_mode_active\");\n\t}\n\n\toverride write(data: string): void {\n\t\tsuper.write(data);\n\t\t// TUI ends each content frame with synchronized-output end. Setup writes do not count.\n\t\tif (this.watchForFirstFrame && data.includes(\"\\x1b[?2026l\")) {\n\t\t\tthis.watchForFirstFrame = false;\n\t\t\tmarkStartupMilestone(\"first_frame_committed\");\n\t\t\tthis.firstFrameCallback?.();\n\t\t}\n\t}\n}\n\nexport class InteractiveView {\n\treadonly ui: TUI;\n\treadonly editor: ReturnType<typeof getChatboxEditor>;\n\treadonly keybindings: KeybindingsManager;\n\tprivate submitRequested = false;\n\tprivate inputUnsubscribe?: () => void;\n\tprivate modalActive = false;\n\tprivate readonly terminal: StartupProcessTerminal;\n\tprivate readonly status = new Text(\"\", 1, 0);\n\treadonly header: Component;\n\treadonly footer: Component;\n\treadonly statusContainer = new Container();\n\tprivate readonly editorContainer = new Container();\n\tprivate firstFramePromise: Promise<void>;\n\tprivate resolveFirstFrame!: () => void;\n\tprivate exitPromise: Promise<void>;\n\tprivate resolveExit!: () => void;\n\tprivate started = false;\n\tprivate handedOff = false;\n\tprivate exitRequested = false;\n\tprivate lastClearAt = 0;\n\tprivate currentEditor: () => EditorComponent = () => this.editor;\n\n\tconstructor() {\n\t\tconst settings = readDisplaySettings();\n\t\tconst permission = settings.defaultPermissionMode;\n\t\tregisterPermissionModeBridge(() =>\n\t\t\tpermission === \"auto\" || permission === \"yolo\" || permission === \"plan\" ? permission : \"manual\",\n\t\t);\n\t\tinitTheme(typeof settings.theme === \"string\" ? settings.theme : undefined);\n\t\tthis.terminal = new StartupProcessTerminal();\n\t\tthis.ui = new TUI(this.terminal, settings.showHardwareCursor);\n\t\tthis.ui.setClearOnShrink(settings.terminal?.clearOnShrink ?? false);\n\t\tthis.keybindings = KeybindingsManager.create();\n\t\tsetKeybindings(this.keybindings);\n\t\tconst ctx = {\n\t\t\tmode: \"tui\" as const,\n\t\t\thasUI: true,\n\t\t\tmodel: settings.defaultModel ? { id: settings.defaultModel, provider: settings.defaultProvider } : undefined,\n\t\t\tsessionManager: { getEntries: () => [] },\n\t\t\tgetContextUsage: () => undefined,\n\t\t\tui: { theme, setEditorComponent() {}, setFooter() {} },\n\t\t};\n\t\tconst effort = settings.defaultThinkingLevel ?? \"off\";\n\t\tthis.editor = getChatboxEditor(this.ui, getEditorTheme(), this.keybindings as never, ctx, {\n\t\t\tgetThinkingLevel: () => effort,\n\t\t\ton() {},\n\t\t});\n\t\tthis.editor.borderColor = (text) => theme.fg(thinkingThemeToken(effort) as Parameters<typeof theme.fg>[0], text);\n\t\tthis.editor.disableSubmit = true;\n\t\tthis.header = settings.quietStartup\n\t\t\t? new Text(\"\", 0, 0)\n\t\t\t: new BootScreenComponent(theme.bold(theme.fg(\"accent\", APP_NAME)) + theme.fg(\"dim\", ` v${VERSION}`), [\n\t\t\t\t\t{ label: \"directory\", value: process.cwd() },\n\t\t\t\t\t{ label: \"config\", value: getAgentDir() },\n\t\t\t\t\t{ label: \"theme\", value: getThemeName() },\n\t\t\t\t]);\n\t\tthis.footer = {\n\t\t\tinvalidate() {},\n\t\t\trender: (width) =>\n\t\t\t\trenderStatsLine(width, ctx, theme, {\n\t\t\t\t\tgetGitBranch: () => null,\n\t\t\t\t\tgetExtensionStatuses: () => new Map(),\n\t\t\t\t\tgetAvailableProviderCount: () => 0,\n\t\t\t\t\tonBranchChange: () => () => {},\n\t\t\t\t}),\n\t\t};\n\t\tthis.editorContainer.addChild(this.editor);\n\t\tthis.statusContainer.addChild(this.status);\n\t\tthis.firstFramePromise = new Promise((resolve) => {\n\t\t\tthis.resolveFirstFrame = resolve;\n\t\t});\n\t\tthis.exitPromise = new Promise((resolve) => {\n\t\t\tthis.resolveExit = resolve;\n\t\t});\n\t\tthis.terminal.setFirstFrameCallback(this.resolveFirstFrame);\n\t\tthis.installInputHandlers();\n\t}\n\n\tget isExitRequested(): boolean {\n\t\treturn this.exitRequested;\n\t}\n\n\tstart(): void {\n\t\tif (this.started) return;\n\t\tthis.restoreLayout();\n\t\tthis.ui.setAlternateScreen(true);\n\t\tthis.ui.start();\n\t\tthis.started = true;\n\t}\n\n\tpause(): void {\n\t\tif (!this.started || this.handedOff) return;\n\t\tthis.ui.stop();\n\t\tthis.started = false;\n\t}\n\n\tresume(): void {\n\t\tif (this.started || this.handedOff || this.exitRequested) return;\n\t\tthis.restoreLayout();\n\t\tthis.ui.start();\n\t\tthis.started = true;\n\t}\n\n\twaitForFirstFrame(): Promise<void> {\n\t\treturn this.firstFramePromise;\n\t}\n\n\twaitForExit(): Promise<void> {\n\t\treturn this.exitPromise;\n\t}\n\n\tbinding(): InteractiveView {\n\t\tthis.handedOff = true;\n\t\treturn this;\n\t}\n\n\tsetCurrentEditor(getEditor: () => EditorComponent): void {\n\t\tthis.currentEditor = getEditor;\n\t}\n\n\t/** Called only after the normal submit handler and all extensions are ready. */\n\tactivate(): void {\n\t\tif (this.exitRequested) return;\n\t\tthis.inputUnsubscribe?.();\n\t\tthis.inputUnsubscribe = undefined;\n\t\tthis.editor.onPasteImage = undefined;\n\t\tthis.editor.disableSubmit = false;\n\t\tthis.status.setText(\"\");\n\t\tif (this.submitRequested) {\n\t\t\tthis.submitRequested = false;\n\t\t\tthis.currentEditor().handleInput(\"\\r\");\n\t\t}\n\t\tthis.ui.requestRender();\n\t}\n\n\tshowError(error: unknown): void {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthis.status.setText(\n\t\t\t`Startup failed: ${message}\\nYour draft is intact. Press Ctrl+C twice or Ctrl+D on an empty draft to exit.`,\n\t\t);\n\t\tthis.editor.disableSubmit = true;\n\t\tthis.statusContainer.clear();\n\t\tthis.statusContainer.addChild(this.status);\n\t\tthis.ui.requestRender();\n\t}\n\n\tasync fail(error: unknown): Promise<void> {\n\t\tthis.showError(error);\n\t\tif (process.env.PI_STARTUP_BENCHMARK === \"1\") {\n\t\t\tthis.stop();\n\t\t\treturn;\n\t\t}\n\t\tawait this.exitPromise;\n\t}\n\n\tstop(): void {\n\t\tif (this.exitRequested) return;\n\t\tthis.exitRequested = true;\n\t\tif (this.started) {\n\t\t\tthis.ui.stop();\n\t\t\tthis.started = false;\n\t\t}\n\t\tthis.inputUnsubscribe?.();\n\t\tthis.resolveFirstFrame();\n\t\tthis.resolveExit();\n\t}\n\n\tasync select<T>(title: string, options: Array<{ label: string; value: T }>): Promise<T | undefined> {\n\t\tconst { ExtensionSelectorComponent } = await import(\"../modes/interactive/components/extension-selector.ts\");\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tconst finish = (value: T | undefined) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tthis.restoreLayout();\n\t\t\t\tresolve(value);\n\t\t\t};\n\t\t\tconst selector = new ExtensionSelectorComponent(\n\t\t\t\ttitle,\n\t\t\t\toptions.map((option) => option.label),\n\t\t\t\t(label) => finish(options.find((option) => option.label === label)?.value),\n\t\t\t\t() => finish(undefined),\n\t\t\t\t{ tui: this.ui },\n\t\t\t);\n\t\t\tthis.showModal(selector, selector);\n\t\t});\n\t}\n\n\tasync confirm(title: string, message: string): Promise<boolean> {\n\t\treturn (\n\t\t\t(await this.select(`${title}\\n${message}`, [\n\t\t\t\t{ label: \"Yes\", value: true },\n\t\t\t\t{ label: \"No\", value: false },\n\t\t\t])) ?? false\n\t\t);\n\t}\n\n\tasync input(title: string, placeholder?: string): Promise<string | undefined> {\n\t\tconst { ExtensionInputComponent } = await import(\"../modes/interactive/components/extension-input.ts\");\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tconst finish = (value: string | undefined) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tinput.dispose();\n\t\t\t\tthis.restoreLayout();\n\t\t\t\tresolve(value);\n\t\t\t};\n\t\t\tconst input = new ExtensionInputComponent(title, placeholder, finish, () => finish(undefined), {\n\t\t\t\ttui: this.ui,\n\t\t\t});\n\t\t\tthis.showModal(input, input);\n\t\t});\n\t}\n\n\tasync selectSession(\n\t\tcurrentSessionsLoader: SessionsLoader,\n\t\tallSessionsLoader: SessionsLoader,\n\t): Promise<string | null> {\n\t\tconst { SessionSelectorComponent } = await import(\"../modes/interactive/components/session-selector.ts\");\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tconst finish = (path: string | null) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tthis.restoreLayout();\n\t\t\t\tresolve(path);\n\t\t\t};\n\t\t\tconst selector = new SessionSelectorComponent(\n\t\t\t\tcurrentSessionsLoader,\n\t\t\t\tallSessionsLoader,\n\t\t\t\t(path) => finish(path),\n\t\t\t\t() => finish(null),\n\t\t\t\t() => this.stop(),\n\t\t\t\t() => this.ui.requestRender(),\n\t\t\t\t{ showRenameHint: false, keybindings: this.keybindings },\n\t\t\t);\n\t\t\tthis.showModal(selector, selector.getSessionList());\n\t\t});\n\t}\n\n\tprivate showModal(component: Parameters<TUI[\"addChild\"]>[0], focus: Parameters<TUI[\"setFocus\"]>[0]): void {\n\t\tthis.modalActive = true;\n\t\tthis.ui.pinFrom(null);\n\t\tthis.ui.clear();\n\t\tthis.ui.addChild(component);\n\t\tthis.ui.setFocus(focus);\n\t\tthis.ui.requestRender(true);\n\t}\n\n\tprivate restoreLayout(): void {\n\t\tthis.modalActive = false;\n\t\tthis.ui.pinFrom(null);\n\t\tthis.ui.clear();\n\t\tthis.ui.addChild(new Spacer(1));\n\t\tthis.ui.addChild(this.header);\n\t\tthis.ui.addChild(new Spacer(1));\n\t\tthis.ui.addChild(this.statusContainer);\n\t\tthis.ui.addChild(this.editorContainer);\n\t\tthis.ui.addChild(this.footer);\n\t\tthis.ui.pinFrom(this.editorContainer);\n\t\tthis.ui.setFocus(this.editor);\n\t\tthis.ui.requestRender(true);\n\t}\n\n\tprivate installInputHandlers(): void {\n\t\tthis.editor.onAction(\"app.clear\", () => {\n\t\t\tconst now = Date.now();\n\t\t\tif (this.editor.getText().length === 0 && now - this.lastClearAt < 500) {\n\t\t\t\tthis.stop();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.editor.setText(\"\");\n\t\t\tthis.lastClearAt = now;\n\t\t});\n\t\tthis.editor.onCtrlD = () => this.stop();\n\t\tthis.editor.onPasteImage = () => void this.pasteClipboard();\n\t\tthis.inputUnsubscribe = this.ui.addInputListener((data) => {\n\t\t\tconst editor = this.currentEditor();\n\t\t\tif (this.modalActive || !isFocusable(editor) || !editor.focused) return;\n\t\t\tif (this.keybindings.matches(data, \"tui.input.submit\")) {\n\t\t\t\tthis.submitRequested = editor.getText().trim().length > 0;\n\t\t\t\treturn { consume: true };\n\t\t\t}\n\t\t\tif (this.keybindings.matches(data, \"app.interrupt\") || this.keybindings.matches(data, \"app.clear\")) {\n\t\t\t\tthis.submitRequested = false;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t});\n\t}\n\n\tprivate async pasteClipboard(): Promise<void> {\n\t\ttry {\n\t\t\tconst [{ readClipboardText }, { extensionForImageMimeType, readClipboardImage }] = await Promise.all([\n\t\t\t\timport(\"../utils/clipboard.ts\"),\n\t\t\t\timport(\"../utils/clipboard-image.ts\"),\n\t\t\t]);\n\t\t\tconst image = await readClipboardImage();\n\t\t\tif (image) {\n\t\t\t\tconst extension = extensionForImageMimeType(image.mimeType) ?? \"png\";\n\t\t\t\tconst filePath = path.join(os.tmpdir(), `lunr-clipboard-${crypto.randomUUID()}.${extension}`);\n\t\t\t\tfs.writeFileSync(filePath, Buffer.from(image.bytes));\n\t\t\t\tconst id = this.editor.insertImageMarker({ path: filePath, mimeType: image.mimeType });\n\t\t\t\tthis.status.setText(`Pasted [image_${id}] while startup continues.`);\n\t\t\t\tthis.ui.requestRender();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst text = await readClipboardText();\n\t\t\tif (text) {\n\t\t\t\tthis.editor.insertTextAtCursor(text);\n\t\t\t\tthis.ui.requestRender();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.status.setText(\"Clipboard contains no image or text.\");\n\t\t} catch (error) {\n\t\t\tthis.status.setText(`Clipboard paste failed: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\t\tthis.ui.requestRender();\n\t}\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type PreloadLaunchMode = "interactive" | "deferred";
|
|
2
|
+
export interface PreloadLaunchEnvironment {
|
|
3
|
+
stdinIsTTY: boolean;
|
|
4
|
+
stdoutIsTTY: boolean;
|
|
5
|
+
startupBenchmark: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function resolvePreloadLaunchMode(args: readonly string[], environment: PreloadLaunchEnvironment): PreloadLaunchMode;
|
|
8
|
+
//# sourceMappingURL=launch-routing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-routing.d.ts","sourceRoot":"","sources":["../../src/startup/launch-routing.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,UAAU,CAAC;AAc3D,MAAM,WAAW,wBAAwB;IACxC,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,wBAAwB,CACvC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,WAAW,EAAE,wBAAwB,GACnC,iBAAiB,CAenB","sourcesContent":["export type PreloadLaunchMode = \"interactive\" | \"deferred\";\n\nconst DEFERRED_COMMANDS = new Set([\n\t\"config\",\n\t\"features\",\n\t\"gateway\",\n\t\"install\",\n\t\"list\",\n\t\"remove\",\n\t\"setup\",\n\t\"uninstall\",\n\t\"update\",\n]);\n\nexport interface PreloadLaunchEnvironment {\n\tstdinIsTTY: boolean;\n\tstdoutIsTTY: boolean;\n\tstartupBenchmark: boolean;\n}\n\nexport function resolvePreloadLaunchMode(\n\targs: readonly string[],\n\tenvironment: PreloadLaunchEnvironment,\n): PreloadLaunchMode {\n\tif (DEFERRED_COMMANDS.has(args[0] ?? \"\")) return \"deferred\";\n\tconst parsed = parseArgs([...args]);\n\tif (\n\t\tparsed.help ||\n\t\tparsed.version ||\n\t\tparsed.print ||\n\t\tparsed.export ||\n\t\tparsed.listModels !== undefined ||\n\t\tparsed.mode === \"rpc\" ||\n\t\tparsed.mode === \"json\"\n\t)\n\t\treturn \"deferred\";\n\tif (environment.startupBenchmark) return \"interactive\";\n\treturn environment.stdinIsTTY && environment.stdoutIsTTY ? \"interactive\" : \"deferred\";\n}\n\nimport { parseArgs } from \"../cli/args.ts\";\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const DEFERRED_COMMANDS = new Set([
|
|
2
|
+
"config",
|
|
3
|
+
"features",
|
|
4
|
+
"gateway",
|
|
5
|
+
"install",
|
|
6
|
+
"list",
|
|
7
|
+
"remove",
|
|
8
|
+
"setup",
|
|
9
|
+
"uninstall",
|
|
10
|
+
"update",
|
|
11
|
+
]);
|
|
12
|
+
export function resolvePreloadLaunchMode(args, environment) {
|
|
13
|
+
if (DEFERRED_COMMANDS.has(args[0] ?? ""))
|
|
14
|
+
return "deferred";
|
|
15
|
+
const parsed = parseArgs([...args]);
|
|
16
|
+
if (parsed.help ||
|
|
17
|
+
parsed.version ||
|
|
18
|
+
parsed.print ||
|
|
19
|
+
parsed.export ||
|
|
20
|
+
parsed.listModels !== undefined ||
|
|
21
|
+
parsed.mode === "rpc" ||
|
|
22
|
+
parsed.mode === "json")
|
|
23
|
+
return "deferred";
|
|
24
|
+
if (environment.startupBenchmark)
|
|
25
|
+
return "interactive";
|
|
26
|
+
return environment.stdinIsTTY && environment.stdoutIsTTY ? "interactive" : "deferred";
|
|
27
|
+
}
|
|
28
|
+
import { parseArgs } from "../cli/args.js";
|
|
29
|
+
//# sourceMappingURL=launch-routing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-routing.js","sourceRoot":"","sources":["../../src/startup/launch-routing.ts"],"names":[],"mappings":"AAEA,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IACjC,QAAQ;IACR,UAAU;IACV,SAAS;IACT,SAAS;IACT,MAAM;IACN,QAAQ;IACR,OAAO;IACP,WAAW;IACX,QAAQ;CACR,CAAC,CAAC;AAQH,MAAM,UAAU,wBAAwB,CACvC,IAAuB,EACvB,WAAqC,EACjB;IACpB,IAAI,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAAE,OAAO,UAAU,CAAC;IAC5D,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACpC,IACC,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,OAAO;QACd,MAAM,CAAC,KAAK;QACZ,MAAM,CAAC,MAAM;QACb,MAAM,CAAC,UAAU,KAAK,SAAS;QAC/B,MAAM,CAAC,IAAI,KAAK,KAAK;QACrB,MAAM,CAAC,IAAI,KAAK,MAAM;QAEtB,OAAO,UAAU,CAAC;IACnB,IAAI,WAAW,CAAC,gBAAgB;QAAE,OAAO,aAAa,CAAC;IACvD,OAAO,WAAW,CAAC,UAAU,IAAI,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC;AAAA,CACtF;AAED,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC","sourcesContent":["export type PreloadLaunchMode = \"interactive\" | \"deferred\";\n\nconst DEFERRED_COMMANDS = new Set([\n\t\"config\",\n\t\"features\",\n\t\"gateway\",\n\t\"install\",\n\t\"list\",\n\t\"remove\",\n\t\"setup\",\n\t\"uninstall\",\n\t\"update\",\n]);\n\nexport interface PreloadLaunchEnvironment {\n\tstdinIsTTY: boolean;\n\tstdoutIsTTY: boolean;\n\tstartupBenchmark: boolean;\n}\n\nexport function resolvePreloadLaunchMode(\n\targs: readonly string[],\n\tenvironment: PreloadLaunchEnvironment,\n): PreloadLaunchMode {\n\tif (DEFERRED_COMMANDS.has(args[0] ?? \"\")) return \"deferred\";\n\tconst parsed = parseArgs([...args]);\n\tif (\n\t\tparsed.help ||\n\t\tparsed.version ||\n\t\tparsed.print ||\n\t\tparsed.export ||\n\t\tparsed.listModels !== undefined ||\n\t\tparsed.mode === \"rpc\" ||\n\t\tparsed.mode === \"json\"\n\t)\n\t\treturn \"deferred\";\n\tif (environment.startupBenchmark) return \"interactive\";\n\treturn environment.stdinIsTTY && environment.stdoutIsTTY ? \"interactive\" : \"deferred\";\n}\n\nimport { parseArgs } from \"../cli/args.ts\";\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const STARTUP_MILESTONE_PREFIX = "LUNR_STARTUP_MILESTONE ";
|
|
2
|
+
export type StartupMilestoneName = "process_entry" | "mode_routed" | "input_handler_armed" | "raw_mode_active" | "first_frame_committed" | "runtime_hydrated" | "prompt_barrier_open";
|
|
3
|
+
export declare function markStartupMilestone(name: StartupMilestoneName): void;
|
|
4
|
+
//# sourceMappingURL=startup-milestones.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"startup-milestones.d.ts","sourceRoot":"","sources":["../../src/startup/startup-milestones.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,wBAAwB,4BAA4B,CAAC;AAElE,MAAM,MAAM,oBAAoB,GAC7B,eAAe,GACf,aAAa,GACb,qBAAqB,GACrB,iBAAiB,GACjB,uBAAuB,GACvB,kBAAkB,GAClB,qBAAqB,CAAC;AAKzB,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAOrE","sourcesContent":["import { performance } from \"node:perf_hooks\";\n\nexport const STARTUP_MILESTONE_PREFIX = \"LUNR_STARTUP_MILESTONE \";\n\nexport type StartupMilestoneName =\n\t| \"process_entry\"\n\t| \"mode_routed\"\n\t| \"input_handler_armed\"\n\t| \"raw_mode_active\"\n\t| \"first_frame_committed\"\n\t| \"runtime_hydrated\"\n\t| \"prompt_barrier_open\";\n\nconst enabled = process.env.PI_TIMING === \"1\" || process.env.PI_STARTUP_BENCHMARK === \"1\";\nconst recorded = new Set<StartupMilestoneName>();\n\nexport function markStartupMilestone(name: StartupMilestoneName): void {\n\tif (!enabled || recorded.has(name)) return;\n\trecorded.add(name);\n\t// performance.now() includes Node's entry-module loading, before this module\n\t// could start its own timer. Report time since process start, not import end.\n\tconst ms = performance.now();\n\tprocess.stderr.write(`${STARTUP_MILESTONE_PREFIX}${JSON.stringify({ name, ms: Number(ms.toFixed(3)) })}\\n`);\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { performance } from "node:perf_hooks";
|
|
2
|
+
export const STARTUP_MILESTONE_PREFIX = "LUNR_STARTUP_MILESTONE ";
|
|
3
|
+
const enabled = process.env.PI_TIMING === "1" || process.env.PI_STARTUP_BENCHMARK === "1";
|
|
4
|
+
const recorded = new Set();
|
|
5
|
+
export function markStartupMilestone(name) {
|
|
6
|
+
if (!enabled || recorded.has(name))
|
|
7
|
+
return;
|
|
8
|
+
recorded.add(name);
|
|
9
|
+
// performance.now() includes Node's entry-module loading, before this module
|
|
10
|
+
// could start its own timer. Report time since process start, not import end.
|
|
11
|
+
const ms = performance.now();
|
|
12
|
+
process.stderr.write(`${STARTUP_MILESTONE_PREFIX}${JSON.stringify({ name, ms: Number(ms.toFixed(3)) })}\n`);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=startup-milestones.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"startup-milestones.js","sourceRoot":"","sources":["../../src/startup/startup-milestones.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,MAAM,CAAC,MAAM,wBAAwB,GAAG,yBAAyB,CAAC;AAWlE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,GAAG,CAAC;AAC1F,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAwB,CAAC;AAEjD,MAAM,UAAU,oBAAoB,CAAC,IAA0B,EAAQ;IACtE,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO;IAC3C,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnB,6EAA6E;IAC7E,8EAA8E;IAC9E,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,wBAAwB,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;AAAA,CAC5G","sourcesContent":["import { performance } from \"node:perf_hooks\";\n\nexport const STARTUP_MILESTONE_PREFIX = \"LUNR_STARTUP_MILESTONE \";\n\nexport type StartupMilestoneName =\n\t| \"process_entry\"\n\t| \"mode_routed\"\n\t| \"input_handler_armed\"\n\t| \"raw_mode_active\"\n\t| \"first_frame_committed\"\n\t| \"runtime_hydrated\"\n\t| \"prompt_barrier_open\";\n\nconst enabled = process.env.PI_TIMING === \"1\" || process.env.PI_STARTUP_BENCHMARK === \"1\";\nconst recorded = new Set<StartupMilestoneName>();\n\nexport function markStartupMilestone(name: StartupMilestoneName): void {\n\tif (!enabled || recorded.has(name)) return;\n\trecorded.add(name);\n\t// performance.now() includes Node's entry-module loading, before this module\n\t// could start its own timer. Report time since process start, not import end.\n\tconst ms = performance.now();\n\tprocess.stderr.write(`${STARTUP_MILESTONE_PREFIX}${JSON.stringify({ name, ms: Number(ms.toFixed(3)) })}\\n`);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syntax-highlight.d.ts","sourceRoot":"","sources":["../../src/utils/syntax-highlight.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"syntax-highlight.d.ts","sourceRoot":"","sources":["../../src/utils/syntax-highlight.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;AAC1D,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC;AAEzE,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,cAAc,CAAC;CACvB;AAoED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,cAAmB,GAAG,MAAM,CAoDtF;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAQ9E;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD","sourcesContent":["import { createRequire } from \"node:module\";\nimport type Highlighter from \"highlight.js/lib/index.js\";\nimport { decodeHtmlEntityAt } from \"./html.ts\";\n\nconst require = createRequire(import.meta.url);\nlet highlighter: typeof Highlighter | undefined;\nfunction getHighlighter(): typeof Highlighter {\n\thighlighter ??= require(\"highlight.js/lib/index.js\") as typeof Highlighter;\n\treturn highlighter;\n}\n\nexport type HighlightFormatter = (text: string) => string;\nexport type HighlightTheme = Partial<Record<string, HighlightFormatter>>;\n\nexport interface HighlightOptions {\n\tlanguage?: string;\n\tignoreIllegals?: boolean;\n\tlanguageSubset?: string[];\n\ttheme?: HighlightTheme;\n}\n\nconst SPAN_CLOSE = \"</span>\";\nconst HIGHLIGHT_CLASS_PREFIX = \"hljs-\";\n\nfunction getScopeFromSpanTag(tag: string): string | undefined {\n\tconst match = /\\sclass\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)')/.exec(tag);\n\tconst classValue = match?.[1] ?? match?.[2];\n\tif (!classValue) {\n\t\treturn undefined;\n\t}\n\n\tfor (const className of classValue.split(/\\s+/)) {\n\t\tif (className.startsWith(HIGHLIGHT_CLASS_PREFIX)) {\n\t\t\treturn className.slice(HIGHLIGHT_CLASS_PREFIX.length);\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nfunction getScopeFormatter(scope: string, theme: HighlightTheme): HighlightFormatter | undefined {\n\tconst exact = theme[scope];\n\tif (exact) {\n\t\treturn exact;\n\t}\n\n\tconst dotIndex = scope.indexOf(\".\");\n\tif (dotIndex !== -1) {\n\t\tconst prefixFormatter = theme[scope.slice(0, dotIndex)];\n\t\tif (prefixFormatter) {\n\t\t\treturn prefixFormatter;\n\t\t}\n\t}\n\n\tconst dashIndex = scope.indexOf(\"-\");\n\tif (dashIndex !== -1) {\n\t\tconst prefixFormatter = theme[scope.slice(0, dashIndex)];\n\t\tif (prefixFormatter) {\n\t\t\treturn prefixFormatter;\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nfunction getActiveFormatter(scopes: Array<string | undefined>, theme: HighlightTheme): HighlightFormatter | undefined {\n\tfor (let i = scopes.length - 1; i >= 0; i--) {\n\t\tconst scope = scopes[i];\n\t\tif (!scope) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst formatter = getScopeFormatter(scope, theme);\n\t\tif (formatter) {\n\t\t\treturn formatter;\n\t\t}\n\t}\n\treturn theme.default;\n}\n\nfunction isSpanOpenTagStart(html: string, index: number): boolean {\n\tif (!html.startsWith(\"<span\", index)) {\n\t\treturn false;\n\t}\n\tconst nextChar = html[index + \"<span\".length];\n\treturn nextChar === \">\" || nextChar === \" \" || nextChar === \"\\t\" || nextChar === \"\\n\" || nextChar === \"\\r\";\n}\n\nexport function renderHighlightedHtml(html: string, theme: HighlightTheme = {}): string {\n\tlet output = \"\";\n\tlet textBuffer = \"\";\n\tconst scopes: Array<string | undefined> = [];\n\n\tconst flushText = () => {\n\t\tif (!textBuffer) {\n\t\t\treturn;\n\t\t}\n\t\tconst formatter = getActiveFormatter(scopes, theme);\n\t\toutput += formatter ? formatter(textBuffer) : textBuffer;\n\t\ttextBuffer = \"\";\n\t};\n\n\tlet index = 0;\n\twhile (index < html.length) {\n\t\tif (isSpanOpenTagStart(html, index)) {\n\t\t\tconst tagEndIndex = html.indexOf(\">\", index + 5);\n\t\t\tif (tagEndIndex !== -1) {\n\t\t\t\tflushText();\n\t\t\t\tconst tag = html.slice(index, tagEndIndex + 1);\n\t\t\t\tconst scope = getScopeFromSpanTag(tag);\n\t\t\t\tscopes.push(scope);\n\t\t\t\tindex = tagEndIndex + 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif (html.startsWith(SPAN_CLOSE, index)) {\n\t\t\tflushText();\n\t\t\tif (scopes.length > 0) {\n\t\t\t\tscopes.pop();\n\t\t\t}\n\t\t\tindex += SPAN_CLOSE.length;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (html[index] === \"&\") {\n\t\t\tconst decoded = decodeHtmlEntityAt(html, index);\n\t\t\tif (decoded) {\n\t\t\t\ttextBuffer += decoded.text;\n\t\t\t\tindex += decoded.length;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\ttextBuffer += html[index];\n\t\tindex++;\n\t}\n\n\tflushText();\n\treturn output;\n}\n\nexport function highlight(code: string, options: HighlightOptions = {}): string {\n\tconst html = options.language\n\t\t? getHighlighter().highlight(code, {\n\t\t\t\tlanguage: options.language,\n\t\t\t\tignoreIllegals: options.ignoreIllegals,\n\t\t\t}).value\n\t\t: getHighlighter().highlightAuto(code, options.languageSubset).value;\n\treturn renderHighlightedHtml(html, options.theme);\n}\n\nexport function supportsLanguage(name: string): boolean {\n\treturn getHighlighter().getLanguage(name) !== undefined;\n}\n"]}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
2
|
import { decodeHtmlEntityAt } from "./html.js";
|
|
3
|
+
const require = createRequire(import.meta.url);
|
|
4
|
+
let highlighter;
|
|
5
|
+
function getHighlighter() {
|
|
6
|
+
highlighter ??= require("highlight.js/lib/index.js");
|
|
7
|
+
return highlighter;
|
|
8
|
+
}
|
|
3
9
|
const SPAN_CLOSE = "</span>";
|
|
4
10
|
const HIGHLIGHT_CLASS_PREFIX = "hljs-";
|
|
5
11
|
function getScopeFromSpanTag(tag) {
|
|
@@ -105,14 +111,14 @@ export function renderHighlightedHtml(html, theme = {}) {
|
|
|
105
111
|
}
|
|
106
112
|
export function highlight(code, options = {}) {
|
|
107
113
|
const html = options.language
|
|
108
|
-
?
|
|
114
|
+
? getHighlighter().highlight(code, {
|
|
109
115
|
language: options.language,
|
|
110
116
|
ignoreIllegals: options.ignoreIllegals,
|
|
111
117
|
}).value
|
|
112
|
-
:
|
|
118
|
+
: getHighlighter().highlightAuto(code, options.languageSubset).value;
|
|
113
119
|
return renderHighlightedHtml(html, options.theme);
|
|
114
120
|
}
|
|
115
121
|
export function supportsLanguage(name) {
|
|
116
|
-
return
|
|
122
|
+
return getHighlighter().getLanguage(name) !== undefined;
|
|
117
123
|
}
|
|
118
124
|
//# sourceMappingURL=syntax-highlight.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syntax-highlight.js","sourceRoot":"","sources":["../../src/utils/syntax-highlight.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"syntax-highlight.js","sourceRoot":"","sources":["../../src/utils/syntax-highlight.ts"],"names":[],"mappings":"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","sourcesContent":["import { createRequire } from \"node:module\";\nimport type Highlighter from \"highlight.js/lib/index.js\";\nimport { decodeHtmlEntityAt } from \"./html.ts\";\n\nconst require = createRequire(import.meta.url);\nlet highlighter: typeof Highlighter | undefined;\nfunction getHighlighter(): typeof Highlighter {\n\thighlighter ??= require(\"highlight.js/lib/index.js\") as typeof Highlighter;\n\treturn highlighter;\n}\n\nexport type HighlightFormatter = (text: string) => string;\nexport type HighlightTheme = Partial<Record<string, HighlightFormatter>>;\n\nexport interface HighlightOptions {\n\tlanguage?: string;\n\tignoreIllegals?: boolean;\n\tlanguageSubset?: string[];\n\ttheme?: HighlightTheme;\n}\n\nconst SPAN_CLOSE = \"</span>\";\nconst HIGHLIGHT_CLASS_PREFIX = \"hljs-\";\n\nfunction getScopeFromSpanTag(tag: string): string | undefined {\n\tconst match = /\\sclass\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)')/.exec(tag);\n\tconst classValue = match?.[1] ?? match?.[2];\n\tif (!classValue) {\n\t\treturn undefined;\n\t}\n\n\tfor (const className of classValue.split(/\\s+/)) {\n\t\tif (className.startsWith(HIGHLIGHT_CLASS_PREFIX)) {\n\t\t\treturn className.slice(HIGHLIGHT_CLASS_PREFIX.length);\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nfunction getScopeFormatter(scope: string, theme: HighlightTheme): HighlightFormatter | undefined {\n\tconst exact = theme[scope];\n\tif (exact) {\n\t\treturn exact;\n\t}\n\n\tconst dotIndex = scope.indexOf(\".\");\n\tif (dotIndex !== -1) {\n\t\tconst prefixFormatter = theme[scope.slice(0, dotIndex)];\n\t\tif (prefixFormatter) {\n\t\t\treturn prefixFormatter;\n\t\t}\n\t}\n\n\tconst dashIndex = scope.indexOf(\"-\");\n\tif (dashIndex !== -1) {\n\t\tconst prefixFormatter = theme[scope.slice(0, dashIndex)];\n\t\tif (prefixFormatter) {\n\t\t\treturn prefixFormatter;\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nfunction getActiveFormatter(scopes: Array<string | undefined>, theme: HighlightTheme): HighlightFormatter | undefined {\n\tfor (let i = scopes.length - 1; i >= 0; i--) {\n\t\tconst scope = scopes[i];\n\t\tif (!scope) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst formatter = getScopeFormatter(scope, theme);\n\t\tif (formatter) {\n\t\t\treturn formatter;\n\t\t}\n\t}\n\treturn theme.default;\n}\n\nfunction isSpanOpenTagStart(html: string, index: number): boolean {\n\tif (!html.startsWith(\"<span\", index)) {\n\t\treturn false;\n\t}\n\tconst nextChar = html[index + \"<span\".length];\n\treturn nextChar === \">\" || nextChar === \" \" || nextChar === \"\\t\" || nextChar === \"\\n\" || nextChar === \"\\r\";\n}\n\nexport function renderHighlightedHtml(html: string, theme: HighlightTheme = {}): string {\n\tlet output = \"\";\n\tlet textBuffer = \"\";\n\tconst scopes: Array<string | undefined> = [];\n\n\tconst flushText = () => {\n\t\tif (!textBuffer) {\n\t\t\treturn;\n\t\t}\n\t\tconst formatter = getActiveFormatter(scopes, theme);\n\t\toutput += formatter ? formatter(textBuffer) : textBuffer;\n\t\ttextBuffer = \"\";\n\t};\n\n\tlet index = 0;\n\twhile (index < html.length) {\n\t\tif (isSpanOpenTagStart(html, index)) {\n\t\t\tconst tagEndIndex = html.indexOf(\">\", index + 5);\n\t\t\tif (tagEndIndex !== -1) {\n\t\t\t\tflushText();\n\t\t\t\tconst tag = html.slice(index, tagEndIndex + 1);\n\t\t\t\tconst scope = getScopeFromSpanTag(tag);\n\t\t\t\tscopes.push(scope);\n\t\t\t\tindex = tagEndIndex + 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif (html.startsWith(SPAN_CLOSE, index)) {\n\t\t\tflushText();\n\t\t\tif (scopes.length > 0) {\n\t\t\t\tscopes.pop();\n\t\t\t}\n\t\t\tindex += SPAN_CLOSE.length;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (html[index] === \"&\") {\n\t\t\tconst decoded = decodeHtmlEntityAt(html, index);\n\t\t\tif (decoded) {\n\t\t\t\ttextBuffer += decoded.text;\n\t\t\t\tindex += decoded.length;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\ttextBuffer += html[index];\n\t\tindex++;\n\t}\n\n\tflushText();\n\treturn output;\n}\n\nexport function highlight(code: string, options: HighlightOptions = {}): string {\n\tconst html = options.language\n\t\t? getHighlighter().highlight(code, {\n\t\t\t\tlanguage: options.language,\n\t\t\t\tignoreIllegals: options.ignoreIllegals,\n\t\t\t}).value\n\t\t: getHighlighter().highlightAuto(code, options.languageSubset).value;\n\treturn renderHighlightedHtml(html, options.theme);\n}\n\nexport function supportsLanguage(name: string): boolean {\n\treturn getHighlighter().getLanguage(name) !== undefined;\n}\n"]}
|
package/docs/features.md
CHANGED
|
@@ -82,10 +82,10 @@ Without runnable adapters (enabled platform + resolvable token), `lunr gateway`
|
|
|
82
82
|
- `/thinking`, `/effort`, and `/reasoning` are full-parity aliases. `/thinking` only offers levels the session model supports (`getSupportedThinkingLevels`). `xhigh` and `max` are opt-in.
|
|
83
83
|
- `/usage` is **this-session** context plus every stored-credential subscription plan. The current provider is included for env-only auth. There is no `/token-usage`.
|
|
84
84
|
- `/fast [on|off|status]` controls `service_tier: "fast"` for OpenAI Codex subscriptions only. It persists across new sessions, gateway turns, and subagents. Paid `openai` API models do not use it.
|
|
85
|
-
- Footer plan bar prefers a 5h window and falls back to weekly (`planUsageWindow`). Customize
|
|
85
|
+
- Footer plan bar prefers a 5h window and falls back to weekly (`planUsageWindow`). In Customize, Plan usage hides the whole segment while Plan bar hides only the █░ fill and keeps the percent.
|
|
86
86
|
- Click a ✻ Thought or tool card to expand/collapse that item. `app.tools.expand` is unbound. `/tree` still uses `ctrl+o` for filters.
|
|
87
87
|
- Smooth streaming (`smoothStreaming`, default off) is **interactive TUI only** (grapheme reveal at ~30 FPS). Print, RPC, and gateway stay unsmoothed.
|
|
88
|
-
- Image paste inserts `[image_n]` chips.
|
|
88
|
+
- Image paste inserts `[image_n]` chips. Windows uses **Alt+V**; VS Code must forward it because it owns Ctrl+V and Alt+V. `/paste-image` bypasses terminal shortcuts.
|
|
89
89
|
- Model tiers: `/settings` Enable model tiers. Per-tier thinking; unset = parent session.
|
|
90
90
|
|
|
91
91
|
## Updates, catalogs, local models
|