@tarunspandit/codexflow 0.29.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 (92) hide show
  1. package/AGENTS.example.md +18 -0
  2. package/CHANGELOG.md +311 -0
  3. package/CHATGPT_PROMPT.md +12 -0
  4. package/CODEX_PROMPT.md +12 -0
  5. package/CONTRIBUTING.md +51 -0
  6. package/DOMAIN_SETUP.md +241 -0
  7. package/FAQ.md +327 -0
  8. package/FAQ_ZH.md +279 -0
  9. package/LICENSE +21 -0
  10. package/NOTICE +9 -0
  11. package/PUBLIC_LAUNCH_CHECKLIST.md +111 -0
  12. package/README.md +287 -0
  13. package/README_ZH.md +461 -0
  14. package/SECURITY.md +145 -0
  15. package/config.example.env +31 -0
  16. package/dist/analysis/cache.js +27 -0
  17. package/dist/analysis/cache.js.map +1 -0
  18. package/dist/analysis/classify.js +102 -0
  19. package/dist/analysis/classify.js.map +1 -0
  20. package/dist/analysis/extract.js +139 -0
  21. package/dist/analysis/extract.js.map +1 -0
  22. package/dist/analysis/graph.js +22 -0
  23. package/dist/analysis/graph.js.map +1 -0
  24. package/dist/analysis/impact.js +167 -0
  25. package/dist/analysis/impact.js.map +1 -0
  26. package/dist/analysis/index.js +215 -0
  27. package/dist/analysis/index.js.map +1 -0
  28. package/dist/analysis/inventory.js +51 -0
  29. package/dist/analysis/inventory.js.map +1 -0
  30. package/dist/analysis/providers.js +24 -0
  31. package/dist/analysis/providers.js.map +1 -0
  32. package/dist/analysis/rank.js +27 -0
  33. package/dist/analysis/rank.js.map +1 -0
  34. package/dist/analysis/types.js +8 -0
  35. package/dist/analysis/types.js.map +1 -0
  36. package/dist/bashOps.js +233 -0
  37. package/dist/bashOps.js.map +1 -0
  38. package/dist/capabilitiesOps.js +365 -0
  39. package/dist/capabilitiesOps.js.map +1 -0
  40. package/dist/codexSessions.js +379 -0
  41. package/dist/codexSessions.js.map +1 -0
  42. package/dist/config.js +289 -0
  43. package/dist/config.js.map +1 -0
  44. package/dist/fsOps.js +286 -0
  45. package/dist/fsOps.js.map +1 -0
  46. package/dist/gitOps.js +79 -0
  47. package/dist/gitOps.js.map +1 -0
  48. package/dist/guard.js +198 -0
  49. package/dist/guard.js.map +1 -0
  50. package/dist/http.js +1671 -0
  51. package/dist/http.js.map +1 -0
  52. package/dist/proContext.js +274 -0
  53. package/dist/proContext.js.map +1 -0
  54. package/dist/profileStore.js +89 -0
  55. package/dist/profileStore.js.map +1 -0
  56. package/dist/projectCatalog.js +134 -0
  57. package/dist/projectCatalog.js.map +1 -0
  58. package/dist/redact.js +73 -0
  59. package/dist/redact.js.map +1 -0
  60. package/dist/searchOps.js +186 -0
  61. package/dist/searchOps.js.map +1 -0
  62. package/dist/server.js +2502 -0
  63. package/dist/server.js.map +1 -0
  64. package/dist/stdio.js +36 -0
  65. package/dist/stdio.js.map +1 -0
  66. package/dist/toolCardWidget.js +1155 -0
  67. package/dist/toolCardWidget.js.map +1 -0
  68. package/dist/workspaceOps.js +229 -0
  69. package/dist/workspaceOps.js.map +1 -0
  70. package/docs/.nojekyll +1 -0
  71. package/docs/favicon.svg +5 -0
  72. package/docs/index.html +638 -0
  73. package/docs/og.png +0 -0
  74. package/docs/script.js +80 -0
  75. package/docs/star.svg +11 -0
  76. package/docs/styles.css +1229 -0
  77. package/docs/zh.html +436 -0
  78. package/package.json +94 -0
  79. package/scripts/analysis-cli-smoke.mjs +81 -0
  80. package/scripts/analysis-smoke.mjs +179 -0
  81. package/scripts/clean.mjs +6 -0
  82. package/scripts/cli-smoke.mjs +168 -0
  83. package/scripts/codexflow.mjs +4375 -0
  84. package/scripts/doctor-smoke.mjs +90 -0
  85. package/scripts/execute-handoff-smoke.mjs +1110 -0
  86. package/scripts/http-smoke.mjs +812 -0
  87. package/scripts/pro-apply.mjs +141 -0
  88. package/scripts/pro-bundle.mjs +121 -0
  89. package/scripts/pro-smoke.mjs +95 -0
  90. package/scripts/settings-smoke.mjs +756 -0
  91. package/scripts/smoke.mjs +1194 -0
  92. package/scripts/stress.mjs +835 -0
