merlion 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 (162) hide show
  1. package/bin/merlion.js +2 -0
  2. package/dist/artifacts/agents.d.ts +11 -0
  3. package/dist/artifacts/agents.d.ts.map +1 -0
  4. package/dist/artifacts/agents.js +81 -0
  5. package/dist/artifacts/agents.js.map +1 -0
  6. package/dist/artifacts/codebase_index.d.ts +16 -0
  7. package/dist/artifacts/codebase_index.d.ts.map +1 -0
  8. package/dist/artifacts/codebase_index.js +193 -0
  9. package/dist/artifacts/codebase_index.js.map +1 -0
  10. package/dist/artifacts/progress.d.ts +23 -0
  11. package/dist/artifacts/progress.d.ts.map +1 -0
  12. package/dist/artifacts/progress.js +152 -0
  13. package/dist/artifacts/progress.js.map +1 -0
  14. package/dist/cli/diff.d.ts +11 -0
  15. package/dist/cli/diff.d.ts.map +1 -0
  16. package/dist/cli/diff.js +58 -0
  17. package/dist/cli/diff.js.map +1 -0
  18. package/dist/cli/experience.d.ts +71 -0
  19. package/dist/cli/experience.d.ts.map +1 -0
  20. package/dist/cli/experience.js +489 -0
  21. package/dist/cli/experience.js.map +1 -0
  22. package/dist/cli/keybindings.d.ts +3 -0
  23. package/dist/cli/keybindings.d.ts.map +1 -0
  24. package/dist/cli/keybindings.js +14 -0
  25. package/dist/cli/keybindings.js.map +1 -0
  26. package/dist/cli/markdown.d.ts +7 -0
  27. package/dist/cli/markdown.d.ts.map +1 -0
  28. package/dist/cli/markdown.js +77 -0
  29. package/dist/cli/markdown.js.map +1 -0
  30. package/dist/cli/message_content.d.ts +13 -0
  31. package/dist/cli/message_content.d.ts.map +1 -0
  32. package/dist/cli/message_content.js +23 -0
  33. package/dist/cli/message_content.js.map +1 -0
  34. package/dist/cli/render.d.ts +23 -0
  35. package/dist/cli/render.d.ts.map +1 -0
  36. package/dist/cli/render.js +44 -0
  37. package/dist/cli/render.js.map +1 -0
  38. package/dist/cli/repl.d.ts +32 -0
  39. package/dist/cli/repl.d.ts.map +1 -0
  40. package/dist/cli/repl.js +54 -0
  41. package/dist/cli/repl.js.map +1 -0
  42. package/dist/cli/sanitize.d.ts +2 -0
  43. package/dist/cli/sanitize.d.ts.map +1 -0
  44. package/dist/cli/sanitize.js +66 -0
  45. package/dist/cli/sanitize.js.map +1 -0
  46. package/dist/cli/status.d.ts +3 -0
  47. package/dist/cli/status.d.ts.map +1 -0
  48. package/dist/cli/status.js +27 -0
  49. package/dist/cli/status.js.map +1 -0
  50. package/dist/cli/tui_frame.d.ts +10 -0
  51. package/dist/cli/tui_frame.d.ts.map +1 -0
  52. package/dist/cli/tui_frame.js +44 -0
  53. package/dist/cli/tui_frame.js.map +1 -0
  54. package/dist/config/store.d.ts +27 -0
  55. package/dist/config/store.d.ts.map +1 -0
  56. package/dist/config/store.js +73 -0
  57. package/dist/config/store.js.map +1 -0
  58. package/dist/config/wizard.d.ts +27 -0
  59. package/dist/config/wizard.d.ts.map +1 -0
  60. package/dist/config/wizard.js +83 -0
  61. package/dist/config/wizard.js.map +1 -0
  62. package/dist/context/compact.d.ts +11 -0
  63. package/dist/context/compact.d.ts.map +1 -0
  64. package/dist/context/compact.js +38 -0
  65. package/dist/context/compact.js.map +1 -0
  66. package/dist/context/orientation.d.ts +19 -0
  67. package/dist/context/orientation.d.ts.map +1 -0
  68. package/dist/context/orientation.js +111 -0
  69. package/dist/context/orientation.js.map +1 -0
  70. package/dist/index.d.ts +2 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +401 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/permissions/store.d.ts +3 -0
  75. package/dist/permissions/store.d.ts.map +1 -0
  76. package/dist/permissions/store.js +22 -0
  77. package/dist/permissions/store.js.map +1 -0
  78. package/dist/providers/openai.d.ts +16 -0
  79. package/dist/providers/openai.d.ts.map +1 -0
  80. package/dist/providers/openai.js +75 -0
  81. package/dist/providers/openai.js.map +1 -0
  82. package/dist/runtime/budget.d.ts +11 -0
  83. package/dist/runtime/budget.d.ts.map +1 -0
  84. package/dist/runtime/budget.js +43 -0
  85. package/dist/runtime/budget.js.map +1 -0
  86. package/dist/runtime/cost_gate.d.ts +34 -0
  87. package/dist/runtime/cost_gate.d.ts.map +1 -0
  88. package/dist/runtime/cost_gate.js +85 -0
  89. package/dist/runtime/cost_gate.js.map +1 -0
  90. package/dist/runtime/executor.d.ts +25 -0
  91. package/dist/runtime/executor.d.ts.map +1 -0
  92. package/dist/runtime/executor.js +136 -0
  93. package/dist/runtime/executor.js.map +1 -0
  94. package/dist/runtime/loop.d.ts +48 -0
  95. package/dist/runtime/loop.d.ts.map +1 -0
  96. package/dist/runtime/loop.js +184 -0
  97. package/dist/runtime/loop.js.map +1 -0
  98. package/dist/runtime/retry.d.ts +7 -0
  99. package/dist/runtime/retry.d.ts.map +1 -0
  100. package/dist/runtime/retry.js +42 -0
  101. package/dist/runtime/retry.js.map +1 -0
  102. package/dist/runtime/session.d.ts +26 -0
  103. package/dist/runtime/session.d.ts.map +1 -0
  104. package/dist/runtime/session.js +146 -0
  105. package/dist/runtime/session.js.map +1 -0
  106. package/dist/runtime/usage.d.ts +29 -0
  107. package/dist/runtime/usage.d.ts.map +1 -0
  108. package/dist/runtime/usage.js +71 -0
  109. package/dist/runtime/usage.js.map +1 -0
  110. package/dist/tools/builtin/bash.d.ts +3 -0
  111. package/dist/tools/builtin/bash.d.ts.map +1 -0
  112. package/dist/tools/builtin/bash.js +104 -0
  113. package/dist/tools/builtin/bash.js.map +1 -0
  114. package/dist/tools/builtin/create_file.d.ts +3 -0
  115. package/dist/tools/builtin/create_file.d.ts.map +1 -0
  116. package/dist/tools/builtin/create_file.js +64 -0
  117. package/dist/tools/builtin/create_file.js.map +1 -0
  118. package/dist/tools/builtin/edit_file.d.ts +3 -0
  119. package/dist/tools/builtin/edit_file.d.ts.map +1 -0
  120. package/dist/tools/builtin/edit_file.js +128 -0
  121. package/dist/tools/builtin/edit_file.js.map +1 -0
  122. package/dist/tools/builtin/fetch.d.ts +3 -0
  123. package/dist/tools/builtin/fetch.d.ts.map +1 -0
  124. package/dist/tools/builtin/fetch.js +82 -0
  125. package/dist/tools/builtin/fetch.js.map +1 -0
  126. package/dist/tools/builtin/index.d.ts +3 -0
  127. package/dist/tools/builtin/index.d.ts.map +1 -0
  128. package/dist/tools/builtin/index.js +18 -0
  129. package/dist/tools/builtin/index.js.map +1 -0
  130. package/dist/tools/builtin/read_file.d.ts +3 -0
  131. package/dist/tools/builtin/read_file.d.ts.map +1 -0
  132. package/dist/tools/builtin/read_file.js +77 -0
  133. package/dist/tools/builtin/read_file.js.map +1 -0
  134. package/dist/tools/builtin/search.d.ts +3 -0
  135. package/dist/tools/builtin/search.d.ts.map +1 -0
  136. package/dist/tools/builtin/search.js +91 -0
  137. package/dist/tools/builtin/search.js.map +1 -0
  138. package/dist/tools/registry.d.ts +8 -0
  139. package/dist/tools/registry.d.ts.map +1 -0
  140. package/dist/tools/registry.js +16 -0
  141. package/dist/tools/registry.js.map +1 -0
  142. package/dist/tools/types.d.ts +45 -0
  143. package/dist/tools/types.d.ts.map +1 -0
  144. package/dist/tools/types.js +2 -0
  145. package/dist/tools/types.js.map +1 -0
  146. package/dist/types.d.ts +56 -0
  147. package/dist/types.d.ts.map +1 -0
  148. package/dist/types.js +2 -0
  149. package/dist/types.js.map +1 -0
  150. package/dist/verification/checks.d.ts +10 -0
  151. package/dist/verification/checks.d.ts.map +1 -0
  152. package/dist/verification/checks.js +501 -0
  153. package/dist/verification/checks.js.map +1 -0
  154. package/dist/verification/fix_round.d.ts +20 -0
  155. package/dist/verification/fix_round.d.ts.map +1 -0
  156. package/dist/verification/fix_round.js +59 -0
  157. package/dist/verification/fix_round.js.map +1 -0
  158. package/dist/verification/runner.d.ts +26 -0
  159. package/dist/verification/runner.d.ts.map +1 -0
  160. package/dist/verification/runner.js +155 -0
  161. package/dist/verification/runner.js.map +1 -0
  162. package/package.json +29 -0
