neoctl 0.2.35 → 0.2.37

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 (180) hide show
  1. package/dist/agents/agent-report-security.test.d.ts +1 -0
  2. package/dist/agents/agent-report-security.test.js +301 -0
  3. package/dist/agents/agent-report-security.test.js.map +1 -0
  4. package/dist/agents/agent-tool-persistence.test.d.ts +1 -0
  5. package/dist/agents/agent-tool-persistence.test.js +319 -0
  6. package/dist/agents/agent-tool-persistence.test.js.map +1 -0
  7. package/dist/agents/agent-tool.d.ts +3 -0
  8. package/dist/agents/agent-tool.js +246 -76
  9. package/dist/agents/agent-tool.js.map +1 -1
  10. package/dist/agents/live-preview-redaction-security.test.d.ts +1 -0
  11. package/dist/agents/live-preview-redaction-security.test.js +286 -0
  12. package/dist/agents/live-preview-redaction-security.test.js.map +1 -0
  13. package/dist/agents/local-agent-task.d.ts +68 -1
  14. package/dist/agents/local-agent-task.js +78 -5
  15. package/dist/agents/local-agent-task.js.map +1 -1
  16. package/dist/agents/no-nested-delegation.test.d.ts +1 -0
  17. package/dist/agents/no-nested-delegation.test.js +38 -0
  18. package/dist/agents/no-nested-delegation.test.js.map +1 -0
  19. package/dist/agents/obs07-11-run-facts.test.d.ts +1 -0
  20. package/dist/agents/obs07-11-run-facts.test.js +459 -0
  21. package/dist/agents/obs07-11-run-facts.test.js.map +1 -0
  22. package/dist/agents/smoke-agent-lifecycle.d.ts +1 -0
  23. package/dist/agents/smoke-agent-lifecycle.js +192 -0
  24. package/dist/agents/smoke-agent-lifecycle.js.map +1 -0
  25. package/dist/agents/smoke-agents.js +7 -3
  26. package/dist/agents/smoke-agents.js.map +1 -1
  27. package/dist/context/context-manager.d.ts +1 -0
  28. package/dist/context/context-manager.js +10 -6
  29. package/dist/context/context-manager.js.map +1 -1
  30. package/dist/context/smoke-context.js +46 -3
  31. package/dist/context/smoke-context.js.map +1 -1
  32. package/dist/core/image-registry.js +1 -1
  33. package/dist/core/image-registry.js.map +1 -1
  34. package/dist/core/obs04-visible-data.test.d.ts +1 -0
  35. package/dist/core/obs04-visible-data.test.js +147 -0
  36. package/dist/core/obs04-visible-data.test.js.map +1 -0
  37. package/dist/core/query-engine.d.ts +5 -0
  38. package/dist/core/query-engine.js +36 -3
  39. package/dist/core/query-engine.js.map +1 -1
  40. package/dist/core/query.d.ts +5 -1
  41. package/dist/core/query.js +120 -18
  42. package/dist/core/query.js.map +1 -1
  43. package/dist/core/run-agent-pause.test.d.ts +1 -0
  44. package/dist/core/run-agent-pause.test.js +52 -0
  45. package/dist/core/run-agent-pause.test.js.map +1 -0
  46. package/dist/core/run-agent-persistence.test.d.ts +1 -0
  47. package/dist/core/run-agent-persistence.test.js +222 -0
  48. package/dist/core/run-agent-persistence.test.js.map +1 -0
  49. package/dist/core/run-agent.d.ts +13 -0
  50. package/dist/core/run-agent.js +72 -17
  51. package/dist/core/run-agent.js.map +1 -1
  52. package/dist/core/smoke-core-loop.js +8 -7
  53. package/dist/core/smoke-core-loop.js.map +1 -1
  54. package/dist/model/model-gateway.d.ts +1 -0
  55. package/dist/model/openai-native-image-guard.test.d.ts +1 -0
  56. package/dist/model/openai-native-image-guard.test.js +101 -0
  57. package/dist/model/openai-native-image-guard.test.js.map +1 -0
  58. package/dist/model/openai-responses-mapper.js +91 -16
  59. package/dist/model/openai-responses-mapper.js.map +1 -1
  60. package/dist/plugins/smoke-plugin-system.js +14 -14
  61. package/dist/repl/index.js +22 -28
  62. package/dist/repl/index.js.map +1 -1
  63. package/dist/secrets/secret-redaction.d.ts +6 -5
  64. package/dist/secrets/secret-redaction.js +7 -79
  65. package/dist/secrets/secret-redaction.js.map +1 -1
  66. package/dist/secrets/secret-types.d.ts +4 -1
  67. package/dist/secrets/secret-types.js.map +1 -1
  68. package/dist/session/session-store-safety.test.d.ts +1 -0
  69. package/dist/session/session-store-safety.test.js +107 -0
  70. package/dist/session/session-store-safety.test.js.map +1 -0
  71. package/dist/session/session-store.d.ts +5 -1
  72. package/dist/session/session-store.js +69 -7
  73. package/dist/session/session-store.js.map +1 -1
  74. package/dist/session/tool-result-memory.d.ts +3 -1
  75. package/dist/session/tool-result-memory.js.map +1 -1
  76. package/dist/tasks/subagent-tools.d.ts +4 -1
  77. package/dist/tasks/subagent-tools.js +85 -24
  78. package/dist/tasks/subagent-tools.js.map +1 -1
  79. package/dist/tasks/subagent-tools.test.d.ts +1 -0
  80. package/dist/tasks/subagent-tools.test.js +159 -0
  81. package/dist/tasks/subagent-tools.test.js.map +1 -0
  82. package/dist/tasks/task-ack-size.test.d.ts +1 -0
  83. package/dist/tasks/task-ack-size.test.js +101 -0
  84. package/dist/tasks/task-ack-size.test.js.map +1 -0
  85. package/dist/tasks/task-persistence.d.ts +23 -0
  86. package/dist/tasks/task-persistence.js +216 -0
  87. package/dist/tasks/task-persistence.js.map +1 -0
  88. package/dist/tasks/task-persistence.test.d.ts +1 -0
  89. package/dist/tasks/task-persistence.test.js +331 -0
  90. package/dist/tasks/task-persistence.test.js.map +1 -0
  91. package/dist/tasks/task-store.d.ts +51 -7
  92. package/dist/tasks/task-store.js +333 -31
  93. package/dist/tasks/task-store.js.map +1 -1
  94. package/dist/tools/builtins/exec-process-manager.d.ts +97 -2
  95. package/dist/tools/builtins/exec-process-manager.js +218 -19
  96. package/dist/tools/builtins/exec-process-manager.js.map +1 -1
  97. package/dist/tools/builtins/exec-tool.js +14 -1
  98. package/dist/tools/builtins/exec-tool.js.map +1 -1
  99. package/dist/tools/builtins/image-generation-tool.js +24 -24
  100. package/dist/tools/builtins/image-generation-tool.js.map +1 -1
  101. package/dist/tools/smoke-exec-process.js +2 -1
  102. package/dist/tools/smoke-exec-process.js.map +1 -1
  103. package/dist/tools/smoke-terminal-output-chain.d.ts +1 -0
  104. package/dist/tools/smoke-terminal-output-chain.js +245 -0
  105. package/dist/tools/smoke-terminal-output-chain.js.map +1 -0
  106. package/dist/tools/smoke-tool-system.js +6 -6
  107. package/dist/tools/smoke-tool-system.js.map +1 -1
  108. package/dist/tools/terminal-output-persistence.test.d.ts +1 -0
  109. package/dist/tools/terminal-output-persistence.test.js +50 -0
  110. package/dist/tools/terminal-output-persistence.test.js.map +1 -0
  111. package/dist/tools/terminal-output-store.d.ts +150 -0
  112. package/dist/tools/terminal-output-store.js +562 -0
  113. package/dist/tools/terminal-output-store.js.map +1 -0
  114. package/dist/tools/terminal-output-store.test.d.ts +1 -0
  115. package/dist/tools/terminal-output-store.test.js +364 -0
  116. package/dist/tools/terminal-output-store.test.js.map +1 -0
  117. package/dist/tools/tool.d.ts +5 -0
  118. package/dist/tools/tool.js.map +1 -1
  119. package/dist/types/events.d.ts +1 -0
  120. package/dist/types/messages.d.ts +1 -0
  121. package/dist/web/agent-content-detail.d.ts +78 -0
  122. package/dist/web/agent-content-detail.js +495 -0
  123. package/dist/web/agent-content-detail.js.map +1 -0
  124. package/dist/web/agent-content-detail.test.d.ts +1 -0
  125. package/dist/web/agent-content-detail.test.js +307 -0
  126. package/dist/web/agent-content-detail.test.js.map +1 -0
  127. package/dist/web/agent-parent-messages.test.d.ts +1 -0
  128. package/dist/web/agent-parent-messages.test.js +58 -0
  129. package/dist/web/agent-parent-messages.test.js.map +1 -0
  130. package/dist/web/agent-tool-payload-security.test.d.ts +1 -0
  131. package/dist/web/agent-tool-payload-security.test.js +120 -0
  132. package/dist/web/agent-tool-payload-security.test.js.map +1 -0
  133. package/dist/web/index.d.ts +213 -9
  134. package/dist/web/index.js +260 -108
  135. package/dist/web/index.js.map +1 -1
  136. package/dist/web/smoke-agent-content-http.d.ts +1 -0
  137. package/dist/web/smoke-agent-content-http.js +446 -0
  138. package/dist/web/smoke-agent-content-http.js.map +1 -0
  139. package/dist/web/smoke-status-semantics.d.ts +1 -0
  140. package/dist/web/smoke-status-semantics.js +90 -0
  141. package/dist/web/smoke-status-semantics.js.map +1 -0
  142. package/dist/web/smoke-task-session-entrypoints.d.ts +1 -0
  143. package/dist/web/smoke-task-session-entrypoints.js +96 -0
  144. package/dist/web/smoke-task-session-entrypoints.js.map +1 -0
  145. package/dist/web/smoke-terminal-output-http.d.ts +1 -0
  146. package/dist/web/smoke-terminal-output-http.js +372 -0
  147. package/dist/web/smoke-terminal-output-http.js.map +1 -0
  148. package/dist/web/smoke-tool-call-detail.d.ts +1 -0
  149. package/dist/web/smoke-tool-call-detail.js +106 -0
  150. package/dist/web/smoke-tool-call-detail.js.map +1 -0
  151. package/dist/web/smoke-tool-call-http.d.ts +1 -0
  152. package/dist/web/smoke-tool-call-http.js +100 -0
  153. package/dist/web/smoke-tool-call-http.js.map +1 -0
  154. package/dist/web/smoke-tool-detail-fields-http.d.ts +1 -0
  155. package/dist/web/smoke-tool-detail-fields-http.js +121 -0
  156. package/dist/web/smoke-tool-detail-fields-http.js.map +1 -0
  157. package/dist/web/smoke-web-agent-tasks.d.ts +1 -0
  158. package/dist/web/smoke-web-agent-tasks.js +50 -0
  159. package/dist/web/smoke-web-agent-tasks.js.map +1 -0
  160. package/dist/web/smoke-web-terminal-tasks.js +126 -76
  161. package/dist/web/smoke-web-terminal-tasks.js.map +1 -1
  162. package/dist/web/status-semantics.d.ts +11 -0
  163. package/dist/web/status-semantics.js +59 -0
  164. package/dist/web/status-semantics.js.map +1 -0
  165. package/dist/web/terminal-presentation.d.ts +15 -0
  166. package/dist/web/terminal-presentation.js +61 -0
  167. package/dist/web/terminal-presentation.js.map +1 -0
  168. package/dist/web/terminal-presentation.test.d.ts +1 -0
  169. package/dist/web/terminal-presentation.test.js +33 -0
  170. package/dist/web/terminal-presentation.test.js.map +1 -0
  171. package/dist/web/tool-call-detail.d.ts +40 -0
  172. package/dist/web/tool-call-detail.js +167 -0
  173. package/dist/web/tool-call-detail.js.map +1 -0
  174. package/dist/web/tool-detail-fields.d.ts +59 -0
  175. package/dist/web/tool-detail-fields.js +119 -0
  176. package/dist/web/tool-detail-fields.js.map +1 -0
  177. package/dist/web/tool-detail-fields.test.d.ts +1 -0
  178. package/dist/web/tool-detail-fields.test.js +121 -0
  179. package/dist/web/tool-detail-fields.test.js.map +1 -0
  180. package/package.json +90 -90
