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
package/bin/merlion.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import '../dist/index.js'
@@ -0,0 +1,11 @@
1
+ export interface AgentsGuidance {
2
+ text: string;
3
+ files: string[];
4
+ tokensEstimate: number;
5
+ truncated: boolean;
6
+ }
7
+ export interface LoadAgentsGuidanceOptions {
8
+ maxTokens?: number;
9
+ }
10
+ export declare function loadAgentsGuidance(cwd: string, options?: LoadAgentsGuidanceOptions): Promise<AgentsGuidance>;
11
+ //# sourceMappingURL=agents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/artifacts/agents.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAwDD,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,yBAAyB,GAClC,OAAO,CAAC,cAAc,CAAC,CAyBzB"}
@@ -0,0 +1,81 @@
1
+ import { access, readFile } from 'node:fs/promises';
2
+ import { join, relative, resolve, sep } from 'node:path';
3
+ import { constants } from 'node:fs';
4
+ function estimateTokens(text) {
5
+ return Math.ceil(text.length / 4);
6
+ }
7
+ async function fileExists(path) {
8
+ try {
9
+ await access(path, constants.F_OK);
10
+ return true;
11
+ }
12
+ catch {
13
+ return false;
14
+ }
15
+ }
16
+ async function findProjectRoot(startCwd) {
17
+ let cursor = resolve(startCwd);
18
+ for (;;) {
19
+ const gitPath = join(cursor, '.git');
20
+ if (await fileExists(gitPath))
21
+ return cursor;
22
+ const parent = resolve(cursor, '..');
23
+ if (parent === cursor)
24
+ return resolve(startCwd);
25
+ cursor = parent;
26
+ }
27
+ }
28
+ function ancestorsFromRoot(projectRoot, cwd) {
29
+ const root = resolve(projectRoot);
30
+ const target = resolve(cwd);
31
+ if (!target.startsWith(root)) {
32
+ return [root];
33
+ }
34
+ const rel = relative(root, target);
35
+ if (rel === '')
36
+ return [root];
37
+ const segments = rel.split(sep).filter(Boolean);
38
+ const paths = [root];
39
+ let cursor = root;
40
+ for (const segment of segments) {
41
+ cursor = join(cursor, segment);
42
+ paths.push(cursor);
43
+ }
44
+ return paths;
45
+ }
46
+ function truncateByTokenBudget(text, maxTokens) {
47
+ if (maxTokens <= 0)
48
+ return { text: '', truncated: text.length > 0 };
49
+ const maxChars = maxTokens * 4;
50
+ if (text.length <= maxChars)
51
+ return { text, truncated: false };
52
+ return {
53
+ text: `${text.slice(0, Math.max(0, maxChars - 48))}\n\n[...AGENTS guidance truncated by budget...]`,
54
+ truncated: true,
55
+ };
56
+ }
57
+ export async function loadAgentsGuidance(cwd, options) {
58
+ const maxTokens = options?.maxTokens ?? 500;
59
+ const projectRoot = await findProjectRoot(cwd);
60
+ const searchDirs = ancestorsFromRoot(projectRoot, cwd);
61
+ const files = [];
62
+ const blocks = [];
63
+ for (const dir of searchDirs) {
64
+ const path = join(dir, 'AGENTS.md');
65
+ if (!(await fileExists(path)))
66
+ continue;
67
+ const content = await readFile(path, 'utf8');
68
+ files.push(path);
69
+ const rel = relative(projectRoot, path) || 'AGENTS.md';
70
+ blocks.push(`## ${rel}\n${content.trim()}`);
71
+ }
72
+ const merged = blocks.join('\n\n');
73
+ const clipped = truncateByTokenBudget(merged, maxTokens);
74
+ return {
75
+ text: clipped.text,
76
+ files,
77
+ tokensEstimate: estimateTokens(clipped.text),
78
+ truncated: clipped.truncated
79
+ };
80
+ }
81
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/artifacts/agents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export interface CodebaseIndexArtifact {
2
+ path: string;
3
+ content: string;
4
+ }
5
+ export interface ReadCodebaseIndexOptions {
6
+ maxTokens?: number;
7
+ }
8
+ export declare function ensureCodebaseIndex(cwd: string): Promise<CodebaseIndexArtifact>;
9
+ export declare function readCodebaseIndex(cwd: string, options?: ReadCodebaseIndexOptions): Promise<{
10
+ path: string;
11
+ text: string;
12
+ tokensEstimate: number;
13
+ truncated: boolean;
14
+ }>;
15
+ export declare function updateCodebaseIndexWithChangedFiles(cwd: string, changedPaths: string[]): Promise<CodebaseIndexArtifact>;
16
+ //# sourceMappingURL=codebase_index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codebase_index.d.ts","sourceRoot":"","sources":["../../src/artifacts/codebase_index.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAuHD,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAWrF;AAYD,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CASrF;AA8BD,wBAAsB,mCAAmC,CACvD,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,qBAAqB,CAAC,CAkBhC"}
@@ -0,0 +1,193 @@
1
+ import { access, mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promises';
2
+ import { constants } from 'node:fs';
3
+ import { join, relative, resolve } from 'node:path';
4
+ const MAX_FILE_MAP_LINES = 80;
5
+ const MAX_CHANGED_FILES = 50;
6
+ const IGNORE_DIRS = new Set(['.git', 'node_modules', '.merlion', 'dist', 'build', '.next']);
7
+ function estimateTokens(text) {
8
+ return Math.ceil(text.length / 4);
9
+ }
10
+ async function fileExists(path) {
11
+ try {
12
+ await access(path, constants.F_OK);
13
+ return true;
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ }
19
+ async function findProjectRoot(startCwd) {
20
+ let cursor = resolve(startCwd);
21
+ for (;;) {
22
+ if (await fileExists(join(cursor, '.git')))
23
+ return cursor;
24
+ const parent = resolve(cursor, '..');
25
+ if (parent === cursor)
26
+ return resolve(startCwd);
27
+ cursor = parent;
28
+ }
29
+ }
30
+ async function listTopLevel(root) {
31
+ const entries = await readdir(root, { withFileTypes: true });
32
+ const rows = entries
33
+ .filter((entry) => !IGNORE_DIRS.has(entry.name))
34
+ .map((entry) => `${entry.isDirectory() ? '[dir]' : '[file]'} ${entry.name}`)
35
+ .sort();
36
+ return rows;
37
+ }
38
+ async function readScripts(root) {
39
+ const pkgPath = join(root, 'package.json');
40
+ if (!(await fileExists(pkgPath)))
41
+ return [];
42
+ try {
43
+ const text = await readFile(pkgPath, 'utf8');
44
+ const parsed = JSON.parse(text);
45
+ const scripts = parsed.scripts ?? {};
46
+ return Object.keys(scripts)
47
+ .sort()
48
+ .map((name) => `${name}: ${scripts[name]}`);
49
+ }
50
+ catch {
51
+ return [];
52
+ }
53
+ }
54
+ async function walkFiles(root, includeDirs) {
55
+ const result = [];
56
+ async function walk(dir) {
57
+ if (result.length >= MAX_FILE_MAP_LINES)
58
+ return;
59
+ const entries = await readdir(dir, { withFileTypes: true });
60
+ for (const entry of entries) {
61
+ if (result.length >= MAX_FILE_MAP_LINES)
62
+ return;
63
+ if (entry.name.startsWith('.'))
64
+ continue;
65
+ const full = join(dir, entry.name);
66
+ if (entry.isDirectory()) {
67
+ if (IGNORE_DIRS.has(entry.name))
68
+ continue;
69
+ await walk(full);
70
+ continue;
71
+ }
72
+ if (!entry.isFile())
73
+ continue;
74
+ result.push(relative(root, full));
75
+ }
76
+ }
77
+ for (const dir of includeDirs) {
78
+ const full = join(root, dir);
79
+ if (!(await fileExists(full)))
80
+ continue;
81
+ const st = await stat(full);
82
+ if (!st.isDirectory())
83
+ continue;
84
+ await walk(full);
85
+ }
86
+ return result.sort();
87
+ }
88
+ function renderIndex(params) {
89
+ const lines = [];
90
+ lines.push('# Codebase Index');
91
+ lines.push('');
92
+ lines.push(`Generated at: ${new Date().toISOString()}`);
93
+ lines.push('');
94
+ lines.push('## Top-level');
95
+ lines.push(...(params.topLevel.length > 0 ? params.topLevel.map((x) => `- ${x}`) : ['- (empty)']));
96
+ lines.push('');
97
+ lines.push('## Dev Scripts');
98
+ lines.push(...(params.scripts.length > 0 ? params.scripts.map((x) => `- ${x}`) : ['- (none)']));
99
+ lines.push('');
100
+ lines.push('## File Map (sample)');
101
+ lines.push(...(params.fileMap.length > 0 ? params.fileMap.map((x) => `- ${x}`) : ['- (none)']));
102
+ lines.push('');
103
+ if (params.changedFiles && params.changedFiles.length > 0) {
104
+ lines.push('## Recent Changed Files');
105
+ lines.push(...params.changedFiles.map((x) => `- changed: ${x}`));
106
+ lines.push('');
107
+ }
108
+ return lines.join('\n');
109
+ }
110
+ async function resolveIndexPath(cwd) {
111
+ const root = await findProjectRoot(cwd);
112
+ return { root, path: join(root, 'docs', 'codebase_index.md') };
113
+ }
114
+ export async function ensureCodebaseIndex(cwd) {
115
+ const { root, path } = await resolveIndexPath(cwd);
116
+ if (!(await fileExists(path))) {
117
+ await mkdir(join(path, '..'), { recursive: true });
118
+ const topLevel = await listTopLevel(root);
119
+ const scripts = await readScripts(root);
120
+ const fileMap = await walkFiles(root, ['src', 'tests', 'docs']);
121
+ await writeFile(path, renderIndex({ topLevel, scripts, fileMap }), 'utf8');
122
+ }
123
+ const content = await readFile(path, 'utf8');
124
+ return { path, content };
125
+ }
126
+ function truncate(text, maxTokens) {
127
+ if (maxTokens <= 0)
128
+ return { text: '', truncated: text.length > 0 };
129
+ const maxChars = maxTokens * 4;
130
+ if (text.length <= maxChars)
131
+ return { text, truncated: false };
132
+ return {
133
+ text: `${text.slice(0, Math.max(0, maxChars - 44))}\n\n[...codebase_index truncated...]`,
134
+ truncated: true,
135
+ };
136
+ }
137
+ export async function readCodebaseIndex(cwd, options) {
138
+ const artifact = await ensureCodebaseIndex(cwd);
139
+ const clipped = truncate(artifact.content, options?.maxTokens ?? 400);
140
+ return {
141
+ path: artifact.path,
142
+ text: clipped.text,
143
+ tokensEstimate: estimateTokens(clipped.text),
144
+ truncated: clipped.truncated,
145
+ };
146
+ }
147
+ function parseChangedFiles(content) {
148
+ const marker = '## Recent Changed Files';
149
+ const start = content.indexOf(marker);
150
+ if (start === -1)
151
+ return [];
152
+ const afterStart = content.slice(start + marker.length);
153
+ const nextHeadingPos = afterStart.indexOf('\n## ');
154
+ const block = (nextHeadingPos === -1 ? afterStart : afterStart.slice(0, nextHeadingPos)).trim();
155
+ return block
156
+ .split('\n')
157
+ .map((line) => line.trim())
158
+ .filter((line) => line.startsWith('- changed: '))
159
+ .map((line) => line.slice('- changed: '.length).trim())
160
+ .filter(Boolean);
161
+ }
162
+ function replaceOrAppendChangedSection(content, changedFiles) {
163
+ const marker = '## Recent Changed Files';
164
+ const section = [marker, ...changedFiles.map((x) => `- changed: ${x}`), ''].join('\n');
165
+ const start = content.indexOf(marker);
166
+ if (start === -1) {
167
+ return `${content.trimEnd()}\n\n${section}`;
168
+ }
169
+ const afterStart = content.slice(start + marker.length);
170
+ const nextHeadingPos = afterStart.indexOf('\n## ');
171
+ const end = nextHeadingPos === -1 ? content.length : start + marker.length + nextHeadingPos + 1;
172
+ return `${content.slice(0, start)}${section}${content.slice(end)}`;
173
+ }
174
+ export async function updateCodebaseIndexWithChangedFiles(cwd, changedPaths) {
175
+ const artifact = await ensureCodebaseIndex(cwd);
176
+ const { root, path } = await resolveIndexPath(cwd);
177
+ const existing = parseChangedFiles(artifact.content);
178
+ const normalized = changedPaths
179
+ .map((p) => relative(root, resolve(cwd, p)))
180
+ .map((p) => p.replace(/\\/g, '/'))
181
+ .filter((p) => !p.startsWith('..') && p !== '');
182
+ const merged = [];
183
+ for (const item of [...normalized, ...existing]) {
184
+ if (!merged.includes(item))
185
+ merged.push(item);
186
+ if (merged.length >= MAX_CHANGED_FILES)
187
+ break;
188
+ }
189
+ const updated = replaceOrAppendChangedSection(artifact.content, merged);
190
+ await writeFile(path, updated, 'utf8');
191
+ return { path, content: updated };
192
+ }
193
+ //# sourceMappingURL=codebase_index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codebase_index.js","sourceRoot":"","sources":["../../src/artifacts/codebase_index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export interface ProgressArtifact {
2
+ path: string;
3
+ content: string;
4
+ }
5
+ export interface ProgressUpdatePatch {
6
+ objective?: string;
7
+ done?: string[];
8
+ next?: string[];
9
+ blockers?: string[];
10
+ decisions?: string[];
11
+ }
12
+ export interface ReadProgressOptions {
13
+ maxTokens?: number;
14
+ }
15
+ export declare function ensureProgressArtifact(cwd: string, initialObjective?: string): Promise<ProgressArtifact>;
16
+ export declare function readProgressArtifact(cwd: string, options?: ReadProgressOptions): Promise<{
17
+ path: string;
18
+ text: string;
19
+ tokensEstimate: number;
20
+ truncated: boolean;
21
+ }>;
22
+ export declare function updateProgressArtifact(cwd: string, patch: ProgressUpdatePatch): Promise<ProgressArtifact>;
23
+ //# sourceMappingURL=progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/artifacts/progress.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAsGD,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,MAAM,EACX,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,gBAAgB,CAAC,CAQ3B;AAED,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CASrF;AAED,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,gBAAgB,CAAC,CA8B3B"}
@@ -0,0 +1,152 @@
1
+ import { access, mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { constants } from 'node:fs';
3
+ import { join, resolve } from 'node:path';
4
+ function estimateTokens(text) {
5
+ return Math.ceil(text.length / 4);
6
+ }
7
+ async function fileExists(path) {
8
+ try {
9
+ await access(path, constants.F_OK);
10
+ return true;
11
+ }
12
+ catch {
13
+ return false;
14
+ }
15
+ }
16
+ async function findProjectRoot(startCwd) {
17
+ let cursor = resolve(startCwd);
18
+ for (;;) {
19
+ if (await fileExists(join(cursor, '.git')))
20
+ return cursor;
21
+ const parent = resolve(cursor, '..');
22
+ if (parent === cursor)
23
+ return resolve(startCwd);
24
+ cursor = parent;
25
+ }
26
+ }
27
+ function sectionLines(items) {
28
+ const cleaned = (items ?? []).map((item) => item.trim()).filter((item) => item !== '');
29
+ if (cleaned.length === 0)
30
+ return ['- (none)'];
31
+ return cleaned.map((item) => `- ${item}`);
32
+ }
33
+ function renderTemplate(objective) {
34
+ return [
35
+ '# Merlion Progress',
36
+ '',
37
+ '## Objective',
38
+ objective && objective.trim() !== '' ? objective.trim() : '(not set)',
39
+ '',
40
+ '## Done',
41
+ ...sectionLines(),
42
+ '',
43
+ '## Next',
44
+ ...sectionLines(),
45
+ '',
46
+ '## Blockers',
47
+ ...sectionLines(),
48
+ '',
49
+ '## Decisions',
50
+ ...sectionLines(),
51
+ '',
52
+ ].join('\n');
53
+ }
54
+ function extractSection(content, heading) {
55
+ const marker = `## ${heading}`;
56
+ const start = content.indexOf(marker);
57
+ if (start === -1)
58
+ return [];
59
+ const afterStart = content.slice(start + marker.length);
60
+ const nextHeadingPos = afterStart.indexOf('\n## ');
61
+ const block = nextHeadingPos === -1 ? afterStart : afterStart.slice(0, nextHeadingPos);
62
+ return block
63
+ .split('\n')
64
+ .map((line) => line.trim())
65
+ .filter((line) => line.startsWith('- '))
66
+ .map((line) => line.slice(2).trim())
67
+ .filter((line) => line !== '' && line !== '(none)');
68
+ }
69
+ function extractObjective(content) {
70
+ const marker = '## Objective';
71
+ const start = content.indexOf(marker);
72
+ if (start === -1)
73
+ return '(not set)';
74
+ const afterStart = content.slice(start + marker.length);
75
+ const nextHeadingPos = afterStart.indexOf('\n## ');
76
+ const block = (nextHeadingPos === -1 ? afterStart : afterStart.slice(0, nextHeadingPos)).trim();
77
+ return block === '' ? '(not set)' : block;
78
+ }
79
+ function mergeSection(existing, incoming) {
80
+ if (!incoming || incoming.length === 0)
81
+ return existing;
82
+ const merged = [...existing];
83
+ for (const item of incoming.map((s) => s.trim()).filter(Boolean)) {
84
+ if (!merged.includes(item))
85
+ merged.push(item);
86
+ }
87
+ return merged;
88
+ }
89
+ function truncate(text, maxTokens) {
90
+ if (maxTokens <= 0)
91
+ return { text: '', truncated: text.length > 0 };
92
+ const maxChars = maxTokens * 4;
93
+ if (text.length <= maxChars)
94
+ return { text, truncated: false };
95
+ return {
96
+ text: `${text.slice(0, Math.max(0, maxChars - 44))}\n\n[...progress truncated...]`,
97
+ truncated: true,
98
+ };
99
+ }
100
+ async function resolveProgressPath(cwd) {
101
+ const root = await findProjectRoot(cwd);
102
+ return join(root, '.merlion', 'progress.md');
103
+ }
104
+ export async function ensureProgressArtifact(cwd, initialObjective) {
105
+ const path = await resolveProgressPath(cwd);
106
+ await mkdir(join(path, '..'), { recursive: true });
107
+ if (!(await fileExists(path))) {
108
+ await writeFile(path, renderTemplate(initialObjective), 'utf8');
109
+ }
110
+ const content = await readFile(path, 'utf8');
111
+ return { path, content };
112
+ }
113
+ export async function readProgressArtifact(cwd, options) {
114
+ const { path, content } = await ensureProgressArtifact(cwd);
115
+ const clipped = truncate(content, options?.maxTokens ?? 300);
116
+ return {
117
+ path,
118
+ text: clipped.text,
119
+ tokensEstimate: estimateTokens(clipped.text),
120
+ truncated: clipped.truncated,
121
+ };
122
+ }
123
+ export async function updateProgressArtifact(cwd, patch) {
124
+ const { path, content } = await ensureProgressArtifact(cwd);
125
+ const objective = patch.objective?.trim() || extractObjective(content);
126
+ const done = mergeSection(extractSection(content, 'Done'), patch.done);
127
+ const next = mergeSection(extractSection(content, 'Next'), patch.next);
128
+ const blockers = mergeSection(extractSection(content, 'Blockers'), patch.blockers);
129
+ const decisions = mergeSection(extractSection(content, 'Decisions'), patch.decisions);
130
+ const updated = [
131
+ '# Merlion Progress',
132
+ '',
133
+ '## Objective',
134
+ objective || '(not set)',
135
+ '',
136
+ '## Done',
137
+ ...sectionLines(done),
138
+ '',
139
+ '## Next',
140
+ ...sectionLines(next),
141
+ '',
142
+ '## Blockers',
143
+ ...sectionLines(blockers),
144
+ '',
145
+ '## Decisions',
146
+ ...sectionLines(decisions),
147
+ '',
148
+ ].join('\n');
149
+ await writeFile(path, updated, 'utf8');
150
+ return { path, content: updated };
151
+ }
152
+ //# sourceMappingURL=progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/artifacts/progress.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { EditDiffUiPayload } from '../tools/types.js';
2
+ export interface RenderedDiffLine {
3
+ tone: 'meta' | 'context' | 'add' | 'remove';
4
+ text: string;
5
+ }
6
+ export declare function renderEditDiffLines(payload: EditDiffUiPayload, options?: {
7
+ maxLines?: number;
8
+ maxCharsPerLine?: number;
9
+ }): RenderedDiffLine[];
10
+ export declare function summarizeEditDiff(payload: EditDiffUiPayload): RenderedDiffLine[];
11
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/cli/diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAG1D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,CAAA;IAC3C,IAAI,EAAE,MAAM,CAAA;CACb;AASD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,GACxD,gBAAgB,EAAE,CAmCpB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,EAAE,CAYhF"}
@@ -0,0 +1,58 @@
1
+ import { sanitizeRenderableText } from "./sanitize.js";
2
+ function clip(text, maxChars) {
3
+ if (maxChars < 1)
4
+ return '';
5
+ if (text.length <= maxChars)
6
+ return text;
7
+ if (maxChars === 1)
8
+ return '…';
9
+ return `${text.slice(0, maxChars - 1)}…`;
10
+ }
11
+ export function renderEditDiffLines(payload, options) {
12
+ const maxLines = Math.max(8, options?.maxLines ?? 120);
13
+ const maxCharsPerLine = Math.max(20, options?.maxCharsPerLine ?? 240);
14
+ const lines = [
15
+ {
16
+ tone: 'meta',
17
+ text: `diff ${sanitizeRenderableText(payload.path)} (+${payload.addedLines} -${payload.removedLines})`
18
+ }
19
+ ];
20
+ for (const hunk of payload.hunks) {
21
+ lines.push({
22
+ tone: 'meta',
23
+ text: `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`
24
+ });
25
+ for (const line of hunk.lines) {
26
+ const prefix = line.type === 'add' ? '+' : line.type === 'remove' ? '-' : ' ';
27
+ lines.push({
28
+ tone: line.type,
29
+ text: `${prefix}${sanitizeRenderableText(line.text)}`
30
+ });
31
+ }
32
+ }
33
+ const clipped = lines.map((line) => ({
34
+ tone: line.tone,
35
+ text: clip(line.text, maxCharsPerLine)
36
+ }));
37
+ if (clipped.length <= maxLines)
38
+ return clipped;
39
+ const keep = Math.max(2, maxLines - 1);
40
+ return [
41
+ ...clipped.slice(0, keep),
42
+ { tone: 'meta', text: `... diff truncated (${clipped.length - keep} line(s) hidden)` }
43
+ ];
44
+ }
45
+ export function summarizeEditDiff(payload) {
46
+ const totalChanged = payload.addedLines + payload.removedLines;
47
+ return [
48
+ {
49
+ tone: 'meta',
50
+ text: `diff ${sanitizeRenderableText(payload.path)} (+${payload.addedLines} -${payload.removedLines})`
51
+ },
52
+ {
53
+ tone: 'meta',
54
+ text: `${payload.hunks.length} hunk(s), ${totalChanged} changed line(s)`
55
+ }
56
+ ];
57
+ }
58
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/cli/diff.ts"],"names":[],"mappings":"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"}