@@ -0,0 +1,77 @@
1
+ import { sanitizeRenderableText } from "./sanitize.js";
2
+ function normalizeInline(text) {
3
+ return text
4
+ .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1 <$2>')
5
+ .replace(/`([^`]+)`/g, '$1')
6
+ .replace(/\*\*([^*]+)\*\*/g, '$1')
7
+ .replace(/__([^_]+)__/g, '$1');
8
+ }
9
+ export function looksLikeMarkdown(text) {
10
+ if (text.trim() === '')
11
+ return false;
12
+ return /(^|\n)(#{1,6}\s+|[-*+]\s+|\d+\.\s+|>\s+|```|[-*_]{3,}\s*$|\|.+\|)/m.test(text);
13
+ }
14
+ export function renderMarkdownLines(markdown) {
15
+ const lines = markdown.replace(/\r\n/g, '\n').split('\n');
16
+ const rendered = [];
17
+ let inCode = false;
18
+ let codeLanguage = 'text';
19
+ for (const line of lines) {
20
+ const raw = sanitizeRenderableText(line);
21
+ const fence = raw.trim().match(/^```(\S+)?$/);
22
+ if (fence) {
23
+ if (!inCode) {
24
+ codeLanguage = fence[1] ? sanitizeRenderableText(fence[1]) : 'text';
25
+ rendered.push({ kind: 'code_meta', text: `code:${codeLanguage}` });
26
+ inCode = true;
27
+ }
28
+ else {
29
+ inCode = false;
30
+ codeLanguage = 'text';
31
+ }
32
+ continue;
33
+ }
34
+ if (inCode) {
35
+ rendered.push({ kind: 'code', text: raw });
36
+ continue;
37
+ }
38
+ if (/^\s*$/.test(raw)) {
39
+ rendered.push({ kind: 'plain', text: '' });
40
+ continue;
41
+ }
42
+ const heading = raw.match(/^\s*(#{1,6})\s+(.*)$/);
43
+ if (heading) {
44
+ const level = heading[1].length;
45
+ const prefix = '#'.repeat(level);
46
+ rendered.push({ kind: 'heading', text: `${prefix} ${normalizeInline(heading[2])}` });
47
+ continue;
48
+ }
49
+ const quote = raw.match(/^\s*>\s?(.*)$/);
50
+ if (quote) {
51
+ rendered.push({ kind: 'quote', text: `> ${normalizeInline(quote[1])}` });
52
+ continue;
53
+ }
54
+ const list = raw.match(/^\s*([-*+]|\d+\.)\s+(.*)$/);
55
+ if (list) {
56
+ rendered.push({ kind: 'list', text: `${list[1]} ${normalizeInline(list[2])}` });
57
+ continue;
58
+ }
59
+ if (/^\s*([-*_])\1\1+\s*$/.test(raw)) {
60
+ rendered.push({ kind: 'rule', text: '────────────────────────' });
61
+ continue;
62
+ }
63
+ if (raw.includes('|') && /\|/.test(raw.trim())) {
64
+ rendered.push({ kind: 'table', text: normalizeInline(raw) });
65
+ continue;
66
+ }
67
+ rendered.push({ kind: 'plain', text: normalizeInline(raw) });
68
+ }
69
+ while (rendered.length > 0) {
70
+ const last = rendered[rendered.length - 1];
71
+ if (!last || last.kind !== 'plain' || last.text !== '')
72
+ break;
73
+ rendered.pop();
74
+ }
75
+ return rendered;
76
+ }
77
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/cli/markdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export type MessageTone = 'plain' | 'heading' | 'list' | 'quote' | 'code' | 'code_meta' | 'rule' | 'table';
2
+ export interface MessageRenderLine {
3
+ tone: MessageTone;
4
+ text: string;
5
+ }
6
+ export interface AssistantRenderPlan {
7
+ mode: 'plain' | 'markdown';
8
+ lines: MessageRenderLine[];
9
+ }
10
+ export declare function buildAssistantRenderPlan(output: string, options?: {
11
+ markdownEnabled?: boolean;
12
+ }): AssistantRenderPlan;
13
+ //# sourceMappingURL=message_content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message_content.d.ts","sourceRoot":"","sources":["../../src/cli/message_content.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAA;AAE1G,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,WAAW,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,GAAG,UAAU,CAAA;IAC1B,KAAK,EAAE,iBAAiB,EAAE,CAAA;CAC3B;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,GACtC,mBAAmB,CAoBrB"}
@@ -0,0 +1,23 @@
1
+ import { sanitizeRenderableText } from "./sanitize.js";
2
+ import { looksLikeMarkdown, renderMarkdownLines } from "./markdown.js";
3
+ export function buildAssistantRenderPlan(output, options) {
4
+ const markdownEnabled = options?.markdownEnabled !== false;
5
+ if (markdownEnabled && looksLikeMarkdown(output)) {
6
+ return {
7
+ mode: 'markdown',
8
+ lines: renderMarkdownLines(output).map((line) => ({
9
+ tone: line.kind,
10
+ text: line.text
11
+ }))
12
+ };
13
+ }
14
+ const lines = sanitizeRenderableText(output).split('\n').map((text) => ({
15
+ tone: 'plain',
16
+ text
17
+ }));
18
+ return {
19
+ mode: 'plain',
20
+ lines: lines.length > 0 ? lines : [{ tone: 'plain', text: '' }]
21
+ };
22
+ }
23
+ //# sourceMappingURL=message_content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message_content.js","sourceRoot":"","sources":["../../src/cli/message_content.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AActE,MAAM,UAAU,wBAAwB,CACtC,MAAc,EACd,OAAuC;IAEvC,MAAM,eAAe,GAAG,OAAO,EAAE,eAAe,KAAK,KAAK,CAAA;IAC1D,IAAI,eAAe,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;QACjD,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAChD,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;aAChB,CAAC,CAAC;SACJ,CAAA;IACH,CAAC;IAED,MAAM,KAAK,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACtE,IAAI,EAAE,OAAgB;QACtB,IAAI;KACL,CAAC,CAAC,CAAA;IACH,OAAO;QACL,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;KAChE,CAAA;AACH,CAAC"}
@@ -0,0 +1,23 @@
1
+ export declare function formatTurnStartEvent(event: {
2
+ turn: number;
3
+ }): string;
4
+ export declare function formatAssistantResponseEvent(event: {
5
+ turn: number;
6
+ finish_reason: string;
7
+ tool_calls_count: number;
8
+ }): string;
9
+ export declare function summarizeToolArguments(raw: string, maxLen?: number): string;
10
+ export declare function formatToolStartEvent(event: {
11
+ index: number;
12
+ total: number;
13
+ name: string;
14
+ summary?: string;
15
+ }): string;
16
+ export declare function formatToolResultEvent(event: {
17
+ index: number;
18
+ total: number;
19
+ name: string;
20
+ isError: boolean;
21
+ durationMs: number;
22
+ }): string;
23
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/cli/render.ts"],"names":[],"mappings":"AAEA,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEpE;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IAClD,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,CAAA;IACrB,gBAAgB,EAAE,MAAM,CAAA;CACzB,GAAG,MAAM,CAKT;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,SAAK,GAAG,MAAM,CAsBvE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,GAAG,MAAM,CAGT;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;CACnB,GAAG,MAAM,CAGT"}
@@ -0,0 +1,44 @@
1
+ import { sanitizeRenderableText } from "./sanitize.js";
2
+ export function formatTurnStartEvent(event) {
3
+ return sanitizeRenderableText(`[turn ${event.turn}] requesting model...`);
4
+ }
5
+ export function formatAssistantResponseEvent(event) {
6
+ if (event.finish_reason === 'tool_calls') {
7
+ return sanitizeRenderableText(`[turn ${event.turn}] assistant requested ${event.tool_calls_count} tool call(s)`);
8
+ }
9
+ return sanitizeRenderableText(`[turn ${event.turn}] assistant finish=${event.finish_reason}`);
10
+ }
11
+ export function summarizeToolArguments(raw, maxLen = 80) {
12
+ try {
13
+ const parsed = JSON.parse(raw);
14
+ const keys = Object.keys(parsed);
15
+ if (keys.length === 0)
16
+ return '';
17
+ const parts = keys.slice(0, 2).map((key) => {
18
+ const value = parsed[key];
19
+ if (typeof value === 'string') {
20
+ const compact = value.replace(/\s+/g, ' ').trim();
21
+ return `${key}=${compact.length > 28 ? `${compact.slice(0, 28)}...` : compact}`;
22
+ }
23
+ if (typeof value === 'number' || typeof value === 'boolean') {
24
+ return `${key}=${String(value)}`;
25
+ }
26
+ return `${key}=...`;
27
+ });
28
+ const joined = parts.join(', ');
29
+ const output = joined.length > maxLen ? `${joined.slice(0, maxLen)}...` : joined;
30
+ return sanitizeRenderableText(output);
31
+ }
32
+ catch {
33
+ return '';
34
+ }
35
+ }
36
+ export function formatToolStartEvent(event) {
37
+ const suffix = event.summary && event.summary.trim() !== '' ? ` (${event.summary})` : '';
38
+ return sanitizeRenderableText(`[tool ${event.index}/${event.total}] start ${event.name}${suffix}`);
39
+ }
40
+ export function formatToolResultEvent(event) {
41
+ const status = event.isError ? 'error' : 'ok';
42
+ return sanitizeRenderableText(`[tool ${event.index}/${event.total}] ${status} ${event.name} (${event.durationMs}ms)`);
43
+ }
44
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/cli/render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ export type ReplInput = {
2
+ kind: 'exit';
3
+ } | {
4
+ kind: 'help';
5
+ } | {
6
+ kind: 'empty';
7
+ } | {
8
+ kind: 'set_detail';
9
+ mode: 'full' | 'compact';
10
+ } | {
11
+ kind: 'prompt';
12
+ prompt: string;
13
+ };
14
+ export declare function parseReplInput(input: string): ReplInput;
15
+ export interface RunReplSessionOptions {
16
+ readLine: () => Promise<string | null>;
17
+ write: (text: string) => void;
18
+ runTurn: (prompt: string) => Promise<{
19
+ output: string;
20
+ terminal: string;
21
+ }>;
22
+ promptLabel?: string;
23
+ startupMessage?: string | false;
24
+ onPromptSubmitted?: (prompt: string) => Promise<void> | void;
25
+ onTurnResult?: (result: {
26
+ output: string;
27
+ terminal: string;
28
+ }, prompt: string) => Promise<void> | void;
29
+ onSetDetailMode?: (mode: 'full' | 'compact') => Promise<void> | void;
30
+ }
31
+ export declare function runReplSession(options: RunReplSessionOptions): Promise<void>;
32
+ //# sourceMappingURL=repl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repl.d.ts","sourceRoot":"","sources":["../../src/cli/repl.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtC,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAUvD;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACtC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7B,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IAC/B,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC5D,YAAY,CAAC,EAAE,CACb,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAC5C,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACzB,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CACrE;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsClF"}
@@ -0,0 +1,54 @@
1
+ export function parseReplInput(input) {
2
+ const trimmed = input.trim();
3
+ if (trimmed === '')
4
+ return { kind: 'empty' };
5
+ if (trimmed === ':q' || trimmed === ':quit' || trimmed === ':exit')
6
+ return { kind: 'exit' };
7
+ if (trimmed === ':help')
8
+ return { kind: 'help' };
9
+ const detailMatch = trimmed.match(/^:detail\s+(full|compact)$/i);
10
+ if (detailMatch) {
11
+ return { kind: 'set_detail', mode: detailMatch[1].toLowerCase() };
12
+ }
13
+ return { kind: 'prompt', prompt: trimmed };
14
+ }
15
+ export async function runReplSession(options) {
16
+ if (options.startupMessage !== false) {
17
+ options.write(options.startupMessage ?? 'REPL started. Commands: :help, :q, :detail full|compact\n');
18
+ }
19
+ const promptLabel = options.promptLabel ?? 'merlion> ';
20
+ for (;;) {
21
+ options.write(promptLabel);
22
+ const line = await options.readLine();
23
+ if (line === null)
24
+ break;
25
+ const parsed = parseReplInput(line);
26
+ if (parsed.kind === 'exit') {
27
+ options.write('Bye.\n');
28
+ break;
29
+ }
30
+ if (parsed.kind === 'help') {
31
+ options.write('Commands: :help, :q, :detail full|compact\n');
32
+ continue;
33
+ }
34
+ if (parsed.kind === 'set_detail') {
35
+ await options.onSetDetailMode?.(parsed.mode);
36
+ options.write(`[ui] tool detail mode = ${parsed.mode}\n`);
37
+ continue;
38
+ }
39
+ if (parsed.kind === 'empty')
40
+ continue;
41
+ await options.onPromptSubmitted?.(parsed.prompt);
42
+ const result = await options.runTurn(parsed.prompt);
43
+ if (options.onTurnResult) {
44
+ await options.onTurnResult(result, parsed.prompt);
45
+ }
46
+ else {
47
+ options.write(`${result.output}\n`);
48
+ if (result.terminal !== 'completed') {
49
+ options.write(`[terminal: ${result.terminal}]\n`);
50
+ }
51
+ }
52
+ }
53
+ }
54
+ //# sourceMappingURL=repl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repl.js","sourceRoot":"","sources":["../../src/cli/repl.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;IAC5B,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC5C,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;IAC3F,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;IAChD,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAA;IAChE,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAE,CAAC,WAAW,EAAwB,EAAE,CAAA;IAC1F,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAA;AAC5C,CAAC;AAgBD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAA8B;IACjE,IAAI,OAAO,CAAC,cAAc,KAAK,KAAK,EAAE,CAAC;QACrC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,IAAI,2DAA2D,CAAC,CAAA;IACtG,CAAC;IACD,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,WAAW,CAAA;IAEtD,SAAS,CAAC;QACR,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;QAC1B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAA;QACrC,IAAI,IAAI,KAAK,IAAI;YAAE,MAAK;QAExB,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAA;QACnC,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;YACvB,MAAK;QACP,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAA;YAC5D,SAAQ;QACV,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YACjC,MAAM,OAAO,CAAC,eAAe,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;YAC5C,OAAO,CAAC,KAAK,CAAC,2BAA2B,MAAM,CAAC,IAAI,IAAI,CAAC,CAAA;YACzD,SAAQ;QACV,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;YAAE,SAAQ;QAErC,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAChD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QACnD,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACzB,MAAM,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;QACnD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,CAAA;YACnC,IAAI,MAAM,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;gBACpC,OAAO,CAAC,KAAK,CAAC,cAAc,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAA;YACnD,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function sanitizeRenderableText(text: string): string;
2
+ //# sourceMappingURL=sanitize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/cli/sanitize.ts"],"names":[],"mappings":"AAoDA,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAW3D"}
@@ -0,0 +1,66 @@
1
+ const ANSI_RE = /\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g;
2
+ const LONG_TOKEN_RE = /\S{33,}/g;
3
+ const URL_PREFIX_RE = /^(https?:\/\/|file:\/\/)/i;
4
+ const WINDOWS_DRIVE_RE = /^[a-zA-Z]:[\\/]/;
5
+ const FILE_LIKE_RE = /^[a-zA-Z0-9._-]+$/;
6
+ function hasControlChars(text) {
7
+ for (const ch of text) {
8
+ const code = ch.charCodeAt(0);
9
+ const isAsciiControl = code <= 0x1f && code !== 0x09 && code !== 0x0a && code !== 0x0d;
10
+ const isC1Control = code >= 0x7f && code <= 0x9f;
11
+ if (isAsciiControl || isC1Control)
12
+ return true;
13
+ }
14
+ return false;
15
+ }
16
+ function stripControlChars(text) {
17
+ if (!hasControlChars(text))
18
+ return text;
19
+ let out = '';
20
+ for (const ch of text) {
21
+ const code = ch.charCodeAt(0);
22
+ const isAsciiControl = code <= 0x1f && code !== 0x09 && code !== 0x0a && code !== 0x0d;
23
+ const isC1Control = code >= 0x7f && code <= 0x9f;
24
+ if (!isAsciiControl && !isC1Control)
25
+ out += ch;
26
+ }
27
+ return out;
28
+ }
29
+ function isCopySensitiveToken(token) {
30
+ if (URL_PREFIX_RE.test(token))
31
+ return true;
32
+ if (token.startsWith('/') ||
33
+ token.startsWith('~/') ||
34
+ token.startsWith('./') ||
35
+ token.startsWith('../')) {
36
+ return true;
37
+ }
38
+ if (WINDOWS_DRIVE_RE.test(token) || token.startsWith('\\\\'))
39
+ return true;
40
+ if (token.includes('/') || token.includes('\\'))
41
+ return true;
42
+ return token.includes('_') && FILE_LIKE_RE.test(token);
43
+ }
44
+ function chunkToken(token, max = 32) {
45
+ if (token.length <= max || isCopySensitiveToken(token))
46
+ return token;
47
+ const chunks = [];
48
+ for (let i = 0; i < token.length; i += max) {
49
+ chunks.push(token.slice(i, i + max));
50
+ }
51
+ return chunks.join(' ');
52
+ }
53
+ export function sanitizeRenderableText(text) {
54
+ if (!text)
55
+ return text;
56
+ let out = text;
57
+ if (out.includes('\u001b')) {
58
+ out = out.replace(ANSI_RE, '');
59
+ }
60
+ out = stripControlChars(out);
61
+ if (LONG_TOKEN_RE.test(out)) {
62
+ out = out.replace(LONG_TOKEN_RE, (token) => chunkToken(token));
63
+ }
64
+ return out;
65
+ }
66
+ //# sourceMappingURL=sanitize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/cli/sanitize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { UsageSnapshot } from '../runtime/usage.ts';
2
+ export declare function formatCliStatusLine(snapshot: UsageSnapshot, estimatedCost?: number, provider?: string): string;
3
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/cli/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAWxD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,aAAa,EACvB,aAAa,CAAC,EAAE,MAAM,EACtB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAiBR"}
@@ -0,0 +1,27 @@
1
+ function formatInt(n) {
2
+ return new Intl.NumberFormat('en-US').format(Math.max(0, Math.floor(n)));
3
+ }
4
+ function formatPct(numerator, denominator) {
5
+ if (denominator <= 0)
6
+ return '0.0%';
7
+ return `${((numerator / denominator) * 100).toFixed(1)}%`;
8
+ }
9
+ export function formatCliStatusLine(snapshot, estimatedCost, provider) {
10
+ const cachedPct = formatPct(snapshot.totals.cached_tokens, snapshot.totals.prompt_tokens);
11
+ const parts = [
12
+ `turn ${snapshot.turn}`,
13
+ `Δ in ${formatInt(snapshot.delta.prompt_tokens)} out ${formatInt(snapshot.delta.completion_tokens)} cached ${formatInt(snapshot.delta.cached_tokens)}`,
14
+ `Σ in ${formatInt(snapshot.totals.prompt_tokens)} out ${formatInt(snapshot.totals.completion_tokens)} cached ${formatInt(snapshot.totals.cached_tokens)} (${cachedPct} input cached)`,
15
+ ];
16
+ if (snapshot.turn >= 3 && snapshot.totals.cached_tokens === 0) {
17
+ parts.push('no cache hits yet (model/provider may not support caching)');
18
+ }
19
+ if (provider && provider.trim() !== '') {
20
+ parts.push(`provider ${provider}`);
21
+ }
22
+ if (typeof estimatedCost === 'number' && Number.isFinite(estimatedCost) && estimatedCost >= 0) {
23
+ parts.push(`est $${estimatedCost.toFixed(6)}`);
24
+ }
25
+ return `status · ${parts.join(' · ')}`;
26
+ }
27
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/cli/status.ts"],"names":[],"mappings":"AAEA,SAAS,SAAS,CAAC,CAAS;IAC1B,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAC1E,CAAC;AAED,SAAS,SAAS,CAAC,SAAiB,EAAE,WAAmB;IACvD,IAAI,WAAW,IAAI,CAAC;QAAE,OAAO,MAAM,CAAA;IACnC,OAAO,GAAG,CAAC,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAA;AAC3D,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,QAAuB,EACvB,aAAsB,EACtB,QAAiB;IAEjB,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;IACzF,MAAM,KAAK,GAAG;QACZ,QAAQ,QAAQ,CAAC,IAAI,EAAE;QACvB,QAAQ,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,QAAQ,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,iBAAiB,CAAC,WAAW,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;QACtJ,QAAQ,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,iBAAiB,CAAC,WAAW,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,SAAS,gBAAgB;KACtL,CAAA;IACD,IAAI,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,aAAa,KAAK,CAAC,EAAE,CAAC;QAC9D,KAAK,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAA;IAC1E,CAAC;IACD,IAAI,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,YAAY,QAAQ,EAAE,CAAC,CAAA;IACpC,CAAC;IACD,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;QAC9F,KAAK,CAAC,IAAI,CAAC,QAAQ,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAChD,CAAC;IACD,OAAO,YAAY,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAA;AACxC,CAAC"}
@@ -0,0 +1,10 @@
1
+ export interface TuiFrameInput {
2
+ width: number;
3
+ height: number;
4
+ title: string;
5
+ subtitle: string;
6
+ status: string;
7
+ bodyLines: string[];
8
+ }
9
+ export declare function createTuiFrame(input: TuiFrameInput): string;
10
+ //# sourceMappingURL=tui_frame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui_frame.d.ts","sourceRoot":"","sources":["../../src/cli/tui_frame.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,EAAE,CAAA;CACpB;AAmBD,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAyB3D"}
@@ -0,0 +1,44 @@
1
+ function clip(text, maxWidth) {
2
+ if (maxWidth < 1)
3
+ return '';
4
+ if (text.length <= maxWidth)
5
+ return text;
6
+ if (maxWidth === 1)
7
+ return '…';
8
+ return `${text.slice(0, maxWidth - 1)}…`;
9
+ }
10
+ function pad(text, width) {
11
+ if (text.length >= width)
12
+ return text;
13
+ return `${text}${' '.repeat(width - text.length)}`;
14
+ }
15
+ function normalizeDimension(value, min, max) {
16
+ if (!Number.isFinite(value))
17
+ return min;
18
+ return Math.max(min, Math.min(max, Math.floor(value)));
19
+ }
20
+ export function createTuiFrame(input) {
21
+ const width = normalizeDimension(input.width, 70, 240);
22
+ const height = normalizeDimension(input.height, 18, 100);
23
+ const inner = width - 2;
24
+ const contentWidth = inner - 2;
25
+ const bodyHeight = Math.max(4, height - 7);
26
+ const recent = input.bodyLines.slice(-bodyHeight);
27
+ const body = [...recent];
28
+ while (body.length < bodyHeight)
29
+ body.push('');
30
+ const lines = [
31
+ `╔${'═'.repeat(inner)}╗`,
32
+ `║ ${pad(clip(input.title, contentWidth), contentWidth)} ║`,
33
+ `║ ${pad(clip(input.subtitle, contentWidth), contentWidth)} ║`,
34
+ `╠${'═'.repeat(inner)}╣`,
35
+ ];
36
+ for (const line of body) {
37
+ lines.push(`║ ${pad(clip(line, contentWidth), contentWidth)} ║`);
38
+ }
39
+ lines.push(`╠${'═'.repeat(inner)}╣`);
40
+ lines.push(`║ ${pad(clip(input.status, contentWidth), contentWidth)} ║`);
41
+ lines.push(`╚${'═'.repeat(inner)}╝`);
42
+ return lines.join('\n');
43
+ }
44
+ //# sourceMappingURL=tui_frame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui_frame.js","sourceRoot":"","sources":["../../src/cli/tui_frame.ts"],"names":[],"mappings":"AASA,SAAS,IAAI,CAAC,IAAY,EAAE,QAAgB;IAC1C,IAAI,QAAQ,GAAG,CAAC;QAAE,OAAO,EAAE,CAAA;IAC3B,IAAI,IAAI,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO,IAAI,CAAA;IACxC,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,GAAG,CAAA;IAC9B,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAA;AAC1C,CAAC;AAED,SAAS,GAAG,CAAC,IAAY,EAAE,KAAa;IACtC,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK;QAAE,OAAO,IAAI,CAAA;IACrC,OAAO,GAAG,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAA;AACpD,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa,EAAE,GAAW,EAAE,GAAW;IACjE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,GAAG,CAAA;IACvC,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AACxD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAoB;IACjD,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,CAAC,CAAA;IACtD,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,CAAC,CAAA;IACxD,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC,CAAA;IACvB,MAAM,YAAY,GAAG,KAAK,GAAG,CAAC,CAAA;IAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,CAAA;IAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAA;IACjD,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,CAAA;IACxB,OAAO,IAAI,CAAC,MAAM,GAAG,UAAU;QAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAE9C,MAAM,KAAK,GAAa;QACtB,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG;QACxB,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,YAAY,CAAC,EAAE,YAAY,CAAC,IAAI;QAC3D,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,YAAY,CAAC,IAAI;QAC9D,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG;KACzB,CAAA;IAED,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC,CAAA;IAClE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACpC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC,CAAA;IACxE,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACpC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC"}
@@ -0,0 +1,27 @@
1
+ export interface MerlionConfig {
2
+ apiKey?: string;
3
+ model?: string;
4
+ baseURL?: string;
5
+ }
6
+ /** Returns the directory that holds the config file, honoring XDG_CONFIG_HOME. */
7
+ export declare function configDir(): string;
8
+ export declare function configPath(): string;
9
+ /**
10
+ * Reads the saved config file. Returns an empty object when the file does not
11
+ * exist or cannot be parsed.
12
+ */
13
+ export declare function readConfig(): Promise<MerlionConfig>;
14
+ /**
15
+ * Writes the config file, creating the directory if needed.
16
+ * Sets file permissions to 0o600 (owner read/write only) on POSIX.
17
+ */
18
+ export declare function writeConfig(config: MerlionConfig): Promise<void>;
19
+ /**
20
+ * Merges config sources in priority order (highest first):
21
+ * overrides (CLI flags / env vars) > file config > defaults
22
+ *
23
+ * Each field is taken from the highest-priority source that supplies a
24
+ * non-empty string value.
25
+ */
26
+ export declare function mergeConfig(overrides: Partial<MerlionConfig>, fileConfig: MerlionConfig, defaults: Required<MerlionConfig>): Required<MerlionConfig>;
27
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/config/store.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,kFAAkF;AAClF,wBAAgB,SAAS,IAAI,MAAM,CAIlC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED;;;GAGG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC,CAgBzD;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAMtE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,OAAO,CAAC,aAAa,CAAC,EACjC,UAAU,EAAE,aAAa,EACzB,QAAQ,EAAE,QAAQ,CAAC,aAAa,CAAC,GAChC,QAAQ,CAAC,aAAa,CAAC,CAMzB"}
@@ -0,0 +1,73 @@
1
+ import { readFile, writeFile, mkdir } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ /** Returns the directory that holds the config file, honoring XDG_CONFIG_HOME. */
5
+ export function configDir() {
6
+ const xdg = process.env.XDG_CONFIG_HOME;
7
+ const base = xdg && xdg.trim() !== '' ? xdg : join(homedir(), '.config');
8
+ return join(base, 'merlion');
9
+ }
10
+ export function configPath() {
11
+ return join(configDir(), 'config.json');
12
+ }
13
+ /**
14
+ * Reads the saved config file. Returns an empty object when the file does not
15
+ * exist or cannot be parsed.
16
+ */
17
+ export async function readConfig() {
18
+ const file = configPath();
19
+ let raw;
20
+ try {
21
+ raw = await readFile(file, 'utf8');
22
+ }
23
+ catch (err) {
24
+ if (isNodeError(err) && err.code === 'ENOENT')
25
+ return {};
26
+ throw err;
27
+ }
28
+ try {
29
+ const parsed = JSON.parse(raw);
30
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed))
31
+ return {};
32
+ return parsed;
33
+ }
34
+ catch {
35
+ return {};
36
+ }
37
+ }
38
+ /**
39
+ * Writes the config file, creating the directory if needed.
40
+ * Sets file permissions to 0o600 (owner read/write only) on POSIX.
41
+ */
42
+ export async function writeConfig(config) {
43
+ const dir = configDir();
44
+ await mkdir(dir, { recursive: true });
45
+ const file = configPath();
46
+ const json = JSON.stringify(config, null, 2) + '\n';
47
+ await writeFile(file, json, { mode: 0o600, encoding: 'utf8' });
48
+ }
49
+ /**
50
+ * Merges config sources in priority order (highest first):
51
+ * overrides (CLI flags / env vars) > file config > defaults
52
+ *
53
+ * Each field is taken from the highest-priority source that supplies a
54
+ * non-empty string value.
55
+ */
56
+ export function mergeConfig(overrides, fileConfig, defaults) {
57
+ return {
58
+ apiKey: firstNonEmpty(overrides.apiKey, fileConfig.apiKey, defaults.apiKey),
59
+ model: firstNonEmpty(overrides.model, fileConfig.model, defaults.model),
60
+ baseURL: firstNonEmpty(overrides.baseURL, fileConfig.baseURL, defaults.baseURL)
61
+ };
62
+ }
63
+ function firstNonEmpty(...values) {
64
+ for (const v of values) {
65
+ if (typeof v === 'string' && v.trim() !== '')
66
+ return v;
67
+ }
68
+ return '';
69
+ }
70
+ function isNodeError(err) {
71
+ return err instanceof Error && 'code' in err;
72
+ }
73
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/config/store.ts"],"names":[],"mappings":"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"}