shotops-mcp 0.5.0 → 0.7.0
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/LICENSE +97 -0
- package/README.md +157 -64
- package/THIRD_PARTY_NOTICES +156 -0
- package/dist/local.js +5478 -1617
- package/harness-dist/assets/{index-D1u7TBPd.js → index-DvvjdOuK.js} +169 -169
- package/harness-dist/index.html +1 -1
- package/package.json +19 -5
- package/widget-dist/bundle.js +221 -0
- package/widget-dist/panels.js +188 -0
- package/harness-dist/assets/pixel-optimized-DZsBrOgu.glb +0 -0
package/harness-dist/index.html
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<title>shotops-mcp headless render harness</title>
|
|
6
|
-
<script type="module" crossorigin src="./assets/index-
|
|
6
|
+
<script type="module" crossorigin src="./assets/index-DvvjdOuK.js"></script>
|
|
7
7
|
</head>
|
|
8
8
|
<body>
|
|
9
9
|
</body>
|
package/package.json
CHANGED
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shotops-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "The bundle-emitting MCP server over the @engine/@sync spine. Exposes ShotOps tools to ChatGPT, Claude Code, Cursor, and CI over Streamable HTTP with OAuth or personal API tokens. Zero-custody: no code path accepts, stores, or forwards a store-signing credential — upload stays the user's own fastlane. Renders via headless Playwright Chromium, the engine's native non-browser habitat (same path as mockup-mcp). Also ships as a free LOCAL stdio server (`npx shotops-mcp`) — same render, on your own machine, no account needed.",
|
|
7
|
-
"license": "
|
|
7
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
8
|
+
"homepage": "https://shotops.dev",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/rgehrkedk/storeframe-studio.git",
|
|
12
|
+
"directory": "shotops-mcp"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/rgehrkedk/storeframe-studio/issues"
|
|
16
|
+
},
|
|
8
17
|
"bin": {
|
|
9
18
|
"shotops-mcp": "./dist/local.js"
|
|
10
19
|
},
|
|
11
20
|
"files": [
|
|
12
21
|
"dist",
|
|
13
22
|
"harness-dist",
|
|
14
|
-
"
|
|
23
|
+
"widget-dist",
|
|
24
|
+
"README.md",
|
|
25
|
+
"THIRD_PARTY_NOTICES"
|
|
15
26
|
],
|
|
16
27
|
"engines": {
|
|
17
28
|
"node": ">=20.12"
|
|
@@ -21,15 +32,18 @@
|
|
|
21
32
|
"start": "tsx src/server.ts",
|
|
22
33
|
"build:harness": "vite build --config vite.harness.config.mjs",
|
|
23
34
|
"build:node": "node build.mjs",
|
|
24
|
-
"build": "
|
|
35
|
+
"build:server": "node build.server.mjs",
|
|
36
|
+
"build": "npm run build:harness && npm run build:widget && npm run build:node",
|
|
25
37
|
"prepublishOnly": "npm run build",
|
|
26
|
-
"typecheck": "tsc --noEmit"
|
|
38
|
+
"typecheck": "tsc --noEmit",
|
|
39
|
+
"build:widget": "node build.widget.mjs"
|
|
27
40
|
},
|
|
28
41
|
"dependencies": {
|
|
29
42
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
30
43
|
"express": "^5.2.1",
|
|
31
44
|
"fflate": "^0.8.3",
|
|
32
45
|
"playwright": "1.61.1",
|
|
46
|
+
"sharp": "^0.35.3",
|
|
33
47
|
"tsx": "^4.23.0",
|
|
34
48
|
"zod": "^3.25.76"
|
|
35
49
|
},
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"use strict";(()=>{var z=`
|
|
2
|
+
:root {
|
|
3
|
+
color-scheme: light dark;
|
|
4
|
+
--sf-ink: #15151a;
|
|
5
|
+
--sf-muted: #6c6b76;
|
|
6
|
+
--sf-soft: #f1f0f4;
|
|
7
|
+
--sf-surface: rgba(255, 255, 255, 0.72);
|
|
8
|
+
--sf-line: rgba(24, 22, 31, 0.12);
|
|
9
|
+
--sf-accent: #7657dc;
|
|
10
|
+
--sf-accent-ink: #fff;
|
|
11
|
+
--sf-shadow: 0 18px 44px rgba(26, 19, 46, 0.14);
|
|
12
|
+
}
|
|
13
|
+
@media (prefers-color-scheme: dark) {
|
|
14
|
+
:root {
|
|
15
|
+
--sf-ink: #f4f2f7;
|
|
16
|
+
--sf-muted: #aaa7b3;
|
|
17
|
+
--sf-soft: #24222a;
|
|
18
|
+
--sf-surface: rgba(26, 24, 31, 0.78);
|
|
19
|
+
--sf-line: rgba(255, 255, 255, 0.12);
|
|
20
|
+
--sf-accent: #a58bf2;
|
|
21
|
+
--sf-accent-ink: #17131f;
|
|
22
|
+
--sf-shadow: 0 20px 48px rgba(0, 0, 0, 0.34);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
* { box-sizing: border-box; }
|
|
26
|
+
html, body { margin: 0; min-width: 0; background: transparent; }
|
|
27
|
+
button, a { font: inherit; }
|
|
28
|
+
.sf-root {
|
|
29
|
+
color: var(--sf-ink);
|
|
30
|
+
padding: 14px;
|
|
31
|
+
font: 14px/1.42 ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
32
|
+
}
|
|
33
|
+
.sf-shell {
|
|
34
|
+
overflow: hidden;
|
|
35
|
+
border: 1px solid var(--sf-line);
|
|
36
|
+
border-radius: 18px;
|
|
37
|
+
background: var(--sf-surface);
|
|
38
|
+
box-shadow: var(--sf-shadow);
|
|
39
|
+
}
|
|
40
|
+
.sf-head {
|
|
41
|
+
display: flex;
|
|
42
|
+
align-items: flex-start;
|
|
43
|
+
justify-content: space-between;
|
|
44
|
+
gap: 14px;
|
|
45
|
+
padding: 16px 16px 13px;
|
|
46
|
+
border-bottom: 1px solid var(--sf-line);
|
|
47
|
+
}
|
|
48
|
+
.sf-eyebrow {
|
|
49
|
+
margin: 0 0 3px;
|
|
50
|
+
color: var(--sf-muted);
|
|
51
|
+
font: 600 10px/1.2 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
52
|
+
letter-spacing: .13em;
|
|
53
|
+
text-transform: uppercase;
|
|
54
|
+
}
|
|
55
|
+
.sf-title { margin: 0; font-size: 17px; line-height: 1.25; letter-spacing: -.025em; }
|
|
56
|
+
.sf-sub { margin: 4px 0 0; color: var(--sf-muted); font-size: 12px; }
|
|
57
|
+
.sf-badge {
|
|
58
|
+
flex: 0 0 auto;
|
|
59
|
+
display: inline-flex;
|
|
60
|
+
align-items: center;
|
|
61
|
+
gap: 6px;
|
|
62
|
+
min-height: 26px;
|
|
63
|
+
padding: 5px 9px;
|
|
64
|
+
border-radius: 999px;
|
|
65
|
+
background: var(--sf-soft);
|
|
66
|
+
color: var(--sf-muted);
|
|
67
|
+
font: 600 10px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
68
|
+
letter-spacing: .04em;
|
|
69
|
+
text-transform: uppercase;
|
|
70
|
+
}
|
|
71
|
+
.sf-dot { width: 6px; height: 6px; border-radius: 50%; background: #51ad76; box-shadow: 0 0 0 3px rgba(81,173,118,.14); }
|
|
72
|
+
.sf-download, .sf-open {
|
|
73
|
+
border: 0;
|
|
74
|
+
border-radius: 9px;
|
|
75
|
+
cursor: pointer;
|
|
76
|
+
text-decoration: none;
|
|
77
|
+
transition: transform 140ms ease, opacity 140ms ease;
|
|
78
|
+
}
|
|
79
|
+
.sf-download {
|
|
80
|
+
padding: 6px 8px;
|
|
81
|
+
background: var(--sf-soft);
|
|
82
|
+
color: var(--sf-ink);
|
|
83
|
+
font-size: 11px;
|
|
84
|
+
font-weight: 650;
|
|
85
|
+
}
|
|
86
|
+
.sf-download:hover, .sf-open:hover { transform: translateY(-1px); }
|
|
87
|
+
.sf-download:focus-visible, .sf-open:focus-visible { outline: 2px solid var(--sf-accent); outline-offset: 2px; }
|
|
88
|
+
.sf-meta {
|
|
89
|
+
display: flex;
|
|
90
|
+
flex-wrap: wrap;
|
|
91
|
+
gap: 8px 16px;
|
|
92
|
+
padding: 12px 16px 14px;
|
|
93
|
+
border-top: 1px solid var(--sf-line);
|
|
94
|
+
}
|
|
95
|
+
.sf-stat { min-width: 70px; }
|
|
96
|
+
.sf-k { color: var(--sf-muted); font: 500 10px/1.2 ui-monospace, SFMono-Regular, Menlo, monospace; text-transform: uppercase; letter-spacing: .06em; }
|
|
97
|
+
.sf-v { margin-top: 3px; font-size: 12px; font-variant-numeric: tabular-nums; }
|
|
98
|
+
.sf-actions { margin-left: auto; align-self: center; }
|
|
99
|
+
.sf-open {
|
|
100
|
+
display: inline-flex;
|
|
101
|
+
align-items: center;
|
|
102
|
+
min-height: 34px;
|
|
103
|
+
padding: 8px 11px;
|
|
104
|
+
background: var(--sf-accent);
|
|
105
|
+
color: var(--sf-accent-ink);
|
|
106
|
+
font-size: 12px;
|
|
107
|
+
font-weight: 700;
|
|
108
|
+
}
|
|
109
|
+
.sf-note {
|
|
110
|
+
margin: 0;
|
|
111
|
+
padding: 11px 16px;
|
|
112
|
+
border-top: 1px solid var(--sf-line);
|
|
113
|
+
color: var(--sf-muted);
|
|
114
|
+
font-size: 11px;
|
|
115
|
+
}
|
|
116
|
+
.sf-empty { padding: 18px 16px; color: var(--sf-muted); }
|
|
117
|
+
@media (max-width: 440px) {
|
|
118
|
+
.sf-root { padding: 8px; }
|
|
119
|
+
.sf-head { padding: 14px; }
|
|
120
|
+
.sf-meta { padding-inline: 14px; }
|
|
121
|
+
.sf-actions { width: 100%; margin-left: 0; }
|
|
122
|
+
.sf-open { justify-content: center; width: 100%; }
|
|
123
|
+
}
|
|
124
|
+
@media (prefers-reduced-motion: reduce) {
|
|
125
|
+
.sf-download, .sf-open { transition: none; }
|
|
126
|
+
}
|
|
127
|
+
`;function o(n,e,t){let s=document.createElement(n);return e&&(s.className=e),t!==void 0&&(s.textContent=t),s}function u(n,e,t){let s=o("div","sf-stat");s.append(o("div","sf-k",e),o("div","sf-v",t)),n.append(s)}async function v(n){if(window.openai?.openExternal){await window.openai.openExternal({href:n});return}window.open(n,"_blank","noopener,noreferrer")}function w(n,e,t){let s=o("button",t,n);return s.type="button",s.addEventListener("click",()=>{v(e)}),s}function M(n){let e=document.createElement("style");e.textContent=n.css;let t=o("div","sf-root");t.id=n.rootId,t.append(o("div","sf-empty",n.loading)),document.body.append(e,t);let s=!1,i=r=>{!r||typeof r!="object"||(s=!0,n.render(t,r))};window.addEventListener("message",r=>{if(r.source!==window.parent)return;let p=r.data;!p||p.jsonrpc!=="2.0"||p.method!=="ui/notifications/tool-result"||i(p.params?.structuredContent)},{passive:!0});let a=0,l=()=>{if(i(window.openai?.toolOutput),!s){if(++a>24){t.replaceChildren(o("div","sf-empty",n.empty));return}setTimeout(l,100)}};l()}function L(n){return n<1024?`${n} B`:n<1024*1024?`${Math.round(n/1024)} KB`:`${(n/(1024*1024)).toFixed(1)} MB`}function S(n){if(typeof n.zipBase64=="string"&&n.zipBase64.length>0){let e=n.zipBase64.endsWith("==")?2:n.zipBase64.endsWith("=")?1:0;return{href:`data:application/zip;base64,${n.zipBase64}`,size:L(Math.max(0,n.zipBase64.length*3/4-e))}}return typeof n.zipUrl=="string"&&n.zipUrl.length>0?{href:n.zipUrl,size:null}:null}function E(n){return/^https?:/i.test(n)}function T(n){if(!n)return"Anyone with the link can download it. Links last 14 days.";let e=new Date(n);if(Number.isNaN(e.getTime()))return"Anyone with the link can download it. Links last 14 days.";let t=e.toLocaleDateString(void 0,{day:"numeric",month:"short",year:"numeric"}),s=Math.ceil((e.getTime()-Date.now())/864e5);return s<=0?`This link has expired (${t}). Emit the bundle again for a fresh one.`:`Anyone with the link can download it. Expires ${t} \u2014 ${s} day${s===1?"":"s"} from now.`}function B(n){let e=n.length>0?n:["en-US"],t=["fastlane/"],s=e.slice(0,3);return s.forEach(i=>{t.push(` screenshots/${i}/ the PNGs, named in strip order`)}),e.length>s.length&&t.push(` screenshots/\u2026 +${e.length-s.length} more locale folder(s)`),t.push(" Deliverfile pre-filled, ready to run"),t.push("README.md how to upload with your own key"),t.join(`
|
|
128
|
+
`)}var O=`${z}
|
|
129
|
+
.sf-body { padding: 15px 16px 4px; }
|
|
130
|
+
.sf-zip {
|
|
131
|
+
display: flex;
|
|
132
|
+
align-items: center;
|
|
133
|
+
gap: 13px;
|
|
134
|
+
padding: 13px;
|
|
135
|
+
border: 1px solid var(--sf-line);
|
|
136
|
+
border-radius: 13px;
|
|
137
|
+
background: var(--sf-soft);
|
|
138
|
+
}
|
|
139
|
+
.sf-zip-icon {
|
|
140
|
+
flex: 0 0 auto;
|
|
141
|
+
display: grid;
|
|
142
|
+
place-content: center;
|
|
143
|
+
width: 38px;
|
|
144
|
+
height: 38px;
|
|
145
|
+
border-radius: 10px;
|
|
146
|
+
background: var(--sf-accent);
|
|
147
|
+
color: var(--sf-accent-ink);
|
|
148
|
+
font: 700 15px/1 ui-sans-serif, system-ui, sans-serif;
|
|
149
|
+
}
|
|
150
|
+
.sf-zip-text { min-width: 0; flex: 1 1 auto; }
|
|
151
|
+
.sf-zip-name {
|
|
152
|
+
overflow: hidden;
|
|
153
|
+
text-overflow: ellipsis;
|
|
154
|
+
white-space: nowrap;
|
|
155
|
+
font: 650 13px/1.3 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
156
|
+
}
|
|
157
|
+
.sf-zip-sub { margin-top: 2px; color: var(--sf-muted); font-size: 11px; }
|
|
158
|
+
.sf-get {
|
|
159
|
+
flex: 0 0 auto;
|
|
160
|
+
display: inline-flex;
|
|
161
|
+
align-items: center;
|
|
162
|
+
min-height: 36px;
|
|
163
|
+
padding: 9px 13px;
|
|
164
|
+
border: 0;
|
|
165
|
+
border-radius: 9px;
|
|
166
|
+
background: var(--sf-accent);
|
|
167
|
+
color: var(--sf-accent-ink);
|
|
168
|
+
font-size: 12px;
|
|
169
|
+
font-weight: 700;
|
|
170
|
+
text-decoration: none;
|
|
171
|
+
cursor: pointer;
|
|
172
|
+
transition: transform 140ms ease;
|
|
173
|
+
}
|
|
174
|
+
.sf-get:hover { transform: translateY(-1px); }
|
|
175
|
+
.sf-get:focus-visible { outline: 2px solid var(--sf-accent); outline-offset: 2px; }
|
|
176
|
+
.sf-inside { margin: 14px 0 0; }
|
|
177
|
+
.sf-inside-k {
|
|
178
|
+
margin: 0 0 7px;
|
|
179
|
+
color: var(--sf-muted);
|
|
180
|
+
font: 500 10px/1.2 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
181
|
+
text-transform: uppercase;
|
|
182
|
+
letter-spacing: .06em;
|
|
183
|
+
}
|
|
184
|
+
.sf-tree {
|
|
185
|
+
margin: 0;
|
|
186
|
+
padding: 11px 13px;
|
|
187
|
+
border: 1px solid var(--sf-line);
|
|
188
|
+
border-radius: 11px;
|
|
189
|
+
overflow-x: auto;
|
|
190
|
+
color: var(--sf-muted);
|
|
191
|
+
font: 11px/1.65 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
192
|
+
white-space: pre;
|
|
193
|
+
}
|
|
194
|
+
.sf-share {
|
|
195
|
+
display: flex;
|
|
196
|
+
align-items: center;
|
|
197
|
+
gap: 10px;
|
|
198
|
+
margin-top: 12px;
|
|
199
|
+
padding: 11px 13px;
|
|
200
|
+
border: 1px dashed var(--sf-line);
|
|
201
|
+
border-radius: 11px;
|
|
202
|
+
}
|
|
203
|
+
.sf-share-text { min-width: 0; flex: 1 1 auto; font-size: 12px; }
|
|
204
|
+
.sf-share-sub { margin-top: 2px; color: var(--sf-muted); font-size: 11px; }
|
|
205
|
+
.sf-custody {
|
|
206
|
+
margin: 0;
|
|
207
|
+
padding: 12px 16px 14px;
|
|
208
|
+
color: var(--sf-muted);
|
|
209
|
+
font-size: 11px;
|
|
210
|
+
line-height: 1.5;
|
|
211
|
+
}
|
|
212
|
+
@media (max-width: 440px) {
|
|
213
|
+
.sf-body { padding-inline: 14px; }
|
|
214
|
+
.sf-zip, .sf-share { flex-wrap: wrap; }
|
|
215
|
+
.sf-get { width: 100%; justify-content: center; }
|
|
216
|
+
.sf-custody { padding-inline: 14px; }
|
|
217
|
+
}
|
|
218
|
+
@media (prefers-reduced-motion: reduce) {
|
|
219
|
+
.sf-get { transition: none; }
|
|
220
|
+
}
|
|
221
|
+
`,$="You upload this yourself. ShotOps never holds your Apple credentials, never creates an App Store version, and never submits anything for review.";function A(n,e){let t=o("a","sf-get","Download .zip");return t.href=n.href,t.download=e,t.rel="noopener noreferrer",E(n.href)&&(t.target="_blank",t.addEventListener("click",s=>{window.openai?.openExternal&&(s.preventDefault(),v(n.href))})),t}function C(n,e){n.replaceChildren();let t=Array.isArray(e.locales)&&e.locales.length>0?e.locales:e.locale?[e.locale]:[],s=typeof e.panelCount=="number"?e.panelCount:0,i=typeof e.totalPanelCount=="number"?e.totalPanelCount:s*Math.max(1,t.length),a=o("section","sf-shell"),l=o("header","sf-head"),r=o("div");r.append(o("p","sf-eyebrow","ShotOps / fastlane"),o("h2","sf-title","Your fastlane bundle is ready"),o("p","sf-sub",t.length>1?`${i} screenshots across ${t.length} locales, laid out the way fastlane deliver expects.`:"Laid out the way fastlane deliver expects \u2014 download it and upload with your own key."));let p=o("span","sf-badge");p.append(o("span","sf-dot"),document.createTextNode(e.output==="urls"?"Download link":"Inline zip")),l.append(r,p),a.append(l);let c=o("div","sf-body"),g=S(e),x=o("div","sf-zip");x.append(o("div","sf-zip-icon","ZIP"));let m=o("div","sf-zip-text");m.append(o("div","sf-zip-name",e.filename??"fastlane-bundle.zip"));let y=g?.size?` \xB7 ${g.size}`:"";m.append(o("div","sf-zip-sub",i>0?`${i} screenshot${i===1?"":"s"}${y}`:`Bundle${y}`)),x.append(m),g&&x.append(A(g,e.filename??"fastlane-bundle.zip")),c.append(x);let h=o("div","sf-inside");if(h.append(o("p","sf-inside-k","What's inside")),h.append(o("pre","sf-tree",B(t))),c.append(h),e.shareLink?.url){let f=o("div","sf-share"),b=o("div","sf-share-text");b.append(document.createTextNode("Share link")),b.append(o("div","sf-share-sub",T(e.shareLink.expiresAt))),f.append(b,w("Open \u2197",e.shareLink.url,"sf-open")),c.append(f)}a.append(c);let d=o("footer","sf-meta");if(e.bundleId&&u(d,"Bundle ID",e.bundleId),t.length>0&&u(d,t.length===1?"Locale":"Locales",t.join(", ")),Array.isArray(e.outputs)&&e.outputs.length>0&&u(d,"Devices",e.outputs.join(", ")),s>0&&t.length>1&&u(d,"Per locale",String(s)),e.openUrl){let f=o("div","sf-actions");f.append(w("Open in ShotOps \u2197",e.openUrl,"sf-open")),d.append(f)}d.childElementCount>0&&a.append(d);let k=[e.note,e.projectNote].filter(Boolean).join(" ");k&&a.append(o("p","sf-note",k)),a.append(o("p","sf-custody",$)),n.append(a),window.openai?.notifyIntrinsicHeight?.()}M({css:O,rootId:"shotops-bundle",loading:"Preparing your fastlane bundle\u2026",empty:"No ShotOps bundle result is available.",render:C});})();
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";(()=>{var v=`
|
|
2
|
+
:root {
|
|
3
|
+
color-scheme: light dark;
|
|
4
|
+
--sf-ink: #15151a;
|
|
5
|
+
--sf-muted: #6c6b76;
|
|
6
|
+
--sf-soft: #f1f0f4;
|
|
7
|
+
--sf-surface: rgba(255, 255, 255, 0.72);
|
|
8
|
+
--sf-line: rgba(24, 22, 31, 0.12);
|
|
9
|
+
--sf-accent: #7657dc;
|
|
10
|
+
--sf-accent-ink: #fff;
|
|
11
|
+
--sf-shadow: 0 18px 44px rgba(26, 19, 46, 0.14);
|
|
12
|
+
}
|
|
13
|
+
@media (prefers-color-scheme: dark) {
|
|
14
|
+
:root {
|
|
15
|
+
--sf-ink: #f4f2f7;
|
|
16
|
+
--sf-muted: #aaa7b3;
|
|
17
|
+
--sf-soft: #24222a;
|
|
18
|
+
--sf-surface: rgba(26, 24, 31, 0.78);
|
|
19
|
+
--sf-line: rgba(255, 255, 255, 0.12);
|
|
20
|
+
--sf-accent: #a58bf2;
|
|
21
|
+
--sf-accent-ink: #17131f;
|
|
22
|
+
--sf-shadow: 0 20px 48px rgba(0, 0, 0, 0.34);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
* { box-sizing: border-box; }
|
|
26
|
+
html, body { margin: 0; min-width: 0; background: transparent; }
|
|
27
|
+
button, a { font: inherit; }
|
|
28
|
+
.sf-root {
|
|
29
|
+
color: var(--sf-ink);
|
|
30
|
+
padding: 14px;
|
|
31
|
+
font: 14px/1.42 ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
32
|
+
}
|
|
33
|
+
.sf-shell {
|
|
34
|
+
overflow: hidden;
|
|
35
|
+
border: 1px solid var(--sf-line);
|
|
36
|
+
border-radius: 18px;
|
|
37
|
+
background: var(--sf-surface);
|
|
38
|
+
box-shadow: var(--sf-shadow);
|
|
39
|
+
}
|
|
40
|
+
.sf-head {
|
|
41
|
+
display: flex;
|
|
42
|
+
align-items: flex-start;
|
|
43
|
+
justify-content: space-between;
|
|
44
|
+
gap: 14px;
|
|
45
|
+
padding: 16px 16px 13px;
|
|
46
|
+
border-bottom: 1px solid var(--sf-line);
|
|
47
|
+
}
|
|
48
|
+
.sf-eyebrow {
|
|
49
|
+
margin: 0 0 3px;
|
|
50
|
+
color: var(--sf-muted);
|
|
51
|
+
font: 600 10px/1.2 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
52
|
+
letter-spacing: .13em;
|
|
53
|
+
text-transform: uppercase;
|
|
54
|
+
}
|
|
55
|
+
.sf-title { margin: 0; font-size: 17px; line-height: 1.25; letter-spacing: -.025em; }
|
|
56
|
+
.sf-sub { margin: 4px 0 0; color: var(--sf-muted); font-size: 12px; }
|
|
57
|
+
.sf-badge {
|
|
58
|
+
flex: 0 0 auto;
|
|
59
|
+
display: inline-flex;
|
|
60
|
+
align-items: center;
|
|
61
|
+
gap: 6px;
|
|
62
|
+
min-height: 26px;
|
|
63
|
+
padding: 5px 9px;
|
|
64
|
+
border-radius: 999px;
|
|
65
|
+
background: var(--sf-soft);
|
|
66
|
+
color: var(--sf-muted);
|
|
67
|
+
font: 600 10px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
68
|
+
letter-spacing: .04em;
|
|
69
|
+
text-transform: uppercase;
|
|
70
|
+
}
|
|
71
|
+
.sf-dot { width: 6px; height: 6px; border-radius: 50%; background: #51ad76; box-shadow: 0 0 0 3px rgba(81,173,118,.14); }
|
|
72
|
+
.sf-download, .sf-open {
|
|
73
|
+
border: 0;
|
|
74
|
+
border-radius: 9px;
|
|
75
|
+
cursor: pointer;
|
|
76
|
+
text-decoration: none;
|
|
77
|
+
transition: transform 140ms ease, opacity 140ms ease;
|
|
78
|
+
}
|
|
79
|
+
.sf-download {
|
|
80
|
+
padding: 6px 8px;
|
|
81
|
+
background: var(--sf-soft);
|
|
82
|
+
color: var(--sf-ink);
|
|
83
|
+
font-size: 11px;
|
|
84
|
+
font-weight: 650;
|
|
85
|
+
}
|
|
86
|
+
.sf-download:hover, .sf-open:hover { transform: translateY(-1px); }
|
|
87
|
+
.sf-download:focus-visible, .sf-open:focus-visible { outline: 2px solid var(--sf-accent); outline-offset: 2px; }
|
|
88
|
+
.sf-meta {
|
|
89
|
+
display: flex;
|
|
90
|
+
flex-wrap: wrap;
|
|
91
|
+
gap: 8px 16px;
|
|
92
|
+
padding: 12px 16px 14px;
|
|
93
|
+
border-top: 1px solid var(--sf-line);
|
|
94
|
+
}
|
|
95
|
+
.sf-stat { min-width: 70px; }
|
|
96
|
+
.sf-k { color: var(--sf-muted); font: 500 10px/1.2 ui-monospace, SFMono-Regular, Menlo, monospace; text-transform: uppercase; letter-spacing: .06em; }
|
|
97
|
+
.sf-v { margin-top: 3px; font-size: 12px; font-variant-numeric: tabular-nums; }
|
|
98
|
+
.sf-actions { margin-left: auto; align-self: center; }
|
|
99
|
+
.sf-open {
|
|
100
|
+
display: inline-flex;
|
|
101
|
+
align-items: center;
|
|
102
|
+
min-height: 34px;
|
|
103
|
+
padding: 8px 11px;
|
|
104
|
+
background: var(--sf-accent);
|
|
105
|
+
color: var(--sf-accent-ink);
|
|
106
|
+
font-size: 12px;
|
|
107
|
+
font-weight: 700;
|
|
108
|
+
}
|
|
109
|
+
.sf-note {
|
|
110
|
+
margin: 0;
|
|
111
|
+
padding: 11px 16px;
|
|
112
|
+
border-top: 1px solid var(--sf-line);
|
|
113
|
+
color: var(--sf-muted);
|
|
114
|
+
font-size: 11px;
|
|
115
|
+
}
|
|
116
|
+
.sf-empty { padding: 18px 16px; color: var(--sf-muted); }
|
|
117
|
+
@media (max-width: 440px) {
|
|
118
|
+
.sf-root { padding: 8px; }
|
|
119
|
+
.sf-head { padding: 14px; }
|
|
120
|
+
.sf-meta { padding-inline: 14px; }
|
|
121
|
+
.sf-actions { width: 100%; margin-left: 0; }
|
|
122
|
+
.sf-open { justify-content: center; width: 100%; }
|
|
123
|
+
}
|
|
124
|
+
@media (prefers-reduced-motion: reduce) {
|
|
125
|
+
.sf-download, .sf-open { transition: none; }
|
|
126
|
+
}
|
|
127
|
+
`;function n(t,e,o){let r=document.createElement(t);return e&&(r.className=e),o!==void 0&&(r.textContent=o),r}function g(t,e,o){let r=n("div","sf-stat");r.append(n("div","sf-k",e),n("div","sf-v",o)),t.append(r)}async function S(t){if(window.openai?.openExternal){await window.openai.openExternal({href:t});return}window.open(t,"_blank","noopener,noreferrer")}function w(t,e,o){let r=n("button",o,t);return r.type="button",r.addEventListener("click",()=>{S(e)}),r}function y(t){let e=document.createElement("style");e.textContent=t.css;let o=n("div","sf-root");o.id=t.rootId,o.append(n("div","sf-empty",t.loading)),document.body.append(e,o);let r=!1,l=i=>{!i||typeof i!="object"||(r=!0,t.render(o,i))};window.addEventListener("message",i=>{if(i.source!==window.parent)return;let s=i.data;!s||s.jsonrpc!=="2.0"||s.method!=="ui/notifications/tool-result"||l(s.params?.structuredContent)},{passive:!0});let a=0,f=()=>{if(l(window.openai?.toolOutput),!r){if(++a>24){o.replaceChildren(n("div","sf-empty",t.empty));return}setTimeout(f,100)}};f()}var M=`${v}
|
|
128
|
+
.sf-rail {
|
|
129
|
+
display: grid;
|
|
130
|
+
grid-auto-flow: column;
|
|
131
|
+
grid-auto-columns: clamp(142px, 38vw, 210px);
|
|
132
|
+
gap: 12px;
|
|
133
|
+
overflow-x: auto;
|
|
134
|
+
padding: 15px 16px 18px;
|
|
135
|
+
scroll-snap-type: x proximity;
|
|
136
|
+
scrollbar-width: thin;
|
|
137
|
+
scrollbar-color: var(--sf-line) transparent;
|
|
138
|
+
}
|
|
139
|
+
.sf-panel { min-width: 0; scroll-snap-align: start; }
|
|
140
|
+
.sf-frame {
|
|
141
|
+
position: relative;
|
|
142
|
+
aspect-ratio: var(--sf-ratio, 1290 / 2796);
|
|
143
|
+
overflow: hidden;
|
|
144
|
+
border: 1px solid var(--sf-line);
|
|
145
|
+
border-radius: 13px;
|
|
146
|
+
background:
|
|
147
|
+
linear-gradient(135deg, rgba(118,87,220,.22), transparent 42%),
|
|
148
|
+
linear-gradient(180deg, #1b1930, #0d111a);
|
|
149
|
+
}
|
|
150
|
+
.sf-frame img { display: block; width: 100%; height: 100%; object-fit: cover; }
|
|
151
|
+
.sf-index {
|
|
152
|
+
position: absolute;
|
|
153
|
+
top: 8px;
|
|
154
|
+
left: 8px;
|
|
155
|
+
min-width: 25px;
|
|
156
|
+
padding: 5px 7px;
|
|
157
|
+
border: 1px solid rgba(255,255,255,.22);
|
|
158
|
+
border-radius: 999px;
|
|
159
|
+
background: rgba(12,11,17,.62);
|
|
160
|
+
color: #fff;
|
|
161
|
+
backdrop-filter: blur(10px);
|
|
162
|
+
font: 600 10px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
163
|
+
text-align: center;
|
|
164
|
+
}
|
|
165
|
+
.sf-expired {
|
|
166
|
+
position: absolute;
|
|
167
|
+
inset: 0;
|
|
168
|
+
display: none;
|
|
169
|
+
place-content: center;
|
|
170
|
+
padding: 18px;
|
|
171
|
+
color: rgba(255,255,255,.72);
|
|
172
|
+
text-align: center;
|
|
173
|
+
font-size: 12px;
|
|
174
|
+
}
|
|
175
|
+
.sf-frame.is-error .sf-expired { display: grid; }
|
|
176
|
+
.sf-frame.is-error img { display: none; }
|
|
177
|
+
.sf-panel-foot {
|
|
178
|
+
display: flex;
|
|
179
|
+
align-items: center;
|
|
180
|
+
justify-content: space-between;
|
|
181
|
+
gap: 8px;
|
|
182
|
+
padding-top: 8px;
|
|
183
|
+
}
|
|
184
|
+
.sf-panel-name { color: var(--sf-muted); font: 600 10px/1.2 ui-monospace, SFMono-Regular, Menlo, monospace; text-transform: uppercase; }
|
|
185
|
+
@media (max-width: 440px) {
|
|
186
|
+
.sf-rail { padding-inline: 14px; grid-auto-columns: min(64vw, 190px); }
|
|
187
|
+
}
|
|
188
|
+
`;function E(t){if(typeof t=="string"){let e=t.startsWith("data:")?t:`data:image/png;base64,${t}`;return{src:e,href:e}}return typeof t?.url=="string"&&t.url.length>0?{src:t.url,href:t.url}:null}function T(t,e){let o=n("a","sf-download","Download PNG");return o.href=t,o.download=`shotops-panel-${String(e+1).padStart(2,"0")}.png`,o.target="_blank",o.rel="noopener noreferrer",o}function O(t,e){t.replaceChildren();let o=n("section","sf-shell"),r=n("header","sf-head"),l=n("div"),a=Array.isArray(e.panels)?e.panels:[],f=typeof e.count=="number"?e.count:a.length;l.append(n("p","sf-eyebrow","ShotOps / App Store"),n("h2","sf-title",f===1?"Your panel is ready":`Your ${f}-panel strip is ready`),n("p","sf-sub","Swipe through the final panels, then open or download each PNG."));let i=n("span","sf-badge");if(i.append(n("span","sf-dot"),document.createTextNode(e.output==="urls"?"Full-size links":"Inline result")),r.append(l,i),o.append(r),a.length>0){let p=n("div","sf-rail");e.panelWidth&&e.panelHeight&&p.style.setProperty("--sf-ratio",`${e.panelWidth} / ${e.panelHeight}`),a.forEach((k,c)=>{let m=E(k),b=n("article","sf-panel"),d=n("div","sf-frame");if(d.append(n("span","sf-index",String(c+1).padStart(2,"0"))),m){let u=n("img");u.src=m.src,u.alt=`Rendered App Store panel ${c+1} of ${a.length}`,u.loading=c===0?"eager":"lazy",u.addEventListener("error",()=>d.classList.add("is-error")),d.append(u)}else d.classList.add("is-error");d.append(n("div","sf-expired","Preview unavailable. Ask ShotOps to render this panel again."));let x=n("div","sf-panel-foot");x.append(n("span","sf-panel-name",`Panel ${String(c+1).padStart(2,"0")}`)),m&&x.append(T(m.href,c)),b.append(d,x),p.append(b)}),o.append(p)}else o.append(n("div","sf-empty","The render completed, but no panel previews were returned."));let s=n("footer","sf-meta");if(e.panelWidth&&e.panelHeight&&g(s,"Canvas",`${e.panelWidth}\xD7${e.panelHeight}`),e.panelPresetId&&g(s,"Preset",e.panelPresetId),e.locale&&g(s,"Locale",e.locale),typeof e.renderMs=="number"&&g(s,"Render",`${(e.renderMs/1e3).toFixed(1)}s`),e.openUrl){let p=n("div","sf-actions");p.append(w("Open in ShotOps \u2197",e.openUrl,"sf-open")),s.append(p)}s.childElementCount>0&&o.append(s);let h=[e.note,e.projectNote].filter(Boolean).join(" ");h&&o.append(n("p","sf-note",h)),t.append(o),window.openai?.notifyIntrinsicHeight?.()}y({css:M,rootId:"shotops-result",loading:"Loading ShotOps panels\u2026",empty:"No ShotOps render result is available.",render:O});})();
|
|
Binary file
|