indusagi-coding-agent 0.1.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.
Files changed (240) hide show
  1. package/CHANGELOG.md +2249 -0
  2. package/README.md +546 -0
  3. package/dist/cli/args.js +282 -0
  4. package/dist/cli/config-selector.js +30 -0
  5. package/dist/cli/file-processor.js +78 -0
  6. package/dist/cli/list-models.js +91 -0
  7. package/dist/cli/session-picker.js +31 -0
  8. package/dist/cli.js +10 -0
  9. package/dist/config.js +158 -0
  10. package/dist/core/agent-session.js +2097 -0
  11. package/dist/core/auth-storage.js +278 -0
  12. package/dist/core/bash-executor.js +211 -0
  13. package/dist/core/compaction/branch-summarization.js +241 -0
  14. package/dist/core/compaction/compaction.js +606 -0
  15. package/dist/core/compaction/index.js +6 -0
  16. package/dist/core/compaction/utils.js +137 -0
  17. package/dist/core/diagnostics.js +1 -0
  18. package/dist/core/event-bus.js +24 -0
  19. package/dist/core/exec.js +70 -0
  20. package/dist/core/export-html/ansi-to-html.js +248 -0
  21. package/dist/core/export-html/index.js +221 -0
  22. package/dist/core/export-html/template.css +905 -0
  23. package/dist/core/export-html/template.html +54 -0
  24. package/dist/core/export-html/template.js +1549 -0
  25. package/dist/core/export-html/tool-renderer.js +56 -0
  26. package/dist/core/export-html/vendor/highlight.min.js +1213 -0
  27. package/dist/core/export-html/vendor/marked.min.js +6 -0
  28. package/dist/core/extensions/index.js +8 -0
  29. package/dist/core/extensions/loader.js +395 -0
  30. package/dist/core/extensions/runner.js +499 -0
  31. package/dist/core/extensions/types.js +31 -0
  32. package/dist/core/extensions/wrapper.js +101 -0
  33. package/dist/core/footer-data-provider.js +133 -0
  34. package/dist/core/index.js +8 -0
  35. package/dist/core/keybindings.js +140 -0
  36. package/dist/core/messages.js +122 -0
  37. package/dist/core/model-registry.js +454 -0
  38. package/dist/core/model-resolver.js +309 -0
  39. package/dist/core/package-manager.js +1142 -0
  40. package/dist/core/prompt-templates.js +250 -0
  41. package/dist/core/resource-loader.js +569 -0
  42. package/dist/core/sdk.js +225 -0
  43. package/dist/core/session-manager.js +1078 -0
  44. package/dist/core/settings-manager.js +430 -0
  45. package/dist/core/skills.js +339 -0
  46. package/dist/core/system-prompt.js +136 -0
  47. package/dist/core/timings.js +24 -0
  48. package/dist/core/tools/bash.js +226 -0
  49. package/dist/core/tools/edit-diff.js +242 -0
  50. package/dist/core/tools/edit.js +145 -0
  51. package/dist/core/tools/find.js +205 -0
  52. package/dist/core/tools/grep.js +238 -0
  53. package/dist/core/tools/index.js +60 -0
  54. package/dist/core/tools/ls.js +117 -0
  55. package/dist/core/tools/path-utils.js +52 -0
  56. package/dist/core/tools/read.js +165 -0
  57. package/dist/core/tools/truncate.js +204 -0
  58. package/dist/core/tools/write.js +77 -0
  59. package/dist/index.js +41 -0
  60. package/dist/main.js +565 -0
  61. package/dist/migrations.js +260 -0
  62. package/dist/modes/index.js +7 -0
  63. package/dist/modes/interactive/components/armin.js +328 -0
  64. package/dist/modes/interactive/components/assistant-message.js +86 -0
  65. package/dist/modes/interactive/components/bash-execution.js +155 -0
  66. package/dist/modes/interactive/components/bordered-loader.js +47 -0
  67. package/dist/modes/interactive/components/branch-summary-message.js +41 -0
  68. package/dist/modes/interactive/components/compaction-summary-message.js +42 -0
  69. package/dist/modes/interactive/components/config-selector.js +458 -0
  70. package/dist/modes/interactive/components/countdown-timer.js +27 -0
  71. package/dist/modes/interactive/components/custom-editor.js +61 -0
  72. package/dist/modes/interactive/components/custom-message.js +80 -0
  73. package/dist/modes/interactive/components/diff.js +132 -0
  74. package/dist/modes/interactive/components/dynamic-border.js +19 -0
  75. package/dist/modes/interactive/components/extension-editor.js +96 -0
  76. package/dist/modes/interactive/components/extension-input.js +54 -0
  77. package/dist/modes/interactive/components/extension-selector.js +70 -0
  78. package/dist/modes/interactive/components/footer.js +213 -0
  79. package/dist/modes/interactive/components/index.js +31 -0
  80. package/dist/modes/interactive/components/keybinding-hints.js +60 -0
  81. package/dist/modes/interactive/components/login-dialog.js +138 -0
  82. package/dist/modes/interactive/components/model-selector.js +253 -0
  83. package/dist/modes/interactive/components/oauth-selector.js +91 -0
  84. package/dist/modes/interactive/components/scoped-models-selector.js +262 -0
  85. package/dist/modes/interactive/components/session-selector-search.js +145 -0
  86. package/dist/modes/interactive/components/session-selector.js +698 -0
  87. package/dist/modes/interactive/components/settings-selector.js +250 -0
  88. package/dist/modes/interactive/components/show-images-selector.js +33 -0
  89. package/dist/modes/interactive/components/skill-invocation-message.js +44 -0
  90. package/dist/modes/interactive/components/theme-selector.js +43 -0
  91. package/dist/modes/interactive/components/thinking-selector.js +45 -0
  92. package/dist/modes/interactive/components/tool-execution.js +608 -0
  93. package/dist/modes/interactive/components/tree-selector.js +892 -0
  94. package/dist/modes/interactive/components/user-message-selector.js +109 -0
  95. package/dist/modes/interactive/components/user-message.js +15 -0
  96. package/dist/modes/interactive/components/visual-truncate.js +32 -0
  97. package/dist/modes/interactive/interactive-mode.js +3576 -0
  98. package/dist/modes/interactive/theme/dark.json +85 -0
  99. package/dist/modes/interactive/theme/light.json +84 -0
  100. package/dist/modes/interactive/theme/theme-schema.json +335 -0
  101. package/dist/modes/interactive/theme/theme.js +938 -0
  102. package/dist/modes/print-mode.js +96 -0
  103. package/dist/modes/rpc/rpc-client.js +390 -0
  104. package/dist/modes/rpc/rpc-mode.js +448 -0
  105. package/dist/modes/rpc/rpc-types.js +7 -0
  106. package/dist/utils/changelog.js +86 -0
  107. package/dist/utils/clipboard-image.js +116 -0
  108. package/dist/utils/clipboard.js +58 -0
  109. package/dist/utils/frontmatter.js +25 -0
  110. package/dist/utils/git.js +5 -0
  111. package/dist/utils/image-convert.js +34 -0
  112. package/dist/utils/image-resize.js +180 -0
  113. package/dist/utils/mime.js +25 -0
  114. package/dist/utils/photon.js +120 -0
  115. package/dist/utils/shell.js +164 -0
  116. package/dist/utils/sleep.js +16 -0
  117. package/dist/utils/tools-manager.js +186 -0
  118. package/docs/compaction.md +390 -0
  119. package/docs/custom-provider.md +538 -0
  120. package/docs/development.md +69 -0
  121. package/docs/extensions.md +1733 -0
  122. package/docs/images/doom-extension.png +0 -0
  123. package/docs/images/interactive-mode.png +0 -0
  124. package/docs/images/tree-view.png +0 -0
  125. package/docs/json.md +79 -0
  126. package/docs/keybindings.md +162 -0
  127. package/docs/models.md +193 -0
  128. package/docs/packages.md +163 -0
  129. package/docs/prompt-templates.md +67 -0
  130. package/docs/providers.md +147 -0
  131. package/docs/rpc.md +1048 -0
  132. package/docs/sdk.md +957 -0
  133. package/docs/session.md +412 -0
  134. package/docs/settings.md +216 -0
  135. package/docs/shell-aliases.md +13 -0
  136. package/docs/skills.md +226 -0
  137. package/docs/terminal-setup.md +65 -0
  138. package/docs/themes.md +295 -0
  139. package/docs/tree.md +219 -0
  140. package/docs/tui.md +887 -0
  141. package/docs/windows.md +17 -0
  142. package/examples/README.md +25 -0
  143. package/examples/extensions/README.md +192 -0
  144. package/examples/extensions/antigravity-image-gen.ts +414 -0
  145. package/examples/extensions/auto-commit-on-exit.ts +49 -0
  146. package/examples/extensions/bookmark.ts +50 -0
  147. package/examples/extensions/claude-rules.ts +86 -0
  148. package/examples/extensions/confirm-destructive.ts +59 -0
  149. package/examples/extensions/custom-compaction.ts +115 -0
  150. package/examples/extensions/custom-footer.ts +65 -0
  151. package/examples/extensions/custom-header.ts +73 -0
  152. package/examples/extensions/custom-provider-anthropic/index.ts +605 -0
  153. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  154. package/examples/extensions/custom-provider-anthropic/package.json +19 -0
  155. package/examples/extensions/custom-provider-gitlab-duo/index.ts +350 -0
  156. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
  157. package/examples/extensions/custom-provider-gitlab-duo/test.ts +83 -0
  158. package/examples/extensions/dirty-repo-guard.ts +56 -0
  159. package/examples/extensions/doom-overlay/README.md +46 -0
  160. package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
  161. package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  162. package/examples/extensions/doom-overlay/doom/build.sh +152 -0
  163. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  164. package/examples/extensions/doom-overlay/doom-component.ts +133 -0
  165. package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  166. package/examples/extensions/doom-overlay/doom-keys.ts +105 -0
  167. package/examples/extensions/doom-overlay/index.ts +74 -0
  168. package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
  169. package/examples/extensions/event-bus.ts +43 -0
  170. package/examples/extensions/file-trigger.ts +41 -0
  171. package/examples/extensions/git-checkpoint.ts +53 -0
  172. package/examples/extensions/handoff.ts +151 -0
  173. package/examples/extensions/hello.ts +25 -0
  174. package/examples/extensions/inline-bash.ts +94 -0
  175. package/examples/extensions/input-transform.ts +43 -0
  176. package/examples/extensions/interactive-shell.ts +196 -0
  177. package/examples/extensions/mac-system-theme.ts +47 -0
  178. package/examples/extensions/message-renderer.ts +60 -0
  179. package/examples/extensions/modal-editor.ts +86 -0
  180. package/examples/extensions/model-status.ts +31 -0
  181. package/examples/extensions/notify.ts +25 -0
  182. package/examples/extensions/overlay-qa-tests.ts +882 -0
  183. package/examples/extensions/overlay-test.ts +151 -0
  184. package/examples/extensions/permission-gate.ts +34 -0
  185. package/examples/extensions/pirate.ts +47 -0
  186. package/examples/extensions/plan-mode/README.md +65 -0
  187. package/examples/extensions/plan-mode/index.ts +341 -0
  188. package/examples/extensions/plan-mode/utils.ts +168 -0
  189. package/examples/extensions/preset.ts +399 -0
  190. package/examples/extensions/protected-paths.ts +30 -0
  191. package/examples/extensions/qna.ts +120 -0
  192. package/examples/extensions/question.ts +265 -0
  193. package/examples/extensions/questionnaire.ts +428 -0
  194. package/examples/extensions/rainbow-editor.ts +88 -0
  195. package/examples/extensions/sandbox/index.ts +318 -0
  196. package/examples/extensions/sandbox/package-lock.json +92 -0
  197. package/examples/extensions/sandbox/package.json +19 -0
  198. package/examples/extensions/send-user-message.ts +97 -0
  199. package/examples/extensions/session-name.ts +27 -0
  200. package/examples/extensions/shutdown-command.ts +63 -0
  201. package/examples/extensions/snake.ts +344 -0
  202. package/examples/extensions/space-invaders.ts +561 -0
  203. package/examples/extensions/ssh.ts +220 -0
  204. package/examples/extensions/status-line.ts +40 -0
  205. package/examples/extensions/subagent/README.md +172 -0
  206. package/examples/extensions/subagent/agents/planner.md +37 -0
  207. package/examples/extensions/subagent/agents/reviewer.md +35 -0
  208. package/examples/extensions/subagent/agents/scout.md +50 -0
  209. package/examples/extensions/subagent/agents/worker.md +24 -0
  210. package/examples/extensions/subagent/agents.ts +127 -0
  211. package/examples/extensions/subagent/index.ts +964 -0
  212. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  213. package/examples/extensions/subagent/prompts/implement.md +10 -0
  214. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  215. package/examples/extensions/summarize.ts +196 -0
  216. package/examples/extensions/timed-confirm.ts +70 -0
  217. package/examples/extensions/todo.ts +300 -0
  218. package/examples/extensions/tool-override.ts +144 -0
  219. package/examples/extensions/tools.ts +147 -0
  220. package/examples/extensions/trigger-compact.ts +40 -0
  221. package/examples/extensions/truncated-tool.ts +193 -0
  222. package/examples/extensions/widget-placement.ts +17 -0
  223. package/examples/extensions/with-deps/index.ts +36 -0
  224. package/examples/extensions/with-deps/package-lock.json +31 -0
  225. package/examples/extensions/with-deps/package.json +22 -0
  226. package/examples/sdk/01-minimal.ts +22 -0
  227. package/examples/sdk/02-custom-model.ts +50 -0
  228. package/examples/sdk/03-custom-prompt.ts +55 -0
  229. package/examples/sdk/04-skills.ts +46 -0
  230. package/examples/sdk/05-tools.ts +56 -0
  231. package/examples/sdk/06-extensions.ts +88 -0
  232. package/examples/sdk/07-context-files.ts +40 -0
  233. package/examples/sdk/08-prompt-templates.ts +47 -0
  234. package/examples/sdk/09-api-keys-and-oauth.ts +48 -0
  235. package/examples/sdk/10-settings.ts +38 -0
  236. package/examples/sdk/11-sessions.ts +48 -0
  237. package/examples/sdk/12-full-control.ts +82 -0
  238. package/examples/sdk/13-codex-oauth.ts +37 -0
  239. package/examples/sdk/README.md +144 -0
  240. package/package.json +85 -0
