wtt-connect 0.2.44 → 0.2.45
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 +1 -1
- package/src/main.js +72 -4
- package/src/runner.js +2 -2
package/package.json
CHANGED
package/src/main.js
CHANGED
|
@@ -97,6 +97,9 @@ function parseArgs(args) {
|
|
|
97
97
|
else if (a === '--preview-name') out.previewName = args[++i];
|
|
98
98
|
else if (a === '--preview-token') out.previewToken = args[++i];
|
|
99
99
|
else if (a === '--keep-last') out.keepLast = Number(args[++i]);
|
|
100
|
+
else if (a === '--snapshot-dir') out.snapshotDir = args[++i];
|
|
101
|
+
else if (a === '--snapshot-entry') out.snapshotEntry = args[++i];
|
|
102
|
+
else if (a === '--no-snapshot') out.noSnapshot = true;
|
|
100
103
|
else if (a === '--timeout') out.timeout = Number(args[++i]) * 1000;
|
|
101
104
|
else if (a === '--sender-agent-id') out.senderAgentId = args[++i];
|
|
102
105
|
else if (a === '--sender-token') out.senderToken = args[++i];
|
|
@@ -134,8 +137,8 @@ Commands:
|
|
|
134
137
|
upload-artifact --dir <path> Upload an OpenDesign/artifact directory to WTT
|
|
135
138
|
opendesign-upload --dir <path>
|
|
136
139
|
Alias for upload-artifact
|
|
137
|
-
preview-port --port <port> [--topic-id <id>]
|
|
138
|
-
Create a Cloud Sandbox
|
|
140
|
+
preview-port --port <port> [--topic-id <id>] [--snapshot-dir <dir>]
|
|
141
|
+
Create a Cloud Sandbox preview URL and optional persistent snapshot
|
|
139
142
|
cleanup-previews Stop preview servers previously registered by this agent
|
|
140
143
|
help Show this help
|
|
141
144
|
`);
|
|
@@ -159,7 +162,17 @@ async function previewPort(config, argv) {
|
|
|
159
162
|
const url = preview.preview_url || preview.url;
|
|
160
163
|
if (!url) throw new Error('Cloud Sandbox preview API returned no URL');
|
|
161
164
|
const title = String(argv.title || argv.previewName || preview.name || 'Cloud Sandbox Preview').trim();
|
|
162
|
-
const
|
|
165
|
+
const snapshot = argv.noSnapshot ? null : await createPreviewSnapshot(config, argv, { title });
|
|
166
|
+
const snapshotUrl = snapshot?.snapshot_url || '';
|
|
167
|
+
const markdown = JSON.stringify({
|
|
168
|
+
type: 'cloud_sandbox_preview',
|
|
169
|
+
title,
|
|
170
|
+
preview_url: url,
|
|
171
|
+
url,
|
|
172
|
+
...(snapshotUrl ? { snapshot_url: snapshotUrl } : {}),
|
|
173
|
+
...(snapshot?.artifact_url ? { artifact_url: snapshot.artifact_url } : {}),
|
|
174
|
+
...(snapshot?.artifact_id ? { artifact_id: snapshot.artifact_id } : {}),
|
|
175
|
+
});
|
|
163
176
|
const topicId = String(argv.topicId || argv.sourceId || '').trim();
|
|
164
177
|
let published = null;
|
|
165
178
|
if (topicId) {
|
|
@@ -170,6 +183,8 @@ async function previewPort(config, argv) {
|
|
|
170
183
|
type: 'cloud_sandbox_preview',
|
|
171
184
|
port,
|
|
172
185
|
preview_url: url,
|
|
186
|
+
...(snapshotUrl ? { snapshot_url: snapshotUrl } : {}),
|
|
187
|
+
...(snapshot?.artifact_id ? { artifact_id: snapshot.artifact_id } : {}),
|
|
173
188
|
preview_cleanup: cleanup,
|
|
174
189
|
});
|
|
175
190
|
} finally {
|
|
@@ -177,7 +192,60 @@ async function previewPort(config, argv) {
|
|
|
177
192
|
}
|
|
178
193
|
}
|
|
179
194
|
recordPreview(config, { port, url, name: preview.name || title });
|
|
180
|
-
console.log(JSON.stringify({ ok: true, port, url, preview_url: url, markdown, cleanup, published }, null, 2));
|
|
195
|
+
console.log(JSON.stringify({ ok: true, port, url, preview_url: url, snapshot, markdown, cleanup, published }, null, 2));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async function createPreviewSnapshot(config, argv, { title = 'Cloud Sandbox Preview' } = {}) {
|
|
199
|
+
const dir = String(argv.snapshotDir || '').trim();
|
|
200
|
+
if (!dir) return null;
|
|
201
|
+
const resolved = resolveSnapshotDir(dir, config);
|
|
202
|
+
if (!fs.existsSync(resolved) || !fs.statSync(resolved).isDirectory()) {
|
|
203
|
+
throw new Error(`snapshot directory not found: ${resolved}`);
|
|
204
|
+
}
|
|
205
|
+
const store = new DurableStore(config.storeFile).load();
|
|
206
|
+
const artifacts = new ArtifactManager(config, store);
|
|
207
|
+
const entry = String(argv.snapshotEntry || 'index.html').trim();
|
|
208
|
+
const artifact = await artifacts.uploadDirectory(resolved, {
|
|
209
|
+
source: 'cloud_sandbox_preview',
|
|
210
|
+
sourceId: String(argv.topicId || argv.sourceId || ''),
|
|
211
|
+
title,
|
|
212
|
+
entry,
|
|
213
|
+
type: 'cloud_sandbox_preview_snapshot',
|
|
214
|
+
metadata: {
|
|
215
|
+
uploaded_by: 'wtt-connect',
|
|
216
|
+
command: 'preview-port',
|
|
217
|
+
live_preview_port: Number(argv.port || argv._?.[0] || 0),
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
const previewUrl = absoluteWttUrl(config.wttBaseUrl, artifact.preview_url || artifact.url || '');
|
|
221
|
+
return {
|
|
222
|
+
artifact_id: artifact.artifact_id || artifact.id || '',
|
|
223
|
+
artifact_url: absoluteWttUrl(config.wttBaseUrl, artifact.url || ''),
|
|
224
|
+
snapshot_url: previewUrl,
|
|
225
|
+
entry,
|
|
226
|
+
dir: resolved,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function resolveSnapshotDir(dir, config) {
|
|
231
|
+
const expanded = dir.startsWith('~/') ? path.join(process.env.HOME || '', dir.slice(2)) : dir;
|
|
232
|
+
const base = path.resolve(config.workDir || process.cwd());
|
|
233
|
+
const resolved = path.resolve(path.isAbsolute(expanded) ? expanded : path.join(base, expanded));
|
|
234
|
+
const roots = [
|
|
235
|
+
config.workDir,
|
|
236
|
+
config.artifactDir,
|
|
237
|
+
config.persistentOutputDir,
|
|
238
|
+
].filter(Boolean).map((root) => path.resolve(root));
|
|
239
|
+
if (!roots.some((root) => isPathInside(resolved, root))) {
|
|
240
|
+
throw new Error(`snapshot-dir refused path outside WTT workspace/state/persistent roots: ${resolved}`);
|
|
241
|
+
}
|
|
242
|
+
return resolved;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function absoluteWttUrl(base, maybeRelative) {
|
|
246
|
+
if (!maybeRelative) return '';
|
|
247
|
+
if (/^https?:\/\//i.test(maybeRelative)) return maybeRelative;
|
|
248
|
+
return `${String(base || '').replace(/\/$/, '')}${String(maybeRelative).startsWith('/') ? '' : '/'}${maybeRelative}`;
|
|
181
249
|
}
|
|
182
250
|
|
|
183
251
|
async function cleanupPreviewsCommand(config, argv) {
|
package/src/runner.js
CHANGED
|
@@ -943,11 +943,11 @@ function renderCloudSandboxStorageInstruction(config, topicId = '') {
|
|
|
943
943
|
'- Before publishing a preview URL, verify the server is actually listening and serving content with `curl -fsS http://127.0.0.1:<port>/ >/dev/null`.',
|
|
944
944
|
'- If local curl fails, fix or restart the web server first. Never publish a preview URL for a dead port.',
|
|
945
945
|
'- `wtt-connect preview-port` automatically keeps the most recent preview servers for this agent and stops older registered previews beyond the retention limit. Default retention is 3 live previews; use `--keep-last <n>` only when the user asks.',
|
|
946
|
-
'- For
|
|
946
|
+
'- For static pages, animations, charts, dashboards, and HTML demos, pass the generated static directory to `wtt-connect preview-port --snapshot-dir <dir> --snapshot-entry index.html` so WTT stores a persistent snapshot fallback. Live preview URLs are for recent interactive previews; snapshots/artifacts preserve history after cleanup.',
|
|
947
947
|
'- If you start a web server in the sandbox and the user should preview it, call the Cloudflare Sandbox outbound Worker directly with curl and include the returned `preview_url` in your reply as `[preview_url:Short Title](<preview_url>)`.',
|
|
948
948
|
'- Preview ports must be 1024-65535 and cannot be 3000. For Vite/Next-style dev servers prefer 5173, 4173, or 8080.',
|
|
949
949
|
`- Preview curl rule: curl -sS -X POST "\${WTT_SANDBOX_OUTBOX_URL:-http://wtt.preview}/preview-port" -H 'content-type: application/json' -d '{"agent_id":"'\${WTT_AGENT_ID:-cloud-agent}'","port":<port>}'`,
|
|
950
|
-
`- Prefer automatic WTT publishing when topic id is available: wtt-connect preview-port --port <port>${topicId ? ` --topic-id ${topicId}` : ' --topic-id <topic_id>'} --title "Short Title". This publishes a cloud_sandbox_preview card
|
|
950
|
+
`- Prefer automatic WTT publishing when topic id is available: wtt-connect preview-port --port <port>${topicId ? ` --topic-id ${topicId}` : ' --topic-id <topic_id>'} --title "Short Title" --snapshot-dir <static_dir> --snapshot-entry index.html. This publishes a cloud_sandbox_preview card with live and snapshot URLs.`,
|
|
951
951
|
);
|
|
952
952
|
return lines.join('\n');
|
|
953
953
|
}
|