@valni/cli-darwin-x64 0.0.0-stage → 0.1.2

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 (236) hide show
  1. package/LICENSE +53 -0
  2. package/package.json +18 -5
  3. package/runtime/LICENSE +53 -0
  4. package/runtime/README.md +674 -0
  5. package/runtime/assets/clankolas.png +0 -0
  6. package/runtime/docs/extensions.md +2910 -0
  7. package/runtime/docs/json.md +82 -0
  8. package/runtime/docs/models.md +540 -0
  9. package/runtime/docs/packages.md +228 -0
  10. package/runtime/docs/rpc.md +1480 -0
  11. package/runtime/docs/sdk.md +1183 -0
  12. package/runtime/docs/session-format.md +422 -0
  13. package/runtime/docs/settings.md +315 -0
  14. package/runtime/docs/shell-aliases.md +13 -0
  15. package/runtime/docs/terminal-setup.md +142 -0
  16. package/runtime/docs/termux.md +127 -0
  17. package/runtime/docs/tmux.md +63 -0
  18. package/runtime/docs/tui.md +927 -0
  19. package/runtime/docs/windows.md +17 -0
  20. package/runtime/examples/README.md +25 -0
  21. package/runtime/examples/extensions/README.md +212 -0
  22. package/runtime/examples/extensions/auto-commit-on-exit.ts +49 -0
  23. package/runtime/examples/extensions/bash-spawn-hook.ts +30 -0
  24. package/runtime/examples/extensions/bookmark.ts +50 -0
  25. package/runtime/examples/extensions/border-status-editor.ts +145 -0
  26. package/runtime/examples/extensions/built-in-tool-renderer.ts +249 -0
  27. package/runtime/examples/extensions/claude-rules.ts +86 -0
  28. package/runtime/examples/extensions/commands.ts +72 -0
  29. package/runtime/examples/extensions/confirm-destructive.ts +59 -0
  30. package/runtime/examples/extensions/custom-footer.ts +64 -0
  31. package/runtime/examples/extensions/custom-header.ts +73 -0
  32. package/runtime/examples/extensions/custom-provider-anthropic/index.ts +604 -0
  33. package/runtime/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  34. package/runtime/examples/extensions/custom-provider-anthropic/package.json +19 -0
  35. package/runtime/examples/extensions/dirty-repo-guard.ts +56 -0
  36. package/runtime/examples/extensions/doom-overlay/README.md +46 -0
  37. package/runtime/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
  38. package/runtime/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  39. package/runtime/examples/extensions/doom-overlay/doom/build.sh +152 -0
  40. package/runtime/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  41. package/runtime/examples/extensions/doom-overlay/doom-component.ts +132 -0
  42. package/runtime/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  43. package/runtime/examples/extensions/doom-overlay/doom-keys.ts +104 -0
  44. package/runtime/examples/extensions/doom-overlay/index.ts +74 -0
  45. package/runtime/examples/extensions/doom-overlay/wad-finder.ts +51 -0
  46. package/runtime/examples/extensions/dynamic-resources/SKILL.md +8 -0
  47. package/runtime/examples/extensions/dynamic-resources/dynamic.json +79 -0
  48. package/runtime/examples/extensions/dynamic-resources/dynamic.md +5 -0
  49. package/runtime/examples/extensions/dynamic-resources/index.ts +15 -0
  50. package/runtime/examples/extensions/dynamic-tools.ts +74 -0
  51. package/runtime/examples/extensions/entry-renderer.ts +41 -0
  52. package/runtime/examples/extensions/event-bus.ts +43 -0
  53. package/runtime/examples/extensions/file-trigger.ts +41 -0
  54. package/runtime/examples/extensions/git-checkpoint.ts +53 -0
  55. package/runtime/examples/extensions/git-merge-and-resolve.ts +115 -0
  56. package/runtime/examples/extensions/github-issue-autocomplete.ts +185 -0
  57. package/runtime/examples/extensions/gondolin/index.ts +531 -0
  58. package/runtime/examples/extensions/gondolin/package-lock.json +185 -0
  59. package/runtime/examples/extensions/gondolin/package.json +19 -0
  60. package/runtime/examples/extensions/hello.ts +26 -0
  61. package/runtime/examples/extensions/hidden-thinking-label.ts +53 -0
  62. package/runtime/examples/extensions/inline-bash.ts +94 -0
  63. package/runtime/examples/extensions/input-transform-streaming.ts +39 -0
  64. package/runtime/examples/extensions/input-transform.ts +43 -0
  65. package/runtime/examples/extensions/interactive-shell.ts +196 -0
  66. package/runtime/examples/extensions/mac-system-theme.ts +47 -0
  67. package/runtime/examples/extensions/message-renderer.ts +59 -0
  68. package/runtime/examples/extensions/minimal-mode.ts +426 -0
  69. package/runtime/examples/extensions/modal-editor.ts +85 -0
  70. package/runtime/examples/extensions/model-status.ts +31 -0
  71. package/runtime/examples/extensions/notify.ts +55 -0
  72. package/runtime/examples/extensions/overlay-qa-tests.ts +1450 -0
  73. package/runtime/examples/extensions/overlay-test.ts +153 -0
  74. package/runtime/examples/extensions/permission-gate.ts +34 -0
  75. package/runtime/examples/extensions/pirate.ts +47 -0
  76. package/runtime/examples/extensions/plan-mode/README.md +66 -0
  77. package/runtime/examples/extensions/plan-mode/index.ts +390 -0
  78. package/runtime/examples/extensions/plan-mode/utils.ts +168 -0
  79. package/runtime/examples/extensions/preset.ts +436 -0
  80. package/runtime/examples/extensions/project-trust.ts +64 -0
  81. package/runtime/examples/extensions/prompt-customizer.ts +97 -0
  82. package/runtime/examples/extensions/protected-paths.ts +30 -0
  83. package/runtime/examples/extensions/provider-payload.ts +18 -0
  84. package/runtime/examples/extensions/question.ts +278 -0
  85. package/runtime/examples/extensions/questionnaire.ts +440 -0
  86. package/runtime/examples/extensions/rainbow-editor.ts +88 -0
  87. package/runtime/examples/extensions/reload-runtime.ts +37 -0
  88. package/runtime/examples/extensions/rpc-demo.ts +118 -0
  89. package/runtime/examples/extensions/sandbox/index.ts +321 -0
  90. package/runtime/examples/extensions/sandbox/package-lock.json +92 -0
  91. package/runtime/examples/extensions/sandbox/package.json +19 -0
  92. package/runtime/examples/extensions/send-user-message.ts +97 -0
  93. package/runtime/examples/extensions/session-name.ts +27 -0
  94. package/runtime/examples/extensions/shutdown-command.ts +63 -0
  95. package/runtime/examples/extensions/snake.ts +343 -0
  96. package/runtime/examples/extensions/space-invaders.ts +560 -0
  97. package/runtime/examples/extensions/ssh.ts +220 -0
  98. package/runtime/examples/extensions/status-line.ts +32 -0
  99. package/runtime/examples/extensions/structured-output.ts +65 -0
  100. package/runtime/examples/extensions/subagent/README.md +175 -0
  101. package/runtime/examples/extensions/subagent/agents/planner.md +37 -0
  102. package/runtime/examples/extensions/subagent/agents/reviewer.md +35 -0
  103. package/runtime/examples/extensions/subagent/agents/scout.md +50 -0
  104. package/runtime/examples/extensions/subagent/agents/worker.md +24 -0
  105. package/runtime/examples/extensions/subagent/agents.ts +126 -0
  106. package/runtime/examples/extensions/subagent/index.ts +1009 -0
  107. package/runtime/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  108. package/runtime/examples/extensions/subagent/prompts/implement.md +10 -0
  109. package/runtime/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  110. package/runtime/examples/extensions/system-prompt-header.ts +17 -0
  111. package/runtime/examples/extensions/tic-tac-toe.ts +1008 -0
  112. package/runtime/examples/extensions/timed-confirm.ts +70 -0
  113. package/runtime/examples/extensions/titlebar-spinner.ts +58 -0
  114. package/runtime/examples/extensions/todo.ts +297 -0
  115. package/runtime/examples/extensions/tool-override.ts +144 -0
  116. package/runtime/examples/extensions/tools.ts +146 -0
  117. package/runtime/examples/extensions/trigger-compact.ts +50 -0
  118. package/runtime/examples/extensions/truncated-tool.ts +195 -0
  119. package/runtime/examples/extensions/widget-placement.ts +9 -0
  120. package/runtime/examples/extensions/with-deps/index.ts +32 -0
  121. package/runtime/examples/extensions/with-deps/package-lock.json +31 -0
  122. package/runtime/examples/extensions/with-deps/package.json +22 -0
  123. package/runtime/examples/extensions/working-indicator.ts +123 -0
  124. package/runtime/examples/extensions/working-message-test.ts +25 -0
  125. package/runtime/examples/rpc-extension-ui.ts +632 -0
  126. package/runtime/examples/sdk/01-minimal.ts +26 -0
  127. package/runtime/examples/sdk/02-custom-model.ts +43 -0
  128. package/runtime/examples/sdk/03-custom-prompt.ts +70 -0
  129. package/runtime/examples/sdk/04-skills.ts +55 -0
  130. package/runtime/examples/sdk/05-tools.ts +48 -0
  131. package/runtime/examples/sdk/06-extensions.ts +94 -0
  132. package/runtime/examples/sdk/07-context-files.ts +42 -0
  133. package/runtime/examples/sdk/08-prompt-templates.ts +51 -0
  134. package/runtime/examples/sdk/09-api-keys-and-oauth.ts +34 -0
  135. package/runtime/examples/sdk/10-settings.ts +53 -0
  136. package/runtime/examples/sdk/11-sessions.ts +52 -0
  137. package/runtime/examples/sdk/12-full-control.ts +71 -0
  138. package/runtime/examples/sdk/13-session-runtime.ts +67 -0
  139. package/runtime/examples/sdk/README.md +140 -0
  140. package/runtime/export-html/ansi-to-html.js +249 -0
  141. package/runtime/export-html/index.js +226 -0
  142. package/runtime/export-html/template.css +1066 -0
  143. package/runtime/export-html/template.html +55 -0
  144. package/runtime/export-html/template.js +1864 -0
  145. package/runtime/export-html/tool-renderer.js +108 -0
  146. package/runtime/export-html/vendor/highlight.min.js +1213 -0
  147. package/runtime/export-html/vendor/marked.min.js +78 -0
  148. package/runtime/extensions/pi-switchboard/.github/workflows/ci.yml +51 -0
  149. package/runtime/extensions/pi-switchboard/LICENSE +22 -0
  150. package/runtime/extensions/pi-switchboard/README.md +85 -0
  151. package/runtime/extensions/pi-switchboard/extensions/switchboard/catalog.ts +183 -0
  152. package/runtime/extensions/pi-switchboard/extensions/switchboard/config.ts +97 -0
  153. package/runtime/extensions/pi-switchboard/extensions/switchboard/connections.ts +386 -0
  154. package/runtime/extensions/pi-switchboard/extensions/switchboard/constants.ts +12 -0
  155. package/runtime/extensions/pi-switchboard/extensions/switchboard/device-auth.ts +127 -0
  156. package/runtime/extensions/pi-switchboard/extensions/switchboard/envelope.ts +199 -0
  157. package/runtime/extensions/pi-switchboard/extensions/switchboard/errors.ts +180 -0
  158. package/runtime/extensions/pi-switchboard/extensions/switchboard/index.ts +125 -0
  159. package/runtime/extensions/pi-switchboard/extensions/switchboard/participant.ts +17 -0
  160. package/runtime/extensions/pi-switchboard/extensions/switchboard/sessionStream.ts +131 -0
  161. package/runtime/extensions/pi-switchboard/extensions/switchboard/toolProxy.ts +136 -0
  162. package/runtime/extensions/pi-switchboard/extensions/switchboard/tools.ts +16 -0
  163. package/runtime/extensions/pi-switchboard/extensions/switchboard/types.ts +37 -0
  164. package/runtime/extensions/pi-switchboard/package.json +30 -0
  165. package/runtime/extensions/pi-switchboard/tsconfig.json +13 -0
  166. package/runtime/extensions/switchboard-local/.github/workflows/ci.yml +80 -0
  167. package/runtime/extensions/switchboard-local/.github/workflows/release.yml +46 -0
  168. package/runtime/extensions/switchboard-local/README.md +98 -0
  169. package/runtime/extensions/switchboard-local/extensions/local/engine.ts +28 -0
  170. package/runtime/extensions/switchboard-local/extensions/local/engines/gguf.ts +324 -0
  171. package/runtime/extensions/switchboard-local/extensions/local/engines/llamaBuild.ts +62 -0
  172. package/runtime/extensions/switchboard-local/extensions/local/engines/mlx.ts +245 -0
  173. package/runtime/extensions/switchboard-local/extensions/local/engines/select.ts +38 -0
  174. package/runtime/extensions/switchboard-local/extensions/local/engines/support.ts +151 -0
  175. package/runtime/extensions/switchboard-local/extensions/local/hf.ts +106 -0
  176. package/runtime/extensions/switchboard-local/extensions/local/index.ts +67 -0
  177. package/runtime/extensions/switchboard-local/extensions/local/nativeStream.ts +602 -0
  178. package/runtime/extensions/switchboard-local/extensions/local/paths.ts +44 -0
  179. package/runtime/extensions/switchboard-local/extensions/local/provider.ts +57 -0
  180. package/runtime/extensions/switchboard-local/extensions/local/store.ts +82 -0
  181. package/runtime/extensions/switchboard-local/extensions/local/ui.ts +60 -0
  182. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard/dist/apiTypes.js +74 -0
  183. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard/dist/client.js +292 -0
  184. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard/dist/deviceAuth.js +155 -0
  185. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard/dist/errors.js +95 -0
  186. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard/dist/index.js +8 -0
  187. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard/dist/messages.js +253 -0
  188. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard/dist/models.js +19 -0
  189. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard/dist/native.js +886 -0
  190. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard/dist/wire.js +85 -0
  191. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard/package.json +39 -0
  192. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard-native/package.json +29 -0
  193. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard-native/src/anthropic.ts +127 -0
  194. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard-native/src/google.ts +111 -0
  195. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard-native/src/index.ts +8 -0
  196. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard-native/src/modelRecord.test.ts +25 -0
  197. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard-native/src/modelRecord.ts +57 -0
  198. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard-native/src/openaiGeneric.ts +103 -0
  199. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard-native/src/openaiPro.ts +89 -0
  200. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard-native/src/profile.ts +120 -0
  201. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard-native/src/routing.test.ts +82 -0
  202. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard-native/src/routing.ts +74 -0
  203. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard-native/src/validateConfig.google.test.ts +137 -0
  204. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard-native/src/validateConfig.openai.test.ts +241 -0
  205. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard-native/src/validateConfig.test.ts +174 -0
  206. package/runtime/extensions/switchboard-local/node_modules/@valni/switchboard-native/src/validateConfig.ts +438 -0
  207. package/runtime/extensions/switchboard-local/package.json +34 -0
  208. package/runtime/extensions/switchboard-local/tsconfig.json +13 -0
  209. package/runtime/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node +0 -0
  210. package/runtime/node_modules/@mariozechner/clipboard/.yarnrc.yml +1 -0
  211. package/runtime/node_modules/@mariozechner/clipboard/Cargo.toml +45 -0
  212. package/runtime/node_modules/@mariozechner/clipboard/README.md +60 -0
  213. package/runtime/node_modules/@mariozechner/clipboard/build.rs +5 -0
  214. package/runtime/node_modules/@mariozechner/clipboard/clipboard.darwin-x64.node +0 -0
  215. package/runtime/node_modules/@mariozechner/clipboard/exp.ts +12 -0
  216. package/runtime/node_modules/@mariozechner/clipboard/index.js +606 -0
  217. package/runtime/node_modules/@mariozechner/clipboard/package.json +56 -0
  218. package/runtime/node_modules/@mariozechner/clipboard/src/clipboard_rs/common.rs +307 -0
  219. package/runtime/node_modules/@mariozechner/clipboard/src/clipboard_rs/mod.rs +93 -0
  220. package/runtime/node_modules/@mariozechner/clipboard/src/clipboard_rs/platform/ios.rs +313 -0
  221. package/runtime/node_modules/@mariozechner/clipboard/src/clipboard_rs/platform/macos.rs +471 -0
  222. package/runtime/node_modules/@mariozechner/clipboard/src/clipboard_rs/platform/mod.rs +252 -0
  223. package/runtime/node_modules/@mariozechner/clipboard/src/clipboard_rs/platform/wayland.rs +431 -0
  224. package/runtime/node_modules/@mariozechner/clipboard/src/clipboard_rs/platform/win.rs +712 -0
  225. package/runtime/node_modules/@mariozechner/clipboard/src/clipboard_rs/platform/x11.rs +916 -0
  226. package/runtime/node_modules/@mariozechner/clipboard/src/lib.rs +194 -0
  227. package/runtime/node_modules/@mariozechner/clipboard-darwin-x64/README.md +3 -0
  228. package/runtime/node_modules/@mariozechner/clipboard-darwin-x64/clipboard.darwin-x64.node +0 -0
  229. package/runtime/node_modules/@mariozechner/clipboard-darwin-x64/package.json +22 -0
  230. package/runtime/package.json +104 -0
  231. package/runtime/photon_rs_bg.wasm +0 -0
  232. package/runtime/theme/dark.json +87 -0
  233. package/runtime/theme/light.json +86 -0
  234. package/runtime/theme/theme-schema.json +340 -0
  235. package/runtime/valni +4 -0
  236. package/README.md +0 -3
