@easynet/agent-runtime 1.0.3 → 1.0.4

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 (205) hide show
  1. package/.github/workflows/ci.yml +9 -24
  2. package/.github/workflows/release.yml +14 -35
  3. package/agent-runtime/.github/workflows/ci.yml +69 -0
  4. package/agent-runtime/.github/workflows/release.yml +118 -0
  5. package/agent-runtime/.releaserc.cjs +26 -0
  6. package/agent-runtime/config/agent.deep.yaml +25 -0
  7. package/agent-runtime/config/agent.react.yaml +24 -0
  8. package/agent-runtime/example/basic-usage.ts +49 -0
  9. package/agent-runtime/package-lock.json +7740 -0
  10. package/agent-runtime/package.json +49 -0
  11. package/agent-runtime/pnpm-lock.yaml +3712 -0
  12. package/agent-runtime/scripts/resolve-deps.js +54 -0
  13. package/agent-runtime/src/agents/deep-agent.ts +165 -0
  14. package/agent-runtime/src/agents/react-agent.helpers.ts +227 -0
  15. package/agent-runtime/src/agents/react-agent.ts +584 -0
  16. package/{src → agent-runtime/src/agents}/sub-agent.ts +2 -2
  17. package/agent-runtime/src/cli/args.ts +15 -0
  18. package/agent-runtime/src/cli/event-listener.ts +162 -0
  19. package/agent-runtime/src/cli/interactive.ts +144 -0
  20. package/agent-runtime/src/cli/runtime.ts +31 -0
  21. package/agent-runtime/src/cli/spinner.ts +23 -0
  22. package/agent-runtime/src/cli/terminal-render.ts +322 -0
  23. package/agent-runtime/src/cli/types.ts +33 -0
  24. package/agent-runtime/src/cli.ts +134 -0
  25. package/agent-runtime/src/config/helpers.ts +179 -0
  26. package/agent-runtime/src/config/index.ts +245 -0
  27. package/agent-runtime/src/config/types.ts +62 -0
  28. package/agent-runtime/src/core/context.ts +266 -0
  29. package/agent-runtime/src/index.ts +55 -0
  30. package/agent-runtime/tsconfig.json +18 -0
  31. package/apps/imessagebot/README.md +38 -0
  32. package/apps/imessagebot/config/.agent/cache/easynet/agent-tool-buildin/0.0.45/README.md +33 -0
  33. package/apps/imessagebot/config/.agent/cache/easynet/agent-tool-buildin/0.0.45/package-lock.json +15257 -0
  34. package/apps/imessagebot/config/.agent/cache/easynet/agent-tool-buildin/0.0.45/package.json +55 -0
  35. package/apps/imessagebot/config/agents/deep/agent.yaml +31 -0
  36. package/apps/imessagebot/config/agents/react/agent.yaml +58 -0
  37. package/apps/imessagebot/config/agents/shared/.agent/cache/easynet/agent-tool-buildin/0.0.43/README.md +33 -0
  38. package/apps/imessagebot/config/agents/shared/.agent/cache/easynet/agent-tool-buildin/0.0.43/package-lock.json +15457 -0
  39. package/apps/imessagebot/config/agents/shared/.agent/cache/easynet/agent-tool-buildin/0.0.43/package.json +55 -0
  40. package/apps/imessagebot/config/agents/shared/.agent/cache/easynet/agent-tool-buildin/0.0.46/README.md +33 -0
  41. package/apps/imessagebot/config/agents/shared/.agent/cache/easynet/agent-tool-buildin/0.0.46/package-lock.json +15257 -0
  42. package/apps/imessagebot/config/agents/shared/.agent/cache/easynet/agent-tool-buildin/0.0.46/package.json +62 -0
  43. package/apps/imessagebot/config/agents/shared/memory.yaml +31 -0
  44. package/apps/imessagebot/config/agents/shared/model.yaml +23 -0
  45. package/apps/imessagebot/config/agents/shared/tool.yaml +13 -0
  46. package/apps/imessagebot/config/app.yaml +14 -0
  47. package/apps/imessagebot/package-lock.json +53695 -0
  48. package/apps/imessagebot/package.json +41 -0
  49. package/apps/imessagebot/pnpm-lock.yaml +1589 -0
  50. package/apps/imessagebot/scripts/resolve-deps.js +41 -0
  51. package/apps/imessagebot/scripts/test-llm.mjs +27 -0
  52. package/apps/imessagebot/scripts/validate-tools-config.mjs +174 -0
  53. package/apps/imessagebot/src/config.ts +76 -0
  54. package/apps/imessagebot/src/context.ts +35 -0
  55. package/apps/imessagebot/src/index.ts +17 -0
  56. package/apps/imessagebot/tsconfig.json +18 -0
  57. package/apps/itermbot/.github/workflows/ci.yml +61 -0
  58. package/apps/itermbot/.github/workflows/release.yml +80 -0
  59. package/apps/itermbot/.releaserc.cjs +26 -0
  60. package/apps/itermbot/README.md +82 -0
  61. package/apps/itermbot/config/app.yaml +29 -0
  62. package/apps/itermbot/config/tsconfig.json +18 -0
  63. package/apps/itermbot/macos_disk_usage_agent_plan.md +244 -0
  64. package/apps/itermbot/package-lock.json +53697 -0
  65. package/apps/itermbot/package.json +57 -0
  66. package/apps/itermbot/pnpm-lock.yaml +3966 -0
  67. package/apps/itermbot/scripts/patch-buildin-cache.sh +25 -0
  68. package/apps/itermbot/scripts/resolve-deps.js +41 -0
  69. package/apps/itermbot/scripts/test-llm.mjs +32 -0
  70. package/apps/itermbot/skills/command-explain-and-guard/SKILL.md +39 -0
  71. package/apps/itermbot/skills/command-explain-and-guard/handler.js +86 -0
  72. package/apps/itermbot/skills/disk-usage-investigate/SKILL.md +44 -0
  73. package/apps/itermbot/skills/disk-usage-investigate/handler.js +12 -0
  74. package/apps/itermbot/skills/gpu-ssh-monitor/SKILL.md +64 -0
  75. package/apps/itermbot/skills/repo-triage/SKILL.md +40 -0
  76. package/apps/itermbot/skills/repo-triage/handler.js +56 -0
  77. package/apps/itermbot/skills/test-failure-diagnose/SKILL.md +43 -0
  78. package/apps/itermbot/skills/test-failure-diagnose/handler.js +107 -0
  79. package/apps/itermbot/src/config.ts +95 -0
  80. package/apps/itermbot/src/context.ts +35 -0
  81. package/apps/itermbot/src/index.ts +223 -0
  82. package/apps/itermbot/src/iterm/session-hint.ts +40 -0
  83. package/apps/itermbot/src/iterm/target-routing.ts +419 -0
  84. package/apps/itermbot/src/startup/colors.ts +317 -0
  85. package/apps/itermbot/src/startup/diagnostics.ts +97 -0
  86. package/apps/itermbot/src/startup/ui.ts +141 -0
  87. package/config/agent.deep.yaml +25 -0
  88. package/config/agent.react.yaml +24 -0
  89. package/dist/agents/deep-agent.d.ts +37 -0
  90. package/dist/agents/deep-agent.d.ts.map +1 -0
  91. package/dist/agents/deep-agent.js +115 -0
  92. package/dist/agents/deep-agent.js.map +1 -0
  93. package/dist/agents/react-agent.d.ts +40 -0
  94. package/dist/agents/react-agent.d.ts.map +1 -0
  95. package/dist/agents/react-agent.helpers.d.ts +40 -0
  96. package/dist/agents/react-agent.helpers.d.ts.map +1 -0
  97. package/dist/agents/react-agent.helpers.js +196 -0
  98. package/dist/agents/react-agent.helpers.js.map +1 -0
  99. package/dist/agents/react-agent.js +400 -0
  100. package/dist/agents/react-agent.js.map +1 -0
  101. package/dist/agents/sub-agent.d.ts +34 -0
  102. package/dist/agents/sub-agent.d.ts.map +1 -0
  103. package/dist/agents/sub-agent.js +53 -0
  104. package/dist/agents/sub-agent.js.map +1 -0
  105. package/dist/cli/args.d.ts +8 -0
  106. package/dist/cli/args.d.ts.map +1 -0
  107. package/dist/cli/args.js +9 -0
  108. package/dist/cli/args.js.map +1 -0
  109. package/dist/cli/event-listener.d.ts +3 -0
  110. package/dist/cli/event-listener.d.ts.map +1 -0
  111. package/dist/cli/event-listener.js +131 -0
  112. package/dist/cli/event-listener.js.map +1 -0
  113. package/dist/cli/interactive.d.ts +4 -0
  114. package/dist/cli/interactive.d.ts.map +1 -0
  115. package/dist/cli/interactive.js +118 -0
  116. package/dist/cli/interactive.js.map +1 -0
  117. package/dist/cli/runtime.d.ts +8 -0
  118. package/dist/cli/runtime.d.ts.map +1 -0
  119. package/dist/cli/runtime.js +27 -0
  120. package/dist/cli/runtime.js.map +1 -0
  121. package/dist/cli/spinner.d.ts +2 -0
  122. package/dist/cli/spinner.d.ts.map +1 -0
  123. package/dist/cli/spinner.js +22 -0
  124. package/dist/cli/spinner.js.map +1 -0
  125. package/dist/cli/terminal-render.d.ts +7 -0
  126. package/dist/cli/terminal-render.d.ts.map +1 -0
  127. package/dist/cli/terminal-render.js +282 -0
  128. package/dist/cli/terminal-render.js.map +1 -0
  129. package/dist/cli/types.d.ts +29 -0
  130. package/dist/cli/types.d.ts.map +1 -0
  131. package/dist/cli/types.js +3 -0
  132. package/dist/cli/types.js.map +1 -0
  133. package/dist/cli.d.ts +4 -41
  134. package/dist/cli.d.ts.map +1 -1
  135. package/dist/cli.js +84 -588
  136. package/dist/cli.js.map +1 -1
  137. package/dist/config/helpers.d.ts +6 -0
  138. package/dist/config/helpers.d.ts.map +1 -0
  139. package/dist/config/helpers.js +164 -0
  140. package/dist/config/helpers.js.map +1 -0
  141. package/dist/config/index.d.ts +15 -0
  142. package/dist/config/index.d.ts.map +1 -0
  143. package/dist/config/index.js +160 -0
  144. package/dist/config/index.js.map +1 -0
  145. package/dist/config/types.d.ts +57 -0
  146. package/dist/config/types.d.ts.map +1 -0
  147. package/dist/config/types.js +2 -0
  148. package/dist/config/types.js.map +1 -0
  149. package/dist/context.d.ts +8 -69
  150. package/dist/context.d.ts.map +1 -1
  151. package/dist/context.js +44 -24
  152. package/dist/context.js.map +1 -1
  153. package/dist/core/context.d.ts +66 -0
  154. package/dist/core/context.d.ts.map +1 -0
  155. package/dist/core/context.js +149 -0
  156. package/dist/core/context.js.map +1 -0
  157. package/dist/deep-agent.d.ts +5 -2
  158. package/dist/deep-agent.d.ts.map +1 -1
  159. package/dist/deep-agent.js +44 -11
  160. package/dist/deep-agent.js.map +1 -1
  161. package/dist/index.d.ts +6 -6
  162. package/dist/index.d.ts.map +1 -1
  163. package/dist/index.js +6 -6
  164. package/dist/index.js.map +1 -1
  165. package/dist/middleware/malformed-tool-call-middleware.d.ts +8 -0
  166. package/dist/middleware/malformed-tool-call-middleware.d.ts.map +1 -0
  167. package/dist/middleware/malformed-tool-call-middleware.js +191 -0
  168. package/dist/middleware/malformed-tool-call-middleware.js.map +1 -0
  169. package/dist/react-agent.d.ts +2 -2
  170. package/dist/react-agent.d.ts.map +1 -1
  171. package/dist/react-agent.js +28 -9
  172. package/dist/react-agent.js.map +1 -1
  173. package/package.json +1 -1
  174. package/scripts/resolve-deps.js +54 -0
  175. package/src/agents/deep-agent.ts +165 -0
  176. package/src/agents/react-agent.helpers.ts +227 -0
  177. package/src/agents/react-agent.ts +584 -0
  178. package/src/agents/sub-agent.ts +82 -0
  179. package/src/cli/args.ts +15 -0
  180. package/src/cli/event-listener.ts +162 -0
  181. package/src/cli/interactive.ts +144 -0
  182. package/src/cli/runtime.ts +31 -0
  183. package/src/cli/spinner.ts +23 -0
  184. package/src/cli/terminal-render.ts +322 -0
  185. package/src/cli/types.ts +33 -0
  186. package/src/cli.ts +91 -702
  187. package/src/config/helpers.ts +179 -0
  188. package/src/config/index.ts +245 -0
  189. package/src/config/types.ts +62 -0
  190. package/src/core/context.ts +266 -0
  191. package/src/index.ts +13 -11
  192. package/src/middleware/malformed-tool-call-middleware.ts +239 -0
  193. package/src/types/markdown-it-terminal.d.ts +4 -0
  194. package/src/types/marked-terminal.d.ts +16 -0
  195. package/dist/config.d.ts +0 -86
  196. package/dist/config.d.ts.map +0 -1
  197. package/dist/config.js +0 -84
  198. package/dist/config.js.map +0 -1
  199. package/src/config.ts +0 -177
  200. package/src/context.ts +0 -247
  201. package/src/deep-agent.ts +0 -104
  202. package/src/react-agent.ts +0 -576
  203. /package/{src → agent-runtime/src/middleware}/malformed-tool-call-middleware.ts +0 -0
  204. /package/{src → agent-runtime/src/types}/markdown-it-terminal.d.ts +0 -0
  205. /package/{src → agent-runtime/src/types}/marked-terminal.d.ts +0 -0
