thinkpool-pair 0.7.299 → 0.7.301
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/codex-session.mjs +1 -2
- package/package.json +1 -1
- package/thinkpool-capabilities.json +3 -3
- package/viewport.mjs +18 -3
package/codex-session.mjs
CHANGED
|
@@ -577,14 +577,13 @@ export function startCodexSession({ cwd, model, effort: initialEffort = 'high',
|
|
|
577
577
|
appServerThreadReady = true
|
|
578
578
|
pushMappedEvent({ type: 'thread.started', thread_id: sessionId })
|
|
579
579
|
return true
|
|
580
|
-
} catch
|
|
580
|
+
} catch {
|
|
581
581
|
// Fallback is safe only here: no turn/start request has been accepted, so
|
|
582
582
|
// there is no possibility of running the same prompt twice.
|
|
583
583
|
appServerDisabled = true
|
|
584
584
|
try { appServer?.end() } catch { /* noop */ }
|
|
585
585
|
appServer = null
|
|
586
586
|
appServerThreadReady = false
|
|
587
|
-
note(`Codex App Server unavailable; using codex exec: ${error?.message || error}`)
|
|
588
587
|
return false
|
|
589
588
|
}
|
|
590
589
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"bundleVersion":
|
|
3
|
+
"bundleVersion": 10,
|
|
4
4
|
"contracts": [
|
|
5
5
|
{
|
|
6
6
|
"id": "room-coordination",
|
|
@@ -88,13 +88,13 @@
|
|
|
88
88
|
},
|
|
89
89
|
{
|
|
90
90
|
"id": "visual-proof",
|
|
91
|
-
"version":
|
|
91
|
+
"version": 2,
|
|
92
92
|
"routes": [
|
|
93
93
|
{
|
|
94
94
|
"id": "visual-proof",
|
|
95
95
|
"tools": ["preview_start", "preview_capture", "preview_inspect", "preview_stop"],
|
|
96
96
|
"trigger": "\\b(ui|ux|visual|design|frontend|html|css|page|route|mockup|screenshot|responsive|desktop|mobile|preview)\\b",
|
|
97
|
-
"prompt": "For built visual work, run the build, use preview_start, preview_capture at desktop and mobile, preview_inspect when rendered state matters, and preview_stop when finished. Surface PNG evidence only when no interactive source-backed Design card is displayed."
|
|
97
|
+
"prompt": "For built visual work, run the build, use preview_start, preview_capture at desktop and mobile, preview_inspect when rendered state matters, and preview_stop when finished. preview_capture uses a fresh isolated browser, so authenticated app routes require an authenticated visual harness; if a room route resolves to the signed-out invitation, the capture is rejected and no mockup card is created. Surface PNG evidence only when no interactive source-backed Design card is displayed."
|
|
98
98
|
}
|
|
99
99
|
],
|
|
100
100
|
"impact": [
|
package/viewport.mjs
CHANGED
|
@@ -64,6 +64,12 @@ export function safeSlug(value = 'viewport') {
|
|
|
64
64
|
.slice(0, 56) || 'viewport'
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
export function isSignedOutRoomPreview(route, snapshot) {
|
|
68
|
+
const parsed = new URL(normalizeRoute(route), 'http://127.0.0.1')
|
|
69
|
+
if (!parsed.searchParams.get('r')) return false
|
|
70
|
+
return /\bid\s*=\s*["']invitation-room-title["']/i.test(String(snapshot || ''))
|
|
71
|
+
}
|
|
72
|
+
|
|
67
73
|
export function findBrowserExecutable({ env = process.env, platform = process.platform, exists = fs.existsSync } = {}) {
|
|
68
74
|
const candidates = [
|
|
69
75
|
env.TP_BROWSER_PATH,
|
|
@@ -425,6 +431,17 @@ export class ViewportManager {
|
|
|
425
431
|
if (names.some((name) => !DEFAULT_VIEWPORTS[name])) throw new Error('viewports must be "both", "desktop", or "mobile".')
|
|
426
432
|
await fsp.mkdir(this.outbox, { recursive: true })
|
|
427
433
|
const slug = `${safeSlug(title)}-${Date.now().toString(36)}`
|
|
434
|
+
// A preview browser is deliberately isolated and cannot inherit the room
|
|
435
|
+
// member's Supabase session. Catch the production failure mode where an
|
|
436
|
+
// agent requests /?r=ROOM expecting Code, but actually renders the public
|
|
437
|
+
// invitation landing and publishes it under an unrelated feature title.
|
|
438
|
+
// Validate before writing screenshots or a manifest so no misleading card
|
|
439
|
+
// can enter the room.
|
|
440
|
+
const snapshotViewport = names.includes('desktop') ? DEFAULT_VIEWPORTS.desktop : DEFAULT_VIEWPORTS[names[0]]
|
|
441
|
+
const snapshot = await this.browser.snapshot({ url, viewport: snapshotViewport, waitMs })
|
|
442
|
+
if (isSignedOutRoomPreview(normalizedRoute, snapshot)) {
|
|
443
|
+
throw new Error('Preview resolved to the signed-out room invitation instead of the authenticated Code room. preview_capture uses a fresh isolated browser and cannot inherit a person\'s login. Use an authenticated visual harness or signed-in browser evidence; no mockup card was created.')
|
|
444
|
+
}
|
|
428
445
|
const captures = {}
|
|
429
446
|
for (const name of names) {
|
|
430
447
|
const result = await this.browser.capture({ url, viewport: DEFAULT_VIEWPORTS[name], fullPage, waitMs })
|
|
@@ -432,8 +449,6 @@ export class ViewportManager {
|
|
|
432
449
|
await fsp.writeFile(file, result.png)
|
|
433
450
|
captures[name] = { ...result, file }
|
|
434
451
|
}
|
|
435
|
-
const snapshotViewport = names.includes('desktop') ? DEFAULT_VIEWPORTS.desktop : DEFAULT_VIEWPORTS[names[0]]
|
|
436
|
-
const snapshot = await this.browser.snapshot({ url, viewport: snapshotViewport, waitMs })
|
|
437
452
|
const snapshotPath = path.join(this.outbox, `${slug}--source.html`)
|
|
438
453
|
await fsp.writeFile(snapshotPath, snapshot)
|
|
439
454
|
const workspace = await fsp.realpath(this.workspaceRoot)
|
|
@@ -487,7 +502,7 @@ export function createViewportTools({ tool, z, manager }) {
|
|
|
487
502
|
),
|
|
488
503
|
tool(
|
|
489
504
|
'preview_capture',
|
|
490
|
-
'Capture this lane preview at exact desktop (1440×900) and mobile (390×844) CSS viewports. Defaults to both and full-page.
|
|
505
|
+
'Capture this lane preview in a fresh isolated browser at exact desktop (1440×900) and mobile (390×844) CSS viewports. Defaults to both and full-page. Authenticated app routes require an authenticated visual harness; a room route that resolves to the signed-out invitation is rejected. Successful captures return PNGs to your vision context and surface a mockup card in the ThinkPool room.',
|
|
491
506
|
{
|
|
492
507
|
path: z.string().max(500).optional().describe('route within the preview, e.g. / or /settings; never a full URL'),
|
|
493
508
|
viewports: z.enum(['both', 'desktop', 'mobile']).optional(),
|