@@ -0,0 +1,221 @@
1
+ import { existsSync, readFileSync, writeFileSync } from "fs";
2
+ import { basename, join } from "path";
3
+ import { APP_NAME, getExportTemplateDir } from "../../config.js";
4
+ import { getResolvedThemeColors, getThemeExportColors } from "../../modes/interactive/theme/theme.js";
5
+ import { SessionManager } from "../session-manager.js";
6
+ /** Parse a color string to RGB values. Supports hex (#RRGGBB) and rgb(r,g,b) formats. */
7
+ function parseColor(color) {
8
+ const hexMatch = color.match(/^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/);
9
+ if (hexMatch) {
10
+ return {
11
+ r: Number.parseInt(hexMatch[1], 16),
12
+ g: Number.parseInt(hexMatch[2], 16),
13
+ b: Number.parseInt(hexMatch[3], 16),
14
+ };
15
+ }
16
+ const rgbMatch = color.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/);
17
+ if (rgbMatch) {
18
+ return {
19
+ r: Number.parseInt(rgbMatch[1], 10),
20
+ g: Number.parseInt(rgbMatch[2], 10),
21
+ b: Number.parseInt(rgbMatch[3], 10),
22
+ };
23
+ }
24
+ return undefined;
25
+ }
26
+ /** Calculate relative luminance of a color (0-1, higher = lighter). */
27
+ function getLuminance(r, g, b) {
28
+ const toLinear = (c) => {
29
+ const s = c / 255;
30
+ return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
31
+ };
32
+ return 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);
33
+ }
34
+ /** Adjust color brightness. Factor > 1 lightens, < 1 darkens. */
35
+ function adjustBrightness(color, factor) {
36
+ const parsed = parseColor(color);
37
+ if (!parsed)
38
+ return color;
39
+ const adjust = (c) => Math.min(255, Math.max(0, Math.round(c * factor)));
40
+ return `rgb(${adjust(parsed.r)}, ${adjust(parsed.g)}, ${adjust(parsed.b)})`;
41
+ }
42
+ /** Derive export background colors from a base color (e.g., userMessageBg). */
43
+ function deriveExportColors(baseColor) {
44
+ const parsed = parseColor(baseColor);
45
+ if (!parsed) {
46
+ return {
47
+ pageBg: "rgb(24, 24, 30)",
48
+ cardBg: "rgb(30, 30, 36)",
49
+ infoBg: "rgb(60, 55, 40)",
50
+ };
51
+ }
52
+ const luminance = getLuminance(parsed.r, parsed.g, parsed.b);
53
+ const isLight = luminance > 0.5;
54
+ if (isLight) {
55
+ return {
56
+ pageBg: adjustBrightness(baseColor, 0.96),
57
+ cardBg: baseColor,
58
+ infoBg: `rgb(${Math.min(255, parsed.r + 10)}, ${Math.min(255, parsed.g + 5)}, ${Math.max(0, parsed.b - 20)})`,
59
+ };
60
+ }
61
+ return {
62
+ pageBg: adjustBrightness(baseColor, 0.7),
63
+ cardBg: adjustBrightness(baseColor, 0.85),
64
+ infoBg: `rgb(${Math.min(255, parsed.r + 20)}, ${Math.min(255, parsed.g + 15)}, ${parsed.b})`,
65
+ };
66
+ }
67
+ /**
68
+ * Generate CSS custom property declarations from theme colors.
69
+ */
70
+ function generateThemeVars(themeName) {
71
+ const colors = getResolvedThemeColors(themeName);
72
+ const lines = [];
73
+ for (const [key, value] of Object.entries(colors)) {
74
+ lines.push(`--${key}: ${value};`);
75
+ }
76
+ // Use explicit theme export colors if available, otherwise derive from userMessageBg
77
+ const themeExport = getThemeExportColors(themeName);
78
+ const userMessageBg = colors.userMessageBg || "#343541";
79
+ const derivedColors = deriveExportColors(userMessageBg);
80
+ lines.push(`--exportPageBg: ${themeExport.pageBg ?? derivedColors.pageBg};`);
81
+ lines.push(`--exportCardBg: ${themeExport.cardBg ?? derivedColors.cardBg};`);
82
+ lines.push(`--exportInfoBg: ${themeExport.infoBg ?? derivedColors.infoBg};`);
83
+ return lines.join("\n ");
84
+ }
85
+ /**
86
+ * Core HTML generation logic shared by both export functions.
87
+ */
88
+ function generateHtml(sessionData, themeName) {
89
+ const templateDir = getExportTemplateDir();
90
+ const template = readFileSync(join(templateDir, "template.html"), "utf-8");
91
+ const templateCss = readFileSync(join(templateDir, "template.css"), "utf-8");
92
+ const templateJs = readFileSync(join(templateDir, "template.js"), "utf-8");
93
+ const markedJs = readFileSync(join(templateDir, "vendor", "marked.min.js"), "utf-8");
94
+ const hljsJs = readFileSync(join(templateDir, "vendor", "highlight.min.js"), "utf-8");
95
+ const themeVars = generateThemeVars(themeName);
96
+ const colors = getResolvedThemeColors(themeName);
97
+ const exportColors = deriveExportColors(colors.userMessageBg || "#343541");
98
+ const bodyBg = exportColors.pageBg;
99
+ const containerBg = exportColors.cardBg;
100
+ const infoBg = exportColors.infoBg;
101
+ // Base64 encode session data to avoid escaping issues
102
+ const sessionDataBase64 = Buffer.from(JSON.stringify(sessionData)).toString("base64");
103
+ // Build the CSS with theme variables injected
104
+ const css = templateCss
105
+ .replace("{{THEME_VARS}}", themeVars)
106
+ .replace("{{BODY_BG}}", bodyBg)
107
+ .replace("{{CONTAINER_BG}}", containerBg)
108
+ .replace("{{INFO_BG}}", infoBg);
109
+ return template
110
+ .replace("{{CSS}}", css)
111
+ .replace("{{JS}}", templateJs)
112
+ .replace("{{SESSION_DATA}}", sessionDataBase64)
113
+ .replace("{{MARKED_JS}}", markedJs)
114
+ .replace("{{HIGHLIGHT_JS}}", hljsJs);
115
+ }
116
+ /** Built-in tool names that have custom rendering in template.js */
117
+ const BUILTIN_TOOLS = new Set(["bash", "read", "write", "edit", "ls", "find", "grep"]);
118
+ /**
119
+ * Pre-render custom tools to HTML using their TUI renderers.
120
+ */
121
+ function preRenderCustomTools(entries, toolRenderer) {
122
+ const renderedTools = {};
123
+ for (const entry of entries) {
124
+ if (entry.type !== "message")
125
+ continue;
126
+ const msg = entry.message;
127
+ // Find tool calls in assistant messages
128
+ if (msg.role === "assistant" && Array.isArray(msg.content)) {
129
+ for (const block of msg.content) {
130
+ if (block.type === "toolCall" && !BUILTIN_TOOLS.has(block.name)) {
131
+ const callHtml = toolRenderer.renderCall(block.name, block.arguments);
132
+ if (callHtml) {
133
+ renderedTools[block.id] = { callHtml };
134
+ }
135
+ }
136
+ }
137
+ }
138
+ // Find tool results
139
+ if (msg.role === "toolResult" && msg.toolCallId) {
140
+ const toolName = msg.toolName || "";
141
+ // Only render if we have a pre-rendered call OR it's not a built-in tool
142
+ const existing = renderedTools[msg.toolCallId];
143
+ if (existing || !BUILTIN_TOOLS.has(toolName)) {
144
+ const resultHtml = toolRenderer.renderResult(toolName, msg.content, msg.details, msg.isError || false);
145
+ if (resultHtml) {
146
+ renderedTools[msg.toolCallId] = {
147
+ ...existing,
148
+ resultHtml,
149
+ };
150
+ }
151
+ }
152
+ }
153
+ }
154
+ return renderedTools;
155
+ }
156
+ /**
157
+ * Export session to HTML using SessionManager and AgentState.
158
+ * Used by TUI's /export command.
159
+ */
160
+ export async function exportSessionToHtml(sm, state, options) {
161
+ const opts = typeof options === "string" ? { outputPath: options } : options || {};
162
+ const sessionFile = sm.getSessionFile();
163
+ if (!sessionFile) {
164
+ throw new Error("Cannot export in-memory session to HTML");
165
+ }
166
+ if (!existsSync(sessionFile)) {
167
+ throw new Error("Nothing to export yet - start a conversation first");
168
+ }
169
+ const entries = sm.getEntries();
170
+ // Pre-render custom tools if a tool renderer is provided
171
+ let renderedTools;
172
+ if (opts.toolRenderer) {
173
+ renderedTools = preRenderCustomTools(entries, opts.toolRenderer);
174
+ // Only include if we actually rendered something
175
+ if (Object.keys(renderedTools).length === 0) {
176
+ renderedTools = undefined;
177
+ }
178
+ }
179
+ const sessionData = {
180
+ header: sm.getHeader(),
181
+ entries,
182
+ leafId: sm.getLeafId(),
183
+ systemPrompt: state?.systemPrompt,
184
+ tools: state?.tools?.map((t) => ({ name: t.name, description: t.description })),
185
+ renderedTools,
186
+ };
187
+ const html = generateHtml(sessionData, opts.themeName);
188
+ let outputPath = opts.outputPath;
189
+ if (!outputPath) {
190
+ const sessionBasename = basename(sessionFile, ".jsonl");
191
+ outputPath = `${APP_NAME}-session-${sessionBasename}.html`;
192
+ }
193
+ writeFileSync(outputPath, html, "utf8");
194
+ return outputPath;
195
+ }
196
+ /**
197
+ * Export session file to HTML (standalone, without AgentState).
198
+ * Used by CLI for exporting arbitrary session files.
199
+ */
200
+ export async function exportFromFile(inputPath, options) {
201
+ const opts = typeof options === "string" ? { outputPath: options } : options || {};
202
+ if (!existsSync(inputPath)) {
203
+ throw new Error(`File not found: ${inputPath}`);
204
+ }
205
+ const sm = SessionManager.open(inputPath);
206
+ const sessionData = {
207
+ header: sm.getHeader(),
208
+ entries: sm.getEntries(),
209
+ leafId: sm.getLeafId(),
210
+ systemPrompt: undefined,
211
+ tools: undefined,
212
+ };
213
+ const html = generateHtml(sessionData, opts.themeName);
214
+ let outputPath = opts.outputPath;
215
+ if (!outputPath) {
216
+ const inputBasename = basename(inputPath, ".jsonl");
217
+ outputPath = `${APP_NAME}-session-${inputBasename}.html`;
218
+ }
219
+ writeFileSync(outputPath, html, "utf8");
220
+ return outputPath;
221
+ }