wtt-connect 0.2.32 → 0.2.33

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.32",
3
+ "version": "0.2.33",
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/main.js CHANGED
@@ -35,6 +35,7 @@ export async function main(args) {
35
35
  if (cmd === 'smoke-chat') return smokeChat(loadConfig(argv), argv);
36
36
  if (cmd === 'upload-file' || cmd === 'send-file') return uploadFile(loadConfig(argv), argv);
37
37
  if (cmd === 'upload-artifact' || cmd === 'opendesign-upload') return uploadArtifact(loadConfig(argv), argv);
38
+ if (cmd === 'preview-port' || cmd === 'sandbox-preview') return previewPort(loadConfig(argv), argv);
38
39
  if (cmd === 'start') {
39
40
  const config = loadConfig(argv);
40
41
  if (!config.agentId) throw new Error('WTT_AGENT_ID is required');
@@ -91,6 +92,9 @@ function parseArgs(args) {
91
92
  else if (a === '--title') out.title = args[++i];
92
93
  else if (a === '--entry') out.entry = args[++i];
93
94
  else if (a === '--type') out.type = args[++i];
95
+ else if (a === '--port') out.port = Number(args[++i]);
96
+ else if (a === '--preview-name') out.previewName = args[++i];
97
+ else if (a === '--preview-token') out.previewToken = args[++i];
94
98
  else if (a === '--timeout') out.timeout = Number(args[++i]) * 1000;
95
99
  else if (a === '--sender-agent-id') out.senderAgentId = args[++i];
96
100
  else if (a === '--sender-token') out.senderToken = args[++i];
@@ -128,10 +132,43 @@ Commands:
128
132
  upload-artifact --dir <path> Upload an OpenDesign/artifact directory to WTT
129
133
  opendesign-upload --dir <path>
130
134
  Alias for upload-artifact
135
+ preview-port --port <port> [--topic-id <id>]
136
+ Create a Cloud Sandbox port preview URL
131
137
  help Show this help
132
138
  `);
133
139
  }
134
140
 
141
+ async function previewPort(config, argv) {
142
+ const port = Number(argv.port || argv._[0]);
143
+ if (!Number.isInteger(port) || port < 1 || port > 65535) {
144
+ throw new Error('preview-port requires --port <1-65535>');
145
+ }
146
+ const api = new WTTApi(config);
147
+ const preview = await api.createSandboxPreviewUrl(port, {
148
+ name: String(argv.previewName || argv.title || '').trim(),
149
+ token: String(argv.previewToken || '').trim(),
150
+ });
151
+ const url = preview.preview_url || preview.url;
152
+ if (!url) throw new Error('Cloud Sandbox preview API returned no URL');
153
+ const markdown = preview.markdown || `[preview_url](${url})`;
154
+ const topicId = String(argv.topicId || argv.sourceId || '').trim();
155
+ let published = null;
156
+ if (topicId) {
157
+ const wtt = new WTTClient(config, async () => {});
158
+ try {
159
+ await wtt.connectForActions();
160
+ published = await wtt.publish(topicId, markdown, argv.semanticType || 'CHAT_REPLY', {
161
+ type: 'cloud_sandbox_preview',
162
+ port,
163
+ preview_url: url,
164
+ });
165
+ } finally {
166
+ await wtt.close();
167
+ }
168
+ }
169
+ console.log(JSON.stringify({ ok: true, port, url, preview_url: url, markdown, published }, null, 2));
170
+ }
171
+
135
172
  async function uploadFile(config, argv) {
136
173
  const topicId = String(argv.topicId || argv.sourceId || '').trim();
137
174
  if (!topicId) throw new Error('upload-file requires --topic-id <topic_id>');
package/src/runner.js CHANGED
@@ -221,7 +221,7 @@ export class Runner {
221
221
  '',
222
222
  staged.promptBlock,
223
223
  renderTranscriptBlock(transcripts),
224
- renderCloudSandboxStorageInstruction(this.config),
224
+ renderCloudSandboxStorageInstruction(this.config, topicId),
225
225
  renderGeneratedFileArtifactInstruction(this.config, topicId),
226
226
  'Reply naturally and concisely unless the user asks for detail.',
227
227
  ].filter(Boolean).join('\n');
@@ -917,7 +917,7 @@ function renderGeneratedFileArtifactInstruction(config, topicId = '') {
917
917
  ].join('\n');
918
918
  }
919
919
 
920
- function renderCloudSandboxStorageInstruction(config) {
920
+ function renderCloudSandboxStorageInstruction(config, topicId = '') {
921
921
  if (!config.cloudSandbox) return '';
922
922
  const workDir = config.workDir || process.cwd();
923
923
  const persistentDir = String(config.persistentOutputDir || '').trim();
@@ -937,6 +937,7 @@ function renderCloudSandboxStorageInstruction(config) {
937
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
938
  '- Keep only source edits, small manifests, notes, and temporary scratch files in the workspace.',
939
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
+ `- If you start a web server in the sandbox and the user should preview it, expose that port with: wtt-connect preview-port --port <port>${topicId ? ` --topic-id ${topicId}` : ' --topic-id <topic_id>'}. This creates a Cloudflare Sandbox preview URL and does not use the legacy artifact/media preview flow.`,
940
941
  );
941
942
  return lines.join('\n');
942
943
  }
@@ -1381,7 +1382,7 @@ function buildTaskPrompt(task, config, staged = { promptBlock: '' }, transcripts
1381
1382
  renderTranscriptBlock(transcripts),
1382
1383
  '',
1383
1384
  config.requireCommitPush ? 'For code changes, commit and push before final response, and include commit id.' : '',
1384
- renderCloudSandboxStorageInstruction(config),
1385
+ renderCloudSandboxStorageInstruction(config, task.topic_id || task.topicId || ''),
1385
1386
  renderGeneratedFileArtifactInstruction(config, task.topic_id || task.topicId || ''),
1386
1387
  'Return a concise final summary with evidence, changed files, tests, artifacts, and blockers.',
1387
1388
  ].filter(Boolean).join('\n');
package/src/wtt-api.js CHANGED
@@ -102,4 +102,16 @@ export class WTTApi {
102
102
  json: { agent_id: this.config.agentId, result },
103
103
  });
104
104
  }
105
+
106
+ async createSandboxPreviewUrl(port, { name = '', token = '' } = {}) {
107
+ if (!this.config.agentId) throw new Error('WTT_AGENT_ID is required');
108
+ return this.request('POST', `/cloud-agents/${encodeURIComponent(this.config.agentId)}/preview`, {
109
+ headers: this.agentHeaders(),
110
+ json: {
111
+ port,
112
+ ...(name ? { name } : {}),
113
+ ...(token ? { token } : {}),
114
+ },
115
+ });
116
+ }
105
117
  }