@@ -0,0 +1,835 @@
1
+ import { spawn, spawnSync } from 'node:child_process';
2
+ import fs from 'node:fs/promises';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+
6
+ function assert(ok, message) {
7
+ if (!ok) throw new Error(message);
8
+ }
9
+
10
+ async function pathExists(file) {
11
+ try {
12
+ await fs.access(file);
13
+ return true;
14
+ } catch {
15
+ return false;
16
+ }
17
+ }
18
+
19
+ class McpStdioClient {
20
+ constructor(root, env = {}) {
21
+ this.child = spawn(process.execPath, ['dist/stdio.js'], {
22
+ cwd: path.resolve('.'),
23
+ env: {
24
+ ...process.env,
25
+ ...env,
26
+ CODEXFLOW_ROOT: root,
27
+ CODEXFLOW_ALLOWED_ROOTS: root,
28
+ CODEXFLOW_TOOL_MODE: env.CODEXFLOW_TOOL_MODE ?? 'full',
29
+ CODEXFLOW_BASH_MODE: env.CODEXFLOW_BASH_MODE ?? 'safe',
30
+ CODEXFLOW_MAX_SEARCH_RESULTS: '2000',
31
+ CODEXFLOW_MAX_OUTPUT_BYTES: '2000000',
32
+ CODEXFLOW_TOOL_CARDS: env.CODEXFLOW_TOOL_CARDS ?? '0'
33
+ }
34
+ });
35
+ this.buffer = '';
36
+ this.stderr = '';
37
+ this.nextId = 1;
38
+ this.pending = new Map();
39
+ this.child.stdout.on('data', (chunk) => this.onData(String(chunk)));
40
+ this.child.stderr.on('data', (chunk) => {
41
+ this.stderr += String(chunk);
42
+ });
43
+ this.child.on('exit', (code) => {
44
+ for (const { reject } of this.pending.values()) reject(new Error(`server exited ${code}\n${this.stderr}`));
45
+ this.pending.clear();
46
+ });
47
+ }
48
+
49
+ onData(chunk) {
50
+ this.buffer += chunk;
51
+ while (true) {
52
+ const index = this.buffer.indexOf('\n');
53
+ if (index < 0) return;
54
+ const line = this.buffer.slice(0, index).replace(/\r$/, '');
55
+ this.buffer = this.buffer.slice(index + 1);
56
+ if (!line.trim()) continue;
57
+ const msg = JSON.parse(line);
58
+ if (!msg.id || !this.pending.has(msg.id)) continue;
59
+ const { resolve, reject, timer } = this.pending.get(msg.id);
60
+ clearTimeout(timer);
61
+ this.pending.delete(msg.id);
62
+ if (msg.error) reject(new Error(msg.error.message));
63
+ else resolve(msg.result);
64
+ }
65
+ }
66
+
67
+ request(method, params) {
68
+ const id = this.nextId++;
69
+ this.child.stdin.write(`${JSON.stringify({ jsonrpc: '2.0', id, method, params })}\n`);
70
+ return new Promise((resolve, reject) => {
71
+ const timer = setTimeout(() => reject(new Error(`timeout waiting for ${method}\n${this.stderr}`)), 20000);
72
+ timer.unref();
73
+ this.pending.set(id, { resolve, reject, timer });
74
+ });
75
+ }
76
+
77
+ notify(method, params = {}) {
78
+ this.child.stdin.write(`${JSON.stringify({ jsonrpc: '2.0', method, params })}\n`);
79
+ }
80
+
81
+ close() {
82
+ this.child.kill('SIGTERM');
83
+ }
84
+ }
85
+
86
+ async function initClient(root, env) {
87
+ const client = new McpStdioClient(root, env);
88
+ await client.request('initialize', {
89
+ protocolVersion: '2024-11-05',
90
+ capabilities: {},
91
+ clientInfo: { name: 'codexflow-stress', version: '0.1.0' }
92
+ });
93
+ client.notify('notifications/initialized');
94
+ return client;
95
+ }
96
+
97
+ async function expectToolError(client, name, args, pattern) {
98
+ const result = await client.request('tools/call', { name, arguments: args });
99
+ assert(result.isError === true, `${name} unexpectedly succeeded`);
100
+ const text = JSON.stringify(result);
101
+ if (pattern) assert(pattern.test(text), `${name} error did not match ${pattern}: ${text}`);
102
+ return result;
103
+ }
104
+
105
+ async function makeFixture() {
106
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'codexflow-stress-'));
107
+ await fs.writeFile(path.join(root, 'AGENTS.md'), '# Stress Agents\n\nKeep checks local.\n', 'utf8');
108
+ await fs.writeFile(path.join(root, 'demo.txt'), 'alpha\n--flag root\narrow -> value\n', 'utf8');
109
+ await fs.writeFile(path.join(root, '.hidden.txt'), 'needle hidden\n', 'utf8');
110
+ await fs.writeFile(path.join(root, 'visible:123:file.txt'), 'needle colon path\n', 'utf8');
111
+ await fs.mkdir(path.join(root, '.github', 'workflows'), { recursive: true });
112
+ await fs.writeFile(path.join(root, '.github', 'workflows', 'ci.yml'), 'name: ci\n', 'utf8');
113
+ await fs.mkdir(path.join(root, 'many'), { recursive: true });
114
+ for (let file = 0; file < 50; file += 1) {
115
+ const lines = Array.from({ length: 60 }, (_, line) => `file ${file} line ${line} --flag -> stress-needle-${line % 11}`);
116
+ await fs.writeFile(path.join(root, 'many', `hits-${file}.txt`), `${lines.join('\n')}\n`, 'utf8');
117
+ }
118
+ for (let i = 0; i < 140; i += 1) {
119
+ const name = `stress-skill-${String(i).padStart(3, '0')}`;
120
+ const dir = path.join(root, '.codex', 'skills', name);
121
+ await fs.mkdir(dir, { recursive: true });
122
+ await fs.writeFile(path.join(dir, 'SKILL.md'), `---\nname: ${name}\ndescription: Stress skill ${i}.\n---\n\n# Stress Skill ${i}\n`, 'utf8');
123
+ }
124
+ await fs.mkdir(path.join(root, '.ai-bridge'), { recursive: true });
125
+ await fs.writeFile(path.join(root, '.ai-bridge', 'agent-status.md'), '# Agent Status\n\nPASS stress handoff.\n', 'utf8');
126
+ await fs.writeFile(path.join(root, '.ai-bridge', 'implementation-diff.patch'), 'diff --git a/demo.txt b/demo.txt\n', 'utf8');
127
+ await fs.writeFile(path.join(root, '.ai-bridge', 'execution-log.jsonl'), `${JSON.stringify({ ts: new Date().toISOString(), event: 'stress' })}\n`, 'utf8');
128
+ return root;
129
+ }
130
+
131
+ async function runFullModeStress(root) {
132
+ const client = await initClient(root);
133
+ try {
134
+ const tools = await client.request('tools/list', {});
135
+ const names = tools.tools.map((tool) => tool.name);
136
+ for (const name of ['codexflow', 'codexflow_inventory', 'open_current_workspace', 'search', 'load_skill', 'wait_for_handoff', 'export_pro_context', 'bash']) {
137
+ assert(names.includes(name), `full mode missing ${name}`);
138
+ }
139
+
140
+ const config = await client.request('tools/call', { name: 'server_config', arguments: {} });
141
+ assert(config.structuredContent.toolMode === 'full', `expected full tool mode, got ${config.structuredContent.toolMode}`);
142
+ assert(config.structuredContent.registeredTools.includes('codexflow'), 'server_config missing codexflow supertool');
143
+
144
+ const superActions = await client.request('tools/call', {
145
+ name: 'codexflow',
146
+ arguments: { action: 'list_actions' }
147
+ });
148
+ assert(superActions.structuredContent.actions.includes('search'), 'supertool actions missing search');
149
+ assert(superActions.structuredContent.actions.includes('export_pro_context'), 'supertool actions missing export_pro_context');
150
+
151
+ const opened = await client.request('tools/call', { name: 'open_current_workspace', arguments: { include_tree: false } });
152
+ assert(opened.structuredContent.skill_inventory.length === 0, 'default workspace open loaded skills');
153
+ const ws = opened.structuredContent.workspace_id;
154
+
155
+ const superOpened = await client.request('tools/call', {
156
+ name: 'codexflow',
157
+ arguments: { action: 'open', args: { include_tree: false } }
158
+ });
159
+ assert(superOpened.structuredContent.wrapped_tool === 'open_current_workspace', 'supertool open alias did not wrap open_current_workspace');
160
+ assert(superOpened.structuredContent.skill_inventory.length === 0, 'supertool default workspace open loaded skills');
161
+
162
+ const withSkills = await client.request('tools/call', {
163
+ name: 'open_current_workspace',
164
+ arguments: { include_tree: false, include_skills: true, include_global_skills: false }
165
+ });
166
+ assert(withSkills.structuredContent.skill_inventory.length === 120, `expected capped 120 skills, got ${withSkills.structuredContent.skill_inventory.length}`);
167
+
168
+ const firstSkill = withSkills.structuredContent.skill_inventory[0];
169
+ const loaded = await client.request('tools/call', {
170
+ name: 'load_skill',
171
+ arguments: { workspace_id: ws, name: firstSkill.name, source: firstSkill.source, path: firstSkill.path }
172
+ });
173
+ assert(loaded.structuredContent.text.includes('# Stress Skill'), 'load_skill did not return skill body');
174
+
175
+ const inventory = await client.request('tools/call', {
176
+ name: 'codexflow_inventory',
177
+ arguments: { workspace_id: ws, include_global_skills: false, include_mcp_servers: false, max_skills: 140 }
178
+ });
179
+ assert(inventory.structuredContent.skill_count === 140, `expected 140 inventory skills, got ${inventory.structuredContent.skill_count}`);
180
+ const lastSkill = inventory.structuredContent.skills.find((skill) => skill.name === 'stress-skill-139');
181
+ assert(lastSkill, 'inventory did not include stress-skill-139');
182
+ const loadedLast = await client.request('tools/call', {
183
+ name: 'load_skill',
184
+ arguments: { workspace_id: ws, name: lastSkill.name, source: lastSkill.source, path: lastSkill.path }
185
+ });
186
+ assert(loadedLast.structuredContent.text.includes('# Stress Skill 139'), 'load_skill did not load high-cap inventory skill');
187
+
188
+ const largeSearch = await client.request('tools/call', {
189
+ name: 'search',
190
+ arguments: { workspace_id: ws, query: '--flag', path: 'many', max_results: 2000 }
191
+ });
192
+ assert(largeSearch.structuredContent.matches.length === 2000, `expected 2000 search matches, got ${largeSearch.structuredContent.matches.length}`);
193
+ assert(largeSearch.structuredContent.truncated === true, 'large search did not report truncation');
194
+ assert(!('text' in largeSearch.structuredContent), 'search duplicated text in structuredContent with cards off');
195
+
196
+ if (spawnSync(process.platform === 'win32' ? 'where' : 'sh', process.platform === 'win32' ? ['rg'] : ['-lc', 'command -v rg >/dev/null 2>&1']).status === 0) {
197
+ const rgRegex = await client.request('tools/call', {
198
+ name: 'search',
199
+ arguments: { workspace_id: ws, query: '(?i)STRESS-NEEDLE-3', path: 'many', regex: true, max_results: 10 }
200
+ });
201
+ assert(rgRegex.structuredContent.used === 'ripgrep' && rgRegex.structuredContent.matches.length === 10, 'ripgrep regex search rejected rg syntax');
202
+ }
203
+
204
+ const hiddenSearch = await client.request('tools/call', {
205
+ name: 'search',
206
+ arguments: { workspace_id: ws, query: 'needle hidden', include_hidden: true, max_results: 10 }
207
+ });
208
+ assert(hiddenSearch.structuredContent.matches.some((match) => match.path === '.hidden.txt'), 'include_hidden search missed hidden file');
209
+
210
+ const colonSearch = await client.request('tools/call', {
211
+ name: 'search',
212
+ arguments: { workspace_id: ws, query: 'needle colon path', max_results: 10 }
213
+ });
214
+ assert(colonSearch.structuredContent.matches.some((match) => match.path === 'visible:123:file.txt' && match.line === 1), `colon path search parsed incorrectly: ${JSON.stringify(colonSearch.structuredContent.matches)}`);
215
+
216
+ const superRead = await client.request('tools/call', {
217
+ name: 'codexflow',
218
+ arguments: { action: 'read', args: { workspace_id: ws, path: 'demo.txt', start_line: 1, end_line: 3 } }
219
+ });
220
+ assert(superRead.structuredContent.codexflow_tool === 'read' && superRead.structuredContent.wrapped_tool === 'read' && superRead.structuredContent.text.includes('--flag root'), 'supertool read failed');
221
+
222
+ const superSearch = await client.request('tools/call', {
223
+ name: 'codexflow',
224
+ arguments: { action: 'search', args: { workspace_id: ws, query: 'stress-needle-3', path: 'many', max_results: 20 } }
225
+ });
226
+ assert(superSearch.structuredContent.codexflow_tool === 'search' && superSearch.structuredContent.wrapped_tool === 'search', 'supertool search did not report wrapped tool');
227
+ assert(superSearch.structuredContent.matches.length === 20, `supertool search returned ${superSearch.structuredContent.matches.length} matches`);
228
+
229
+ const safePwd = await client.request('tools/call', {
230
+ name: 'bash',
231
+ arguments: { workspace_id: ws, command: 'pwd' }
232
+ });
233
+ assert(safePwd.isError !== true && safePwd.structuredContent.exitCode === 0, 'safe bash rejected allowed pwd command');
234
+
235
+ const newlineDirectTarget = path.join(root, 'newline-direct-owned');
236
+ const blockedNewline = await client.request('tools/call', {
237
+ name: 'bash',
238
+ arguments: { workspace_id: ws, command: 'pwd\ntouch newline-direct-owned' }
239
+ });
240
+ assert(blockedNewline.isError === true && String(blockedNewline.structuredContent.error).includes('blocked'), 'safe bash allowed newline command chaining');
241
+ assert(!(await pathExists(newlineDirectTarget)), 'safe bash newline command created a file');
242
+
243
+ const newlineSuperTarget = path.join(root, 'newline-supertool-owned');
244
+ const blockedSuperNewline = await client.request('tools/call', {
245
+ name: 'codexflow',
246
+ arguments: { action: 'bash', args: { workspace_id: ws, command: 'pwd\ntouch newline-supertool-owned' } }
247
+ });
248
+ assert(blockedSuperNewline.isError === true && blockedSuperNewline.structuredContent.codexflow_tool === 'bash', 'supertool safe bash newline error was not tagged as bash');
249
+ assert(!(await pathExists(newlineSuperTarget)), 'supertool safe bash newline command created a file');
250
+
251
+ const blockedOutputFlag = await client.request('tools/call', {
252
+ name: 'bash',
253
+ arguments: { workspace_id: ws, command: 'git diff "--output=safe-bash-owned.patch"' }
254
+ });
255
+ assert(blockedOutputFlag.isError === true && String(blockedOutputFlag.structuredContent.error).includes('blocked'), 'safe bash allowed quoted git output path');
256
+ assert(!(await pathExists(path.join(root, 'safe-bash-owned.patch'))), 'safe bash git output path created a file');
257
+
258
+ const blockedDollarExpansion = await client.request('tools/call', {
259
+ name: 'codexflow',
260
+ arguments: { action: 'bash', args: { workspace_id: ws, command: "git diff $'--output=supertool-owned.patch'" } }
261
+ });
262
+ assert(blockedDollarExpansion.isError === true && blockedDollarExpansion.structuredContent.codexflow_tool === 'bash', 'supertool safe bash allowed dollar-quoted expansion');
263
+ assert(!(await pathExists(path.join(root, 'supertool-owned.patch'))), 'supertool dollar-quoted git output path created a file');
264
+
265
+ const blockedFindFprint0 = await client.request('tools/call', {
266
+ name: 'bash',
267
+ arguments: { workspace_id: ws, command: 'find . "-fprint0" find-owned.txt' }
268
+ });
269
+ assert(blockedFindFprint0.isError === true && String(blockedFindFprint0.structuredContent.error).includes('blocked'), 'safe bash allowed quoted find -fprint0 path write');
270
+ assert(!(await pathExists(path.join(root, 'find-owned.txt'))), 'safe bash find -fprint0 created a file');
271
+
272
+ const blockedEnvWrite = await client.request('tools/call', {
273
+ name: 'write',
274
+ arguments: { workspace_id: ws, path: '.env/notes.txt', content: 'not a literal secret\n' }
275
+ });
276
+ assert(blockedEnvWrite.isError === true, 'write allowed .env descendant path');
277
+ assert(!(await pathExists(path.join(root, '.env', 'notes.txt'))), 'blocked .env descendant write created a file');
278
+
279
+ const arrows = await Promise.all(Array.from({ length: 12 }, () =>
280
+ client.request('tools/call', { name: 'search', arguments: { workspace_id: ws, query: '->', path: 'many', max_results: 25 } })
281
+ ));
282
+ assert(arrows.every((result) => result.structuredContent.matches.length === 25), 'concurrent arrow searches failed');
283
+
284
+ await fs.writeFile(path.join(root, '.ai-bridge', 'handoff-run-state.json'), `${JSON.stringify({
285
+ version: 1,
286
+ state: 'completed',
287
+ iteration: 7,
288
+ plan_hash: 'stress-plan',
289
+ executor: 'codex',
290
+ model: 'local-test',
291
+ exit_code: 0,
292
+ timed_out: false,
293
+ started_at: new Date(Date.now() - 1000).toISOString(),
294
+ finished_at: new Date().toISOString(),
295
+ status_file: '.ai-bridge/agent-status.md',
296
+ diff_file: '.ai-bridge/implementation-diff.patch',
297
+ log_file: '.ai-bridge/execution-log.jsonl'
298
+ }, null, 2)}\n`, 'utf8');
299
+ const completed = await client.request('tools/call', {
300
+ name: 'wait_for_handoff',
301
+ arguments: { workspace_id: ws, plan_hash: 'stress-plan', since_iteration: 6, max_wait_seconds: 1, poll_ms: 250 }
302
+ });
303
+ assert(completed.structuredContent.awaited_completed === true && completed.structuredContent.state === 'completed', 'wait_for_handoff did not complete expected state');
304
+ assert(String(completed.structuredContent.status_excerpt ?? '').includes('PASS stress handoff'), 'wait_for_handoff missed status excerpt');
305
+
306
+ const superWait = await client.request('tools/call', {
307
+ name: 'codexflow',
308
+ arguments: { action: 'handoff_poll', args: { workspace_id: ws, plan_hash: 'stress-plan', since_iteration: 6, max_wait_seconds: 1, poll_ms: 250 } }
309
+ });
310
+ assert(superWait.structuredContent.codexflow_tool === 'wait_for_handoff' && superWait.structuredContent.wrapped_tool === 'wait_for_handoff' && superWait.structuredContent.succeeded === true, 'supertool handoff_poll failed');
311
+
312
+ const mismatch = await client.request('tools/call', {
313
+ name: 'wait_for_handoff',
314
+ arguments: { workspace_id: ws, plan_hash: 'wrong-plan', max_wait_seconds: 1, poll_ms: 250 }
315
+ });
316
+ assert(mismatch.structuredContent.awaited_completed === false && mismatch.structuredContent.plan_hash_mismatch === true, 'wait_for_handoff mismatch did not fail closed');
317
+
318
+ await fs.rm(path.join(root, '.ai-bridge', 'handoff-run-state.json'), { force: true });
319
+ const slowPollStart = Date.now();
320
+ await client.request('tools/call', {
321
+ name: 'wait_for_handoff',
322
+ arguments: { workspace_id: ws, max_wait_seconds: 1, poll_ms: 5000 }
323
+ });
324
+ assert(Date.now() - slowPollStart < 2500, 'wait_for_handoff exceeded max_wait_seconds by a full poll interval');
325
+
326
+ const exactExport = await client.request('tools/call', {
327
+ name: 'export_pro_context',
328
+ arguments: {
329
+ workspace_id: ws,
330
+ selected_paths: ['demo.txt'],
331
+ include_important_files: false,
332
+ include_changed_files: false,
333
+ include_diff: false,
334
+ include_ai_bridge: false,
335
+ max_files: 1,
336
+ max_total_bytes: 20000
337
+ }
338
+ });
339
+ assert(exactExport.structuredContent.files_included.length === 1 && exactExport.structuredContent.files_included[0] === 'demo.txt', `exact Pro export included wrong files: ${JSON.stringify(exactExport.structuredContent.files_included)}`);
340
+
341
+ const superExport = await client.request('tools/call', {
342
+ name: 'codexflow',
343
+ arguments: {
344
+ action: 'pro_export',
345
+ args: {
346
+ workspace_id: ws,
347
+ selected_paths: ['demo.txt'],
348
+ include_important_files: false,
349
+ include_changed_files: false,
350
+ include_diff: false,
351
+ include_ai_bridge: false,
352
+ max_files: 1,
353
+ max_total_bytes: 20000
354
+ }
355
+ }
356
+ });
357
+ assert(superExport.structuredContent.codexflow_tool === 'export_pro_context' && superExport.structuredContent.wrapped_tool === 'export_pro_context', 'supertool pro_export did not wrap export_pro_context');
358
+ assert(superExport.structuredContent.files_included.length === 1 && superExport.structuredContent.files_included[0] === 'demo.txt', `supertool Pro export included wrong files: ${JSON.stringify(superExport.structuredContent.files_included)}`);
359
+
360
+ const hiddenGlobExport = await client.request('tools/call', {
361
+ name: 'export_pro_context',
362
+ arguments: {
363
+ workspace_id: ws,
364
+ extra_globs: ['.github/**/*.yml'],
365
+ include_important_files: false,
366
+ include_changed_files: false,
367
+ include_diff: false,
368
+ include_ai_bridge: false,
369
+ max_files: 4,
370
+ max_total_bytes: 20000
371
+ }
372
+ });
373
+ assert(hiddenGlobExport.structuredContent.files_included.includes('.github/workflows/ci.yml'), `Pro export extra_globs missed hidden path: ${JSON.stringify(hiddenGlobExport.structuredContent.files_included)}`);
374
+
375
+ const selfTest = await client.request('tools/call', { name: 'codexflow_self_test', arguments: { workspace_id: ws } });
376
+ assert(selfTest.structuredContent.status !== 'fail', `codexflow_self_test failed: ${JSON.stringify(selfTest.structuredContent.checks)}`);
377
+ } finally {
378
+ client.close();
379
+ }
380
+ }
381
+
382
+ async function runGlobalSkillStress(root) {
383
+ void root;
384
+ const isolatedRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'codexflow-stress-global-root-'));
385
+ const name = `000-codexflow-global-stress-${Date.now()}`;
386
+ const dir = path.join(os.homedir(), '.codex', 'skills', name);
387
+ await fs.mkdir(dir, { recursive: true });
388
+ await fs.writeFile(path.join(dir, 'SKILL.md'), `---\nname: ${name}\ndescription: Global stress skill.\n---\n\n# Global Only Skill\n`, 'utf8');
389
+ let client;
390
+ try {
391
+ client = await initClient(isolatedRoot);
392
+ const opened = await client.request('tools/call', { name: 'open_current_workspace', arguments: { include_tree: false } });
393
+ const inventory = await client.request('tools/call', {
394
+ name: 'codexflow_inventory',
395
+ arguments: { workspace_id: opened.structuredContent.workspace_id, include_mcp_servers: false, max_skills: 500 }
396
+ });
397
+ const skill = inventory.structuredContent.skills.find((item) => item.name === name);
398
+ assert(skill, 'default inventory did not include global skill');
399
+ const loaded = await client.request('tools/call', {
400
+ name: 'load_skill',
401
+ arguments: { workspace_id: opened.structuredContent.workspace_id, name: skill.name, source: skill.source, path: skill.path }
402
+ });
403
+ assert(loaded.structuredContent.text.includes('# Global Only Skill'), 'default load_skill did not load inventory global skill');
404
+ const loadedByName = await client.request('tools/call', {
405
+ name: 'load_skill',
406
+ arguments: { workspace_id: opened.structuredContent.workspace_id, name }
407
+ });
408
+ assert(loadedByName.structuredContent.text.includes('# Global Only Skill'), 'load_skill did not load unique user skill by name');
409
+ } finally {
410
+ client?.close();
411
+ await fs.rm(dir, { recursive: true, force: true });
412
+ }
413
+ }
414
+
415
+ async function runRedactionStress() {
416
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'codexflow-stress-redact-'));
417
+ const ngrokToken = '2redactDEFghiJKLmnopQRSTuvWXyz_1234567890';
418
+ const cloudflareToken = 'eyJhbGciOiJIUzI1NiJ9.eyJ0dW5uZWwiOiJzdHJlc3MifQ.signature1234567890';
419
+ const tokenFile = '/Users/rebel/.codexflow/cloudflare-tunnel-token';
420
+ await fs.writeFile(path.join(root, 'tokens.txt'), [
421
+ `ngrok config add-authtoken ${ngrokToken}`,
422
+ `cloudflared tunnel run --token ${cloudflareToken}`,
423
+ `cloudflared tunnel run --token-file ${tokenFile}`
424
+ ].join('\n'), 'utf8');
425
+
426
+ const client = await initClient(root);
427
+ try {
428
+ const opened = await client.request('tools/call', { name: 'open_current_workspace', arguments: { include_tree: false } });
429
+ for (const request of [
430
+ { name: 'read', arguments: { workspace_id: opened.structuredContent.workspace_id, path: 'tokens.txt' } },
431
+ { name: 'codexflow', arguments: { action: 'read', args: { workspace_id: opened.structuredContent.workspace_id, path: 'tokens.txt' } } }
432
+ ]) {
433
+ const result = await client.request('tools/call', request);
434
+ const payload = JSON.stringify(result);
435
+ assert(!payload.includes(ngrokToken), 'read leaked ngrok authtoken');
436
+ assert(!payload.includes(cloudflareToken), 'read leaked cloudflared token');
437
+ assert(payload.includes(tokenFile), 'redaction hid non-secret token-file path');
438
+ }
439
+ } finally {
440
+ client.close();
441
+ }
442
+ }
443
+
444
+ async function runMcpInventoryStress() {
445
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'codexflow-stress-mcp-root-'));
446
+ const fakeHome = await fs.mkdtemp(path.join(os.tmpdir(), 'codexflow-stress-mcp-home-'));
447
+ await fs.mkdir(path.join(fakeHome, '.codex'), { recursive: true });
448
+ await fs.mkdir(path.join(fakeHome, '.cursor'), { recursive: true });
449
+ const toml = Array.from({ length: 80 }, (_, i) =>
450
+ `[mcp_servers.codex_${String(i).padStart(3, '0')}]\ncommand = "secret-command"\nargs = ["secret-arg"]\n`
451
+ ).join('\n');
452
+ const cursorServers = Object.fromEntries(Array.from({ length: 80 }, (_, i) => [
453
+ `cursor_${String(i).padStart(3, '0')}`,
454
+ { command: 'secret-command', args: ['secret-arg'] }
455
+ ]));
456
+ await fs.writeFile(path.join(fakeHome, '.codex', 'config.toml'), toml, 'utf8');
457
+ await fs.writeFile(path.join(fakeHome, '.cursor', 'mcp.json'), JSON.stringify({ mcpServers: cursorServers }), 'utf8');
458
+
459
+ const client = await initClient(root, { HOME: fakeHome });
460
+ try {
461
+ const opened = await client.request('tools/call', { name: 'open_current_workspace', arguments: { include_tree: false } });
462
+ const inventory = await client.request('tools/call', {
463
+ name: 'codexflow_inventory',
464
+ arguments: { workspace_id: opened.structuredContent.workspace_id, include_global_skills: false, include_mcp_servers: true }
465
+ });
466
+ const superInventory = await client.request('tools/call', {
467
+ name: 'codexflow',
468
+ arguments: { action: 'inventory', args: { workspace_id: opened.structuredContent.workspace_id, include_global_skills: false, include_mcp_servers: true } }
469
+ });
470
+ assert(inventory.structuredContent.mcp_server_count === 120, `MCP inventory was not capped: ${inventory.structuredContent.mcp_server_count}`);
471
+ assert(superInventory.structuredContent.codexflow_tool === 'codexflow_inventory' && superInventory.structuredContent.mcp_server_count === 120, 'supertool MCP inventory was not capped');
472
+ const payload = JSON.stringify([inventory, superInventory]);
473
+ for (const leaked of [fakeHome, '~/.codex', '~/.cursor', '.cursor/mcp.json', '.codex/config.toml', 'secret-command', 'secret-arg']) {
474
+ assert(!payload.includes(leaked), `MCP inventory leaked ${leaked}`);
475
+ }
476
+ } finally {
477
+ client.close();
478
+ }
479
+ }
480
+
481
+ async function runSupertoolModeStress(root) {
482
+ const client = await initClient(root, {
483
+ CODEXFLOW_TOOL_MODE: 'minimal',
484
+ CODEXFLOW_BASH_MODE: 'off'
485
+ });
486
+ try {
487
+ const tools = await client.request('tools/list', {});
488
+ const names = tools.tools.map((tool) => tool.name);
489
+ assert(names.includes('codexflow'), 'minimal mode missing codexflow supertool');
490
+ assert(!names.includes('bash'), 'minimal no-bash mode exposed bash');
491
+ assert(!names.includes('search'), 'minimal mode exposed search');
492
+
493
+ const actions = await client.request('tools/call', { name: 'codexflow', arguments: { action: 'list_actions' } });
494
+ assert(actions.structuredContent.actions.includes('read'), 'minimal supertool actions missing read');
495
+ assert(!actions.structuredContent.actions.includes('bash'), 'minimal no-bash supertool actions exposed bash');
496
+ assert(!actions.structuredContent.actions.includes('search'), 'minimal supertool actions exposed search');
497
+
498
+ const opened = await client.request('tools/call', {
499
+ name: 'codexflow',
500
+ arguments: { action: 'open', args: { include_tree: false } }
501
+ });
502
+ const read = await client.request('tools/call', {
503
+ name: 'codexflow',
504
+ arguments: { action: 'read', args: { workspace_id: opened.structuredContent.workspace_id, path: 'demo.txt', start_line: 1, end_line: 2 } }
505
+ });
506
+ assert(read.structuredContent.codexflow_tool === 'read' && read.structuredContent.wrapped_tool === 'read' && read.structuredContent.text.includes('alpha'), 'minimal supertool read failed');
507
+
508
+ const blockedSearch = await client.request('tools/call', {
509
+ name: 'codexflow',
510
+ arguments: { action: 'search', args: { workspace_id: opened.structuredContent.workspace_id, query: 'alpha' } }
511
+ });
512
+ assert(blockedSearch.isError === true && String(blockedSearch.structuredContent.error).includes('not available'), 'supertool allowed disabled search action');
513
+
514
+ const missingRead = await client.request('tools/call', {
515
+ name: 'codexflow',
516
+ arguments: { action: 'read', args: { workspace_id: opened.structuredContent.workspace_id, path: 'missing.txt' } }
517
+ });
518
+ assert(missingRead.isError === true && missingRead.structuredContent.codexflow_tool === 'read' && missingRead.structuredContent.wrapped_tool === 'read', 'supertool failed read was not tagged as read');
519
+
520
+ const malformedRead = await client.request('tools/call', {
521
+ name: 'codexflow',
522
+ arguments: { action: 'read', args: { workspace_id: opened.structuredContent.workspace_id, path: ['demo.txt'] } }
523
+ });
524
+ const malformedReadError = String(malformedRead.structuredContent.error ?? '');
525
+ assert(malformedRead.isError === true && malformedRead.structuredContent.codexflow_tool === 'read' && malformedRead.structuredContent.wrapped_tool === 'read', 'supertool malformed read was not tagged as read');
526
+ assert(malformedReadError.includes('Invalid arguments for read') && !malformedReadError.includes('TypeError'), `supertool malformed read leaked raw handler error: ${malformedReadError}`);
527
+
528
+ const blockedBash = await client.request('tools/call', {
529
+ name: 'codexflow',
530
+ arguments: { action: 'bash', args: { workspace_id: opened.structuredContent.workspace_id, command: 'pwd' } }
531
+ });
532
+ assert(blockedBash.isError === true && String(blockedBash.structuredContent.error).includes('not available'), 'supertool allowed disabled bash action');
533
+ } finally {
534
+ client.close();
535
+ }
536
+ }
537
+
538
+ async function runMaxReadSearchStress() {
539
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'codexflow-stress-max-read-'));
540
+ await fs.writeFile(path.join(root, 'many-lines.txt'), `${Array.from({ length: 1200 }, (_, i) => `x${i % 10}`).join('\n')}\n`, 'utf8');
541
+ await fs.writeFile(path.join(root, 'large.txt'), `intro\n${'x'.repeat(4500)}\nneedle in large file\n`, 'utf8');
542
+ await fs.writeFile(path.join(root, 'huge.txt'), `needle in huge file\n${'x'.repeat(20000)}\n`, 'utf8');
543
+ const client = await initClient(root, { CODEXFLOW_MAX_READ_BYTES: '1000' });
544
+ try {
545
+ const opened = await client.request('tools/call', { name: 'open_current_workspace', arguments: { include_tree: false } });
546
+ const manyLinesRead = await client.request('tools/call', {
547
+ name: 'read',
548
+ arguments: { workspace_id: opened.structuredContent.workspace_id, path: 'many-lines.txt' }
549
+ });
550
+ assert(manyLinesRead.isError !== true && manyLinesRead.structuredContent.endLine === 1201, `full read under maxReadBytes failed after line numbering: ${JSON.stringify(manyLinesRead.structuredContent)}`);
551
+ const fullRead = await client.request('tools/call', {
552
+ name: 'read',
553
+ arguments: { workspace_id: opened.structuredContent.workspace_id, path: 'large.txt' }
554
+ });
555
+ assert(fullRead.isError === true && String(fullRead.structuredContent.error).includes('too large'), 'full read ignored maxReadBytes');
556
+ const rangedRead = await client.request('tools/call', {
557
+ name: 'read',
558
+ arguments: { workspace_id: opened.structuredContent.workspace_id, path: 'large.txt', start_line: 3, end_line: 3 }
559
+ });
560
+ assert(rangedRead.isError !== true && rangedRead.structuredContent.text.includes('needle in large file'), `ranged read failed above maxReadBytes: ${JSON.stringify(rangedRead.structuredContent)}`);
561
+ const search = await client.request('tools/call', {
562
+ name: 'search',
563
+ arguments: { workspace_id: opened.structuredContent.workspace_id, query: 'needle', max_results: 10 }
564
+ });
565
+ assert(search.structuredContent.matches.some((match) => match.path === 'large.txt'), `search skipped slightly large file: ${JSON.stringify(search.structuredContent.matches)}`);
566
+ assert(!search.structuredContent.matches.some((match) => match.path === 'huge.txt'), `search scanned file beyond text scan cap: ${JSON.stringify(search.structuredContent.matches)}`);
567
+ } finally {
568
+ client.close();
569
+ }
570
+ }
571
+
572
+ async function runNodeFallbackSearchLimitStress() {
573
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'codexflow-stress-node-search-'));
574
+ await fs.writeFile(path.join(root, 'exact.txt'), 'needle one\nneedle two\n', 'utf8');
575
+ await fs.writeFile(path.join(root, 'overflow.txt'), 'needle one\nneedle two\nneedle three\n', 'utf8');
576
+ const client = await initClient(root, { PATH: '/usr/bin:/bin' });
577
+ try {
578
+ const opened = await client.request('tools/call', { name: 'open_current_workspace', arguments: { include_tree: false } });
579
+ const exact = await client.request('tools/call', {
580
+ name: 'search',
581
+ arguments: { workspace_id: opened.structuredContent.workspace_id, query: 'needle', path: 'exact.txt', max_results: 2 }
582
+ });
583
+ assert(exact.structuredContent.used === 'node', `expected node fallback, got ${exact.structuredContent.used}`);
584
+ assert(exact.structuredContent.matches.length === 2, `node fallback exact-limit search returned ${exact.structuredContent.matches.length} matches`);
585
+ assert(exact.structuredContent.truncated === false, `node fallback exact-limit search was incorrectly truncated: ${JSON.stringify(exact.structuredContent)}`);
586
+
587
+ const overflow = await client.request('tools/call', {
588
+ name: 'search',
589
+ arguments: { workspace_id: opened.structuredContent.workspace_id, query: 'needle', path: 'overflow.txt', max_results: 2 }
590
+ });
591
+ assert(overflow.structuredContent.matches.length === 2 && overflow.structuredContent.truncated === true, `node fallback overflow search did not report truncation: ${JSON.stringify(overflow.structuredContent)}`);
592
+ } finally {
593
+ client.close();
594
+ }
595
+ }
596
+
597
+ async function runGuardEdgeStress() {
598
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'codexflow-stress-guard-'));
599
+ const outside = await fs.mkdtemp(path.join(os.tmpdir(), 'codexflow-stress-outside-'));
600
+ await fs.writeFile(path.join(root, 'visible.txt'), 'needle visible\n', 'utf8');
601
+ await fs.writeFile(path.join(root, 'late-null.txt'), Buffer.concat([
602
+ Buffer.from('needle before\n'),
603
+ Buffer.alloc(5000, 65),
604
+ Buffer.from([0]),
605
+ Buffer.from('\nneedle after\n')
606
+ ]));
607
+ await fs.mkdir(path.join(root, '.env'), { recursive: true });
608
+ await fs.writeFile(path.join(root, '.env', 'secret.txt'), 'needle blocked env\n', 'utf8');
609
+ await fs.mkdir(path.join(outside, 'outside-dir'), { recursive: true });
610
+ await fs.writeFile(path.join(outside, 'outside-dir', 'secret.txt'), 'needle outside\n', 'utf8');
611
+
612
+ let outsideDirLink;
613
+ let aliasRoot;
614
+ try {
615
+ outsideDirLink = path.join(root, 'outside-dir-link');
616
+ await fs.symlink(path.join(outside, 'outside-dir'), outsideDirLink, 'dir');
617
+ aliasRoot = path.join(outside, 'workspace-alias');
618
+ await fs.symlink(root, aliasRoot, 'dir');
619
+ } catch (error) {
620
+ if (process.platform !== 'win32' || error?.code !== 'EPERM') throw error;
621
+ outsideDirLink = undefined;
622
+ aliasRoot = undefined;
623
+ }
624
+
625
+ const client = await initClient(root);
626
+ try {
627
+ const opened = await client.request('tools/call', { name: 'open_current_workspace', arguments: { include_tree: false } });
628
+ const ws = opened.structuredContent.workspace_id;
629
+
630
+ await expectToolError(client, 'read', { workspace_id: ws, path: 'late-null.txt' }, /binary/i);
631
+ await expectToolError(client, 'edit', { workspace_id: ws, path: 'late-null.txt', old_text: 'needle before', new_text: 'changed' }, /binary/i);
632
+
633
+ const blockedSearch = await client.request('tools/call', {
634
+ name: 'search',
635
+ arguments: { workspace_id: ws, query: 'needle blocked env', glob: '.env/**', include_hidden: true, max_results: 10 }
636
+ });
637
+ assert(blockedSearch.structuredContent.matches.length === 0, `blocked search glob leaked matches: ${JSON.stringify(blockedSearch.structuredContent.matches)}`);
638
+ assert(blockedSearch.structuredContent.truncated === false, `blocked-only search reported truncation: ${JSON.stringify(blockedSearch.structuredContent)}`);
639
+
640
+ if (outsideDirLink) {
641
+ await expectToolError(client, 'tree', { workspace_id: ws, path: 'outside-dir-link', include_hidden: true }, /symlink|outside/i);
642
+ await expectToolError(client, 'search', { workspace_id: ws, query: 'needle outside', path: 'outside-dir-link', include_hidden: true }, /symlink|outside/i);
643
+ await expectToolError(client, 'read', { workspace_id: ws, path: 'outside-dir-link/secret.txt' }, /symlink|outside/i);
644
+ }
645
+
646
+ if (aliasRoot) {
647
+ const aliasVisible = path.join(aliasRoot, 'visible.txt');
648
+ const aliasRead = await client.request('tools/call', { name: 'read', arguments: { workspace_id: ws, path: aliasVisible } });
649
+ assert(aliasRead.isError !== true && aliasRead.structuredContent.path === 'visible.txt', `absolute realpath-inside read failed: ${JSON.stringify(aliasRead.structuredContent)}`);
650
+ const aliasSearch = await client.request('tools/call', { name: 'search', arguments: { workspace_id: ws, query: 'needle visible', path: aliasVisible, max_results: 10 } });
651
+ assert(aliasSearch.structuredContent.matches.some((match) => match.path === 'visible.txt'), `absolute realpath-inside search failed: ${JSON.stringify(aliasSearch.structuredContent)}`);
652
+ await expectToolError(client, 'write', { workspace_id: ws, path: path.join(aliasRoot, '.env', 'created.txt'), content: 'blocked\n' }, /blocked/i);
653
+ assert(!(await pathExists(path.join(root, '.env', 'created.txt'))), 'absolute alias write created a blocked file');
654
+ }
655
+ } finally {
656
+ client.close();
657
+ }
658
+ }
659
+
660
+ async function runShowChangesStatsStress() {
661
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'codexflow-stress-git-'));
662
+ await fs.writeFile(path.join(root, 'demo.txt'), 'alpha\n', 'utf8');
663
+ await fs.writeFile(path.join(root, 'other.txt'), 'one\n', 'utf8');
664
+ await fs.writeFile(path.join(root, 'staged file.txt'), 'one\n', 'utf8');
665
+ spawnSync('git', ['init'], { cwd: root, stdio: 'ignore' });
666
+ spawnSync('git', ['config', 'user.email', 'stress@example.com'], { cwd: root, stdio: 'ignore' });
667
+ spawnSync('git', ['config', 'user.name', 'Stress Test'], { cwd: root, stdio: 'ignore' });
668
+ spawnSync('git', ['add', 'demo.txt'], { cwd: root, stdio: 'ignore' });
669
+ spawnSync('git', ['add', 'other.txt'], { cwd: root, stdio: 'ignore' });
670
+ spawnSync('git', ['add', 'staged file.txt'], { cwd: root, stdio: 'ignore' });
671
+ spawnSync('git', ['commit', '-m', 'init'], { cwd: root, stdio: 'ignore' });
672
+ await fs.appendFile(path.join(root, 'demo.txt'), 'beta\n', 'utf8');
673
+ await fs.appendFile(path.join(root, 'other.txt'), 'two\n', 'utf8');
674
+ await fs.appendFile(path.join(root, 'staged file.txt'), 'two\n', 'utf8');
675
+ spawnSync('git', ['add', 'staged file.txt'], { cwd: root, stdio: 'ignore' });
676
+ const client = await initClient(root);
677
+ try {
678
+ const opened = await client.request('tools/call', { name: 'open_current_workspace', arguments: { include_tree: false } });
679
+ const scopedStatus = await client.request('tools/call', {
680
+ name: 'git_status',
681
+ arguments: { workspace_id: opened.structuredContent.workspace_id, path: 'demo.txt' }
682
+ });
683
+ assert(scopedStatus.structuredContent.changed_files.length === 1 && scopedStatus.structuredContent.changed_files[0].includes('demo.txt'), `git_status path leaked unrelated files: ${JSON.stringify(scopedStatus.structuredContent.changed_files)}`);
684
+ const superScopedStatus = await client.request('tools/call', {
685
+ name: 'codexflow',
686
+ arguments: { action: 'git_status', args: { workspace_id: opened.structuredContent.workspace_id, path: 'demo.txt' } }
687
+ });
688
+ assert(superScopedStatus.structuredContent.codexflow_tool === 'git_status' && superScopedStatus.structuredContent.changed_files.length === 1 && superScopedStatus.structuredContent.changed_files[0].includes('demo.txt'), `supertool git_status path leaked unrelated files: ${JSON.stringify(superScopedStatus.structuredContent.changed_files)}`);
689
+ const changes = await client.request('tools/call', {
690
+ name: 'show_changes',
691
+ arguments: { workspace_id: opened.structuredContent.workspace_id, path: 'demo.txt', include_diff: false }
692
+ });
693
+ assert(changes.structuredContent.additions === 1 && changes.structuredContent.deletions === 0 && changes.structuredContent.diff === '', `show_changes include_diff=false lost stats: ${JSON.stringify(changes.structuredContent)}`);
694
+ const fullChanges = await client.request('tools/call', {
695
+ name: 'show_changes',
696
+ arguments: { workspace_id: opened.structuredContent.workspace_id, path: './demo.txt' }
697
+ });
698
+ assert(fullChanges.structuredContent.changed && fullChanges.structuredContent.diff.includes('demo.txt') && fullChanges.structuredContent.review_checkpoint_hit !== true, `show_changes include_diff=false consumed full diff: ${JSON.stringify(fullChanges.structuredContent)}`);
699
+ const statsOnlyAfterCheckpoint = await client.request('tools/call', {
700
+ name: 'show_changes',
701
+ arguments: { workspace_id: opened.structuredContent.workspace_id, path: 'demo.txt', include_diff: false }
702
+ });
703
+ assert(statsOnlyAfterCheckpoint.structuredContent.changed && statsOnlyAfterCheckpoint.structuredContent.additions === 1 && statsOnlyAfterCheckpoint.structuredContent.diff === '', `show_changes include_diff=false lost stats after checkpoint: ${JSON.stringify(statsOnlyAfterCheckpoint.structuredContent)}`);
704
+ assert(statsOnlyAfterCheckpoint.structuredContent.review_marked === false, `show_changes include_diff=false claimed checkpoint was marked: ${JSON.stringify(statsOnlyAfterCheckpoint.structuredContent)}`);
705
+ const stagedDiff = await client.request('tools/call', {
706
+ name: 'git_diff',
707
+ arguments: { workspace_id: opened.structuredContent.workspace_id, path: 'staged file.txt', staged: true, include_diff: false }
708
+ });
709
+ assert(stagedDiff.structuredContent.additions === 1 && stagedDiff.structuredContent.deletions === 0 && stagedDiff.structuredContent.diff === '', `git_diff staged path stats failed: ${JSON.stringify(stagedDiff.structuredContent)}`);
710
+ const stagedChanges = await client.request('tools/call', {
711
+ name: 'show_changes',
712
+ arguments: { workspace_id: opened.structuredContent.workspace_id, staged: true }
713
+ });
714
+ assert(stagedChanges.structuredContent.changed && stagedChanges.structuredContent.diff.includes('staged file.txt') && !stagedChanges.structuredContent.diff.includes('demo.txt'), `show_changes staged review mixed unstaged files: ${JSON.stringify(stagedChanges.structuredContent)}`);
715
+ const defaultStagedPathChanges = await client.request('tools/call', {
716
+ name: 'show_changes',
717
+ arguments: { workspace_id: opened.structuredContent.workspace_id, path: 'staged file.txt' }
718
+ });
719
+ assert(!defaultStagedPathChanges.structuredContent.changed && defaultStagedPathChanges.structuredContent.additions === 0 && defaultStagedPathChanges.structuredContent.diff === '', `default show_changes reported staged-only changes: ${JSON.stringify(defaultStagedPathChanges.structuredContent)}`);
720
+ await fs.writeFile(path.join(root, 'new-review.txt'), 'new file\n', 'utf8');
721
+ const untrackedChanges = await client.request('tools/call', {
722
+ name: 'show_changes',
723
+ arguments: { workspace_id: opened.structuredContent.workspace_id, path: 'new-review.txt' }
724
+ });
725
+ assert(untrackedChanges.structuredContent.changed && untrackedChanges.structuredContent.changed_files.some((line) => line.includes('new-review.txt')), `show_changes did not report untracked new file: ${JSON.stringify(untrackedChanges.structuredContent)}`);
726
+ await fs.writeFile(path.join(root, 'new-review.txt'), 'new file changed\n', 'utf8');
727
+ const changedUntrackedChanges = await client.request('tools/call', {
728
+ name: 'show_changes',
729
+ arguments: { workspace_id: opened.structuredContent.workspace_id, path: 'new-review.txt' }
730
+ });
731
+ assert(changedUntrackedChanges.structuredContent.changed && changedUntrackedChanges.structuredContent.review_checkpoint_hit !== true, `show_changes checkpoint hid changed untracked file content: ${JSON.stringify(changedUntrackedChanges.structuredContent)}`);
732
+ } finally {
733
+ client.close();
734
+ }
735
+ }
736
+
737
+ async function runMinimalHandoffStress(root) {
738
+ const client = await initClient(root, {
739
+ CODEXFLOW_TOOL_MODE: 'minimal',
740
+ CODEXFLOW_BASH_MODE: 'off',
741
+ CODEXFLOW_WRITE_MODE: 'handoff'
742
+ });
743
+ try {
744
+ const tools = await client.request('tools/list', {});
745
+ const names = tools.tools.map((tool) => tool.name);
746
+ assert(names.includes('handoff_to_agent'), 'minimal handoff mode missing handoff_to_agent');
747
+ assert(!names.includes('write') && !names.includes('edit') && !names.includes('apply_patch'), 'minimal handoff mode exposed write/edit/apply_patch');
748
+ const actions = await client.request('tools/call', { name: 'codexflow', arguments: { action: 'list_actions' } });
749
+ assert(actions.structuredContent.actions.includes('handoff_to_agent'), 'minimal handoff supertool actions missing handoff_to_agent');
750
+ assert(!actions.structuredContent.actions.includes('write') && !actions.structuredContent.actions.includes('edit') && !actions.structuredContent.actions.includes('apply_patch'), 'minimal handoff supertool actions exposed write/edit/apply_patch');
751
+ const handoff = await client.request('tools/call', {
752
+ name: 'codexflow',
753
+ arguments: { action: 'agent_handoff', args: { title: 'Stress Plan', plan: '- keep it narrow' } }
754
+ });
755
+ assert(handoff.structuredContent.codexflow_tool === 'handoff_to_agent' && handoff.structuredContent.wrapped_tool === 'handoff_to_agent', 'minimal handoff supertool did not write plan');
756
+ const blockedWrite = await client.request('tools/call', {
757
+ name: 'codexflow',
758
+ arguments: { action: 'write', args: { path: 'demo.txt', content: 'bypass\n' } }
759
+ });
760
+ assert(blockedWrite.isError === true && String(blockedWrite.structuredContent.error).includes('not available'), 'minimal handoff supertool allowed disabled write');
761
+ } finally {
762
+ client.close();
763
+ }
764
+ }
765
+
766
+ async function runCardStress(root) {
767
+ const client = await initClient(root, { CODEXFLOW_TOOL_CARDS: '1' });
768
+ try {
769
+ await client.request('tools/list', {});
770
+ const opened = await client.request('tools/call', { name: 'open_current_workspace', arguments: { include_tree: false } });
771
+ const search = await client.request('tools/call', {
772
+ name: 'search',
773
+ arguments: { workspace_id: opened.structuredContent.workspace_id, query: '--flag', path: 'many', max_results: 2000 }
774
+ });
775
+ assert(typeof search.structuredContent.text === 'string' && search.structuredContent.text.includes('--flag'), 'tool-card search did not include structured text');
776
+ assert(search.structuredContent.text.includes('[structured field truncated to 30000 chars]'), 'tool-card search text was not capped');
777
+ const structured = await client.request('tools/call', {
778
+ name: 'search',
779
+ arguments: { workspace_id: opened.structuredContent.workspace_id, query: '--flag', path: 'many', intent: 'text', max_results: 2000 }
780
+ });
781
+ assert(structured.structuredContent.analysis.groups.references.length <= 24, `structured card references were not compacted: ${structured.structuredContent.analysis.groups.references.length}`);
782
+ assert(structured.structuredContent.analysis.matches.length <= 80, `structured card match summary was not compacted: ${structured.structuredContent.analysis.matches.length}`);
783
+ const inspected = await client.request('tools/call', { name: 'inspect_workspace', arguments: { workspace_id: opened.structuredContent.workspace_id } });
784
+ assert(inspected.structuredContent.files.length <= 120, `workspace card file inventory was not compacted: ${inspected.structuredContent.files.length}`);
785
+ } finally {
786
+ client.close();
787
+ }
788
+ }
789
+
790
+ async function runAnalysisBudgetStress() {
791
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'codexflow-stress-analysis-'));
792
+ await fs.mkdir(path.join(root, 'src'), { recursive: true });
793
+ for (let index = 0; index < 105; index += 1) {
794
+ await fs.writeFile(path.join(root, 'src', `module-${String(index).padStart(3, '0')}.ts`), `export function module${index}() { return ${index}; }\n`, 'utf8');
795
+ }
796
+ await fs.writeFile(path.join(root, '.env'), 'PRIVATE_TOKEN=never-visible\n', 'utf8');
797
+ const client = await initClient(root, {
798
+ CODEXFLOW_ANALYSIS_MAX_INVENTORY_FILES: '100',
799
+ CODEXFLOW_ANALYSIS_MAX_ANALYZED_FILES: '100'
800
+ });
801
+ try {
802
+ const opened = await client.request('tools/call', { name: 'open_current_workspace', arguments: { include_tree: false } });
803
+ const inspected = await client.request('tools/call', { name: 'inspect_workspace', arguments: { workspace_id: opened.structuredContent.workspace_id } });
804
+ assert(inspected.structuredContent.coverage.truncated === true, `analysis inventory did not report truncation: ${JSON.stringify(inspected.structuredContent.coverage)}`);
805
+ assert(inspected.structuredContent.files.length === 100, `expected 100 bounded inventory files, got ${inspected.structuredContent.files.length}`);
806
+ assert(!inspected.structuredContent.files.some((file) => file.path === '.env'), 'analysis inventory exposed blocked .env');
807
+ const limitedOutput = await client.request('tools/call', {
808
+ name: 'inspect_workspace',
809
+ arguments: { workspace_id: opened.structuredContent.workspace_id, max_files: 25, max_symbols: 10, max_relationships: 5 }
810
+ });
811
+ assert(limitedOutput.structuredContent.files.length === 25, `inspect max_files returned ${limitedOutput.structuredContent.files.length} records`);
812
+ assert(limitedOutput.structuredContent.symbols.length === 10, `inspect max_symbols returned ${limitedOutput.structuredContent.symbols.length} records`);
813
+ assert(limitedOutput.structuredContent.returned.files === 25 && limitedOutput.structuredContent.returned.symbols === 10, `inspect returned counts were incorrect: ${JSON.stringify(limitedOutput.structuredContent.returned)}`);
814
+ assert(limitedOutput.structuredContent.output_limited === true, 'inspect output limit was not exposed in structured content');
815
+ assert(limitedOutput.structuredContent.warnings.some((warning) => warning.includes('Structured output was limited')), 'inspect output limit did not report a warning');
816
+ } finally {
817
+ client.close();
818
+ await fs.rm(root, { recursive: true, force: true });
819
+ }
820
+ }
821
+
822
+ const root = await makeFixture();
823
+ await runFullModeStress(root);
824
+ await runGlobalSkillStress(root);
825
+ await runRedactionStress();
826
+ await runMcpInventoryStress();
827
+ await runMaxReadSearchStress();
828
+ await runNodeFallbackSearchLimitStress();
829
+ await runGuardEdgeStress();
830
+ await runSupertoolModeStress(root);
831
+ await runShowChangesStatsStress();
832
+ await runMinimalHandoffStress(root);
833
+ await runCardStress(root);
834
+ await runAnalysisBudgetStress();
835
+ console.log(`✓ stress test passed (${root})`);