@@ -0,0 +1,131 @@
1
+ function asRecord(value) {
2
+ return typeof value === "object" && value !== null ? value : null;
3
+ }
4
+ function asNumber(value) {
5
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
6
+ }
7
+ function asTrimmedString(value) {
8
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
9
+ }
10
+ function asString(value) {
11
+ return typeof value === "string" ? value : null;
12
+ }
13
+ function parseJsonObject(value) {
14
+ if (typeof value !== "string")
15
+ return null;
16
+ try {
17
+ return asRecord(JSON.parse(value));
18
+ }
19
+ catch {
20
+ return null;
21
+ }
22
+ }
23
+ function extractCommandMeta(args) {
24
+ const rec = asRecord(args) ?? parseJsonObject(args);
25
+ if (!rec)
26
+ return null;
27
+ const commandRaw = asString(rec.command);
28
+ if (commandRaw === null)
29
+ return null;
30
+ return {
31
+ command: commandRaw.trim(),
32
+ windowId: asNumber(rec.windowId),
33
+ tabIndex: asNumber(rec.tabIndex),
34
+ sessionId: asTrimmedString(rec.sessionId),
35
+ };
36
+ }
37
+ function isNoopCaptureCommand(command) {
38
+ const normalized = command.trim().replace(/\s+/g, " ");
39
+ return normalized === "" || normalized === ":" || normalized === "true" || normalized === "printf ''" || normalized === 'printf ""';
40
+ }
41
+ function extractToolResultMeta(payload) {
42
+ const payloadRec = asRecord(payload);
43
+ const rawResult = payloadRec ? (payloadRec.result ?? null) : null;
44
+ const resultRec = asRecord(rawResult) ?? parseJsonObject(rawResult);
45
+ const nestedResult = resultRec ? asRecord(resultRec.result) : null;
46
+ const output = asTrimmedString((nestedResult ?? resultRec ?? {}).output)
47
+ ?? asTrimmedString((nestedResult ?? resultRec ?? {}).result);
48
+ const error = asTrimmedString((nestedResult ?? resultRec ?? {}).error);
49
+ return {
50
+ outputLines: output ? output.split(/\r?\n/).filter((line) => line.length > 0).length : null,
51
+ error,
52
+ };
53
+ }
54
+ function recordToolStart(state, event) {
55
+ state.step += 1;
56
+ const payload = (event.payload ?? {});
57
+ const commandMeta = extractCommandMeta(payload.args);
58
+ if (!commandMeta) {
59
+ state.stepActionByNumber.set(state.step, `tool: ${event.to}`);
60
+ return;
61
+ }
62
+ const signature = `${commandMeta.command}|${commandMeta.windowId ?? ""}|${commandMeta.tabIndex ?? ""}|${commandMeta.sessionId ?? ""}`;
63
+ const isRepeat = signature === state.lastCommandSignature;
64
+ state.lastCommandSignature = signature;
65
+ const action = isNoopCaptureCommand(commandMeta.command) ? "capture current screen" : commandMeta.command;
66
+ state.stepActionByNumber.set(state.step, `${action}${isRepeat ? " (repeat)" : ""}`);
67
+ }
68
+ function writeToolDone(state, event, writer, okMark) {
69
+ const resultMeta = extractToolResultMeta(event.payload);
70
+ const action = state.stepActionByNumber.get(state.step) ?? `tool: ${event.to}`;
71
+ if (resultMeta.error) {
72
+ writer(`[step ${state.step}] ${action} ✖ (${resultMeta.error})`);
73
+ state.stepActionByNumber.delete(state.step);
74
+ return;
75
+ }
76
+ writer(`[step ${state.step}] ${action} ${okMark}`);
77
+ state.stepActionByNumber.delete(state.step);
78
+ }
79
+ function writeToolError(state, event, writer) {
80
+ const payload = (event.payload ?? {});
81
+ const action = state.stepActionByNumber.get(state.step) ?? `tool: ${event.to}`;
82
+ const message = typeof payload.error === "string"
83
+ ? payload.error
84
+ : payload.error instanceof Error
85
+ ? payload.error.message
86
+ : "unknown error";
87
+ writer(`[step ${state.step}] ${action} ✖ (${message})`);
88
+ state.stepActionByNumber.delete(state.step);
89
+ }
90
+ function handleEvent(state, event, writer, okMark) {
91
+ switch (event.name) {
92
+ case "agent.react.run.start":
93
+ case "agent.deep.run.start":
94
+ state.step = 0;
95
+ state.lastCommandSignature = "";
96
+ state.stepActionByNumber.clear();
97
+ writer("Analyzing started");
98
+ return;
99
+ case "agent.react.skill.matched": {
100
+ const payload = (event.payload ?? {});
101
+ const score = typeof payload.score === "number" ? payload.score.toFixed(3) : "?";
102
+ writer(`[skill] matched ${payload.skill ?? "unknown"} (score ${score})`);
103
+ return;
104
+ }
105
+ case "agent.react.tool.invoke.start":
106
+ recordToolStart(state, event);
107
+ return;
108
+ case "agent.react.tool.invoke.done":
109
+ writeToolDone(state, event, writer, okMark);
110
+ return;
111
+ case "agent.react.tool.invoke.error":
112
+ writeToolError(state, event, writer);
113
+ return;
114
+ case "agent.react.run.done":
115
+ case "agent.deep.run.done":
116
+ writer("completed");
117
+ return;
118
+ default:
119
+ return;
120
+ }
121
+ }
122
+ export function createStructuredRunEventListener(writer = console.error) {
123
+ const state = {
124
+ step: 0,
125
+ lastCommandSignature: "",
126
+ stepActionByNumber: new Map(),
127
+ };
128
+ const okMark = process.stderr.isTTY && !process.env.NO_COLOR ? "\x1b[32m✔\x1b[0m" : "✔";
129
+ return (event) => handleEvent(state, event, writer, okMark);
130
+ }
131
+ //# sourceMappingURL=event-listener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-listener.js","sourceRoot":"","sources":["../../src/cli/event-listener.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { BotContext } from "../core/context.js";
2
+ import { type AgentKind, type AppCliOptions } from "./types.js";
3
+ export declare function interactive(ctx: BotContext, kind: AgentKind, options: AppCliOptions, exitApp: (code: number) => never): Promise<void>;
4
+ //# sourceMappingURL=interactive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../../src/cli/interactive.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIrD,OAAO,EAAe,KAAK,SAAS,EAAE,KAAK,aAAa,EAAkC,MAAM,YAAY,CAAC;AAoG7G,wBAAsB,WAAW,CAC/B,GAAG,EAAE,UAAU,EACf,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,GAC/B,OAAO,CAAC,IAAI,CAAC,CAgCf"}
@@ -0,0 +1,118 @@
1
+ import os from "node:os";
2
+ import { createInterface } from "node:readline";
3
+ import { createRuntime } from "./runtime.js";
4
+ import { startLoadingSpinner } from "./spinner.js";
5
+ import { renderForTerminal } from "./terminal-render.js";
6
+ import { DEEP, REACT } from "./types.js";
7
+ const builtinInteractiveCommands = {
8
+ "list tools": (ctx) => {
9
+ const tools = ctx.tools
10
+ .map((tool) => ({
11
+ name: typeof tool.name === "string" ? tool.name : "(unnamed-tool)",
12
+ description: typeof tool.description === "string" && tool.description.trim().length > 0
13
+ ? tool.description.trim()
14
+ : "No description",
15
+ }))
16
+ .sort((a, b) => a.name.localeCompare(b.name));
17
+ console.log(`Available tools (${tools.length}):`);
18
+ for (const tool of tools) {
19
+ console.log(`- ${tool.name}: ${tool.description}`);
20
+ }
21
+ },
22
+ "list skills": (ctx) => {
23
+ const skills = (ctx.skillSet?.list() ?? [])
24
+ .map((skill) => ({ name: skill.name, description: (skill.description ?? "").trim() || "No description" }))
25
+ .sort((a, b) => a.name.localeCompare(b.name));
26
+ console.log(`Available skills (${skills.length}):`);
27
+ for (const skill of skills) {
28
+ console.log(`- ${skill.name}: ${skill.description}`);
29
+ }
30
+ },
31
+ };
32
+ function escapeRegExp(value) {
33
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
34
+ }
35
+ function createCliColors(useColor) {
36
+ return {
37
+ reset: useColor ? "\x1b[0m" : "",
38
+ dim: useColor ? "\x1b[2m" : "",
39
+ user: useColor ? "\x1b[38;5;39m" : "",
40
+ bot: useColor ? "\x1b[38;5;48m" : "",
41
+ prompt: useColor ? "\x1b[38;5;245m" : "",
42
+ promptUser: useColor ? "\x1b[1;38;5;45m" : "",
43
+ };
44
+ }
45
+ function resolveUiOptions(kind, options) {
46
+ const userLabel = options.ui?.userLabel ?? os.userInfo().username;
47
+ const assistantLabel = options.ui?.assistantLabel ?? (kind === REACT ? "ReAct" : "Deep");
48
+ const useColor = options.ui?.useColor ?? (Boolean(process.stdout.isTTY) && !process.env.NO_COLOR);
49
+ const renderMarkdown = options.ui?.renderMarkdown ?? true;
50
+ const echoUserQuestion = options.ui?.echoUserQuestion ?? true;
51
+ const showProcessingSpinner = options.ui?.processingSpinner ?? Boolean(process.stderr.isTTY);
52
+ const processingText = options.ui?.processingText ?? "Processing";
53
+ return { userLabel, assistantLabel, useColor, renderMarkdown, echoUserQuestion, showProcessingSpinner, processingText };
54
+ }
55
+ async function runInteractiveCommand(ctx, input, commands) {
56
+ const key = input.toLowerCase();
57
+ const handler = commands?.[key] ?? builtinInteractiveCommands[key];
58
+ if (!handler)
59
+ return false;
60
+ await handler(ctx);
61
+ return true;
62
+ }
63
+ async function runUserQuery(query, runtime, ui, visuals) {
64
+ let stopProcessingSpinner = null;
65
+ try {
66
+ console.log(`\n${visuals.hr}`);
67
+ if (ui.echoUserQuestion) {
68
+ console.log(visuals.userPrefix);
69
+ console.log(`> ${query}`);
70
+ console.log("");
71
+ }
72
+ console.log(visuals.assistantPrefix);
73
+ stopProcessingSpinner = ui.showProcessingSpinner
74
+ ? startLoadingSpinner(ui.processingText === false ? "⏳" : `⏳ ${ui.processingText}`)
75
+ : null;
76
+ const { text } = await runtime.run(query);
77
+ stopProcessingSpinner?.();
78
+ stopProcessingSpinner = null;
79
+ console.log(renderForTerminal(text, { renderMarkdown: ui.renderMarkdown, useColor: ui.useColor }));
80
+ console.log(`${visuals.hr}\n`);
81
+ }
82
+ catch (err) {
83
+ stopProcessingSpinner?.();
84
+ console.error("Error:", err instanceof Error ? err.message : err);
85
+ }
86
+ }
87
+ export async function interactive(ctx, kind, options, exitApp) {
88
+ const runtime = await createRuntime(ctx, kind);
89
+ const ui = resolveUiOptions(kind, options);
90
+ const color = createCliColors(ui.useColor);
91
+ const hr = `${color.dim}${"-".repeat(56)}${color.reset}`;
92
+ const promptText = `${color.prompt}[${color.promptUser}${ui.userLabel}${color.reset}${color.prompt}]${color.reset} `;
93
+ const userPrefix = `${color.user}[${ui.userLabel}]${color.reset}`;
94
+ const assistantPrefix = `${color.bot}[${ui.assistantLabel}]${color.reset}`;
95
+ const userLabelPrefixPattern = new RegExp(`^(?:\\[${escapeRegExp(ui.userLabel)}\\]\\s*)+`, "i");
96
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
97
+ const introText = options.ui?.interactiveIntro ?? `${options.appName} (${kind === DEEP ? "Deep" : "ReAct"} agent). Type your message or "exit" to quit.`;
98
+ if (introText !== false)
99
+ console.log(`${introText}\n`);
100
+ const prompt = () => {
101
+ rl.question(promptText, async (line) => {
102
+ const query = line?.trim()?.replace(userLabelPrefixPattern, "").trim();
103
+ if (!query)
104
+ return prompt();
105
+ if (query === "exit" || query === "quit") {
106
+ rl.close();
107
+ exitApp(0);
108
+ }
109
+ const handled = await runInteractiveCommand(ctx, query, options.interactiveCommands);
110
+ if (handled)
111
+ return prompt();
112
+ await runUserQuery(query, runtime, ui, { hr, userPrefix, assistantPrefix });
113
+ prompt();
114
+ });
115
+ };
116
+ prompt();
117
+ }
118
+ //# sourceMappingURL=interactive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive.js","sourceRoot":"","sources":["../../src/cli/interactive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { type ReactAgentRuntime } from "../agents/react-agent.js";
2
+ import { type DeepAgentRuntime } from "../agents/deep-agent.js";
3
+ import type { BotContext } from "../core/context.js";
4
+ import { type AgentKind } from "./types.js";
5
+ export declare function readDefaultAgentKindFromConfig(ctx: BotContext): AgentKind | undefined;
6
+ export declare function createRuntime(ctx: BotContext, kind: AgentKind): Promise<ReactAgentRuntime | DeepAgentRuntime>;
7
+ export declare function runOne(ctx: BotContext, kind: AgentKind, query: string): Promise<string>;
8
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/cli/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEjF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAEzD,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,CAMrF;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,UAAU,EACf,IAAI,EAAE,SAAS,GACd,OAAO,CAAC,iBAAiB,GAAG,gBAAgB,CAAC,CAO/C;AAED,wBAAsB,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI7F"}
@@ -0,0 +1,27 @@
1
+ import { createReactAgent } from "../agents/react-agent.js";
2
+ import { createDeepAgent } from "../agents/deep-agent.js";
3
+ import { malformedToolCallMiddleware } from "../middleware/malformed-tool-call-middleware.js";
4
+ import { DEEP, REACT } from "./types.js";
5
+ export function readDefaultAgentKindFromConfig(ctx) {
6
+ const defaultAgent = ctx.config?.app?.defaultAgent;
7
+ if (typeof defaultAgent !== "string")
8
+ return undefined;
9
+ const value = defaultAgent.trim().toLowerCase();
10
+ if (value === REACT || value === DEEP)
11
+ return value;
12
+ return undefined;
13
+ }
14
+ export async function createRuntime(ctx, kind) {
15
+ if (kind === REACT) {
16
+ return createReactAgent(ctx, {
17
+ middleware: [malformedToolCallMiddleware()],
18
+ });
19
+ }
20
+ return createDeepAgent(ctx);
21
+ }
22
+ export async function runOne(ctx, kind, query) {
23
+ const runtime = await createRuntime(ctx, kind);
24
+ const { text } = await runtime.run(query);
25
+ return text;
26
+ }
27
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/cli/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA0B,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,eAAe,EAAyB,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAAE,2BAA2B,EAAE,MAAM,iDAAiD,CAAC;AAE9F,OAAO,EAAE,IAAI,EAAE,KAAK,EAAkB,MAAM,YAAY,CAAC;AAEzD,MAAM,UAAU,8BAA8B,CAAC,GAAe;IAC5D,MAAM,YAAY,GAAI,GAAG,CAAC,MAAM,EAAE,GAA8C,EAAE,YAAY,CAAC;IAC/F,IAAI,OAAO,YAAY,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACvD,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAChD,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACpD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAe,EACf,IAAe;IAEf,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACnB,OAAO,gBAAgB,CAAC,GAAG,EAAE;YAC3B,UAAU,EAAE,CAAC,2BAA2B,EAAE,CAAC;SAC5C,CAAC,CAAC;IACL,CAAC;IACD,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,GAAe,EAAE,IAAe,EAAE,KAAa;IAC1E,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC/C,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function startLoadingSpinner(message: string): () => void;
2
+ //# sourceMappingURL=spinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/cli/spinner.ts"],"names":[],"mappings":"AAAA,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,IAAI,CAsB/D"}
@@ -0,0 +1,22 @@
1
+ export function startLoadingSpinner(message) {
2
+ const frames = ["", ".", "..", "..."];
3
+ let frameIndex = 0;
4
+ let lastLength = 0;
5
+ const render = () => {
6
+ const frame = frames[frameIndex % frames.length] ?? "";
7
+ const trimmed = message.trim();
8
+ const base = trimmed.startsWith("⏳") ? trimmed : `⏳ ${trimmed}`;
9
+ const line = `${base}${frame}`;
10
+ const padded = lastLength > line.length ? line.padEnd(lastLength, " ") : line;
11
+ process.stderr.write(`\r${padded}\r`);
12
+ lastLength = padded.length;
13
+ frameIndex += 1;
14
+ };
15
+ render();
16
+ const timer = setInterval(render, 90);
17
+ return () => {
18
+ clearInterval(timer);
19
+ process.stderr.write(`\r${" ".repeat(lastLength)}\r`);
20
+ };
21
+ }
22
+ //# sourceMappingURL=spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/cli/spinner.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,MAAM,MAAM,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IACtC,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACvD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;QAChE,MAAM,IAAI,GAAG,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC;QACtC,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;QAC3B,UAAU,IAAI,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,MAAM,EAAE,CAAC;IACT,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACtC,OAAO,GAAG,EAAE;QACV,aAAa,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ interface RenderOptions {
2
+ renderMarkdown: boolean;
3
+ useColor: boolean;
4
+ }
5
+ export declare function renderForTerminal(text: string, options: RenderOptions): string;
6
+ export {};
7
+ //# sourceMappingURL=terminal-render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-render.d.ts","sourceRoot":"","sources":["../../src/cli/terminal-render.ts"],"names":[],"mappings":"AAGA,UAAU,aAAa;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAmTD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAQ9E"}
@@ -0,0 +1,282 @@
1
+ import MarkdownIt from "markdown-it";
2
+ import markdownItTerminal from "markdown-it-terminal";
3
+ const markdownRenderers = new Map();
4
+ function createAnsi(useColor) {
5
+ return {
6
+ reset: useColor ? "\x1b[0m" : "",
7
+ dim: useColor ? "\x1b[2m" : "",
8
+ heading: useColor ? "\x1b[1;38;5;45m" : "",
9
+ bullet: useColor ? "\x1b[38;5;81m" : "",
10
+ code: useColor ? "\x1b[38;5;221m" : "",
11
+ quote: useColor ? "\x1b[38;5;245m" : "",
12
+ hr: useColor ? "\x1b[38;5;240m" : "",
13
+ };
14
+ }
15
+ function styleInlineMarkdown(line, ansi) {
16
+ return line
17
+ .replace(/`([^`]+)`/g, `${ansi.code}\`$1\`${ansi.reset}`)
18
+ .replace(/\*\*([^*]+)\*\*/g, `${ansi.heading}$1${ansi.reset}`);
19
+ }
20
+ function parseTableRow(line) {
21
+ const trimmed = line.trim().replace(/^\|/, "").replace(/\|$/, "");
22
+ return trimmed.split("|").map((cell) => cell.trim());
23
+ }
24
+ function isTableSeparatorRow(cells) {
25
+ return cells.length > 0 && cells.every((c) => /^:?-{3,}:?$/.test(c));
26
+ }
27
+ function renderTable(rows, ansi) {
28
+ const normalized = rows.map((row) => [...row]);
29
+ const colCount = Math.max(...normalized.map((row) => row.length));
30
+ for (const row of normalized) {
31
+ while (row.length < colCount)
32
+ row.push("");
33
+ }
34
+ const widths = Array.from({ length: colCount }, (_, i) => Math.max(...normalized.map((row) => (row[i] ?? "").length)));
35
+ const border = `+${widths.map((w) => "-".repeat(w + 2)).join("+")}+`;
36
+ const output = [`${ansi.hr}${border}${ansi.reset}`];
37
+ normalized.forEach((row, idx) => {
38
+ const body = row.map((cell, i) => ` ${(cell ?? "").padEnd(widths[i] ?? 0)} `).join("|");
39
+ const styled = idx === 0
40
+ ? `${ansi.heading}|${styleInlineMarkdown(body, ansi)}|${ansi.reset}`
41
+ : `|${styleInlineMarkdown(body, ansi)}|`;
42
+ output.push(styled);
43
+ if (idx === 0)
44
+ output.push(`${ansi.hr}${border}${ansi.reset}`);
45
+ });
46
+ output.push(`${ansi.hr}${border}${ansi.reset}`);
47
+ return output;
48
+ }
49
+ function appendCodeFenceLine(line, state, ansi, out) {
50
+ const trimmed = line.trim();
51
+ if (!trimmed.startsWith("```"))
52
+ return;
53
+ if (!state.inCodeBlock) {
54
+ const lang = trimmed.slice(3).trim();
55
+ const title = lang ? ` code:${lang} ` : " code ";
56
+ state.codeBoxWidth = Math.max(16, title.length + 4);
57
+ state.inCodeBlock = true;
58
+ out.push(`${ansi.hr}┌${"─".repeat(state.codeBoxWidth)}┐${ansi.reset}`);
59
+ out.push(`${ansi.hr}│${ansi.reset}${ansi.dim}${title.padEnd(state.codeBoxWidth)}${ansi.reset}${ansi.hr}│${ansi.reset}`);
60
+ return;
61
+ }
62
+ state.inCodeBlock = false;
63
+ out.push(`${ansi.hr}└${"─".repeat(state.codeBoxWidth)}┘${ansi.reset}`);
64
+ }
65
+ function renderMarkdownTable(lines, index, ansi) {
66
+ const line = lines[index] ?? "";
67
+ const next = lines[index + 1] ?? "";
68
+ if (!line.includes("|") || !next.includes("|"))
69
+ return null;
70
+ const header = parseTableRow(line);
71
+ const separator = parseTableRow(next);
72
+ if (!(header.length > 1 && header.length === separator.length && isTableSeparatorRow(separator))) {
73
+ return null;
74
+ }
75
+ const rows = [header];
76
+ let cursor = index + 2;
77
+ while (cursor < lines.length && (lines[cursor] ?? "").includes("|")) {
78
+ rows.push(parseTableRow(lines[cursor] ?? ""));
79
+ cursor += 1;
80
+ }
81
+ return { nextIndex: cursor - 1, rendered: renderTable(rows, ansi) };
82
+ }
83
+ function formatMarkdownForTerminal(markdown, options = { useColor: true }) {
84
+ const ansi = createAnsi(options.useColor);
85
+ const lines = markdown.replace(/\r\n/g, "\n").split("\n");
86
+ const out = [];
87
+ const state = { inCodeBlock: false, codeBoxWidth: 0 };
88
+ for (let i = 0; i < lines.length; i += 1) {
89
+ const line = lines[i] ?? "";
90
+ const before = state.inCodeBlock;
91
+ appendCodeFenceLine(line, state, ansi, out);
92
+ if (line.trim().startsWith("```"))
93
+ continue;
94
+ if (before && state.inCodeBlock) {
95
+ const content = line.length > state.codeBoxWidth ? line.slice(0, state.codeBoxWidth) : line.padEnd(state.codeBoxWidth);
96
+ out.push(`${ansi.hr}│${ansi.reset}${ansi.code}${content}${ansi.reset}${ansi.hr}│${ansi.reset}`);
97
+ continue;
98
+ }
99
+ const table = renderMarkdownTable(lines, i, ansi);
100
+ if (table) {
101
+ out.push(...table.rendered);
102
+ i = table.nextIndex;
103
+ continue;
104
+ }
105
+ if (/^\s*#{1,6}\s+/.test(line)) {
106
+ out.push(`${ansi.heading}${line.replace(/^\s*#{1,6}\s+/, "").trim()}${ansi.reset}`);
107
+ continue;
108
+ }
109
+ if (/^\s*>\s?/.test(line)) {
110
+ out.push(`${ansi.quote}${line}${ansi.reset}`);
111
+ continue;
112
+ }
113
+ if (/^\s*([-*]|\d+\.)\s+/.test(line)) {
114
+ out.push(`${ansi.bullet}${styleInlineMarkdown(line, ansi)}${ansi.reset}`);
115
+ continue;
116
+ }
117
+ if (/^\s*---+\s*$/.test(line)) {
118
+ out.push(`${ansi.hr}${"─".repeat(56)}${ansi.reset}`);
119
+ continue;
120
+ }
121
+ out.push(styleInlineMarkdown(line, ansi));
122
+ }
123
+ return out.join("\n");
124
+ }
125
+ function sanitizeLine(line) {
126
+ let next = line;
127
+ const trimmed = next.trim();
128
+ if (next.includes("```") && !trimmed.startsWith("```")) {
129
+ next = next.replace(/```+/g, "").replace(/\s+$/, "");
130
+ }
131
+ if (/^\s*#{3,}\s+/.test(next)) {
132
+ next = next.replace(/^\s*#{3,}\s+/, "## ");
133
+ }
134
+ return next;
135
+ }
136
+ function normalizeListLine(line) {
137
+ if (/^(\s{2,}|\t+)([*-])\s+/.test(line)) {
138
+ return line.replace(/^(\s{2,}|\t+)([*-])\s+/, "- ");
139
+ }
140
+ if (/^(\s{2,}|\t+)(\d+\.)\s+/.test(line)) {
141
+ return line.replace(/^(\s{2,}|\t+)(\d+\.)\s+/, "$2 ");
142
+ }
143
+ return line;
144
+ }
145
+ function applyHeadingHeuristics(lines, hasMarkdownHeadings) {
146
+ return lines.map((line) => {
147
+ const trimmed = line.trim();
148
+ const bulletHeading = trimmed.match(/^[-*]\s+\*\*([^*]+)\*\*: ?\s*$/);
149
+ if (bulletHeading?.[1])
150
+ return `### ${bulletHeading[1].trim()}`;
151
+ const plainBullet = trimmed.match(/^[-*]\s+([^`].+):\s*$/);
152
+ if (plainBullet?.[1] && plainBullet[1].length <= 48) {
153
+ return `### ${plainBullet[1].trim()}`;
154
+ }
155
+ if (hasMarkdownHeadings)
156
+ return trimmed === "Summary (3‑8 bullets)" ? "## Summary" : line;
157
+ const unwrapped = trimmed.replace(/^\*\*(.+)\*\*$/, "$1").trim();
158
+ if (/^(Key terminal output.*|Current terminal buffer.*|Summary.*|Next steps.*)$/i.test(unwrapped)) {
159
+ return `## ${unwrapped}`;
160
+ }
161
+ if (/^(Key observations|Findings|Analysis|Conclusion)$/i.test(unwrapped)) {
162
+ return `## ${unwrapped}`;
163
+ }
164
+ return line;
165
+ });
166
+ }
167
+ function mergeWrappedListItems(lines) {
168
+ const merged = [];
169
+ for (let i = 0; i < lines.length; i += 1) {
170
+ const current = lines[i] ?? "";
171
+ const next = lines[i + 1] ?? "";
172
+ const isListLine = /^([-*]|\d+\.)\s+/.test(current.trim());
173
+ const nextTrim = next.trim();
174
+ const nextStartsNewBlock = nextTrim.length === 0 ||
175
+ /^([-*]|\d+\.)\s+/.test(nextTrim) ||
176
+ /^#{1,6}\s+/.test(nextTrim) ||
177
+ /^```/.test(nextTrim) ||
178
+ /^---+$/.test(nextTrim);
179
+ const wrappedContinuation = isListLine && !nextStartsNewBlock && /^[0-9./~]/.test(nextTrim);
180
+ if (wrappedContinuation) {
181
+ merged.push(`${current.replace(/\s+$/, "")} ${nextTrim}`);
182
+ i += 1;
183
+ continue;
184
+ }
185
+ merged.push(current);
186
+ }
187
+ return merged;
188
+ }
189
+ function fenceIndentedOutputBlocks(lines) {
190
+ const output = [];
191
+ for (let i = 0; i < lines.length; i += 1) {
192
+ const line = lines[i] ?? "";
193
+ output.push(line);
194
+ const heading = line.trim();
195
+ const isOutputHeading = /^##\s*(Key terminal output|Current terminal buffer|Terminal output)/i.test(heading);
196
+ if (!isOutputHeading)
197
+ continue;
198
+ if ((lines[i + 1] ?? "").trim().startsWith("```"))
199
+ continue;
200
+ let j = i + 1;
201
+ const block = [];
202
+ while (j < lines.length) {
203
+ const current = lines[j] ?? "";
204
+ if (!current.trim()) {
205
+ if (block.length === 0) {
206
+ j += 1;
207
+ continue;
208
+ }
209
+ break;
210
+ }
211
+ if (!/^\s{2,}\S/.test(current))
212
+ break;
213
+ block.push(current.replace(/^\s+/, ""));
214
+ j += 1;
215
+ }
216
+ if (block.length >= 2) {
217
+ output.push("```text", ...block, "```");
218
+ i = j - 1;
219
+ }
220
+ }
221
+ return output;
222
+ }
223
+ function ensureBalancedCodeFences(lines) {
224
+ const count = lines.reduce((acc, line) => acc + (/^\s*```/.test(line) ? 1 : 0), 0);
225
+ if (count % 2 === 0)
226
+ return lines;
227
+ return [...lines, "```"];
228
+ }
229
+ function normalizeAssistantMarkdown(text) {
230
+ const source = text.replace(/\r\n/g, "\n");
231
+ const hasHeadings = /^\s*#{1,6}\s+/m.test(source);
232
+ const sanitized = source.split("\n").map(sanitizeLine).map(normalizeListLine);
233
+ const titled = applyHeadingHeuristics(sanitized, hasHeadings);
234
+ const merged = mergeWrappedListItems(titled);
235
+ const fenced = fenceIndentedOutputBlocks(merged);
236
+ return ensureBalancedCodeFences(fenced).join("\n");
237
+ }
238
+ function getMarkdownRenderer(useColor) {
239
+ const key = useColor ? "color" : "plain";
240
+ const cached = markdownRenderers.get(key);
241
+ if (cached)
242
+ return cached;
243
+ const renderer = new MarkdownIt({ html: false, linkify: true, typographer: true, breaks: false });
244
+ renderer.use(markdownItTerminal, {
245
+ indent: "",
246
+ ...(useColor
247
+ ? {}
248
+ : {
249
+ styleOptions: {
250
+ code: (s) => s,
251
+ blockquote: (s) => s,
252
+ html: (s) => s,
253
+ heading: (s) => s,
254
+ firstHeading: (s) => s,
255
+ hr: (s) => s,
256
+ listitem: (s) => s,
257
+ table: (s) => s,
258
+ paragraph: (s) => s,
259
+ strong: (s) => s,
260
+ em: (s) => s,
261
+ codespan: (s) => s,
262
+ del: (s) => s,
263
+ link: (s) => s,
264
+ href: (s) => s,
265
+ },
266
+ }),
267
+ });
268
+ markdownRenderers.set(key, renderer);
269
+ return renderer;
270
+ }
271
+ export function renderForTerminal(text, options) {
272
+ if (!options.renderMarkdown)
273
+ return text;
274
+ const normalized = normalizeAssistantMarkdown(text);
275
+ try {
276
+ return getMarkdownRenderer(options.useColor).render(normalized, {});
277
+ }
278
+ catch {
279
+ return formatMarkdownForTerminal(normalized, { useColor: options.useColor });
280
+ }
281
+ }
282
+ //# sourceMappingURL=terminal-render.js.map