@deadragdoll/tellymcp 0.0.1

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 (124) hide show
  1. package/.env.example.client +93 -0
  2. package/.env.example.gateway +120 -0
  3. package/CHANGELOG.md +155 -0
  4. package/LICENSE +21 -0
  5. package/README-ru.md +338 -0
  6. package/README.md +1262 -0
  7. package/STANDALONE-ru.md +266 -0
  8. package/STANDALONE.md +266 -0
  9. package/TOOLS.md +1296 -0
  10. package/config/templates/env.both.template +83 -0
  11. package/config/templates/env.client.template +60 -0
  12. package/config/templates/env.gateway.template +82 -0
  13. package/dist/cli.js +636 -0
  14. package/dist/index.js +17 -0
  15. package/dist/lib/logfeed/store.js +52 -0
  16. package/dist/lib/middlewares/tracer.js +172 -0
  17. package/dist/lib/mixins/db.js +267 -0
  18. package/dist/lib/mixins/logfeed.js +34 -0
  19. package/dist/lib/mixins/session.errors.js +142 -0
  20. package/dist/lib/moleculer.js +2 -0
  21. package/dist/lib/trace.js +147 -0
  22. package/dist/lib/traceContext.js +116 -0
  23. package/dist/moleculer.config.js +274 -0
  24. package/dist/services/features/telegram-mcp/approval.service.js +33 -0
  25. package/dist/services/features/telegram-mcp/browser.service.js +42 -0
  26. package/dist/services/features/telegram-mcp/collaboration.service.js +53 -0
  27. package/dist/services/features/telegram-mcp/ensuredb.service.js +337 -0
  28. package/dist/services/features/telegram-mcp/gateway-delivery.service.js +378 -0
  29. package/dist/services/features/telegram-mcp/gateway-loopback.js +10 -0
  30. package/dist/services/features/telegram-mcp/gateway-rmq.service.js +294 -0
  31. package/dist/services/features/telegram-mcp/gateway-socket.service.js +1463 -0
  32. package/dist/services/features/telegram-mcp/gateway.service.js +1141 -0
  33. package/dist/services/features/telegram-mcp/inbox.service.js +33 -0
  34. package/dist/services/features/telegram-mcp/mcp-http.service.js +76 -0
  35. package/dist/services/features/telegram-mcp/mcp-server.service.js +127 -0
  36. package/dist/services/features/telegram-mcp/notify.service.js +33 -0
  37. package/dist/services/features/telegram-mcp/pair.service.js +33 -0
  38. package/dist/services/features/telegram-mcp/runtime.service.js +36 -0
  39. package/dist/services/features/telegram-mcp/session-context.service.js +33 -0
  40. package/dist/services/features/telegram-mcp/src/app/bootstrap/runtime.js +103 -0
  41. package/dist/services/features/telegram-mcp/src/app/config/env.js +317 -0
  42. package/dist/services/features/telegram-mcp/src/app/http.js +774 -0
  43. package/dist/services/features/telegram-mcp/src/app/index.js +2 -0
  44. package/dist/services/features/telegram-mcp/src/app/providers/mcp/server.js +13 -0
  45. package/dist/services/features/telegram-mcp/src/app/providers/redis/client.js +18 -0
  46. package/dist/services/features/telegram-mcp/src/app/webapp/assets.js +740 -0
  47. package/dist/services/features/telegram-mcp/src/app/webapp/auth.js +267 -0
  48. package/dist/services/features/telegram-mcp/src/app/webapp/relay.js +69 -0
  49. package/dist/services/features/telegram-mcp/src/app/webapp/tmux.js +9 -0
  50. package/dist/services/features/telegram-mcp/src/entities/auth/model/types.js +2 -0
  51. package/dist/services/features/telegram-mcp/src/entities/browser/model/types.js +2 -0
  52. package/dist/services/features/telegram-mcp/src/entities/collaboration/model/types.js +2 -0
  53. package/dist/services/features/telegram-mcp/src/entities/inbox/model/types.js +2 -0
  54. package/dist/services/features/telegram-mcp/src/entities/request/model/schema.js +545 -0
  55. package/dist/services/features/telegram-mcp/src/entities/request/model/types.js +2 -0
  56. package/dist/services/features/telegram-mcp/src/entities/session/model/types.js +2 -0
  57. package/dist/services/features/telegram-mcp/src/features/ask-user/model/askUserTelegram.js +33 -0
  58. package/dist/services/features/telegram-mcp/src/features/browser/model/browserClearLogsTool.js +28 -0
  59. package/dist/services/features/telegram-mcp/src/features/browser/model/browserClickTool.js +28 -0
  60. package/dist/services/features/telegram-mcp/src/features/browser/model/browserCloseTool.js +28 -0
  61. package/dist/services/features/telegram-mcp/src/features/browser/model/browserComputedStyleTool.js +28 -0
  62. package/dist/services/features/telegram-mcp/src/features/browser/model/browserConsoleTool.js +28 -0
  63. package/dist/services/features/telegram-mcp/src/features/browser/model/browserDomTool.js +28 -0
  64. package/dist/services/features/telegram-mcp/src/features/browser/model/browserErrorsTool.js +28 -0
  65. package/dist/services/features/telegram-mcp/src/features/browser/model/browserFillTool.js +28 -0
  66. package/dist/services/features/telegram-mcp/src/features/browser/model/browserNetworkFailuresTool.js +28 -0
  67. package/dist/services/features/telegram-mcp/src/features/browser/model/browserOpenTool.js +33 -0
  68. package/dist/services/features/telegram-mcp/src/features/browser/model/browserPressTool.js +28 -0
  69. package/dist/services/features/telegram-mcp/src/features/browser/model/browserReloadTool.js +28 -0
  70. package/dist/services/features/telegram-mcp/src/features/browser/model/browserScreenshotTool.js +28 -0
  71. package/dist/services/features/telegram-mcp/src/features/browser/model/browserService.js +689 -0
  72. package/dist/services/features/telegram-mcp/src/features/browser/model/browserWaitForTool.js +28 -0
  73. package/dist/services/features/telegram-mcp/src/features/browser/model/browserWaitForUrlTool.js +28 -0
  74. package/dist/services/features/telegram-mcp/src/features/collaboration/model/backend.js +2 -0
  75. package/dist/services/features/telegram-mcp/src/features/collaboration/model/collaborationService.js +26 -0
  76. package/dist/services/features/telegram-mcp/src/features/collaboration/model/localCollaborationBackend.js +390 -0
  77. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileService.js +102 -0
  78. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileTool.js +33 -0
  79. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerNoteTool.js +33 -0
  80. package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayCollaborationBackend.js +69 -0
  81. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayHttpService.js +657 -0
  82. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayReplyResolution.js +17 -0
  83. package/dist/services/features/telegram-mcp/src/features/inbox/model/deleteTelegramInboxMessageTool.js +33 -0
  84. package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxCountTool.js +33 -0
  85. package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxTool.js +33 -0
  86. package/dist/services/features/telegram-mcp/src/features/inbox/model/inboxService.js +77 -0
  87. package/dist/services/features/telegram-mcp/src/features/notify/model/notifyService.js +93 -0
  88. package/dist/services/features/telegram-mcp/src/features/notify/model/notifyTelegramTool.js +33 -0
  89. package/dist/services/features/telegram-mcp/src/features/pair-session/model/clearSessionPairingTool.js +33 -0
  90. package/dist/services/features/telegram-mcp/src/features/pair-session/model/createSessionPairCodeTool.js +33 -0
  91. package/dist/services/features/telegram-mcp/src/features/pair-session/model/generatePairCode.js +202 -0
  92. package/dist/services/features/telegram-mcp/src/features/session-context/model/clearSessionContextTool.js +33 -0
  93. package/dist/services/features/telegram-mcp/src/features/session-context/model/getSessionContextTool.js +33 -0
  94. package/dist/services/features/telegram-mcp/src/features/session-context/model/getTmuxTargetTool.js +33 -0
  95. package/dist/services/features/telegram-mcp/src/features/session-context/model/renameSessionTool.js +33 -0
  96. package/dist/services/features/telegram-mcp/src/features/session-context/model/sessionContextService.js +409 -0
  97. package/dist/services/features/telegram-mcp/src/features/session-context/model/setSessionContextTool.js +33 -0
  98. package/dist/services/features/telegram-mcp/src/features/session-context/model/setTmuxTargetTool.js +33 -0
  99. package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownService.js +123 -0
  100. package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownTool.js +33 -0
  101. package/dist/services/features/telegram-mcp/src/processes/human-approval/model/orchestrator.js +243 -0
  102. package/dist/services/features/telegram-mcp/src/shared/api/storage/contract.js +2 -0
  103. package/dist/services/features/telegram-mcp/src/shared/api/tool-registry/registry.js +8 -0
  104. package/dist/services/features/telegram-mcp/src/shared/api/tool-registry/types.js +2 -0
  105. package/dist/services/features/telegram-mcp/src/shared/api/transport/contract.js +2 -0
  106. package/dist/services/features/telegram-mcp/src/shared/integrations/object-storage/minioExchangeStore.js +86 -0
  107. package/dist/services/features/telegram-mcp/src/shared/integrations/redis/stateStore.js +436 -0
  108. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/collabSemantics.js +21 -0
  109. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/collabUi.js +87 -0
  110. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/messageFormat.js +60 -0
  111. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/proxyFetch.js +46 -0
  112. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transport.js +6534 -0
  113. package/dist/services/features/telegram-mcp/src/shared/integrations/tmux/client.js +280 -0
  114. package/dist/services/features/telegram-mcp/src/shared/lib/ids/ids.js +34 -0
  115. package/dist/services/features/telegram-mcp/src/shared/lib/logger/logger.js +68 -0
  116. package/dist/services/features/telegram-mcp/src/shared/lib/project-identity/projectIdentity.js +223 -0
  117. package/dist/services/features/telegram-mcp/src/shared/lib/redact-secrets/redactSecrets.js +22 -0
  118. package/dist/services/features/telegram-mcp/src/shared/lib/truncate/truncate.js +12 -0
  119. package/dist/services/features/telegram-mcp/src/shared/lib/version/versionHandshake.js +124 -0
  120. package/dist/services/features/telegram-mcp/src/shared/types/common.js +2 -0
  121. package/dist/services/features/telegram-mcp/standalone-http.service.js +113 -0
  122. package/dist/services/features/telegram-mcp/tools-sync.service.js +33 -0
  123. package/package.json +110 -0
  124. package/scripts/postinstall.js +60 -0
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RefreshToolsMarkdownTool = void 0;
4
+ const schema_1 = require("../../../entities/request/model/schema");
5
+ function createContent(output) {
6
+ return [
7
+ {
8
+ type: "text",
9
+ text: JSON.stringify(output, null, 2),
10
+ },
11
+ ];
12
+ }
13
+ class RefreshToolsMarkdownTool {
14
+ refreshToolsMarkdownService;
15
+ constructor(refreshToolsMarkdownService) {
16
+ this.refreshToolsMarkdownService = refreshToolsMarkdownService;
17
+ }
18
+ register(server) {
19
+ server.registerTool("refresh_tools_markdown", {
20
+ title: "Refresh TOOLS.md",
21
+ description: "Use this when the user asks to refresh or update agent instructions, tools documentation, or gateway-side working rules. Download the canonical TOOLS.md from the configured gateway, overwrite the local workspace TOOLS.md, then re-read that local TOOLS.md before continuing. If no gateway is configured, refresh from the local file.",
22
+ inputSchema: schema_1.refreshToolsMarkdownInputSchema,
23
+ outputSchema: schema_1.refreshToolsMarkdownOutputSchema,
24
+ }, async (args) => {
25
+ const output = await this.refreshToolsMarkdownService.refresh(args);
26
+ return {
27
+ content: createContent(output),
28
+ structuredContent: output,
29
+ };
30
+ });
31
+ }
32
+ }
33
+ exports.RefreshToolsMarkdownTool = RefreshToolsMarkdownTool;
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HumanApprovalOrchestrator = void 0;
4
+ const redactSecrets_1 = require("../../../shared/lib/redact-secrets/redactSecrets");
5
+ const ids_1 = require("../../../shared/lib/ids/ids");
6
+ function mergeSavedContext(input, session) {
7
+ const savedSections = [];
8
+ if (input.use_saved_context && session?.summary) {
9
+ savedSections.push(session.summary);
10
+ }
11
+ if (input.use_saved_context && session?.files?.length) {
12
+ savedSections.push(`Known files:\n${session.files.map((file) => `- ${file}`).join("\n")}`);
13
+ }
14
+ if (input.use_saved_context && session?.decisions?.length) {
15
+ savedSections.push(`Known decisions:\n${session.decisions.map((item) => `- ${item}`).join("\n")}`);
16
+ }
17
+ if (input.use_saved_context && session?.risks?.length) {
18
+ savedSections.push(`Known risks:\n${session.risks.map((item) => `- ${item}`).join("\n")}`);
19
+ }
20
+ const mergedContext = [input.context, ...savedSections]
21
+ .filter(Boolean)
22
+ .join("\n\n")
23
+ .trim();
24
+ return {
25
+ ...(mergedContext ? { context: mergedContext } : {}),
26
+ ...(input.task
27
+ ? { task: input.task }
28
+ : session?.task
29
+ ? { task: session.task }
30
+ : {}),
31
+ ...(session?.label ? { sessionLabel: session.label } : {}),
32
+ };
33
+ }
34
+ class HumanApprovalOrchestrator {
35
+ config;
36
+ sessionStore;
37
+ bindingStore;
38
+ pendingStore;
39
+ transport;
40
+ logger;
41
+ projectIdentityResolver;
42
+ processingQueue = false;
43
+ queuedJobs = new Map();
44
+ constructor(config, sessionStore, bindingStore, pendingStore, transport, logger, projectIdentityResolver) {
45
+ this.config = config;
46
+ this.sessionStore = sessionStore;
47
+ this.bindingStore = bindingStore;
48
+ this.pendingStore = pendingStore;
49
+ this.transport = transport;
50
+ this.logger = logger;
51
+ this.projectIdentityResolver = projectIdentityResolver;
52
+ }
53
+ async submit(input) {
54
+ const resolved = this.projectIdentityResolver.resolveSessionDefaults({
55
+ session_id: input.session_id,
56
+ });
57
+ const binding = await this.bindingStore.getBinding(resolved.sessionId);
58
+ if (!binding) {
59
+ throw new Error("Session is not linked to Telegram. Call create_session_pair_code first.");
60
+ }
61
+ const session = await this.sessionStore.getSession(resolved.sessionId);
62
+ const merged = mergeSavedContext(input, session);
63
+ const requestId = (0, ids_1.createRequestId)();
64
+ const requestRecord = {
65
+ requestId,
66
+ sessionId: resolved.sessionId,
67
+ ...(merged.sessionLabel
68
+ ? { sessionLabel: merged.sessionLabel }
69
+ : resolved.sessionLabel
70
+ ? { sessionLabel: resolved.sessionLabel }
71
+ : {}),
72
+ question: (0, redactSecrets_1.redactSecrets)(input.question),
73
+ ...(merged.task ? { task: (0, redactSecrets_1.redactSecrets)(merged.task) } : {}),
74
+ ...(merged.context ? { context: (0, redactSecrets_1.redactSecrets)(merged.context) } : {}),
75
+ ...(input.affected_files?.length
76
+ ? {
77
+ affectedFiles: input.affected_files.map((file) => (0, redactSecrets_1.redactSecrets)(file)),
78
+ }
79
+ : {}),
80
+ ...(input.options?.length
81
+ ? { options: input.options.map((option) => (0, redactSecrets_1.redactSecrets)(option)) }
82
+ : {}),
83
+ ...(input.recommended_option
84
+ ? { recommendedOption: (0, redactSecrets_1.redactSecrets)(input.recommended_option) }
85
+ : {}),
86
+ ...(input.risk_level ? { riskLevel: input.risk_level } : {}),
87
+ timeoutSeconds: input.timeout_seconds ?? this.config.telegram.defaultTimeoutSeconds,
88
+ ...(input.fallback_if_timeout
89
+ ? { fallbackIfTimeout: (0, redactSecrets_1.redactSecrets)(input.fallback_if_timeout) }
90
+ : {}),
91
+ telegramChatId: binding.telegramChatId,
92
+ telegramUserId: binding.telegramUserId,
93
+ queuedAt: new Date().toISOString(),
94
+ status: this.config.mode === "queue" ? "queued" : "active",
95
+ };
96
+ if (this.config.mode === "reject") {
97
+ const active = await this.pendingStore.getActive();
98
+ if (active) {
99
+ throw new Error(`Another request is already pending: ${active.requestId}`);
100
+ }
101
+ return this.runRequest(requestRecord);
102
+ }
103
+ return new Promise((resolve, reject) => {
104
+ this.queuedJobs.set(requestId, {
105
+ request: requestRecord,
106
+ resolve,
107
+ reject,
108
+ });
109
+ void this.pendingStore.enqueue(requestRecord).then(() => {
110
+ void this.processQueue();
111
+ }, (error) => {
112
+ this.queuedJobs.delete(requestId);
113
+ reject(error instanceof Error ? error : new Error(String(error)));
114
+ });
115
+ });
116
+ }
117
+ async processQueue() {
118
+ if (this.processingQueue) {
119
+ return;
120
+ }
121
+ this.processingQueue = true;
122
+ try {
123
+ while (true) {
124
+ const next = await this.pendingStore.dequeueNext();
125
+ if (!next) {
126
+ return;
127
+ }
128
+ const queuedJob = this.queuedJobs.get(next.requestId);
129
+ if (!queuedJob) {
130
+ continue;
131
+ }
132
+ try {
133
+ const result = await this.runRequest({
134
+ ...next,
135
+ status: "active",
136
+ });
137
+ this.queuedJobs.delete(next.requestId);
138
+ queuedJob.resolve(result);
139
+ }
140
+ catch (error) {
141
+ this.queuedJobs.delete(next.requestId);
142
+ queuedJob.reject(error instanceof Error ? error : new Error(String(error)));
143
+ }
144
+ }
145
+ }
146
+ finally {
147
+ this.processingQueue = false;
148
+ }
149
+ }
150
+ async runRequest(request) {
151
+ const active = {
152
+ ...request,
153
+ status: "active",
154
+ };
155
+ await this.pendingStore.createPending(active);
156
+ this.logger.info("Pending request created", {
157
+ requestId: active.requestId,
158
+ sessionId: active.sessionId,
159
+ });
160
+ try {
161
+ const sendResult = await this.transport.sendRequest({
162
+ requestId: active.requestId,
163
+ sessionId: active.sessionId,
164
+ ...(active.sessionLabel ? { sessionLabel: active.sessionLabel } : {}),
165
+ recipient: {
166
+ telegramChatId: active.telegramChatId,
167
+ telegramUserId: active.telegramUserId,
168
+ },
169
+ ...(active.task ? { task: active.task } : {}),
170
+ question: active.question,
171
+ ...(active.context ? { context: active.context } : {}),
172
+ ...(active.affectedFiles
173
+ ? { affectedFiles: active.affectedFiles }
174
+ : {}),
175
+ ...(active.options ? { options: active.options } : {}),
176
+ ...(active.recommendedOption
177
+ ? { recommendedOption: active.recommendedOption }
178
+ : {}),
179
+ ...(active.riskLevel ? { riskLevel: active.riskLevel } : {}),
180
+ ...(active.fallbackIfTimeout
181
+ ? { fallbackIfTimeout: active.fallbackIfTimeout }
182
+ : {}),
183
+ });
184
+ const sentRequest = {
185
+ ...active,
186
+ ...(typeof sendResult.externalMessageId === "number"
187
+ ? { telegramMessageId: sendResult.externalMessageId }
188
+ : {}),
189
+ sentAt: new Date().toISOString(),
190
+ };
191
+ await this.pendingStore.updatePending(sentRequest);
192
+ const reply = await this.transport.waitForReply(sentRequest.requestId, sentRequest.timeoutSeconds);
193
+ if (!reply) {
194
+ await this.pendingStore.resolvePending(sentRequest.requestId, {
195
+ status: "timed_out",
196
+ ...(sentRequest.fallbackIfTimeout
197
+ ? { fallbackUsed: sentRequest.fallbackIfTimeout }
198
+ : {}),
199
+ });
200
+ this.logger.warn("Pending request timed out", {
201
+ requestId: sentRequest.requestId,
202
+ });
203
+ return {
204
+ request_id: sentRequest.requestId,
205
+ answer: null,
206
+ timed_out: true,
207
+ ...(sentRequest.fallbackIfTimeout
208
+ ? { fallback_used: sentRequest.fallbackIfTimeout }
209
+ : {}),
210
+ };
211
+ }
212
+ await this.pendingStore.resolvePending(sentRequest.requestId, {
213
+ status: "answered",
214
+ answer: (0, redactSecrets_1.redactSecrets)(reply.answer),
215
+ receivedAt: reply.receivedAt,
216
+ });
217
+ this.logger.info("Pending request answered", {
218
+ requestId: sentRequest.requestId,
219
+ });
220
+ return {
221
+ request_id: sentRequest.requestId,
222
+ answer: (0, redactSecrets_1.redactSecrets)(reply.answer),
223
+ timed_out: false,
224
+ received_at: reply.receivedAt,
225
+ };
226
+ }
227
+ catch (error) {
228
+ await this.pendingStore.resolvePending(active.requestId, {
229
+ status: "failed",
230
+ errorMessage: error instanceof Error ? error.message : String(error),
231
+ });
232
+ this.logger.error("Pending request failed", {
233
+ requestId: active.requestId,
234
+ error: error instanceof Error ? error.message : String(error),
235
+ });
236
+ throw error instanceof Error ? error : new Error(String(error));
237
+ }
238
+ }
239
+ get mode() {
240
+ return this.config.mode;
241
+ }
242
+ }
243
+ exports.HumanApprovalOrchestrator = HumanApprovalOrchestrator;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerTools = registerTools;
4
+ function registerTools(server, tools) {
5
+ for (const tool of tools) {
6
+ tool.register(server);
7
+ }
8
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MinioExchangeStore = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const promises_1 = require("node:fs/promises");
9
+ const client_1 = require("../tmux/client");
10
+ function normalizeRelativePath(relativePath) {
11
+ const normalized = relativePath
12
+ .split(/[/\\]+/u)
13
+ .map((segment) => segment.trim())
14
+ .filter((segment) => segment.length > 0 && segment !== "." && segment !== "..")
15
+ .join("/");
16
+ if (!normalized) {
17
+ throw new Error("Relative exchange path is required.");
18
+ }
19
+ return normalized;
20
+ }
21
+ function resolveWorkspaceDir(session, _tmuxConfig) {
22
+ const workspaceDir = session?.cwd?.trim() || "";
23
+ return workspaceDir || process.cwd();
24
+ }
25
+ class MinioExchangeStore {
26
+ tmuxConfig;
27
+ exchangeDirName;
28
+ logger;
29
+ constructor(_callBroker, _bindingStore, tmuxConfig, exchangeDirName, _vfsScope, logger, _distributedMode = "client", _gatewayPublicUrl, _gatewayAuthToken) {
30
+ this.tmuxConfig = tmuxConfig;
31
+ this.exchangeDirName = exchangeDirName;
32
+ this.logger = logger;
33
+ }
34
+ resolveWorkspaceDir(session) {
35
+ return resolveWorkspaceDir(session, this.tmuxConfig);
36
+ }
37
+ getTempSessionDir(sessionId) {
38
+ return node_path_1.default.resolve(process.cwd(), this.exchangeDirName, "__legacy__", sessionId);
39
+ }
40
+ async storeFile(params) {
41
+ const relativePath = normalizeRelativePath(params.relativePath);
42
+ const workspaceDir = this.resolveWorkspaceDir(params.session);
43
+ const filePath = await (0, client_1.writeXchangeRelativeFile)(this.tmuxConfig, workspaceDir, this.exchangeDirName, relativePath, Buffer.from(params.content));
44
+ this.logger.info("Exchange file stored locally", {
45
+ sessionId: params.sessionId,
46
+ source: params.source,
47
+ relativePath,
48
+ filePath,
49
+ });
50
+ return {
51
+ filePath,
52
+ relativePath,
53
+ sizeBytes: params.content.byteLength,
54
+ };
55
+ }
56
+ async ensureLocalFile(params) {
57
+ const candidates = new Set();
58
+ if (params.filePath?.trim()) {
59
+ candidates.add(node_path_1.default.isAbsolute(params.filePath)
60
+ ? node_path_1.default.resolve(params.filePath)
61
+ : node_path_1.default.resolve(this.resolveWorkspaceDir(params.session), params.filePath));
62
+ }
63
+ if (params.relativePath?.trim()) {
64
+ candidates.add(node_path_1.default.resolve(this.resolveWorkspaceDir(params.session), this.exchangeDirName, normalizeRelativePath(params.relativePath)));
65
+ }
66
+ for (const candidate of candidates) {
67
+ try {
68
+ await (0, promises_1.access)(candidate);
69
+ return candidate;
70
+ }
71
+ catch {
72
+ // try next candidate
73
+ }
74
+ }
75
+ throw new Error(params.storageRef
76
+ ? "Exchange file is not available locally. VFS/S3 relay has been removed."
77
+ : "Exchange file is not available locally.");
78
+ }
79
+ async readStoredContent(_params) {
80
+ throw new Error("Direct VFS/S3 artifact reads are no longer supported.");
81
+ }
82
+ async deleteStoredFile(_params) {
83
+ // Local exchange files are deleted directly by their workspace path.
84
+ }
85
+ }
86
+ exports.MinioExchangeStore = MinioExchangeStore;