wtt-connect 0.2.30 → 0.2.31

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wtt-connect",
3
- "version": "0.2.30",
3
+ "version": "0.2.31",
4
4
  "private": false,
5
5
  "description": "WTT-native connector daemon for Codex, Claude Code, Cursor, Gemini, ACP, and other coding agent surfaces.",
6
6
  "type": "module",
package/src/config.js CHANGED
@@ -55,6 +55,8 @@ export function loadConfig(argv = {}) {
55
55
  providerMap: fileConfig.modelSwitch?.providerMap || parseJsonEnv(process.env.WTT_CONNECT_MODEL_PROVIDER_MAP, {}),
56
56
  },
57
57
  workDir,
58
+ cloudSandbox: parseBool(process.env.WTT_CONNECT_CLOUD_SANDBOX, fileConfig.cloudSandbox ?? false),
59
+ persistentOutputDir: process.env.WTT_CONNECT_PERSISTENT_OUTPUT_DIR || process.env.WTT_CONNECT_R2_OUTPUT_DIR || fileConfig.persistentOutputDir || '',
58
60
  model: process.env.WTT_CONNECT_MODEL || fileConfig.model || '',
59
61
  mode,
60
62
  allowYolo: parseBool(process.env.WTT_CONNECT_ALLOW_YOLO, fileConfig.allowYolo ?? mode === 'yolo'),
package/src/main.js CHANGED
@@ -186,7 +186,7 @@ function packageUploadFiles(files, config, argv) {
186
186
  return { path: zipPath, originalFiles: files };
187
187
  }
188
188
 
189
- function resolveUploadFilePath(filePath, config) {
189
+ export function resolveUploadFilePath(filePath, config) {
190
190
  const raw = String(filePath || '').trim();
191
191
  if (!raw) throw new Error('empty file path');
192
192
  const expanded = raw.startsWith('~/') ? path.join(process.env.HOME || '', raw.slice(2)) : raw;
@@ -197,9 +197,10 @@ function resolveUploadFilePath(filePath, config) {
197
197
  config.artifactDir,
198
198
  config.storeFile ? path.dirname(config.storeFile) : '',
199
199
  config.inboxDir,
200
+ config.persistentOutputDir,
200
201
  ].filter(Boolean).map((root) => path.resolve(root));
201
202
  if (!roots.some((root) => isPathInside(resolved, root))) {
202
- throw new Error(`upload-file refused path outside WTT workspace/state roots: ${resolved}`);
203
+ throw new Error(`upload-file refused path outside WTT workspace/state/persistent roots: ${resolved}`);
203
204
  }
204
205
  return resolved;
205
206
  }
package/src/runner.js CHANGED
@@ -221,6 +221,7 @@ export class Runner {
221
221
  '',
222
222
  staged.promptBlock,
223
223
  renderTranscriptBlock(transcripts),
224
+ renderCloudSandboxStorageInstruction(this.config),
224
225
  renderGeneratedFileArtifactInstruction(this.config, topicId),
225
226
  'Reply naturally and concisely unless the user asks for detail.',
226
227
  ].filter(Boolean).join('\n');
@@ -903,10 +904,11 @@ function truncate(text, maxChars) {
903
904
 
904
905
  function renderGeneratedFileArtifactInstruction(config, topicId = '') {
905
906
  const workDir = config.workDir || process.cwd();
907
+ const outputDir = config.cloudSandbox && config.persistentOutputDir ? config.persistentOutputDir : workDir;
906
908
  const uploadCommand = `wtt-connect upload-file --topic-id ${topicId || '<topic_id>'} --title "optional display name" <file-or-files>`;
907
909
  return [
908
910
  'Generated file artifact rule, for internal execution only:',
909
- `- If you create a user-facing file (.docx, .pptx, .xlsx, .pdf, .csv, .md, .zip, images, or video), save it under your current WTT agent workspace: ${workDir}.`,
911
+ `- If you create a user-facing file (.docx, .pptx, .xlsx, .pdf, .csv, .md, .zip, images, or video), save it under: ${outputDir}.`,
910
912
  `- After creating the file, immediately publish it to this WTT conversation by running: ${uploadCommand}`,
911
913
  '- For multiple related files, pass all file paths to one upload-file command; wtt-connect will package them into one zip before publishing.',
912
914
  '- If upload-file is unavailable, include one marker line per generated file in your final response, exactly like: [WTT_ARTIFACT_FILE path="relative/or/absolute/file.docx" title="optional display name"].',
@@ -915,6 +917,34 @@ function renderGeneratedFileArtifactInstruction(config, topicId = '') {
915
917
  ].join('\n');
916
918
  }
917
919
 
920
+ function renderCloudSandboxStorageInstruction(config) {
921
+ if (!config.cloudSandbox) return '';
922
+ const workDir = config.workDir || process.cwd();
923
+ const persistentDir = String(config.persistentOutputDir || '').trim();
924
+ const lines = [
925
+ 'Cloud Sandbox storage policy, for internal execution only:',
926
+ `- This agent is running inside WTT Cloud Sandbox. Keep the active workspace small: ${workDir}.`,
927
+ ];
928
+ if (persistentDir) {
929
+ lines.push(
930
+ `- Put durable outputs, datasets, downloads, archives, generated reports, build products, and any file expected to survive cleanup under: ${persistentDir}.`,
931
+ `- Create that directory before use: mkdir -p ${shellishQuote(persistentDir)}.`,
932
+ );
933
+ } else {
934
+ lines.push('- Put durable large outputs under the mounted R2 storage area when available, not in the active workspace.');
935
+ }
936
+ lines.push(
937
+ '- Do not install large dependencies, clone large repositories, download datasets, or write bulky generated files into the workspace unless the user explicitly asks for local temporary storage.',
938
+ '- Keep only source edits, small manifests, notes, and temporary scratch files in the workspace.',
939
+ '- If a generated user-facing file is stored in R2/persistent output storage and should appear in WTT chat, still publish it with `wtt-connect upload-file` or a WTT artifact marker.',
940
+ );
941
+ return lines.join('\n');
942
+ }
943
+
944
+ function shellishQuote(value) {
945
+ return `'${String(value).replace(/'/g, `'\\''`)}'`;
946
+ }
947
+
918
948
  async function packageGeneratedFilesIfNeeded(files, config, context = {}) {
919
949
  if (!files.length) return [];
920
950
  if (files.length === 1) return files;
@@ -1351,6 +1381,7 @@ function buildTaskPrompt(task, config, staged = { promptBlock: '' }, transcripts
1351
1381
  renderTranscriptBlock(transcripts),
1352
1382
  '',
1353
1383
  config.requireCommitPush ? 'For code changes, commit and push before final response, and include commit id.' : '',
1384
+ renderCloudSandboxStorageInstruction(config),
1354
1385
  renderGeneratedFileArtifactInstruction(config, task.topic_id || task.topicId || ''),
1355
1386
  'Return a concise final summary with evidence, changed files, tests, artifacts, and blockers.',
1356
1387
  ].filter(Boolean).join('\n');