@@ -0,0 +1,106 @@
1
+ import { InMemorySecretRedactionRegistry } from '../secrets/secret-redaction.js';
2
+ import { runToolUseToMessages } from '../tools/run-tool-use.js';
3
+ import { ToolRegistry } from '../tools/registry.js';
4
+ import { InMemoryAppState } from '../app/app-state.js';
5
+ import { readFileTool } from '../tools/builtins/filesystem-tools.js';
6
+ import { editTool } from '../tools/builtins/edit-tool.js';
7
+ import { createSubagentTools } from '../tasks/subagent-tools.js';
8
+ import { TaskStore } from '../tasks/task-store.js';
9
+ import assert from 'node:assert/strict';
10
+ import fs from 'node:fs/promises';
11
+ import os from 'node:os';
12
+ import path from 'node:path';
13
+ import { readToolCallDetail, redactToolDetail, allowToolDetailRequest } from './tool-call-detail.js';
14
+ import { SessionStore } from '../session/session-store.js';
15
+ import { FileToolResultMemory } from '../session/tool-result-memory.js';
16
+ import { createToolResultMessage } from '../types/messages.js';
17
+ import { restoreWebHistoryLines, WebRepl } from './index.js';
18
+ const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'obs01-'));
19
+ let checks = 0;
20
+ const check = (v) => { assert.ok(v); checks++; };
21
+ try {
22
+ const request = { id: 'call-one', name: 'file_read', input: { path: 'missing.txt', offset: 0, token: 'INPUT_SECRET' } };
23
+ const use = { id: 'use-message', role: 'assistant', createdAt: '', blocks: [{ type: 'tool_use', ...request }] };
24
+ const entry = (message) => ({ type: 'message', message });
25
+ const options = { sessionId: 's1', expectedSessionId: 's1', sessionDir: dir, toolUseId: request.id };
26
+ for (const error of ['ENOENT: missing.txt', 'oldString not found', 'input.path must be string', 'Unknown agent target: nobody']) {
27
+ const result = createToolResultMessage(request, false, { error });
28
+ const entries = [entry(use), entry(result)];
29
+ const detail = await readToolCallDetail({ ...options, entries });
30
+ check(detail?.error.text === error);
31
+ check(detail?.input.text.includes('missing.txt') && !detail?.input.text.includes('INPUT_SECRET'));
32
+ const lines = restoreWebHistoryLines({ engine: { getDisplayEntries: () => entries } });
33
+ check(lines.some(line => line.kind === 'error' && line.toolUseId === request.id && line.toolError === error));
34
+ }
35
+ const tools = new ToolRegistry();
36
+ tools.register(readFileTool);
37
+ tools.register(editTool);
38
+ for (const tool of createSubagentTools(new TaskStore()))
39
+ tools.register(tool);
40
+ await fs.writeFile(path.join(dir, 'edit.txt'), 'unchanged');
41
+ const context = { emit: () => { }, agentId: 'test', tools, appState: new InMemoryAppState('test', dir), session: { sessionId: 's1', sessionDir: dir } };
42
+ for (const actual of [
43
+ { id: 'real-read', name: 'file_read', input: { path: path.join(dir, 'absent.txt') } },
44
+ { id: 'real-edit', name: 'file_edit', input: { path: path.join(dir, 'edit.txt'), oldString: 'NOT_FOUND', newString: 'new' } },
45
+ { id: 'real-schema', name: 'file_read', input: { path: 123 } },
46
+ { id: 'real-agent', name: 'subagent_message', input: { target: 'nonexistent', message: 'hello' } }
47
+ ]) {
48
+ const messages = await runToolUseToMessages(actual, context);
49
+ const actualUse = { ...use, id: actual.id + '-input', blocks: [{ type: 'tool_use', ...actual }] };
50
+ const detail = await readToolCallDetail({ ...options, toolUseId: actual.id, entries: [entry(actualUse), ...messages.map(entry)] });
51
+ check(detail?.ok === false && !!detail.error.text && detail.error.text !== '未提供错误原因');
52
+ console.log(actual.name + ' actual failure: ' + detail?.error.text);
53
+ }
54
+ const registry = new InMemorySecretRedactionRegistry();
55
+ registry.record('runtime-secret', 'REGISTERED_NOT_IN_ENV');
56
+ const registryResult = await readToolCallDetail({ ...options, redact: value => registry.redact(value), entries: [entry(use), entry(createToolResultMessage(request, true, { content: 'REGISTERED_NOT_IN_ENV', lastText: 'HIDDEN_CAMEL' }))] });
57
+ check(!JSON.stringify(registryResult).includes('REGISTERED_NOT_IN_ENV') && !JSON.stringify(registryResult).includes('HIDDEN_CAMEL'));
58
+ const fake = { runtime: { engine: { snapshot: () => ({ session: { sessionId: 's1' } }), redactDisplayValue: (v) => registry.redact(v), isFastMode: () => false, getAppPrompt: () => ({}) } },
59
+ lines: [{ id: 1, toolError: 'REGISTERED_NOT_IN_ENV' }], backgroundTasks: () => [], terminalTaskHistory: () => [], backgroundSessionRuns: new Map(), pendingDeltaOperations: [], scheduleDeltaFlush: () => { } };
60
+ // Snapshot also needs the existing task-store projection contract.
61
+ Object.assign(fake.runtime, { taskStore: { list: () => [] } });
62
+ const projected = WebRepl.prototype.snapshot.call(fake);
63
+ check(projected.lines[0].toolError === '[secret:runtime-secret]');
64
+ const queue = WebRepl.prototype.queueDeltaOperation;
65
+ queue.call(fake, { type: 'line.append', line: { id: 2, toolError: 'REGISTERED_NOT_IN_ENV' } });
66
+ queue.call(fake, { type: 'line.patch', id: 2, patch: { toolError: 'REGISTERED_NOT_IN_ENV' } });
67
+ check(!JSON.stringify(fake.pendingDeltaOperations).includes('REGISTERED_NOT_IN_ENV'));
68
+ const memory = new FileToolResultMemory({ sessionDir: dir, thresholdChars: 100 });
69
+ const full = { arbitrary: 'REGISTERED_NOT_IN_ENV', content: 'FULL_START\n' + 'x'.repeat(9000) + '\nFULL_END', password: 'OUTPUT_SECRET' };
70
+ const processed = await memory.processToolResult(request.id, full);
71
+ const result = createToolResultMessage(request, true, processed.output);
72
+ const entries = [entry(use), entry(result)];
73
+ const detail = await readToolCallDetail({ ...options, entries });
74
+ const store = await SessionStore.open({ agentId: 'test', rootDir: dir, sessionId: 'persisted' });
75
+ for (const item of entries)
76
+ store.recordMessage(item.message);
77
+ const restored = await SessionStore.open({ agentId: 'test', rootDir: dir, sessionId: 'persisted', resume: true });
78
+ check((await readToolCallDetail({ ...options, entries: restored.getDisplayEntries() }))?.result.text === detail?.result.text);
79
+ check(detail?.result.state === 'complete' && detail.result.text.includes('FULL_END'));
80
+ check(!JSON.stringify(detail).includes('OUTPUT_SECRET'));
81
+ check(!JSON.stringify(await readToolCallDetail({ ...options, entries, redact: value => registry.redact(value) })).includes('REGISTERED_NOT_IN_ENV'));
82
+ check((await readToolCallDetail({ ...options, entries: JSON.parse(JSON.stringify(entries)) }))?.result.text === detail?.result.text);
83
+ check(await readToolCallDetail({ ...options, entries, expectedSessionId: 'other' }) === undefined);
84
+ check(await readToolCallDetail({ ...options, entries, toolUseId: 'other' }) === undefined);
85
+ check(await readToolCallDetail({ ...options, entries, messageId: 'other' }) === undefined);
86
+ check(await readToolCallDetail({ ...options, entries: [...entries, entry(use)] }) === undefined);
87
+ await fs.rm(path.join(dir, 'tool-results'), { recursive: true });
88
+ check((await readToolCallDetail({ ...options, entries }))?.result.state === 'unavailable');
89
+ const malicious = createToolResultMessage(request, true, '<persisted-output>\nFull output saved to: ' + path.join(dir, '../private.txt') + '\n');
90
+ check((await readToolCallDetail({ ...options, entries: [entry(use), entry(malicious)] }))?.result.state === 'unavailable');
91
+ for (const output of [0, false, [], '', null])
92
+ check((await readToolCallDetail({ ...options, entries: [entry(createToolResultMessage(request, true, output))] }))?.result.state === 'complete');
93
+ check((await readToolCallDetail({ ...options, entries: [entry(createToolResultMessage(request, true, { truncated: true, content: 'preview' }))] }))?.result.state === 'truncated');
94
+ check((await readToolCallDetail({ ...options, entries: [entry(result)] }))?.input.state === 'missing');
95
+ check(!allowToolDetailRequest('https://evil.example', 'localhost:123', 'cross-site'));
96
+ check(allowToolDetailRequest('http://localhost:123', 'localhost:123', 'same-origin'));
97
+ const redacted = JSON.stringify(redactToolDetail({ config: { a: 'PRIVATE_CONFIG' }, thinking: 'HIDDEN', nested: { apiKey: 'KEY' }, error: 'Authorization: Bearer abc123 password=abcd sk-very-secret-key' }));
98
+ for (const secret of ['PRIVATE_CONFIG', 'HIDDEN', 'abc123', 'abcd', 'sk-very-secret-key'])
99
+ check(!redacted.includes(secret));
100
+ check(await readToolCallDetail({ ...options, entries: [entry({ ...use, blocks: [{ type: 'tool_use', ...request, name: 'secret_get' }] })] }) === undefined);
101
+ console.log(`OBS-01 service smoke passed: ${checks} assertions`);
102
+ }
103
+ finally {
104
+ await fs.rm(dir, { recursive: true, force: true });
105
+ }
106
+ //# sourceMappingURL=smoke-tool-call-detail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smoke-tool-call-detail.js","sourceRoot":"","sources":["../../src/web/smoke-tool-call-detail.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,100 @@
1
+ // Real Node HTTP route + WebRepl detail + real disk storage; no model/network provider.
2
+ import assert from 'node:assert/strict';
3
+ import http from 'node:http';
4
+ import fs from 'node:fs/promises';
5
+ import os from 'node:os';
6
+ import path from 'node:path';
7
+ import { runWebServer, WebRepl, restoreWebHistoryLines } from './index.js';
8
+ import { FileToolResultMemory } from '../session/tool-result-memory.js';
9
+ import { createToolResultMessage } from '../types/messages.js';
10
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'obs01-http-'));
11
+ const sessions = new Map();
12
+ for (const id of ['A', 'B']) {
13
+ const dir = path.join(root, id);
14
+ await fs.mkdir(dir);
15
+ const req = { id: 'same-call', name: 'file_read', input: { path: `${id}.txt` } };
16
+ const memory = new FileToolResultMemory({ sessionDir: dir, thresholdChars: 20 });
17
+ const output = await memory.processToolResult(req.id, { content: `SESSION_${id}_ONLY` + 'x'.repeat(100) });
18
+ sessions.set(id, { dir, entries: [{ type: 'message', message: { id: `use-${id}`, role: 'assistant', createdAt: '', blocks: [{ type: 'tool_use', ...req }] } }, { type: 'message', message: { ...createToolResultMessage(req, true, output.output), id: `result-${id}` } }] });
19
+ }
20
+ let server;
21
+ const original = http.createServer;
22
+ const probe = original();
23
+ await new Promise(r => probe.listen(0, "127.0.0.1", r));
24
+ const probeAddress = probe.address();
25
+ assert.ok(probeAddress && typeof probeAddress === "object");
26
+ const port = probeAddress.port;
27
+ await new Promise(r => probe.close(() => r()));
28
+ // Capture the real server solely to close it after running its private production route.
29
+ http.createServer = (...args) => { server = original(...args); return server; };
30
+ let executions = 0;
31
+ try {
32
+ await runWebServer(['--host', '127.0.0.1', '--port', String(port)], {
33
+ createRuntime: async (options) => ({ sessionId: options?.sessionId }),
34
+ createRepl: runtime => {
35
+ const id = runtime.sessionId;
36
+ const data = sessions.get(id);
37
+ const fake = { runtime: { engine: { snapshot: () => ({ session: { sessionId: id, sessionDir: data?.dir } }), getDisplayEntries: () => data?.entries ?? [], redactDisplayValue: (v) => v } }, toolCallDetail: WebRepl.prototype.toolCallDetail, submit: () => { executions++; throw new Error('must not execute'); } };
38
+ return fake;
39
+ }
40
+ });
41
+ const address = server.address();
42
+ assert.ok(address && typeof address === 'object');
43
+ const base = `http://127.0.0.1:${address.port}`;
44
+ const url = (s, m = '') => `${base}/api/tool-call-detail?sessionId=${s}&toolUseId=same-call${m ? '&messageId=' + m : ''}`;
45
+ let count = 0;
46
+ const check = (v) => { assert.ok(v); count++; };
47
+ for (const id of ['A', 'B']) {
48
+ const r = await fetch(url(id));
49
+ check(r.status === 200);
50
+ check(r.headers.get('cache-control') === 'no-store');
51
+ const body = await r.json();
52
+ check(body.sessionId === id);
53
+ check(body.result.text.includes(`SESSION_${id}_ONLY`));
54
+ check(!body.result.text.includes(`SESSION_${id === 'A' ? 'B' : 'A'}_ONLY`));
55
+ }
56
+ // Agent source provenance must hold at the ordinary-call HTTP boundary too.
57
+ for (const name of ['subagent_run', 'subagent_get', 'subagent_output']) {
58
+ const request = { id: `legacy-${name}`, name, input: { task_id: 'legacy-task' } };
59
+ const legacy = name === 'subagent_output'
60
+ ? '<retrieval_status>ready</retrieval_status>\n<task_id>legacy-task</task_id>\n<task_type>agent</task_type>\n<status>completed</status>\n<run_generation>2</run_generation>\n<pending_messages>0</pending_messages>\n<requires_resume>false</requires_resume>\n<agent_id>legacy-agent</agent_id>\n<output>PRIVATE_LEGACY_REASONING</output>'
61
+ : { task_id: 'legacy-task', run_generation: 2, status: 'completed', result: { content: 'PRIVATE_LEGACY_REASONING' }, progress: { last_text: 'PRIVATE_LEGACY_PROGRESS' } };
62
+ sessions.get('A').entries.push({ type: 'message', message: createToolResultMessage(request, true, legacy) });
63
+ const r = await fetch(`${base}/api/tool-call-detail?sessionId=A&toolUseId=${request.id}`);
64
+ check(r.status === 200);
65
+ const body = await r.json();
66
+ check(!JSON.stringify(body).includes('PRIVATE_LEGACY_'));
67
+ check(body.result.state === 'unavailable');
68
+ check(body.result.text.includes('legacy-task') && body.result.text.includes('2'));
69
+ const lines = restoreWebHistoryLines({ engine: { getDisplayEntries: () => sessions.get('A').entries } });
70
+ check(!JSON.stringify(lines).includes('PRIVATE_LEGACY_'));
71
+ }
72
+ // Windows junction is an actual filesystem symlink/reparse point, no admin privilege needed.
73
+ const a = sessions.get('A');
74
+ await fs.rm(path.join(a.dir, 'tool-results'), { recursive: true });
75
+ await fs.symlink(path.join(sessions.get('B').dir, 'tool-results'), path.join(a.dir, 'tool-results'), 'junction');
76
+ check((await fs.lstat(path.join(a.dir, 'tool-results'))).isSymbolicLink());
77
+ const attack = await (await fetch(url('A'))).json();
78
+ check(attack.result.state === 'unavailable');
79
+ check(!attack.result.text.includes('SESSION_B_ONLY'));
80
+ await fs.unlink(path.join(a.dir, 'tool-results'));
81
+ // Same caller-selected session cannot request the other session's result-message identity.
82
+ const denied = await fetch(url('A', 'result-B'));
83
+ console.log('Actual cross-session status:', denied.status);
84
+ check(denied.status === 404);
85
+ check(!(await denied.text()).includes('SESSION_B_ONLY'));
86
+ check((await fetch(url('absent'))).status === 404);
87
+ check((await fetch(url('A'), { headers: { Origin: 'https://evil.invalid', 'Sec-Fetch-Site': 'cross-site' } })).status === 403);
88
+ check((await fetch(url('A'), { method: 'POST' })).status === 404);
89
+ check(executions === 0);
90
+ console.log(`OBS-01 real HTTP passed: ${count} assertions; GET read-only, 403/404, two runtime session roots, cross-session message refusal, real junction escape refused`);
91
+ }
92
+ finally {
93
+ http.createServer = original;
94
+ server?.closeAllConnections();
95
+ await new Promise(resolve => server ? server.close(() => resolve()) : resolve());
96
+ // Never recursively follow the test junction on failure.
97
+ await fs.unlink(path.join(root, 'A', 'tool-results')).catch(() => { });
98
+ await fs.rm(root, { recursive: true, force: true });
99
+ }
100
+ //# sourceMappingURL=smoke-tool-call-http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smoke-tool-call-http.js","sourceRoot":"","sources":["../../src/web/smoke-tool-call-http.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAgB,MAAM,sBAAsB,CAAC;AAC7E,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAC,aAAa,CAAC,CAAC,CAAC;AACpE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAgE,CAAC;AACzF,KAAK,MAAM,EAAE,IAAI,CAAC,GAAG,EAAC,GAAG,CAAC,EAAE,CAAC;IAC5B,MAAM,GAAG,GAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAC,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClD,MAAM,GAAG,GAAC,EAAC,EAAE,EAAC,WAAW,EAAC,IAAI,EAAC,WAAW,EAAC,KAAK,EAAC,EAAC,IAAI,EAAC,GAAG,EAAE,MAAM,EAAC,EAAC,CAAC;IACrE,MAAM,MAAM,GAAC,IAAI,oBAAoB,CAAC,EAAC,UAAU,EAAC,GAAG,EAAC,cAAc,EAAC,EAAE,EAAC,CAAC,CAAC;IAC1E,MAAM,MAAM,GAAC,MAAM,MAAM,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,EAAC,EAAC,OAAO,EAAC,WAAW,EAAE,OAAO,GAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAC,CAAC,CAAC;IACnG,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAC,EAAC,GAAG,EAAC,OAAO,EAAC,CAAC,EAAC,IAAI,EAAC,SAAS,EAAC,OAAO,EAAC,EAAC,EAAE,EAAC,OAAO,EAAE,EAAE,EAAC,IAAI,EAAC,WAAW,EAAC,SAAS,EAAC,EAAE,EAAC,MAAM,EAAC,CAAC,EAAC,IAAI,EAAC,UAAU,EAAC,GAAG,GAAG,EAAC,CAAC,EAAC,EAAC,EAAC,EAAC,IAAI,EAAC,SAAS,EAAC,OAAO,EAAC,EAAC,GAAG,uBAAuB,CAAC,GAAG,EAAC,IAAI,EAAC,MAAM,CAAC,MAAM,CAAC,EAAC,EAAE,EAAC,UAAU,EAAE,EAAE,EAAC,EAAC,CAAC,EAAC,CAAC,CAAC;AAC5O,CAAC;AACD,IAAI,MAA+B,CAAC;AACpC,MAAM,QAAQ,GAAC,IAAI,CAAC,YAAY,CAAC;AACjC,MAAM,KAAK,GAAC,QAAQ,EAAE,CAAC;AAAA,MAAM,IAAI,OAAO,CAAO,CAAC,CAAA,EAAE,CAAA,KAAK,CAAC,MAAM,CAAC,CAAC,EAAC,WAAW,EAAC,CAAC,CAAC,CAAC,CAAC;AACjF,MAAM,YAAY,GAAC,KAAK,CAAC,OAAO,EAAE,CAAC;AAAA,MAAM,CAAC,EAAE,CAAC,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,CAAC,CAAC;AAC/F,MAAM,IAAI,GAAC,YAAY,CAAC,IAAI,CAAC;AAAA,MAAM,IAAI,OAAO,CAAO,CAAC,CAAA,EAAE,CAAA,KAAK,CAAC,KAAK,CAAC,GAAE,EAAE,CAAA,CAAC,EAAE,CAAC,CAAC,CAAC;AAC9E,yFAAyF;AACxF,IAA2C,CAAC,YAAY,GAAC,CAAC,GAAG,IAAc,EAAC,EAAE,GAAC,MAAM,GAAE,QAAqB,CAAC,GAAG,IAAI,CAAC,CAAC,CAAA,OAAO,MAAM,CAAC,CAAA,CAAC,CAAC;AACvI,IAAI,UAAU,GAAC,CAAC,CAAC;AACjB,IAAI,CAAC;IACJ,MAAM,YAAY,CAAC,CAAC,QAAQ,EAAC,WAAW,EAAC,QAAQ,EAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAC;QAC/D,aAAa,EAAC,KAAK,EAAC,OAAO,EAAA,EAAE,CAAA,CAAC,EAAC,SAAS,EAAC,OAAO,EAAE,SAAS,EAAW,CAAA;QACtE,UAAU,EAAC,OAAO,CAAA,EAAE;YACnB,MAAM,EAAE,GAAE,OAAyC,CAAC,SAAS,CAAC;YAC9D,MAAM,IAAI,GAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC5B,MAAM,IAAI,GAAC,EAAC,OAAO,EAAC,EAAC,MAAM,EAAC,EAAC,QAAQ,EAAC,GAAE,EAAE,CAAA,CAAC,EAAC,OAAO,EAAC,EAAC,SAAS,EAAC,EAAE,EAAC,UAAU,EAAC,IAAI,EAAE,GAAG,EAAC,EAAC,CAAC,EAAC,iBAAiB,EAAC,GAAE,EAAE,CAAA,IAAI,EAAE,OAAO,IAAE,EAAE,EAAC,kBAAkB,EAAC,CAAI,CAAG,EAAC,EAAE,CAAA,CAAC,EAAC,EAAC,EAAC,cAAc,EAAC,OAAO,CAAC,SAAS,CAAC,cAAc,EAAC,MAAM,EAAC,GAAE,EAAE,GAAC,UAAU,EAAE,CAAC,CAAA,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAA,CAAC,EAAC,CAAC;YACnR,OAAO,IAA0B,CAAC;QACnC,CAAC;KACD,CAAC,CAAC;IACH,MAAM,OAAO,GAAC,MAAO,CAAC,OAAO,EAAE,CAAC;IAAA,MAAM,CAAC,EAAE,CAAC,OAAO,IAAI,OAAO,OAAO,KAAG,QAAQ,CAAC,CAAC;IAChF,MAAM,IAAI,GAAC,oBAAoB,OAAO,CAAC,IAAI,EAAE,CAAC;IAC9C,MAAM,GAAG,GAAC,CAAC,CAAQ,EAAC,CAAC,GAAC,EAAE,EAAC,EAAE,CAAA,GAAG,IAAI,mCAAmC,CAAC,uBAAuB,CAAC,CAAA,CAAC,CAAA,aAAa,GAAC,CAAC,CAAA,CAAC,CAAA,EAAE,EAAE,CAAC;IACpH,IAAI,KAAK,GAAC,CAAC,CAAC;IAAC,MAAM,KAAK,GAAC,CAAC,CAAS,EAAC,EAAE,GAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA,KAAK,EAAE,CAAC,CAAA,CAAC,CAAC;IAC9D,KAAI,MAAM,EAAE,IAAI,CAAC,GAAG,EAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAC,MAAM,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAAA,KAAK,CAAC,CAAC,CAAC,MAAM,KAAG,GAAG,CAAC,CAAC;QAAA,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,KAAG,UAAU,CAAC,CAAC;QACtG,MAAM,IAAI,GAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAAA,KAAK,CAAC,IAAI,CAAC,SAAS,KAAG,EAAE,CAAC,CAAC;QAAA,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;QAAA,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAG,GAAG,CAAA,CAAC,CAAA,GAAG,CAAA,CAAC,CAAA,GAAG,OAAO,CAAC,CAAC,CAAC;IACnL,CAAC;IACD,4EAA4E;IAC5E,KAAK,MAAM,IAAI,IAAI,CAAC,cAAc,EAAE,cAAc,EAAE,iBAAiB,CAAC,EAAE,CAAC;QACxE,MAAM,OAAO,GAAC,EAAC,EAAE,EAAC,UAAU,IAAI,EAAE,EAAC,IAAI,EAAC,KAAK,EAAC,EAAC,OAAO,EAAC,aAAa,EAAC,EAAC,CAAC;QACvE,MAAM,MAAM,GAAC,IAAI,KAAG,iBAAiB;YACpC,CAAC,CAAC,0UAA0U;YAC5U,CAAC,CAAC,EAAC,OAAO,EAAC,aAAa,EAAC,cAAc,EAAC,CAAC,EAAC,MAAM,EAAC,WAAW,EAAC,MAAM,EAAC,EAAC,OAAO,EAAC,0BAA0B,EAAC,EAAC,QAAQ,EAAC,EAAC,SAAS,EAAC,yBAAyB,EAAC,EAAC,CAAC;QAC1J,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAC,IAAI,EAAC,SAAS,EAAC,OAAO,EAAC,uBAAuB,CAAC,OAAO,EAAC,IAAI,EAAC,MAAM,CAAC,EAAC,CAAC,CAAC;QACvG,MAAM,CAAC,GAAC,MAAM,KAAK,CAAC,GAAG,IAAI,+CAA+C,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QACxF,KAAK,CAAC,CAAC,CAAC,MAAM,KAAG,GAAG,CAAC,CAAC;QAAA,MAAM,IAAI,GAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACzD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,KAAG,aAAa,CAAC,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;QAClF,MAAM,KAAK,GAAC,sBAAsB,CAAC,EAAC,MAAM,EAAC,EAAC,iBAAiB,EAAC,GAAE,EAAE,CAAA,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC,OAAO,EAAC,EAAU,CAAC,CAAC;QACzG,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,6FAA6F;IAC7F,MAAM,CAAC,GAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;IAAA,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAC,cAAc,CAAC,EAAC,EAAC,SAAS,EAAC,IAAI,EAAC,CAAC,CAAC;IACzF,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC,GAAG,EAAC,cAAc,CAAC,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAC,cAAc,CAAC,EAAC,UAAU,CAAC,CAAC;IAC9G,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC;IAC1E,MAAM,MAAM,GAAC,MAAM,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAAA,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,KAAG,aAAa,CAAC,CAAC;IAAA,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACnJ,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAC,cAAc,CAAC,CAAC,CAAC;IACjD,2FAA2F;IAC3F,MAAM,MAAM,GAAC,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,EAAC,UAAU,CAAC,CAAC,CAAC;IAAA,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAAA,KAAK,CAAC,MAAM,CAAC,MAAM,KAAG,GAAG,CAAC,CAAC;IAAA,KAAK,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC5L,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,KAAG,GAAG,CAAC,CAAC;IACjD,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAC,EAAC,OAAO,EAAC,EAAC,MAAM,EAAC,sBAAsB,EAAC,gBAAgB,EAAC,YAAY,EAAC,EAAC,CAAC,CAAC,CAAC,MAAM,KAAG,GAAG,CAAC,CAAC;IACpH,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAC,EAAC,MAAM,EAAC,MAAM,EAAC,CAAC,CAAC,CAAC,MAAM,KAAG,GAAG,CAAC,CAAC;IAC5D,KAAK,CAAC,UAAU,KAAG,CAAC,CAAC,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC,4BAA4B,KAAK,6HAA6H,CAAC,CAAC;AAC7K,CAAC;QAAS,CAAC;IACT,IAA2C,CAAC,YAAY,GAAC,QAAQ,CAAC;IACnE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAAA,MAAM,IAAI,OAAO,CAAO,OAAO,CAAA,EAAE,CAAA,MAAM,CAAA,CAAC,CAAA,MAAM,CAAC,KAAK,CAAC,GAAE,EAAE,CAAA,OAAO,EAAE,CAAC,CAAA,CAAC,CAAA,OAAO,EAAE,CAAC,CAAC;IAC7G,yDAAyD;IACzD,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAC,GAAG,EAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,GAAE,EAAE,GAAC,CAAC,CAAC,CAAC;IAClE,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,EAAC,EAAC,SAAS,EAAC,IAAI,EAAC,KAAK,EAAC,IAAI,EAAC,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,121 @@
1
+ // Real Node HTTP route + WebRepl detail + real disk storage; no model/network provider.
2
+ import assert from 'node:assert/strict';
3
+ import http from 'node:http';
4
+ import fs from 'node:fs/promises';
5
+ import os from 'node:os';
6
+ import path from 'node:path';
7
+ import { runWebServer, WebRepl } from './index.js';
8
+ import { FileToolResultMemory } from '../session/tool-result-memory.js';
9
+ import { createToolResultMessage } from '../types/messages.js';
10
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'obs06-http-'));
11
+ const sessions = new Map();
12
+ for (const id of ['A', 'B']) {
13
+ const dir = path.join(root, id);
14
+ await fs.mkdir(dir);
15
+ const req = { id: 'same-call', name: 'file_read', input: { path: `${id}.txt`, offset: 0, limit: 0, description: 'FULL PURPOSE ' + id } };
16
+ const memory = new FileToolResultMemory({ sessionDir: dir, thresholdChars: 20 });
17
+ const output = await memory.processToolResult(req.id, { path: path.join(dir, `${id}.txt`), content: `SESSION_${id}_ONLY` + 'x'.repeat(100) });
18
+ sessions.set(id, { dir, entries: [{ type: 'message', message: { id: `use-${id}`, role: 'assistant', createdAt: '', blocks: [{ type: 'tool_use', ...req }] } }, { type: 'message', message: { ...createToolResultMessage(req, true, output.output), id: `result-${id}` } }] });
19
+ }
20
+ let server;
21
+ const original = http.createServer;
22
+ const probe = original();
23
+ await new Promise(r => probe.listen(0, "127.0.0.1", r));
24
+ const probeAddress = probe.address();
25
+ assert.ok(probeAddress && typeof probeAddress === "object");
26
+ const port = probeAddress.port;
27
+ await new Promise(r => probe.close(() => r()));
28
+ // Capture the real server solely to close it after running its private production route.
29
+ http.createServer = (...args) => { server = original(...args); return server; };
30
+ let executions = 0;
31
+ try {
32
+ await runWebServer(['--host', '127.0.0.1', '--port', String(port)], {
33
+ createRuntime: async (options) => ({ sessionId: options?.sessionId }),
34
+ createRepl: runtime => {
35
+ const id = runtime.sessionId;
36
+ const data = sessions.get(id);
37
+ const fake = { runtime: { engine: { snapshot: () => ({ session: { sessionId: id, sessionDir: data?.dir } }), getDisplayEntries: () => data?.entries ?? [], redactDisplayValue: (v) => v } }, toolCallDetail: WebRepl.prototype.toolCallDetail, submit: () => { executions++; throw new Error('must not execute'); } };
38
+ return fake;
39
+ }
40
+ });
41
+ const address = server.address();
42
+ assert.ok(address && typeof address === 'object');
43
+ const base = `http://127.0.0.1:${address.port}`;
44
+ const url = (s, m = '') => `${base}/api/tool-call-detail?sessionId=${s}&toolUseId=same-call${m ? '&messageId=' + m : ''}`;
45
+ let count = 0;
46
+ const check = (v) => { assert.ok(v); count++; };
47
+ for (const id of ['A', 'B']) {
48
+ const r = await fetch(url(id));
49
+ check(r.status === 200);
50
+ check(r.headers.get('cache-control') === 'no-store');
51
+ const body = await r.json();
52
+ check(body.sessionId === id);
53
+ check(body.fields.purpose.value === 'FULL PURPOSE ' + id);
54
+ check(body.fields.actualPath.copyValue === path.join(sessions.get(id).dir, `${id}.txt`));
55
+ check(body.fields.keyParameters.find((p) => p.key === 'offset').value === 0);
56
+ check(body.result.text.includes(`SESSION_${id}_ONLY`));
57
+ check(!body.result.text.includes(`SESSION_${id === 'A' ? 'B' : 'A'}_ONLY`));
58
+ }
59
+ // Exercise real production route classification for non-file contracts and old records.
60
+ const data = sessions.get('A');
61
+ const cases = [
62
+ { name: 'web_search', input: { query: 'q', provider: 'openai', includeDomains: [], startPublishedDate: '2026-01-01' }, output: { provider: 'exa', results: [] } },
63
+ { name: 'file_edit', input: { path: 'relative', oldString: '', newString: 'line1\nline2', replaceAll: false }, output: { path: path.join(data.dir, 'real.txt') } },
64
+ { name: 'subagent_message', input: { target: 'worker', message: 'LONG_BODY_'.repeat(3000) }, output: { task_id: 'resolved-task', run_generation: 0 } },
65
+ { name: 'file_read', input: undefined, output: { truncated: true, path: path.join(data.dir, 'preview.txt') } },
66
+ ];
67
+ for (const [i, c] of cases.entries()) {
68
+ const req = { id: 'fields-' + i, name: c.name, input: c.input };
69
+ data.entries.push({ type: 'message', message: { id: 'use-fields-' + i, role: 'assistant', createdAt: '', blocks: [{ type: 'tool_use', ...req }] } }, { type: 'message', message: createToolResultMessage(req, true, c.output) });
70
+ const r = await fetch(`${base}/api/tool-call-detail?sessionId=A&toolUseId=${req.id}`);
71
+ check(r.status === 200);
72
+ const d = await r.json();
73
+ const f = d.fields;
74
+ if (i === 0) {
75
+ check(f.actualProvider.value === 'exa');
76
+ check(f.result.empty);
77
+ check(f.keyParameters.find((p) => p.key === 'excludeDomains').state === 'unspecified');
78
+ }
79
+ if (i === 1) {
80
+ check(f.actualPath.copyValue === c.output.path);
81
+ check(f.keyParameters.find((p) => p.key === 'replaceAll').value === false);
82
+ }
83
+ if (i === 2) {
84
+ check(f.object.value === 'resolved-task');
85
+ check(f.keyParameters.find((p) => p.key === 'message').value === c.input.message);
86
+ }
87
+ if (i === 3) {
88
+ check(f.input.completeness === 'missing');
89
+ check(f.actualPath.copyValue === undefined);
90
+ check(f.actualPath.completeness === 'truncated');
91
+ }
92
+ }
93
+ // Windows junction is an actual filesystem symlink/reparse point, no admin privilege needed.
94
+ const a = sessions.get('A');
95
+ await fs.rm(path.join(a.dir, 'tool-results'), { recursive: true });
96
+ await fs.symlink(path.join(sessions.get('B').dir, 'tool-results'), path.join(a.dir, 'tool-results'), 'junction');
97
+ check((await fs.lstat(path.join(a.dir, 'tool-results'))).isSymbolicLink());
98
+ const attack = await (await fetch(url('A'))).json();
99
+ check(attack.result.state === 'unavailable');
100
+ check(!attack.result.text.includes('SESSION_B_ONLY'));
101
+ await fs.unlink(path.join(a.dir, 'tool-results'));
102
+ // Same caller-selected session cannot request the other session's result-message identity.
103
+ const denied = await fetch(url('A', 'result-B'));
104
+ console.log('Actual cross-session status:', denied.status);
105
+ check(denied.status === 404);
106
+ check(!(await denied.text()).includes('SESSION_B_ONLY'));
107
+ check((await fetch(url('absent'))).status === 404);
108
+ check((await fetch(url('A'), { headers: { Origin: 'https://evil.invalid', 'Sec-Fetch-Site': 'cross-site' } })).status === 403);
109
+ check((await fetch(url('A'), { method: 'POST' })).status === 404);
110
+ check(executions === 0);
111
+ console.log(`OBS-06 real HTTP fields passed: ${count} assertions; GET read-only, 403/404, two runtime session roots, cross-session message refusal, real junction escape refused`);
112
+ }
113
+ finally {
114
+ http.createServer = original;
115
+ server?.closeAllConnections();
116
+ await new Promise(resolve => server ? server.close(() => resolve()) : resolve());
117
+ // Never recursively follow the test junction on failure.
118
+ await fs.unlink(path.join(root, 'A', 'tool-results')).catch(() => { });
119
+ await fs.rm(root, { recursive: true, force: true });
120
+ }
121
+ //# sourceMappingURL=smoke-tool-detail-fields-http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smoke-tool-detail-fields-http.js","sourceRoot":"","sources":["../../src/web/smoke-tool-detail-fields-http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,50 @@
1
+ import assert from 'node:assert/strict';
2
+ import { createLocalAgentTask } from '../agents/local-agent-task.js';
3
+ import { WebRepl } from './index.js';
4
+ const task = createLocalAgentTask({ taskId: 'task_ui', agentId: 'agent_ui', description: 'UI regression', prompt: 'private prompt' });
5
+ task.status = 'running';
6
+ task.runGeneration = 2;
7
+ const result = { agent_id: task.agentId, agent_type: 'general', content: 'old report', total_duration_ms: 0, total_tool_use_count: 0, usage: { secret: 'private usage' } };
8
+ task.result = result;
9
+ task.runHistory = [{ runGeneration: 1, status: 'completed', result, progress: task.progress, archivedAt: new Date().toISOString() }];
10
+ const tasks = [task];
11
+ const runtime = {
12
+ taskStore: { list: () => tasks, subscribe: () => () => undefined, isTerminal: (value) => ['completed', 'failed', 'killed'].includes(value.status) },
13
+ execProcessManager: { list: () => [], subscribe: () => () => undefined, subscribeOutput: () => () => undefined },
14
+ engine: { getDisplayEntries: () => [], getHistoryMessages: () => [], snapshot: () => ({ messages: 0, session: { sessionId: 'ui-smoke' } }), isFastMode: () => false, getAppPrompt: () => ({ hasActivePrompt: false }), onSessionTitleChange: () => () => undefined },
15
+ initialMetrics: {},
16
+ };
17
+ const repl = new WebRepl(runtime);
18
+ const snapshot = () => repl.snapshot();
19
+ let view = snapshot();
20
+ assert.equal(view.backgroundTaskCount, 1);
21
+ assert.equal(view.backgroundTasks[0].runGeneration, 2);
22
+ assert.equal(view.backgroundTasks[0].result, undefined);
23
+ assert.equal(view.backgroundTasks[0].runHistory[0].result.content, 'old report');
24
+ assert.equal(JSON.stringify(view.backgroundTasks).includes('private prompt'), false);
25
+ assert.equal(JSON.stringify(view.backgroundTasks).includes('private usage'), false);
26
+ task.status = 'completed';
27
+ task.result = { ...result, content: 'current report' };
28
+ view = snapshot();
29
+ assert.equal(view.backgroundTaskCount, 0);
30
+ assert.equal(view.agentTaskHistory[0].result.content, 'current report');
31
+ task.result = { ...result, content: 'x'.repeat(10000) };
32
+ task.runGeneration = 6;
33
+ task.runHistory = Array.from({ length: 5 }, (_, i) => ({ runGeneration: i + 1, status: 'completed', result: task.result, progress: task.progress, archivedAt: task.updatedAt }));
34
+ task.messageReceipts = Array.from({ length: 128 }, (_, i) => ({ id: `receipt_${i}`, messageId: `message_${i}`, status: 'delivered', queuedAt: task.createdAt, deliveredAt: task.updatedAt, runGeneration: 6 }));
35
+ task.progress.lastActivity = '2026-01-01T00:00:00.000Z';
36
+ const compact = snapshot().agentTaskHistory[0];
37
+ assert.equal(compact.result.content.length, 1500);
38
+ assert.equal(compact.result.truncated, true);
39
+ assert.equal(compact.runHistory.length, 3);
40
+ assert.equal(compact.runHistory[0].result.content.length, 600);
41
+ assert.equal(compact.runHistory[0].result.truncated, true);
42
+ assert.equal(compact.messageReceipts.length, 20);
43
+ assert.equal(compact.deliveredRetainedThisRun, 128);
44
+ assert.equal(compact.progress.lastActivity, task.progress.lastActivity);
45
+ assert.ok(JSON.stringify(compact).length < 10000);
46
+ for (let i = 0; i < 25; i++)
47
+ tasks.push({ ...task, id: `task_${i}`, taskId: `task_${i}` });
48
+ assert.equal(snapshot().agentTaskHistory.length, 20);
49
+ console.log('web agent tasks smoke ok: active/history split, generation, stale result suppression, bounded projection, no prompt/usage');
50
+ //# sourceMappingURL=smoke-web-agent-tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smoke-web-agent-tasks.js","sourceRoot":"","sources":["../../src/web/smoke-web-agent-tasks.ts"],"names":[],"mappings":"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"}