@@ -0,0 +1,140 @@
1
+ # SDK Examples
2
+
3
+ Programmatic usage of pi-coding-agent via `createAgentSession()` and `createAgentSessionRuntime()`.
4
+
5
+ The runtime example shows how to build a recreate function that closes over process-global fixed inputs and recreates cwd-bound services and sessions as the active session cwd changes.
6
+
7
+ ## Examples
8
+
9
+ | File | Description |
10
+ |------|-------------|
11
+ | `01-minimal.ts` | Simplest usage with all defaults |
12
+ | `02-custom-model.ts` | Select model and thinking level |
13
+ | `03-custom-prompt.ts` | Replace or modify system prompt |
14
+ | `04-skills.ts` | Discover, filter, or replace skills |
15
+ | `05-tools.ts` | Built-in tool allowlists |
16
+ | `06-extensions.ts` | Logging, blocking, result modification |
17
+ | `07-context-files.ts` | AGENTS.md context files |
18
+ | `08-slash-commands.ts` | File-based slash commands |
19
+ | `09-api-keys-and-oauth.ts` | API key resolution, OAuth config |
20
+ | `10-settings.ts` | Override compaction, retry, terminal settings |
21
+ | `11-sessions.ts` | In-memory, persistent, continue, list sessions |
22
+ | `12-full-control.ts` | Replace everything, no discovery |
23
+ | `13-session-runtime.ts` | Manage runtime-backed session replacement |
24
+
25
+ ## Running
26
+
27
+ ```bash
28
+ cd packages/coding-agent
29
+ npx tsx examples/sdk/01-minimal.ts
30
+ ```
31
+
32
+ ## Quick Reference
33
+
34
+ ```typescript
35
+ import { getModel } from "@valni/ai";
36
+ import {
37
+ createAgentSession,
38
+ DefaultResourceLoader,
39
+ ModelRuntime,
40
+ SessionManager,
41
+ SettingsManager,
42
+ } from "@valni/cli";
43
+
44
+ const modelRuntime = await ModelRuntime.create();
45
+
46
+ // Minimal
47
+ const { session } = await createAgentSession({ modelRuntime });
48
+
49
+ // Custom model
50
+ const model = getModel("anthropic", "claude-opus-4-5");
51
+ const { session } = await createAgentSession({ model, thinkingLevel: "high", modelRuntime });
52
+
53
+ // Modify prompt
54
+ const loader = new DefaultResourceLoader({
55
+ systemPromptOverride: (base) => `${base}\n\nBe concise.`,
56
+ });
57
+ await loader.reload();
58
+ const { session } = await createAgentSession({ resourceLoader: loader, modelRuntime });
59
+
60
+ // Read-only
61
+ const { session } = await createAgentSession({ tools: ["read", "grep", "find", "ls"], modelRuntime });
62
+
63
+ // In-memory
64
+ const { session } = await createAgentSession({
65
+ sessionManager: SessionManager.inMemory(),
66
+ modelRuntime,
67
+ });
68
+
69
+ // Full control
70
+ const customRuntime = await ModelRuntime.create({
71
+ authPath: "/my/app/auth.json",
72
+ modelsPath: "/my/app/models.json",
73
+ });
74
+ customRuntime.setRuntimeApiKey("anthropic", process.env.MY_KEY!);
75
+
76
+ const resourceLoader = new DefaultResourceLoader({
77
+ systemPromptOverride: () => "You are helpful.",
78
+ extensionFactories: [myExtension],
79
+ skillsOverride: () => ({ skills: [], diagnostics: [] }),
80
+ agentsFilesOverride: () => ({ agentsFiles: [] }),
81
+ promptsOverride: () => ({ prompts: [], diagnostics: [] }),
82
+ });
83
+ await resourceLoader.reload();
84
+
85
+ const { session } = await createAgentSession({
86
+ model,
87
+ modelRuntime: customRuntime,
88
+ resourceLoader,
89
+ tools: ["read", "bash", "my_tool"],
90
+ customTools: [myTool],
91
+ sessionManager: SessionManager.inMemory(),
92
+ settingsManager: SettingsManager.inMemory(),
93
+ });
94
+
95
+ // Run prompts
96
+ session.subscribe((event) => {
97
+ if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
98
+ process.stdout.write(event.assistantMessageEvent.delta);
99
+ }
100
+ });
101
+ await session.prompt("Hello");
102
+ ```
103
+
104
+ ## Options
105
+
106
+ | Option | Default | Description |
107
+ |--------|---------|-------------|
108
+ | `modelRuntime` | Runtime using `agentDir/auth.json` and `models.json` | Canonical model and authentication runtime |
109
+ | `cwd` | `process.cwd()` | Working directory |
110
+ | `agentDir` | `~/.valni/agent` | Config directory |
111
+ | `model` | From settings/first available | Model to use |
112
+ | `thinkingLevel` | From settings/"off" | off, low, medium, high |
113
+ | `tools` | `["read", "bash", "edit", "write"]` built-ins | Allowlist tool names across built-in, extension, and custom tools |
114
+ | `customTools` | `[]` | Additional tool definitions |
115
+ | `resourceLoader` | DefaultResourceLoader | Resource loader for extensions, skills, prompts, themes, and context files |
116
+ | `sessionManager` | `SessionManager.create(cwd)` | Persistence |
117
+ | `settingsManager` | `SettingsManager.create(cwd, agentDir)` | Settings overrides |
118
+
119
+ ## Events
120
+
121
+ ```typescript
122
+ session.subscribe((event) => {
123
+ switch (event.type) {
124
+ case "message_update":
125
+ if (event.assistantMessageEvent.type === "text_delta") {
126
+ process.stdout.write(event.assistantMessageEvent.delta);
127
+ }
128
+ break;
129
+ case "tool_execution_start":
130
+ console.log(`Tool: ${event.toolName}`);
131
+ break;
132
+ case "tool_execution_end":
133
+ console.log(`Result: ${event.result}`);
134
+ break;
135
+ case "agent_end":
136
+ console.log("Done");
137
+ break;
138
+ }
139
+ });
140
+ ```
@@ -0,0 +1,249 @@
1
+ /**
2
+ * ANSI escape code to HTML converter.
3
+ *
4
+ * Converts terminal ANSI color/style codes to HTML with inline styles.
5
+ * Supports:
6
+ * - Standard foreground colors (30-37) and bright variants (90-97)
7
+ * - Standard background colors (40-47) and bright variants (100-107)
8
+ * - 256-color palette (38;5;N and 48;5;N)
9
+ * - RGB true color (38;2;R;G;B and 48;2;R;G;B)
10
+ * - Text styles: bold (1), dim (2), italic (3), underline (4)
11
+ * - Reset (0)
12
+ */
13
+ // Standard ANSI color palette (0-15)
14
+ const ANSI_COLORS = [
15
+ "#000000", // 0: black
16
+ "#800000", // 1: red
17
+ "#008000", // 2: green
18
+ "#808000", // 3: yellow
19
+ "#000080", // 4: blue
20
+ "#800080", // 5: magenta
21
+ "#008080", // 6: cyan
22
+ "#c0c0c0", // 7: white
23
+ "#808080", // 8: bright black
24
+ "#ff0000", // 9: bright red
25
+ "#00ff00", // 10: bright green
26
+ "#ffff00", // 11: bright yellow
27
+ "#0000ff", // 12: bright blue
28
+ "#ff00ff", // 13: bright magenta
29
+ "#00ffff", // 14: bright cyan
30
+ "#ffffff", // 15: bright white
31
+ ];
32
+ /**
33
+ * Convert 256-color index to hex.
34
+ */
35
+ function color256ToHex(index) {
36
+ // Standard colors (0-15)
37
+ if (index < 16) {
38
+ return ANSI_COLORS[index];
39
+ }
40
+ // Color cube (16-231): 6x6x6 = 216 colors
41
+ if (index < 232) {
42
+ const cubeIndex = index - 16;
43
+ const r = Math.floor(cubeIndex / 36);
44
+ const g = Math.floor((cubeIndex % 36) / 6);
45
+ const b = cubeIndex % 6;
46
+ const toComponent = (n) => (n === 0 ? 0 : 55 + n * 40);
47
+ const toHex = (n) => toComponent(n).toString(16).padStart(2, "0");
48
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
49
+ }
50
+ // Grayscale (232-255): 24 shades
51
+ const gray = 8 + (index - 232) * 10;
52
+ const grayHex = gray.toString(16).padStart(2, "0");
53
+ return `#${grayHex}${grayHex}${grayHex}`;
54
+ }
55
+ /**
56
+ * Escape HTML special characters.
57
+ */
58
+ function escapeHtml(text) {
59
+ return text
60
+ .replace(/&/g, "&amp;")
61
+ .replace(/</g, "&lt;")
62
+ .replace(/>/g, "&gt;")
63
+ .replace(/"/g, "&quot;")
64
+ .replace(/'/g, "&#039;");
65
+ }
66
+ function createEmptyStyle() {
67
+ return {
68
+ fg: null,
69
+ bg: null,
70
+ bold: false,
71
+ dim: false,
72
+ italic: false,
73
+ underline: false,
74
+ };
75
+ }
76
+ function styleToInlineCSS(style) {
77
+ const parts = [];
78
+ if (style.fg)
79
+ parts.push(`color:${style.fg}`);
80
+ if (style.bg)
81
+ parts.push(`background-color:${style.bg}`);
82
+ if (style.bold)
83
+ parts.push("font-weight:bold");
84
+ if (style.dim)
85
+ parts.push("opacity:0.6");
86
+ if (style.italic)
87
+ parts.push("font-style:italic");
88
+ if (style.underline)
89
+ parts.push("text-decoration:underline");
90
+ return parts.join(";");
91
+ }
92
+ function hasStyle(style) {
93
+ return style.fg !== null || style.bg !== null || style.bold || style.dim || style.italic || style.underline;
94
+ }
95
+ /**
96
+ * Parse ANSI SGR (Select Graphic Rendition) codes and update style.
97
+ */
98
+ function applySgrCode(params, style) {
99
+ let i = 0;
100
+ while (i < params.length) {
101
+ const code = params[i];
102
+ if (code === 0) {
103
+ // Reset all
104
+ style.fg = null;
105
+ style.bg = null;
106
+ style.bold = false;
107
+ style.dim = false;
108
+ style.italic = false;
109
+ style.underline = false;
110
+ }
111
+ else if (code === 1) {
112
+ style.bold = true;
113
+ }
114
+ else if (code === 2) {
115
+ style.dim = true;
116
+ }
117
+ else if (code === 3) {
118
+ style.italic = true;
119
+ }
120
+ else if (code === 4) {
121
+ style.underline = true;
122
+ }
123
+ else if (code === 22) {
124
+ // Reset bold/dim
125
+ style.bold = false;
126
+ style.dim = false;
127
+ }
128
+ else if (code === 23) {
129
+ style.italic = false;
130
+ }
131
+ else if (code === 24) {
132
+ style.underline = false;
133
+ }
134
+ else if (code >= 30 && code <= 37) {
135
+ // Standard foreground colors
136
+ style.fg = ANSI_COLORS[code - 30];
137
+ }
138
+ else if (code === 38) {
139
+ // Extended foreground color
140
+ if (params[i + 1] === 5 && params.length > i + 2) {
141
+ // 256-color: 38;5;N
142
+ style.fg = color256ToHex(params[i + 2]);
143
+ i += 2;
144
+ }
145
+ else if (params[i + 1] === 2 && params.length > i + 4) {
146
+ // RGB: 38;2;R;G;B
147
+ const r = params[i + 2];
148
+ const g = params[i + 3];
149
+ const b = params[i + 4];
150
+ style.fg = `rgb(${r},${g},${b})`;
151
+ i += 4;
152
+ }
153
+ }
154
+ else if (code === 39) {
155
+ // Default foreground
156
+ style.fg = null;
157
+ }
158
+ else if (code >= 40 && code <= 47) {
159
+ // Standard background colors
160
+ style.bg = ANSI_COLORS[code - 40];
161
+ }
162
+ else if (code === 48) {
163
+ // Extended background color
164
+ if (params[i + 1] === 5 && params.length > i + 2) {
165
+ // 256-color: 48;5;N
166
+ style.bg = color256ToHex(params[i + 2]);
167
+ i += 2;
168
+ }
169
+ else if (params[i + 1] === 2 && params.length > i + 4) {
170
+ // RGB: 48;2;R;G;B
171
+ const r = params[i + 2];
172
+ const g = params[i + 3];
173
+ const b = params[i + 4];
174
+ style.bg = `rgb(${r},${g},${b})`;
175
+ i += 4;
176
+ }
177
+ }
178
+ else if (code === 49) {
179
+ // Default background
180
+ style.bg = null;
181
+ }
182
+ else if (code >= 90 && code <= 97) {
183
+ // Bright foreground colors
184
+ style.fg = ANSI_COLORS[code - 90 + 8];
185
+ }
186
+ else if (code >= 100 && code <= 107) {
187
+ // Bright background colors
188
+ style.bg = ANSI_COLORS[code - 100 + 8];
189
+ }
190
+ // Ignore unrecognized codes
191
+ i++;
192
+ }
193
+ }
194
+ // Match ANSI escape sequences: ESC[ followed by params and ending with 'm'
195
+ const ANSI_REGEX = /\x1b\[([\d;]*)m/g;
196
+ /**
197
+ * Convert ANSI-escaped text to HTML with inline styles.
198
+ */
199
+ export function ansiToHtml(text) {
200
+ const style = createEmptyStyle();
201
+ let result = "";
202
+ let lastIndex = 0;
203
+ let inSpan = false;
204
+ // Reset regex state
205
+ ANSI_REGEX.lastIndex = 0;
206
+ let match = ANSI_REGEX.exec(text);
207
+ while (match !== null) {
208
+ // Add text before this escape sequence
209
+ const beforeText = text.slice(lastIndex, match.index);
210
+ if (beforeText) {
211
+ result += escapeHtml(beforeText);
212
+ }
213
+ // Parse SGR parameters
214
+ const paramStr = match[1];
215
+ const params = paramStr ? paramStr.split(";").map((p) => parseInt(p, 10) || 0) : [0];
216
+ // Close existing span if we have one
217
+ if (inSpan) {
218
+ result += "</span>";
219
+ inSpan = false;
220
+ }
221
+ // Apply the codes
222
+ applySgrCode(params, style);
223
+ // Open new span if we have any styling
224
+ if (hasStyle(style)) {
225
+ result += `<span style="${styleToInlineCSS(style)}">`;
226
+ inSpan = true;
227
+ }
228
+ lastIndex = match.index + match[0].length;
229
+ match = ANSI_REGEX.exec(text);
230
+ }
231
+ // Add remaining text
232
+ const remainingText = text.slice(lastIndex);
233
+ if (remainingText) {
234
+ result += escapeHtml(remainingText);
235
+ }
236
+ // Close any open span
237
+ if (inSpan) {
238
+ result += "</span>";
239
+ }
240
+ return result;
241
+ }
242
+ /**
243
+ * Convert array of ANSI-escaped lines to HTML.
244
+ * Each line is wrapped in a div element.
245
+ */
246
+ export function ansiLinesToHtml(lines) {
247
+ return lines.map((line) => `<div class="ansi-line">${ansiToHtml(line) || "&nbsp;"}</div>`).join("");
248
+ }
249
+ //# sourceMappingURL=ansi-to-html.js.map
@@ -0,0 +1,226 @@
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 { normalizePath, resolvePath } from "../../utils/paths.js";
6
+ import { SessionManager } from "../session-manager.js";
7
+ /** Parse a color string to RGB values. Supports hex (#RRGGBB) and rgb(r,g,b) formats. */
8
+ function parseColor(color) {
9
+ const hexMatch = color.match(/^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/);
10
+ if (hexMatch) {
11
+ return {
12
+ r: Number.parseInt(hexMatch[1], 16),
13
+ g: Number.parseInt(hexMatch[2], 16),
14
+ b: Number.parseInt(hexMatch[3], 16),
15
+ };
16
+ }
17
+ const rgbMatch = color.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/);
18
+ if (rgbMatch) {
19
+ return {
20
+ r: Number.parseInt(rgbMatch[1], 10),
21
+ g: Number.parseInt(rgbMatch[2], 10),
22
+ b: Number.parseInt(rgbMatch[3], 10),
23
+ };
24
+ }
25
+ return undefined;
26
+ }
27
+ /** Calculate relative luminance of a color (0-1, higher = lighter). */
28
+ function getLuminance(r, g, b) {
29
+ const toLinear = (c) => {
30
+ const s = c / 255;
31
+ return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
32
+ };
33
+ return 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);
34
+ }
35
+ /** Adjust color brightness. Factor > 1 lightens, < 1 darkens. */
36
+ function adjustBrightness(color, factor) {
37
+ const parsed = parseColor(color);
38
+ if (!parsed)
39
+ return color;
40
+ const adjust = (c) => Math.min(255, Math.max(0, Math.round(c * factor)));
41
+ return `rgb(${adjust(parsed.r)}, ${adjust(parsed.g)}, ${adjust(parsed.b)})`;
42
+ }
43
+ /** Derive export background colors from a base color (e.g., userMessageBg). */
44
+ function deriveExportColors(baseColor) {
45
+ const parsed = parseColor(baseColor);
46
+ if (!parsed) {
47
+ return {
48
+ pageBg: "rgb(24, 24, 30)",
49
+ cardBg: "rgb(30, 30, 36)",
50
+ infoBg: "rgb(60, 55, 40)",
51
+ };
52
+ }
53
+ const luminance = getLuminance(parsed.r, parsed.g, parsed.b);
54
+ const isLight = luminance > 0.5;
55
+ if (isLight) {
56
+ return {
57
+ pageBg: adjustBrightness(baseColor, 0.96),
58
+ cardBg: baseColor,
59
+ infoBg: `rgb(${Math.min(255, parsed.r + 10)}, ${Math.min(255, parsed.g + 5)}, ${Math.max(0, parsed.b - 20)})`,
60
+ };
61
+ }
62
+ return {
63
+ pageBg: adjustBrightness(baseColor, 0.7),
64
+ cardBg: adjustBrightness(baseColor, 0.85),
65
+ infoBg: `rgb(${Math.min(255, parsed.r + 20)}, ${Math.min(255, parsed.g + 15)}, ${parsed.b})`,
66
+ };
67
+ }
68
+ /**
69
+ * Generate CSS custom property declarations from theme colors.
70
+ */
71
+ function generateThemeVars(themeName) {
72
+ const colors = getResolvedThemeColors(themeName);
73
+ const lines = [];
74
+ for (const [key, value] of Object.entries(colors)) {
75
+ lines.push(`--${key}: ${value};`);
76
+ }
77
+ // Use explicit theme export colors if available, otherwise derive from userMessageBg
78
+ const themeExport = getThemeExportColors(themeName);
79
+ const userMessageBg = colors.userMessageBg || "#343541";
80
+ const derivedColors = deriveExportColors(userMessageBg);
81
+ lines.push(`--exportPageBg: ${themeExport.pageBg ?? derivedColors.pageBg};`);
82
+ lines.push(`--exportCardBg: ${themeExport.cardBg ?? derivedColors.cardBg};`);
83
+ lines.push(`--exportInfoBg: ${themeExport.infoBg ?? derivedColors.infoBg};`);
84
+ return lines.join("\n ");
85
+ }
86
+ /**
87
+ * Core HTML generation logic shared by both export functions.
88
+ */
89
+ function generateHtml(sessionData, themeName) {
90
+ const templateDir = getExportTemplateDir();
91
+ const template = readFileSync(join(templateDir, "template.html"), "utf-8");
92
+ const templateCss = readFileSync(join(templateDir, "template.css"), "utf-8");
93
+ const templateJs = readFileSync(join(templateDir, "template.js"), "utf-8");
94
+ const markedJs = readFileSync(join(templateDir, "vendor", "marked.min.js"), "utf-8");
95
+ const hljsJs = readFileSync(join(templateDir, "vendor", "highlight.min.js"), "utf-8");
96
+ const themeVars = generateThemeVars(themeName);
97
+ const colors = getResolvedThemeColors(themeName);
98
+ const themeExport = getThemeExportColors(themeName);
99
+ const derivedExportColors = deriveExportColors(colors.userMessageBg || "#343541");
100
+ const bodyBg = themeExport.pageBg ?? derivedExportColors.pageBg;
101
+ const containerBg = themeExport.cardBg ?? derivedExportColors.cardBg;
102
+ const infoBg = themeExport.infoBg ?? derivedExportColors.infoBg;
103
+ // Base64 encode session data to avoid escaping issues
104
+ const sessionDataBase64 = Buffer.from(JSON.stringify(sessionData)).toString("base64");
105
+ // Build the CSS with theme variables injected
106
+ const css = templateCss
107
+ .replace("{{THEME_VARS}}", themeVars)
108
+ .replace("{{BODY_BG}}", bodyBg)
109
+ .replace("{{CONTAINER_BG}}", containerBg)
110
+ .replace("{{INFO_BG}}", infoBg);
111
+ return template
112
+ .replace("{{CSS}}", css)
113
+ .replace("{{JS}}", templateJs)
114
+ .replace("{{SESSION_DATA}}", sessionDataBase64)
115
+ .replace("{{MARKED_JS}}", markedJs)
116
+ .replace("{{HIGHLIGHT_JS}}", hljsJs);
117
+ }
118
+ /** Tools rendered directly by the HTML template (not pre-rendered via TUI→ANSI→HTML pipeline) */
119
+ const TEMPLATE_RENDERED_TOOLS = new Set(["bash", "read", "write", "edit", "ls"]);
120
+ /**
121
+ * Pre-render custom tools to HTML using their TUI renderers.
122
+ */
123
+ function preRenderCustomTools(entries, toolRenderer) {
124
+ const renderedTools = {};
125
+ for (const entry of entries) {
126
+ if (entry.type !== "message")
127
+ continue;
128
+ const msg = entry.message;
129
+ // Find tool calls in assistant messages
130
+ if (msg.role === "assistant" && Array.isArray(msg.content)) {
131
+ for (const block of msg.content) {
132
+ if (block.type === "toolCall" && !TEMPLATE_RENDERED_TOOLS.has(block.name)) {
133
+ const callHtml = toolRenderer.renderCall(block.id, block.name, block.arguments);
134
+ if (callHtml) {
135
+ renderedTools[block.id] = { callHtml };
136
+ }
137
+ }
138
+ }
139
+ }
140
+ // Find tool results
141
+ if (msg.role === "toolResult" && msg.toolCallId) {
142
+ const toolName = msg.toolName || "";
143
+ // Only render if we have a pre-rendered call OR it's not template-rendered
144
+ const existing = renderedTools[msg.toolCallId];
145
+ if (existing || !TEMPLATE_RENDERED_TOOLS.has(toolName)) {
146
+ const rendered = toolRenderer.renderResult(msg.toolCallId, toolName, msg.content, msg.details, msg.isError || false);
147
+ if (rendered) {
148
+ renderedTools[msg.toolCallId] = {
149
+ ...existing,
150
+ resultHtmlCollapsed: rendered.collapsed,
151
+ resultHtmlExpanded: rendered.expanded,
152
+ };
153
+ }
154
+ }
155
+ }
156
+ }
157
+ return renderedTools;
158
+ }
159
+ /**
160
+ * Export session to HTML using SessionManager and AgentState.
161
+ * Used by TUI's /export command.
162
+ */
163
+ export async function exportSessionToHtml(sm, state, options) {
164
+ const opts = typeof options === "string" ? { outputPath: options } : options || {};
165
+ const sessionFile = sm.getSessionFile();
166
+ if (!sessionFile) {
167
+ throw new Error("Cannot export in-memory session to HTML");
168
+ }
169
+ if (!existsSync(sessionFile)) {
170
+ throw new Error("Nothing to export yet - start a conversation first");
171
+ }
172
+ const entries = sm.getEntries();
173
+ // Pre-render custom tools if a tool renderer is provided
174
+ let renderedTools;
175
+ if (opts.toolRenderer) {
176
+ renderedTools = preRenderCustomTools(entries, opts.toolRenderer);
177
+ // Only include if we actually rendered something
178
+ if (Object.keys(renderedTools).length === 0) {
179
+ renderedTools = undefined;
180
+ }
181
+ }
182
+ const sessionData = {
183
+ header: sm.getHeader(),
184
+ entries,
185
+ leafId: sm.getLeafId(),
186
+ systemPrompt: state?.systemPrompt,
187
+ tools: state?.tools?.map((t) => ({ name: t.name, description: t.description, parameters: t.parameters })),
188
+ renderedTools,
189
+ };
190
+ const html = generateHtml(sessionData, opts.themeName);
191
+ let outputPath = opts.outputPath ? normalizePath(opts.outputPath) : undefined;
192
+ if (!outputPath) {
193
+ const sessionBasename = basename(sessionFile, ".jsonl");
194
+ outputPath = `${APP_NAME}-session-${sessionBasename}.html`;
195
+ }
196
+ writeFileSync(outputPath, html, "utf8");
197
+ return outputPath;
198
+ }
199
+ /**
200
+ * Export session file to HTML (standalone, without AgentState).
201
+ * Used by CLI for exporting arbitrary session files.
202
+ */
203
+ export async function exportFromFile(inputPath, options) {
204
+ const opts = typeof options === "string" ? { outputPath: options } : options || {};
205
+ const resolvedInputPath = resolvePath(inputPath);
206
+ if (!existsSync(resolvedInputPath)) {
207
+ throw new Error(`File not found: ${resolvedInputPath}`);
208
+ }
209
+ const sm = SessionManager.open(resolvedInputPath);
210
+ const sessionData = {
211
+ header: sm.getHeader(),
212
+ entries: sm.getEntries(),
213
+ leafId: sm.getLeafId(),
214
+ systemPrompt: undefined,
215
+ tools: undefined,
216
+ };
217
+ const html = generateHtml(sessionData, opts.themeName);
218
+ let outputPath = opts.outputPath ? normalizePath(opts.outputPath) : undefined;
219
+ if (!outputPath) {
220
+ const inputBasename = basename(resolvedInputPath, ".jsonl");
221
+ outputPath = `${APP_NAME}-session-${inputBasename}.html`;
222
+ }
223
+ writeFileSync(outputPath, html, "utf8");
224
+ return outputPath;
225
+ }
226
+ //# sourceMappingURL=index.js.map