@jxsuite/studio 2.2.2 → 2.3.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.
Files changed (182) hide show
  1. package/data/css-meta.json +1487 -0
  2. package/data/elements-meta.json +370 -0
  3. package/data/html-meta.json +366 -0
  4. package/data/stylebook-meta.json +200 -0
  5. package/data/webdata.json +1621 -0
  6. package/dist/chunks/{Overlay.dev-ymy3et3y.js → Overlay.dev-d2ajy6sj.js} +7 -7
  7. package/dist/chunks/{content-source-r2n7v682.js → content-source-56xpvx83.js} +13 -12
  8. package/dist/chunks/{convert-to-repeater-cnpyvj74.js → convert-to-repeater-0xh9wwek.js} +12 -11
  9. package/dist/chunks/{extension-sections-vpcm4jvx.js → extension-sections-g34239vm.js} +17 -16
  10. package/dist/chunks/{files-zeg88k2d.js → files-gkz202dp.js} +18 -19
  11. package/dist/chunks/{format-host-taymsw55.js → format-host-pej3srnw.js} +2 -2
  12. package/dist/chunks/{git-panel-qp4rrwr9.js → git-panel-4j6xbh8g.js} +12 -11
  13. package/dist/chunks/{layers-panel-kj93w2zg.js → layers-panel-8mvn8sgd.js} +15 -14
  14. package/dist/chunks/{monaco-setup-xy3bs05d.js → monaco-setup-a5wkmbgh.js} +6 -3
  15. package/dist/chunks/{publish-panel-6qz6kp41.js → publish-panel-ptddc3kg.js} +6 -6
  16. package/dist/chunks/{quick-search-9wwa09hh.js → quick-search-j88azfs2.js} +19 -18
  17. package/dist/chunks/right-panel-egkaxy89.js +38 -0
  18. package/dist/chunks/{sp-overlay.dev-h6kdx076.js → sp-overlay.dev-s18hymn9.js} +8 -8
  19. package/dist/chunks/sp-progress-circle.dev-0zxcyz3r.js +15 -0
  20. package/dist/chunks/sp-tooltip.dev-5c6d1kjz.js +15 -0
  21. package/dist/chunks/{studio-753znj4c.js → studio-0e4h32g6.js} +5 -5
  22. package/dist/chunks/{studio-yz9s88s0.js → studio-10s469da.js} +25 -9
  23. package/dist/chunks/{studio-6f0am8f2.js → studio-2w11grav.js} +2 -2
  24. package/dist/chunks/{studio-zqv3w24n.js → studio-3q65xvzv.js} +5 -5
  25. package/dist/chunks/{studio-qhh8r5fz.js → studio-4058pg09.js} +4 -4
  26. package/dist/chunks/{studio-hekaagev.js → studio-4enps87v.js} +17 -17
  27. package/dist/chunks/{studio-tqemhphj.js → studio-50eed4c9.js} +4 -4
  28. package/dist/chunks/studio-53n8bp04.js +16 -0
  29. package/dist/chunks/{studio-nqq8jk8f.js → studio-5amdrjm4.js} +14 -14
  30. package/dist/chunks/{studio-6zzbyx17.js → studio-5ne8mdx9.js} +2 -2
  31. package/dist/chunks/{studio-3z8jjm2p.js → studio-7ejemhej.js} +3 -3
  32. package/dist/chunks/{studio-1kgfcv7s.js → studio-a11d3a1b.js} +12 -11
  33. package/dist/chunks/{studio-rgwcpast.js → studio-ay8wcr2b.js} +2 -2
  34. package/dist/chunks/{studio-fys6z73y.js → studio-bak2cyjr.js} +7 -7
  35. package/dist/chunks/{studio-xmvbhg31.js → studio-c31yb4t6.js} +2 -2
  36. package/dist/chunks/{studio-8sdyjfd6.js → studio-cf4rk7kv.js} +2 -2
  37. package/dist/chunks/{studio-yphy4z9m.js → studio-cv606rs1.js} +5 -5
  38. package/dist/chunks/{studio-5kt960pk.js → studio-hk523hby.js} +133 -147
  39. package/dist/chunks/{studio-x0et2z9g.js → studio-hs8x23fv.js} +15 -15
  40. package/dist/chunks/{studio-p471gg5n.js → studio-kvfx9z2c.js} +7 -3
  41. package/dist/chunks/{studio-22xr4q8q.js → studio-ncnet0ba.js} +18 -29
  42. package/dist/chunks/{studio-ckwz4d3x.js → studio-twsafr1e.js} +2 -2
  43. package/dist/chunks/{studio-qrsfh1w7.js → studio-tzx3xmvx.js} +5 -5
  44. package/dist/chunks/{studio-g8t7g0gp.js → studio-vdpcpada.js} +3 -3
  45. package/dist/chunks/{studio-6a0h7sne.js → studio-vhk5fmfv.js} +2 -2
  46. package/dist/chunks/{studio-hrajjyt2.js → studio-wdt9y92a.js} +2 -2
  47. package/dist/chunks/{studio-r8vx7bkz.js → studio-x3etxs0s.js} +14 -13
  48. package/dist/chunks/{studio-pv8m0h4a.js → studio-yxzgjq8q.js} +28 -23
  49. package/dist/chunks/{studio-300zsz1k.js → studio-zdkgwhkv.js} +6 -6
  50. package/dist/codicon.ttf +0 -0
  51. package/dist/iframe-entry.js +8 -1
  52. package/dist/manifest.json +82 -0
  53. package/dist/studio.js +232 -103
  54. package/index.html +0 -50
  55. package/package.json +11 -4
  56. package/src/canvas/iframe-entry.ts +5 -0
  57. package/src/canvas/iframe-host.ts +45 -4
  58. package/src/content/entry-editor.ts +2 -1
  59. package/src/editor/context-menu.ts +13 -2
  60. package/src/editor/slash-menu.ts +26 -11
  61. package/src/files/files.ts +11 -23
  62. package/src/grid/grid-panel.ts +27 -6
  63. package/src/hosting/document.ts +109 -0
  64. package/src/hosting/layout.ts +211 -0
  65. package/src/hosting/stage.ts +166 -0
  66. package/src/hosting/tsconfig.json +18 -0
  67. package/src/panels/ai-chat/chat-view.ts +25 -14
  68. package/src/panels/git-panel.ts +17 -14
  69. package/src/panels/head-panel.ts +32 -14
  70. package/src/panels/imports-panel.ts +32 -13
  71. package/src/panels/layers-panel.ts +9 -1
  72. package/src/panels/panel-registry.ts +0 -1
  73. package/src/panels/properties-panel.ts +3 -3
  74. package/src/panels/settings-pane.ts +1 -1
  75. package/src/panels/style-panel.ts +3 -3
  76. package/src/panels/stylebook-panel.ts +10 -1
  77. package/src/panels/toolbar.ts +1 -1
  78. package/src/services/bundle-base.ts +69 -0
  79. package/src/services/monaco-setup.ts +19 -13
  80. package/src/shell/tree.ts +155 -0
  81. package/src/shell.ts +0 -2
  82. package/src/studio.ts +22 -2
  83. package/src/types.ts +15 -0
  84. package/src/ui/regions.ts +10 -45
  85. package/styles/overlays.css +35 -0
  86. package/dist/chunks/2020-xp8vnwma.js.map +0 -24
  87. package/dist/chunks/Overlay.dev-ymy3et3y.js.map +0 -9
  88. package/dist/chunks/adapter-jkcyhgtr.js.map +0 -9
  89. package/dist/chunks/cf-settings-g5fbf2zp.js.map +0 -9
  90. package/dist/chunks/components-z6cnkyy1.js.map +0 -9
  91. package/dist/chunks/content-source-r2n7v682.js.map +0 -9
  92. package/dist/chunks/convert-to-repeater-cnpyvj74.js.map +0 -10
  93. package/dist/chunks/editor-cptq5jp1.js.map +0 -9
  94. package/dist/chunks/extension-sections-vpcm4jvx.js.map +0 -11
  95. package/dist/chunks/files-zeg88k2d.js.map +0 -9
  96. package/dist/chunks/flow-qbfgrpeh.js.map +0 -12
  97. package/dist/chunks/focus-trap.esm-ggawf1hy.js.map +0 -11
  98. package/dist/chunks/focus-visible-6eg70z18.js.map +0 -10
  99. package/dist/chunks/format-host-taymsw55.js.map +0 -9
  100. package/dist/chunks/git-panel-qp4rrwr9.js.map +0 -9
  101. package/dist/chunks/index-nj44jpzj.js.map +0 -14
  102. package/dist/chunks/index-zqxmqxmh.js.map +0 -9
  103. package/dist/chunks/javascript-q8kpmfah.js.map +0 -11
  104. package/dist/chunks/jsonMode-dkr040ga.js.map +0 -18
  105. package/dist/chunks/jx-validate-jj9rnt4n.js.map +0 -9
  106. package/dist/chunks/layers-panel-kj93w2zg.js.map +0 -9
  107. package/dist/chunks/monaco-binding-rj6xpx9y.js.map +0 -10
  108. package/dist/chunks/monaco-setup-xy3bs05d.js.map +0 -15
  109. package/dist/chunks/publish-panel-6qz6kp41.js.map +0 -9
  110. package/dist/chunks/quick-search-9wwa09hh.js.map +0 -9
  111. package/dist/chunks/right-panel-faf816ch.js +0 -37
  112. package/dist/chunks/right-panel-faf816ch.js.map +0 -9
  113. package/dist/chunks/section-registry-sx1ykvkw.js.map +0 -9
  114. package/dist/chunks/sp-overlay.dev-h6kdx076.js.map +0 -9
  115. package/dist/chunks/sp-popover.dev-dj9x7e7a.js.map +0 -9
  116. package/dist/chunks/sp-progress-circle.dev-0fpvhm52.js +0 -15
  117. package/dist/chunks/sp-progress-circle.dev-0fpvhm52.js.map +0 -9
  118. package/dist/chunks/sp-tooltip.dev-rvepkw4r.js +0 -15
  119. package/dist/chunks/sp-tooltip.dev-rvepkw4r.js.map +0 -9
  120. package/dist/chunks/sp-tray.dev-64v4pxw8.js.map +0 -12
  121. package/dist/chunks/studio-0a5qrh01.js.map +0 -9
  122. package/dist/chunks/studio-0rqqhrdy.js.map +0 -12
  123. package/dist/chunks/studio-18j3bmcz.js.map +0 -10
  124. package/dist/chunks/studio-1kgfcv7s.js.map +0 -13
  125. package/dist/chunks/studio-22xr4q8q.js.map +0 -13
  126. package/dist/chunks/studio-300zsz1k.js.map +0 -39
  127. package/dist/chunks/studio-3fk1ac9z.js.map +0 -12
  128. package/dist/chunks/studio-3n4ndrzh.js.map +0 -41
  129. package/dist/chunks/studio-3z8jjm2p.js.map +0 -13
  130. package/dist/chunks/studio-4mqb9a0j.js.map +0 -14
  131. package/dist/chunks/studio-4q0wznzf.js.map +0 -73
  132. package/dist/chunks/studio-5ehhackm.js.map +0 -10
  133. package/dist/chunks/studio-5kt960pk.js.map +0 -38
  134. package/dist/chunks/studio-5x5774ak.js.map +0 -10
  135. package/dist/chunks/studio-685s0ytq.js.map +0 -76
  136. package/dist/chunks/studio-6a0h7sne.js.map +0 -15
  137. package/dist/chunks/studio-6f0am8f2.js.map +0 -10
  138. package/dist/chunks/studio-6kv3apa9.js.map +0 -10
  139. package/dist/chunks/studio-6zzbyx17.js.map +0 -12
  140. package/dist/chunks/studio-753znj4c.js.map +0 -16
  141. package/dist/chunks/studio-7afd21nw.js.map +0 -10
  142. package/dist/chunks/studio-8jpzqk5s.js.map +0 -10
  143. package/dist/chunks/studio-8q517dfr.js.map +0 -10
  144. package/dist/chunks/studio-8sdyjfd6.js.map +0 -10
  145. package/dist/chunks/studio-a0tswy0w.js.map +0 -9
  146. package/dist/chunks/studio-a7pzveq1.js.map +0 -11
  147. package/dist/chunks/studio-ahnzd9rg.js.map +0 -10
  148. package/dist/chunks/studio-b9b6t1dg.js.map +0 -651
  149. package/dist/chunks/studio-bw5dz6km.js.map +0 -21
  150. package/dist/chunks/studio-cjm7fdjf.js.map +0 -14
  151. package/dist/chunks/studio-ckwz4d3x.js.map +0 -12
  152. package/dist/chunks/studio-d1ks410h.js.map +0 -10
  153. package/dist/chunks/studio-dg7zyt5x.js.map +0 -10
  154. package/dist/chunks/studio-fys6z73y.js.map +0 -10
  155. package/dist/chunks/studio-g1wdche0.js.map +0 -56
  156. package/dist/chunks/studio-g8t7g0gp.js.map +0 -10
  157. package/dist/chunks/studio-h4rxscfc.js.map +0 -10
  158. package/dist/chunks/studio-hekaagev.js.map +0 -18
  159. package/dist/chunks/studio-hrajjyt2.js.map +0 -10
  160. package/dist/chunks/studio-nqq8jk8f.js.map +0 -14
  161. package/dist/chunks/studio-p471gg5n.js.map +0 -14
  162. package/dist/chunks/studio-pv8m0h4a.js.map +0 -98
  163. package/dist/chunks/studio-qhh8r5fz.js.map +0 -13
  164. package/dist/chunks/studio-qrsfh1w7.js.map +0 -41
  165. package/dist/chunks/studio-r8vx7bkz.js.map +0 -235
  166. package/dist/chunks/studio-rgwcpast.js.map +0 -12
  167. package/dist/chunks/studio-s519zc99.js.map +0 -10
  168. package/dist/chunks/studio-sas7mt3k.js.map +0 -10
  169. package/dist/chunks/studio-t5wqwzdh.js.map +0 -10
  170. package/dist/chunks/studio-tqemhphj.js.map +0 -11
  171. package/dist/chunks/studio-tr20m8g8.js.map +0 -9
  172. package/dist/chunks/studio-tvgyw9xw.js.map +0 -14
  173. package/dist/chunks/studio-x0et2z9g.js.map +0 -32
  174. package/dist/chunks/studio-xm3dbxvn.js.map +0 -19
  175. package/dist/chunks/studio-xmvbhg31.js.map +0 -10
  176. package/dist/chunks/studio-ynxwkrzd.js.map +0 -246
  177. package/dist/chunks/studio-yphy4z9m.js.map +0 -10
  178. package/dist/chunks/studio-yz9s88s0.js.map +0 -54
  179. package/dist/chunks/studio-z6nw2ek2.js.map +0 -10
  180. package/dist/chunks/studio-zqv3w24n.js.map +0 -11
  181. package/dist/chunks/tsMode-76kr53q0.js.map +0 -13
  182. package/dist/chunks/ws-client-6shc5rze.js.map +0 -12
@@ -1,18 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/github/github-auth.ts", "../src/github/github-publish.ts", "../src/project-list.ts", "../src/services/idle.ts", "../src/services/automation.ts", "../src/packages/semver.ts", "../src/packages/jxsuite-update.ts", "../src/packages/pull-package-sync.ts", "../src/panels/git-panel.ts"],
4
- "sourcesContent": [
5
- "/// <reference lib=\"dom\" />\n/**\n * GitHub sign-in for Jx Studio: the desktop's loopback redirect, and the browser's device flow.\n *\n * **Which flow runs depends on what the build has, not on preference.** A desktop launcher exposes\n * `githubAuth` on `globalThis.__jxPlatform`, backed by an RFC 8252 loopback redirect with PKCE —\n * the user signs in on GitHub's own page in their own browser, the authorization code comes back to\n * a loopback server, and the token is stored in the app's config folder at `0600`. A page in a\n * browser has no loopback server to redirect to, so it keeps the Device Flow below.\n *\n * The Device Flow needs no server-side redirect endpoint, which is exactly why it was chosen here\n * and exactly why it is the wrong tool for a desktop app: RFC 8628 designed it for devices that\n * cannot show a browser or take typed input, and it costs the user a code copied between windows.\n *\n * **This flow fails, and until now it failed silently.** `https://github.com/login/device/code`\n * sends no `Access-Control-Allow-Origin`, so a browser cannot call it: in Studio-in-a-browser the\n * very first request rejects with a bare `TypeError`. That rejection used to become a thrown\n * `Error` out of {@link authenticateGithub}, into `void createGithubRepository(…)` in\n * `panels/git-panel.ts`, and from there into an unhandled promise rejection — the user clicked\n * \"Create GitHub repository\" and the app did nothing at all, forever, with no message anywhere.\n *\n * Three failures now reach a surface, each as the kind of record §16 says it is:\n *\n * - **Unreachable** (CORS, offline, DNS) → a **Problem**, because it must be fixed and the fix is not\n * in this dialog, carrying `git.signInToGithub` as its Retry;\n * - **Refused by GitHub** (an HTTP error, `access_denied`, `expired_token`) → a **toast**, because\n * the state is now correct and there is nothing to fix — the user declined, or waited too long;\n * - **A poll that keeps failing** → a Problem after {@link MAX_POLL_FAILURES} consecutive rejections,\n * rather than the previous empty catch that re-armed the timer forever. A dialog that says\n * \"Waiting for authorization…\" against a network that will never answer is the exact dishonesty\n * the feedback system exists to end.\n *\n * **What it cannot tell you.** A cross-origin block and an unplugged cable are the same `TypeError`\n * here — the browser withholds the reason on purpose — so the detail names both rather than\n * guessing between them.\n *\n * The token is returned to callers and never rendered. In a browser it is stored in `localStorage`;\n * on the desktop it is in the launcher's `0600` credential store and this module holds it only in\n * memory for the session. `settings/preferences-accounts.ts` lists it as _stored or not_ and is the\n * only place it can be revoked (`studio.md` §15 rule 1).\n */\n\nimport { html } from \"lit-html\";\nimport { errorMessage } from \"@jxsuite/schema/parse\";\nimport { notify } from \"../services/notify\";\nimport { showDialog } from \"../ui/layers\";\n\nconst CLIENT_ID = \"Ov23liYVlMFpgjOEPXJH\";\nconst STORAGE_KEY = \"jx_github_token\";\n\n/**\n * The desktop launcher's RFC 8252 sign-in, when this build is running inside one.\n *\n * Launcher-only, like `updater` and `windowControls`, and reached the same way — a loopback\n * redirect needs a loopback server, which a page in a browser does not have.\n */\ninterface NativeGithubAuth {\n signIn: (force?: boolean) => Promise<{ token: string }>;\n signOut: () => Promise<{ ok: boolean }>;\n status: () => Promise<{ stored: boolean }>;\n}\n\nfunction nativeAuth(): NativeGithubAuth | null {\n return (\n (globalThis as unknown as { __jxPlatform?: { githubAuth?: NativeGithubAuth } }).__jxPlatform\n ?.githubAuth ?? null\n );\n}\n\n/**\n * The token the desktop store handed us this session.\n *\n * On the desktop the token at rest is a `0600` file in the user's config directory, **not**\n * `localStorage` — so it is not readable by script in the webview between sessions, and it does not\n * survive in a place a stray extension or a copied profile can reach. Holding it in a module\n * variable is what keeps {@link getGithubToken} synchronous for its callers.\n */\nlet nativeToken: string | null = null;\n\n/** Whether the desktop store holds a token, as of the last time it was asked. */\nlet nativeStored = false;\n\n/**\n * Record that the desktop's credential store does (or does not) hold a token.\n *\n * The launcher calls this once at startup. It carries a **boolean, not the token**: the accounts\n * pane only needs to know whether one exists, and handing the webview a credential it has not been\n * asked to use is the exposure the 0600 store exists to remove. When a sign-in does happen the\n * token arrives through {@link authenticateGithub} and lives in memory for that session.\n *\n * @param {boolean} stored\n */\nexport function hydrateGithubToken(stored: boolean): void {\n nativeStored = stored;\n}\n\n/**\n * Whether a GitHub credential exists, wherever it lives.\n *\n * Separate from {@link getGithubToken} because the two questions genuinely differ on the desktop: a\n * token can be stored on disk and not yet in this session's memory, and the accounts pane asks\n * \"signed in?\" while rendering — synchronously — where an API caller asks for the credential itself\n * and can await it.\n *\n * @returns {boolean}\n */\nexport function githubTokenStored(): boolean {\n return nativeToken !== null || nativeStored || localStorage.getItem(STORAGE_KEY) !== null;\n}\n\n/** Where the credential this build would use actually lives, for text that says so. */\nexport function githubTokenLocation(): \"desktop\" | \"browser\" {\n return nativeAuth() ? \"desktop\" : \"browser\";\n}\n\n/** One key for the whole sign-in, so a second attempt REPLACES the first report. */\nconst NOTIFY_KEY = \"github.auth\";\n\nconst SOURCE = \"Source Control\";\n\n/** The Retry every report carries — one command, so the button's label comes off the record. */\nconst RETRY = \"git.signInToGithub\";\n\n/**\n * How many consecutive poll rejections end the wait.\n *\n * Three, not one: the device flow legitimately polls across a laptop's sleep and a Wi-Fi hop, and\n * failing on the first blip would abandon a sign-in the user is in the middle of completing.\n */\nexport const MAX_POLL_FAILURES = 3;\n\n/** Both halves of what a browser will not tell us, said once. */\nconst UNREACHABLE_DETAIL =\n \"The request never reached GitHub. GitHub's device-flow endpoints send no CORS headers, so a \" +\n \"browser cannot call them directly — the desktop app can. A machine that is offline fails \" +\n \"identically, and the browser does not say which happened.\";\n\ninterface DeviceCodeResponse {\n device_code: string;\n user_code: string;\n verification_uri: string;\n interval?: number;\n}\n\ninterface TokenResponse {\n access_token?: string;\n error?: string;\n}\n\nexport function getGithubToken() {\n return nativeToken ?? localStorage.getItem(STORAGE_KEY);\n}\n\nexport function clearGithubToken() {\n nativeToken = null;\n nativeStored = false;\n localStorage.removeItem(STORAGE_KEY);\n // Fire-and-forget: the accounts pane's revoke is synchronous, and a store that failed to forget\n // The token is not something the user can act on from there.\n void nativeAuth()\n ?.signOut()\n .catch(() => {});\n}\n\n/** The request never completed — a Problem, with the one sentence that covers both causes. */\nfunction reportUnreachable(error: unknown): void {\n notify.error(\"Could not reach GitHub to sign in.\", {\n action: RETRY,\n detail: `${UNREACHABLE_DETAIL}\\n\\n${errorMessage(error)}`,\n key: NOTIFY_KEY,\n source: SOURCE,\n });\n}\n\n/** GitHub answered, and said no. Nothing is broken, so this rests rather than persists. */\nfunction reportRefused(message: string, detail: string): void {\n notify.warn(message, { action: RETRY, detail, key: NOTIFY_KEY, source: SOURCE });\n}\n\n/**\n * Start the device flow.\n *\n * @returns The device code payload, or null when the request failed — reported, never thrown, so a\n * caller that forgot to catch cannot turn a network error back into silence.\n */\nasync function requestDeviceCode(): Promise<DeviceCodeResponse | null> {\n let codeRes: Response;\n try {\n codeRes = await fetch(\"https://github.com/login/device/code\", {\n body: JSON.stringify({ client_id: CLIENT_ID, scope: \"repo\" }),\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n } catch (error) {\n reportUnreachable(error);\n return null;\n }\n\n if (!codeRes.ok) {\n reportRefused(\n \"GitHub refused to start the sign-in.\",\n `GitHub answered ${codeRes.status}${codeRes.statusText ? ` ${codeRes.statusText}` : \"\"}.`,\n );\n return null;\n }\n return (await codeRes.json()) as DeviceCodeResponse;\n}\n\n/**\n * Authenticate with GitHub via the Device Flow. Shows a dialog with the user code and polls until\n * the user completes authorization or cancels.\n *\n * @returns {Promise<string | null>} The access token, or null if it failed or was cancelled. Every\n * `null` that is not a cancellation has already been reported.\n */\nexport async function authenticateGithub() {\n const existing = getGithubToken();\n if (existing) {\n return existing;\n }\n\n /*\n * The desktop takes the loopback redirect (RFC 8252): its browser opens the provider's own page,\n * the code comes back to a loopback server, and PKCE binds the exchange. The device flow below is\n * for the browser Studio, which has no loopback server to redirect to — and whose first request\n * to GitHub's device endpoint is refused by CORS anyway.\n */\n const native = nativeAuth();\n if (native) {\n try {\n const { token } = await native.signIn();\n nativeToken = token;\n return token;\n } catch (error) {\n reportRefused(\"GitHub sign-in was not completed.\", errorMessage(error));\n return null;\n }\n }\n\n const codeData = await requestDeviceCode();\n if (!codeData) {\n return null;\n }\n\n const { device_code, user_code, verification_uri, interval = 5 } = codeData;\n\n return showDialog<string | null>((done) => {\n let cancelled = false;\n let pollTimer: ReturnType<typeof setTimeout> | null = null;\n let failures = 0;\n\n const stop = () => {\n cancelled = true;\n if (pollTimer) {\n clearTimeout(pollTimer);\n }\n done(null);\n };\n\n const poll = async () => {\n if (cancelled) {\n return;\n }\n try {\n const tokenRes = await fetch(\"https://github.com/login/oauth/access_token\", {\n body: JSON.stringify({\n client_id: CLIENT_ID,\n device_code,\n grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n }),\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n const tokenData = (await tokenRes.json()) as TokenResponse;\n failures = 0;\n\n if (tokenData.access_token) {\n localStorage.setItem(STORAGE_KEY, tokenData.access_token);\n done(tokenData.access_token);\n return;\n }\n\n if (tokenData.error === \"authorization_pending\") {\n pollTimer = setTimeout(poll, interval * 1000);\n return;\n }\n\n if (tokenData.error === \"slow_down\") {\n pollTimer = setTimeout(poll, (interval + 5) * 1000);\n return;\n }\n\n // Expired_token, access_denied, or anything else GitHub decides to answer. The state is\n // Correct — there is no token because the user did not grant one — so this rests.\n reportRefused(\n \"GitHub sign-in was not completed.\",\n tokenData.error === \"access_denied\"\n ? \"The authorization was declined on GitHub.\"\n : tokenData.error === \"expired_token\"\n ? \"The device code expired before it was entered.\"\n : `GitHub answered \"${tokenData.error ?? \"an unrecognised response\"}\".`,\n );\n cancelled = true;\n done(null);\n } catch (error) {\n failures += 1;\n if (failures >= MAX_POLL_FAILURES) {\n reportUnreachable(error);\n cancelled = true;\n done(null);\n return;\n }\n pollTimer = setTimeout(poll, interval * 1000);\n }\n };\n\n pollTimer = setTimeout(poll, interval * 1000);\n\n return html`\n <sp-dialog-wrapper\n open\n headline=\"Sign in to GitHub\"\n cancel-label=\"Cancel\"\n @cancel=${stop}\n @close=${stop}\n >\n <div class=\"github-auth-dialog\">\n <p>Enter this code on GitHub to authorize Jx Studio:</p>\n <div class=\"github-auth-code\">${user_code}</div>\n <p>\n <a href=\"${verification_uri}\" target=\"_blank\" rel=\"noopener\"\n >Open ${verification_uri}</a\n >\n </p>\n <p class=\"github-auth-waiting\">Waiting for authorization…</p>\n </div>\n </sp-dialog-wrapper>\n `;\n });\n}\n",
6
- "/// <reference lib=\"dom\" />\n/**\n * Create a GitHub repository for a local project, add it as `origin`, and push.\n *\n * **This is not publishing, and it used to say it was.** Two unrelated operations shared the verb\n * (plan §9.5): this one creates a git repository, and `publish/publish-panel.ts` connects a hosting\n * provider that then builds the site. A user who wanted the second and found the first got a GitHub\n * repository and no site, and a user who wanted the first read \"Publish to GitHub\" and reasonably\n * expected a URL. The function, the dialog headline, the activity title and the notification source\n * now all say _Create GitHub Repository_; `Publish:` belongs to `publish/publish-commands.ts`.\n *\n * **It is an Activity, not three toasts.** Three `notify.info` lines sharing one key replaced each\n * other in a corner while a multi-second, three-request, partially-committing operation ran with no\n * log and no cancel — and its middle step (`gitAddRemote`) had no error path at all, so a remote\n * that already existed failed the push with a message about pushing. `beginActivity` gives it the\n * ordered steps, the captured log, and `fail()`, which raises the Problem the failure needs and\n * carries the log as its detail (§7.3). The caller therefore never also notifies.\n */\n\nimport { html } from \"lit-html\";\nimport { errorMessage } from \"@jxsuite/schema/parse\";\nimport { ref } from \"lit-html/directives/ref.js\";\nimport { showDialog } from \"../ui/layers\";\nimport { authenticateGithub } from \"./github-auth\";\nimport { beginActivity } from \"../panels/activity-panel\";\nimport { getPlatform } from \"../platform\";\nimport { notify } from \"../services/notify\";\n\ninterface GithubErrorResponse {\n errors?: { message?: string }[];\n message?: string;\n}\n\ninterface GithubRepoResponse {\n clone_url: string;\n html_url: string;\n}\n\n/** What the dialog collects. */\nexport interface RepoOptions {\n name: string;\n description: string;\n isPrivate: boolean;\n}\n\n/** The ordered steps, named once so the activity and its tests cannot disagree. */\nexport const REPO_STEPS = [\"Create the repository\", \"Add the remote\", \"Push\"] as const;\n\n/**\n * Full \"Create GitHub Repository\" flow: 1. Authenticate (or reuse a stored token) 2. Prompt for\n * repo name / visibility 3. Create the repo via the GitHub API 4. Add remote + push\n *\n * A failed sign-in returns `false` having already reported itself — `github-auth.ts` owns that\n * message, because \"GitHub is unreachable from a browser\" is not a fact about creating a\n * repository.\n *\n * @param {{ projectName: string }} opts\n * @returns {Promise<boolean>} True if the repository was created and pushed.\n */\nexport async function createGithubRepository({ projectName }: { projectName: string }) {\n const token = await authenticateGithub();\n if (!token) {\n return false;\n }\n\n const repoOpts = await showDialog<RepoOptions | null>((done) => {\n let _nameInput: HTMLInputElement | null = null;\n let _descInput: HTMLInputElement | null = null;\n let _privateToggle: HTMLInputElement | null = null;\n\n return html`\n <sp-dialog-wrapper\n open\n headline=\"Create GitHub Repository\"\n confirm-label=\"Create Repository\"\n cancel-label=\"Cancel\"\n @confirm=${() => {\n done({\n description: _descInput?.value || \"\",\n isPrivate: _privateToggle?.checked ?? true,\n name: _nameInput?.value || projectName,\n });\n }}\n @cancel=${() => done(null)}\n @close=${() => done(null)}\n >\n <div class=\"github-publish-dialog\">\n <sp-field-label for=\"repo-name\">Repository name</sp-field-label>\n <sp-textfield\n id=\"repo-name\"\n name=\"repo-name\"\n value=\"${projectName}\"\n placeholder=\"my-project\"\n ${ref((el) => {\n _nameInput = (el as HTMLInputElement | null) || null;\n })}\n ></sp-textfield>\n\n <sp-field-label for=\"repo-desc\">Description (optional)</sp-field-label>\n <sp-textfield\n id=\"repo-desc\"\n name=\"repo-desc\"\n placeholder=\"A brief description\"\n ${ref((el) => {\n _descInput = (el as HTMLInputElement | null) || null;\n })}\n ></sp-textfield>\n\n <sp-field-label>Visibility</sp-field-label>\n <sp-switch\n name=\"repo-private\"\n checked\n ${ref((el) => {\n _privateToggle = (el as HTMLInputElement | null) || null;\n })}\n >Private repository</sp-switch\n >\n </div>\n </sp-dialog-wrapper>\n `;\n });\n\n if (!repoOpts) {\n return false;\n }\n\n const activity = beginActivity({\n source: \"Source Control\",\n status: `Creating ${repoOpts.name}…`,\n steps: [...REPO_STEPS],\n title: \"Create GitHub repository\",\n });\n\n activity.step(REPO_STEPS[0]);\n const createRes = await fetch(\"https://api.github.com/user/repos\", {\n body: JSON.stringify({\n auto_init: false,\n description: repoOpts.description,\n name: repoOpts.name,\n private: repoOpts.isPrivate,\n }),\n headers: {\n Accept: \"application/vnd.github+json\",\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n }).catch((error: unknown) => {\n activity.log(errorMessage(error));\n return null;\n });\n\n if (!createRes) {\n activity.fail(\"Could not reach GitHub to create the repository.\", {\n action: \"git.createGithubRepository\",\n });\n return false;\n }\n\n if (!createRes.ok) {\n const err = (await createRes.json()) as GithubErrorResponse;\n activity.log(err.errors?.[0]?.message || err.message || `GitHub answered ${createRes.status}.`);\n activity.fail(\"Could not create the GitHub repository.\", {\n action: \"git.createGithubRepository\",\n });\n return false;\n }\n\n const repo = (await createRes.json()) as GithubRepoResponse;\n activity.log(`Created ${repo.html_url}`);\n const platform = getPlatform();\n\n activity.step(REPO_STEPS[1]);\n try {\n await platform.gitAddRemote(\"origin\", repo.clone_url);\n } catch (error) {\n // The remote had no error path at all before this, so an `origin` that already existed\n // Surfaced as a push failure describing the push.\n activity.log(errorMessage(error));\n activity.fail(\"The repository was created, but the remote could not be added.\", {\n action: \"panel.focus.git\",\n });\n return false;\n }\n\n activity.step(REPO_STEPS[2]);\n try {\n await platform.gitPush({ setUpstream: true });\n } catch (error) {\n activity.log(errorMessage(error));\n activity.fail(\"The repository was created, but the push failed.\", {\n action: \"git.push\",\n });\n return false;\n }\n\n // Lazy import breaks the github-publish ↔ git-panel module cycle\n const { refreshGitStatus } = await import(\"../panels/git-panel\");\n await refreshGitStatus();\n activity.done(repo.html_url);\n notify.success(`Repository created: ${repo.html_url}`, { key: \"github.repo\" });\n return true;\n}\n",
7
- "/**\n * Project catalogue — a synchronous render cache over the optional `platform.listProjects` PAL\n * member (dev server sites, cloud platforms). Hydrated once at boot (studio.ts) like the\n * recent-projects cache; the welcome screen reads it synchronously.\n */\nimport { getPlatform, hasPlatform } from \"./platform\";\nimport type { ProjectListEntry } from \"./types\";\n\nlet cache: ProjectListEntry[] = [];\n\n/** True when the active platform exposes a project catalogue. */\nexport function platformListsProjects(): boolean {\n return hasPlatform() && typeof getPlatform().listProjects === \"function\";\n}\n\n/** Refresh the cache from the platform; resolves to [] when unsupported or failing. */\nexport async function hydrateProjectList(): Promise<void> {\n if (!platformListsProjects()) {\n cache = [];\n return;\n }\n try {\n cache = (await getPlatform().listProjects?.()) ?? [];\n } catch {\n // Catalogue is progressive enhancement; a failed fetch leaves the section hidden.\n cache = [];\n }\n}\n\n/** Synchronous snapshot for render paths (never awaits). */\nexport function getProjectList(): ProjectListEntry[] {\n return cache;\n}\n\n/** Reset seam for tests. */\nexport function resetProjectList(): void {\n cache = [];\n}\n\n/** Seed seam for tests and the screenshot automation hook (staged catalogues). */\nexport function seedProjectList(entries: ProjectListEntry[]): void {\n cache = entries;\n}\n",
8
- "/// <reference lib=\"dom\" />\n/**\n * Idle.ts — \"settled\" is a predicate, and it can fail.\n *\n * One question — _has Studio finished reacting?_ — asked of the five subsystems that can still be\n * mid-flight, over two consecutive animation frames (spec studio.md §13.5, plan §13.4).\n *\n * **The rejection is the point.** The thing this replaces is 115 `wait: {ms}` steps totalling 73\n * seconds, and a sleep cannot fail: a subsystem that was slow that day got answered with `+500 ms`\n * and the wrong state was photographed, committed and accepted. {@link NotIdleError} carries a\n * `blockedBy` array naming every outstanding item — `[\"canvas[page-1]: gen 7 unacked\", \"platform: 1\n * in-flight (gitStatus)\"]` — so the slow subsystem identifies itself.\n *\n * Nothing here polls a subsystem it does not own. Each source is a function the owning module\n * already had to write for its own reasons:\n *\n * 1. `store.rendersInFlight()` — renderers mid-paint.\n * 2. `panel-scheduler.pendingSchedulers()` — panels with a frame queued or a render withheld.\n * 3. `iframe-host.canvasIdleBlockers()` — per host: unacked generations and patches, plus the frame's\n * own cross-realm report of fonts, running animations and pending image retries.\n * 4. `platform.platformInFlight()` — unsettled PAL calls, counted at the one seam every adapter and\n * all thirty-odd `git*`/fs/fetch methods pass through.\n * 5. `layers.overlayIdleBlockers()` — overlays still in transition. Only the SETTLING window counts: a\n * resting toast is not a blocker, which is what lets `toastsAreHeld()` hold one open for a\n * capture without `probeIdle()` waiting forever alongside it (plan §13.7's named exception).\n * 6. `activity-panel.activityIdleBlockers()` — operations still RUNNING in the Activity tab. Not a\n * duplicate of `platform`: an activity spans a whole operation (an install, a deploy, a clone)\n * across many PAL calls, so the gaps between them look quiet at the seam while the operation is\n * plainly mid-flight. A finished entry never blocks — the list stays on screen forever.\n *\n * The consumers are the `packages/studio:verify` skill, the screenshot runner and P4.2's Activity\n * tracker (this is a read-only projection of the same in-flight set that dock renders).\n */\n\nimport { rendersInFlight } from \"../store\";\nimport { activityIdleBlockers } from \"../panels/activity-panel\";\nimport { pendingSchedulers } from \"../panels/panel-scheduler\";\nimport { canvasIdleBlockers } from \"../canvas/iframe-host\";\nimport { platformInFlight } from \"../platform\";\nimport { overlayIdleBlockers } from \"../ui/layers\";\n\n/** One subsystem that can be outstanding, and its account of why. */\nexport interface IdleSource {\n /** Stable name — `render`, `panels`, `canvas`, `platform`, `overlay`. */\n readonly name: string;\n /** Empty when quiet; otherwise one human-readable line per outstanding item. */\n blockers: () => readonly string[];\n}\n\n/** Consecutive quiet animation frames required before Studio counts as settled. */\nexport const QUIET_FRAMES = 2;\n\n/** How long {@link probeIdle} waits before rejecting with what is still outstanding. */\nexport const DEFAULT_IDLE_TIMEOUT_MS = 10_000;\n\n/** Thrown when Studio did not settle in time — `blockedBy` is the answer, not the message. */\nexport class NotIdleError extends Error {\n readonly blockedBy: readonly string[];\n\n constructor(blockedBy: readonly string[], timeoutMs: number) {\n super(\n blockedBy.length === 0\n ? `Studio did not report ${QUIET_FRAMES} consecutive quiet frames within ${timeoutMs}ms`\n : `Studio was not idle after ${timeoutMs}ms — blocked by ${blockedBy.join(\"; \")}`,\n );\n this.name = \"NotIdleError\";\n this.blockedBy = blockedBy;\n }\n}\n\n/**\n * The six live sources.\n *\n * Built per call rather than held in a module constant so a test can substitute one without\n * unpicking the others, and so a second window's hosts are never read through the first window's\n * closure.\n */\nexport function defaultIdleSources(): IdleSource[] {\n return [\n {\n blockers: () => {\n const count = rendersInFlight();\n return count > 0 ? [`render: ${count} renderer(s) mid-paint`] : [];\n },\n name: \"render\",\n },\n {\n blockers: () => pendingSchedulers().map((panel) => `panels: ${panel}`),\n name: \"panels\",\n },\n { blockers: canvasIdleBlockers, name: \"canvas\" },\n {\n blockers: () => {\n const calls = platformInFlight();\n if (calls.length === 0) {\n return [];\n }\n return [`platform: ${calls.length} in-flight (${[...new Set(calls)].join(\", \")})`];\n },\n name: \"platform\",\n },\n { blockers: overlayIdleBlockers, name: \"overlay\" },\n { blockers: activityIdleBlockers, name: \"activity\" },\n ];\n}\n\n/** Everything outstanding right now, across every source. Empty means this instant is quiet. */\nexport function idleBlockers(sources: readonly IdleSource[] = defaultIdleSources()): string[] {\n const blockers: string[] = [];\n for (const source of sources) {\n blockers.push(...source.blockers());\n }\n return blockers;\n}\n\nexport interface IdleOptions {\n timeoutMs?: number;\n /** Consecutive quiet frames required. Defaults to {@link QUIET_FRAMES}. */\n frames?: number;\n /** Substitute the quiescence sources — what a test states, and what a second window would pass. */\n sources?: readonly IdleSource[];\n /** Frame scheduler, injectable so the loop is testable without a real compositor. */\n raf?: (callback: () => void) => void;\n /** Clock, injectable for the same reason. */\n now?: () => number;\n}\n\n/**\n * Resolve once every source has been quiet for `frames` consecutive animation frames.\n *\n * Rejects with {@link NotIdleError} on timeout. A single quiet frame is not enough: a render commits\n * its DOM in one frame and its layout/animation consequences in the next, which is exactly the\n * window a one-frame check photographs.\n */\nexport function probeIdle(options: IdleOptions = {}): Promise<void> {\n const {\n frames = QUIET_FRAMES,\n now = () => Date.now(),\n raf = (callback: () => void) => {\n requestAnimationFrame(() => callback());\n },\n sources = defaultIdleSources(),\n timeoutMs = DEFAULT_IDLE_TIMEOUT_MS,\n } = options;\n\n return new Promise<void>((resolve, reject) => {\n const deadline = now() + timeoutMs;\n let quiet = 0;\n let settled = false;\n // The last non-empty account, so a timeout that lands on a momentarily-quiet frame still names\n // What kept it from reaching `frames` — \"not idle, blocked by nothing\" helps nobody.\n let lastBlockers: readonly string[] = [];\n\n const tick = () => {\n if (settled) {\n return;\n }\n const blockers = idleBlockers(sources);\n if (blockers.length > 0) {\n lastBlockers = blockers;\n quiet = 0;\n } else {\n quiet += 1;\n if (quiet >= frames) {\n settled = true;\n resolve();\n return;\n }\n }\n if (now() >= deadline) {\n settled = true;\n reject(new NotIdleError(blockers.length > 0 ? blockers : lastBlockers, timeoutMs));\n return;\n }\n raf(tick);\n };\n raf(tick);\n });\n}\n",
9
- "/// <reference lib=\"dom\" />\n/**\n * Automation.ts — the scripting surface, as a PROJECTION of the app.\n *\n * Installed as `window.__jxAutomation` only when the page URL carries `?automation=1`. It exposes\n * exactly three members (spec studio.md §13.5):\n *\n * - `run(id, args)` — **is** `registry.run(id, args)`, behind {@link isScriptable}. There is no\n * second action table. A hand-maintained parallel list of what the app can do is what plan §2\n * principle 1 defines as a defect, and this module used to be 39 entries of exactly that, 16 of\n * them holding raw XPath into the shell and three of them matching RENDERED TEXT.\n * - `seed(id, args)` — the {@link SEEDS} registry, under the **Remote Rule**: a seed may only write\n * state whose real writer is a network or IPC boundary. It stands in for a remote, never for a\n * user. {@link REFUSED_SEEDS} names what that excludes and why.\n * - `probe` — read-only. {@link AutomationProbe.idle} (the predicate that replaced 115 sleeps),\n * `state()` (the full `CommandContext`), `commands()`, `seeds()`, and `pointAt`/`revealPath`,\n * which compose the app's own transforms and answer in top-document coordinates.\n *\n * **What is deliberately absent**, each a normative refusal in spec §13.5:\n *\n * 1. No method that takes a selector. If a script cannot say it in command ids and `JxPath`s, it\n * cannot say it here.\n * 2. No `setStatus`. Staging the word \"Ready\" over the status bar is lying to the reader; if a capture\n * needs a calm status bar, the app has to BE calm.\n * 3. No `toggle*`. A delta against unstated state is what silently inverted 23 manifest steps when the\n * assistant's default flipped, and an agent calling `view.toggleAssistant` is guessing at state\n * it cannot observe. {@link TOGGLE_ID} refuses them at runtime.\n * 4. No compatibility shim. The predecessor carried `setRightTab`'s `if (tab === \"assistant\")`\n * redirect, whose own comment said it existed \"to keep the Screenshot-manifest verb working\" — a\n * pipeline artefact living in production code.\n * 5. No presentation-state pokes. Automation mutates documents by running the commands a user runs, so\n * every write goes through the transaction log.\n */\n\nimport { render } from \"../store\";\nimport { seedProjectList } from \"../project-list\";\nimport { activeTab } from \"../workspace/workspace\";\nimport { shell } from \"../shell\";\nimport { collabState } from \"../collab/collab-state\";\nimport { canvasPointAt, revealCanvasPath } from \"../canvas/iframe-host\";\nimport { probeIdle } from \"./idle\";\nimport type { CanvasPoint } from \"../canvas/iframe-host\";\nimport type { IdleOptions } from \"./idle\";\nimport type { CommandContext } from \"../commands/context\";\nimport type { AnyCommand, CommandRegistry } from \"../commands/registry\";\nimport type { PeerPresence } from \"../collab/collab-state\";\nimport type { SeededAssistantMessage } from \"../panels/ai-panel\";\nimport type { PagesDeploymentInfo } from \"../publish/pages-service\";\nimport type { GitBranchesResult, GitStatusResult, ProjectListEntry } from \"../types\";\nimport type { GitLogEntry } from \"../shell\";\nimport type { JxPath } from \"../state\";\n\n/** Loosely-typed arguments, as they arrive from a manifest step, a palette prompt or a tool call. */\nexport type AutomationArgs = Record<string, unknown>;\n\n/**\n * What the hook needs that it cannot import.\n *\n * Three entries, and the shape is the point: everything the predecessor took by injection —\n * `getCanvasMode`, `openBrowseModal`, `openSettingsModal`, `render`, `setCanvasMode`,\n * `statusMessage` — was a capability being re-implemented here instead of being a command.\n */\nexport interface AutomationDeps {\n /** The registry `run()` projects. One per window, exactly as the bootstrap builds it. */\n registry: CommandRegistry;\n /** The assistant's transcript sink — stands in for the model stream. */\n seedAssistantMessages: (messages: SeededAssistantMessage[]) => void;\n /** The publish panel's connected state — stands in for the Cloudflare Pages API. */\n seedPublishConnected: (options: { accountId?: string; deployment: PagesDeploymentInfo }) => void;\n}\n\n// ─── The idempotence rule ─────────────────────────────────────────────────────\n\n/** `view.toggleAssistant` names a delta; `view.setAssistant` names a state. Only one is runnable. */\nexport const TOGGLE_ID = /\\.toggle[A-Z]/;\n\n/** The idempotent id a toggle should have become — printed so the fix is inside the refusal. */\nexport function setterFor(id: string): string {\n return id.replace(/\\.toggle([A-Z])/, (_match, initial: string) => `.set${initial}`);\n}\n\n/**\n * Whether a command projects into `run()`.\n *\n * Derived, not declared: everything the registry holds is a capability with an id, a gate and a\n * `run`, which is exactly what a script needs. The one exclusion is the idempotence rule, so the\n * projection cannot drift from the registry the way a hand-kept allow-list would.\n */\nexport function isScriptable(command: AnyCommand): boolean {\n return !TOGGLE_ID.test(command.id);\n}\n\n// ─── The registry-gap declaration ─────────────────────────────────────────────\n\n/**\n * How a manifest id the registry does not declare is going to stop existing.\n *\n * - `command` — a thing a user does, so it becomes a registry record. The value names who lands it.\n * - `seed` — a remote's state, addressed through {@link AutomationApi.seed}.\n * - `refused` — §13.3 says the app will never provide it; the manifest step is deleted.\n */\nexport type GapDisposition = \"command\" | \"seed\" | \"refused\";\n\nexport interface ManifestId {\n disposition: GapDisposition;\n /** The phase that lands the record, or the sentence that refuses it. One line, for the error. */\n note: string;\n}\n\n/**\n * Ids the screenshot manifest still depends on and no registry declares. **No handlers, no\n * behaviour.**\n *\n * The export name is the contract `scripts/check-shot-contract.ts` reads (`loadCommandTable` looks\n * for `defaultCommandSet()`, `seedIds()` or `AUTOMATION_COMMANDS`), and it is all that is left of\n * the 39-entry action table this module used to be: every `press`, every XPath, every rendered-text\n * matcher and both label mirrors are gone, and `run()` never consults this map to decide what to DO\n * — only to explain, when the registry refuses an id, which of the three fates that id has.\n *\n * This is a countdown, in the idiom of the checker's own `TOGGLE_DEBT`: it may only shrink. It went\n * 39 → 8 when the manifest converted (S2), and 8 → 7 when `element.insertData` became `insert.data`\n * (P5, `canvas/canvas-render.ts`). What left: every `seed` entry, now read off {@link seedIds} and\n * answered from the live registry rather than from a hand-kept list; every `toggle*` entry, which\n * {@link TOGGLE_ID} refuses before this map is ever consulted; and every `command` entry whose\n * record has since landed.\n *\n * What is left is two kinds. Two `command` entries are the manifest's real registry gaps — each\n * reached today by an `input` step clicking a hand-stamped region, and each of those steps carries\n * an `unstable` hatch naming the phase that lands the record, so this map and that hatch count are\n * the same debt. Five `refused` entries are NOT a countdown: they are §13.3's normative refusals,\n * and they stay so that a caller reaching for one gets the reason instead of \"unknown command\".\n */\nexport const AUTOMATION_COMMANDS: Readonly<Record<string, ManifestId>> = {\n \"file.contextMenu\": {\n disposition: \"refused\",\n note: \"opening a menu to press an item names a control; the ITEM is the command\",\n },\n \"layers.contextMenu\": {\n disposition: \"refused\",\n note: \"matched RENDERED TEXT, which §13's R1 forbids; P5.5 stamps data-jx-path on rows\",\n },\n \"media.browse\": { disposition: \"command\", note: \"P7.5 — media.browse\" },\n \"project.showWelcome\": {\n disposition: \"refused\",\n note: \"cold start is a startup profile (?profile=fresh), not an action\",\n },\n \"settings.setSection\": {\n disposition: \"refused\",\n note: 'mirrored the section registry\\'s LABELS; say settings.open { section: \"cssVars\" }',\n },\n \"view.setStatus\": {\n disposition: \"refused\",\n note: \"the status bar is not staged — if a capture needs a calm shell, the app must BE calm\",\n },\n};\n\n// ─── The seed registry, under the Remote Rule ─────────────────────────────────\n\n/** One staged fixture, and the boundary whose job it is doing. */\nexport interface SeedDefinition {\n id: string;\n /** The network or IPC boundary this seed stands in for. The Remote Rule, written down per seed. */\n boundary: string;\n run: (args: AutomationArgs) => void | Promise<void>;\n}\n\n/**\n * Writes a seed will not do, and the reason, quoted back at the caller.\n *\n * Every one of these was a method on the old surface. Each writes state a USER writes, so each is a\n * COMMAND — and a fixture that stages it photographs a state no session could have reached.\n */\nexport const REFUSED_SEEDS: Readonly<Record<string, string>> = {\n openSettings: 'a user opens Settings — run(\"settings.open\")',\n select: 'a user selects a node — run(\"selection.set\", { path })',\n setActivity: 'a user picks a Navigator panel — run(\"navigator.showPanel\", { panel })',\n setRightTab: 'a user picks an Inspector tab — run(\"inspector.setTab\", { tab })',\n setStatus:\n \"the status bar reports what the app just did; staging it is the one lie §13.3 names outright\",\n setZoom: 'a user zooms — run(\"canvas.setZoom\", { zoom })',\n};\n\nfunction arrayArg<T>(args: AutomationArgs, key: string): T[] {\n const value = args[key];\n if (value === undefined) {\n return [];\n }\n if (!Array.isArray(value)) {\n throw new TypeError(`seed argument \"${key}\" must be an array`);\n }\n return value as T[];\n}\n\nfunction requiredArg<T>(args: AutomationArgs, key: string): T {\n const value = args[key];\n if (value === null || typeof value !== \"object\") {\n throw new TypeError(`seed argument \"${key}\" must be an object`);\n }\n return value as T;\n}\n\nfunction optionalString(args: AutomationArgs, key: string): string | undefined {\n const value = args[key];\n if (value === undefined) {\n return undefined;\n }\n if (typeof value !== \"string\") {\n throw new TypeError(`seed argument \"${key}\" must be a string`);\n }\n return value;\n}\n\n/**\n * The declared seeds.\n *\n * Each one writes exactly what its named boundary would have written, and nothing else — the git\n * seed does not also open the Source Control panel, because a user does that.\n */\nexport function createSeeds(deps: AutomationDeps): SeedDefinition[] {\n return [\n {\n boundary: \"the assistant's model stream\",\n id: \"seed.assistant\",\n run: (args) => {\n deps.seedAssistantMessages(arrayArg<SeededAssistantMessage>(args, \"messages\"));\n },\n },\n {\n boundary: \"the collaboration websocket (awareness + sync)\",\n id: \"seed.collab\",\n run: (args) => {\n const tab = activeTab.value;\n if (!tab) {\n return;\n }\n const state = collabState(tab);\n state.status = \"synced\";\n state.active = true;\n const peers: PeerPresence[] = [];\n for (const peer of arrayArg<PeerPresence>(args, \"peers\")) {\n const peerState = { ...peer.state };\n // A peer with no focused document is focused on THIS one — the presence overlay keys on it.\n peerState.focusedPath ??= tab.documentPath;\n peers.push({ ...peer, state: peerState });\n }\n state.peers = peers;\n render();\n },\n },\n {\n boundary: \"the Cloudflare Pages API\",\n id: \"seed.publish\",\n run: (args) => {\n const accountId = optionalString(args, \"accountId\");\n deps.seedPublishConnected({\n deployment: requiredArg<PagesDeploymentInfo>(args, \"deployment\"),\n ...(accountId ? { accountId } : {}),\n });\n },\n },\n {\n boundary: \"the platform's git routes (`gitStatus` / `gitBranches` / `gitLog`)\",\n id: \"seed.git\",\n run: (args) => {\n // The working tree really is a remote here: the git-panel shot photographs whatever the\n // Author happened to have dirty, because its project lives inside this repository.\n shell.git.status = (args.status as GitStatusResult | undefined) ?? null;\n shell.git.branches = (args.branches as GitBranchesResult | undefined) ?? null;\n shell.git.logEntries = (args.log as GitLogEntry[] | undefined) ?? null;\n shell.git.loading = false;\n shell.git.error = null;\n render();\n },\n },\n {\n boundary: \"the platform's recent-projects store (desktop IPC / cloud API)\",\n id: \"seed.projectList\",\n run: (args) => {\n seedProjectList(arrayArg<ProjectListEntry>(args, \"projects\"));\n render();\n },\n },\n ];\n}\n\n/**\n * Every declared seed id, read off {@link createSeeds} itself.\n *\n * `scripts/check-shot-contract.ts` needs to answer \"is `seed.projectList` a real seed?\" in a bare\n * Bun process with no app. It could have read a hand-kept list — and a hand-kept list is precisely\n * how `seed.git` and `seed.projectList` came to be missing from {@link AUTOMATION_COMMANDS} while\n * both were shipping. Constructing the definitions is free: every seed's dependency is used inside\n * its `run`, never while building it, so the no-op deps below can never be called.\n */\nexport function seedIds(): string[] {\n const inert = {\n registry: undefined as unknown as CommandRegistry,\n seedAssistantMessages: () => {},\n seedPublishConnected: () => {},\n } satisfies AutomationDeps;\n return createSeeds(inert).map((seed) => seed.id);\n}\n\n// ─── The API ──────────────────────────────────────────────────────────────────\n\n/** One command as a script sees it — the projection, not a second declaration. */\nexport interface ScriptableCommand {\n id: string;\n title: string;\n /** Whether its own `enablement` predicate would let it run right now. */\n enabled: boolean;\n /** The `requires` sentence when it would not. */\n requires?: string;\n /** The command's own JSON Schema — the palette's prompt and the AI tool's parameters. */\n args?: object;\n}\n\n/** What `pointAt` can address. Region ids join `path` when P3.8's region registry lands. */\nexport interface AutomationTarget {\n path: JxPath;\n}\n\n/** Read-only questions. Nothing here writes document or presentation state. */\nexport interface AutomationProbe {\n /**\n * Resolve when Studio has settled; reject with `NotIdleError.blockedBy` naming what it is waiting\n * on. See `services/idle.ts` — the rejection is the reason this exists.\n */\n idle: (options?: Pick<IdleOptions, \"frames\" | \"timeoutMs\">) => Promise<void>;\n /** The full `CommandContext` — the same record every `when` predicate and AI tool gate reads. */\n state: () => CommandContext;\n /** Every command a script may run right now, with its gate already evaluated. */\n commands: () => ScriptableCommand[];\n /** The declared seed ids, with the boundary each stands in for. */\n seeds: () => { id: string; boundary: string }[];\n /** Where a node is on screen, in TOP-DOCUMENT coordinates. Measures; moves nothing. */\n pointAt: (target: AutomationTarget) => Promise<CanvasPoint | null>;\n /** Bring a node into view and answer where it landed — the app's own jump-to-node. */\n revealPath: (path: JxPath) => Promise<CanvasPoint | null>;\n}\n\nexport interface AutomationApi {\n run: (id: string, args?: AutomationArgs) => Promise<void>;\n seed: (id: string, args?: AutomationArgs) => Promise<void>;\n probe: AutomationProbe;\n}\n\n/** Thrown when the surface refuses an id on principle rather than because it is unknown. */\nexport class AutomationRefusedError extends Error {\n readonly id: string;\n\n constructor(id: string, reason: string) {\n super(`automation refuses \"${id}\" — ${reason}`);\n this.name = \"AutomationRefusedError\";\n this.id = id;\n }\n}\n\n/** The projection: every visible, scriptable command with its gate already evaluated. */\nexport function scriptableCommands(registry: CommandRegistry): ScriptableCommand[] {\n const projected: ScriptableCommand[] = [];\n for (const command of registry.visible()) {\n if (!isScriptable(command)) {\n continue;\n }\n const requires = registry.disabledReason(command.id);\n const entry: ScriptableCommand = {\n enabled: requires === undefined,\n id: command.id,\n title: command.title,\n };\n if (command.args) {\n entry.args = command.args;\n }\n if (requires !== undefined) {\n entry.requires = requires;\n }\n projected.push(entry);\n }\n return projected;\n}\n\n/** Why an id the registry does not declare is not runnable — the countdown, said out loud. */\nfunction unknownCommandMessage(\n id: string,\n registry: CommandRegistry,\n seeds: ReadonlySet<string>,\n): string {\n // Derived from the live seed registry, not from a hand-kept `disposition: \"seed\"` list: a seed\n // Added next week answers this question without anyone remembering to write it down twice.\n if (seeds.has(id)) {\n return `\"${id}\" is a seed, not a command — call seed(\"${id}\", …)`;\n }\n const gap = AUTOMATION_COMMANDS[id];\n if (gap?.disposition === \"refused\") {\n return `\"${id}\" is refused by spec §13.5: ${gap.note}`;\n }\n if (gap) {\n return `\"${id}\" has no command record yet (${gap.note}) — __jxAutomation.run projects the registry and nothing else`;\n }\n const known = registry\n .list()\n .filter((command) => isScriptable(command))\n .map((command) => command.id);\n return `unknown command \"${id}\" — the registry declares ${known.length} scriptable id(s)`;\n}\n\nexport function createAutomationApi(deps: AutomationDeps): AutomationApi {\n const seeds = new Map(createSeeds(deps).map((seed) => [seed.id, seed]));\n const seedIdSet = new Set(seeds.keys());\n\n return {\n probe: {\n commands: () => scriptableCommands(deps.registry),\n idle: (options = {}) => probeIdle(options),\n pointAt: (target) => canvasPointAt(target.path),\n revealPath: (path) => revealCanvasPath(path),\n seeds: () => [...seeds.values()].map((seed) => ({ boundary: seed.boundary, id: seed.id })),\n state: () => deps.registry.context(),\n },\n async run(id, args = {}) {\n if (TOGGLE_ID.test(id)) {\n throw new AutomationRefusedError(\n id,\n `it names a delta against state the caller cannot observe; call \"${setterFor(id)}\"`,\n );\n }\n const { registry } = deps;\n if (!registry.get(id)) {\n throw new Error(unknownCommandMessage(id, registry, seedIdSet));\n }\n // Refusal propagates as `CommandUnavailableError`: a step asking for a state the app refuses\n // Must FAIL, because that step is lying about what the app can be.\n await registry.run(id, args);\n },\n async seed(id, args = {}) {\n const bare = id.startsWith(\"seed.\") ? id.slice(5) : id;\n const refusal = REFUSED_SEEDS[bare];\n if (refusal) {\n throw new AutomationRefusedError(\n id,\n `a seed stands in for a remote, never for a user: ${refusal}`,\n );\n }\n const seed = seeds.get(id.startsWith(\"seed.\") ? id : `seed.${id}`);\n if (!seed) {\n throw new Error(\n `unknown seed \"${id}\" — declared seeds are ${[...seeds.keys()].join(\", \")}`,\n );\n }\n await seed.run(args);\n },\n };\n}\n\n/** The hook is opt-in per page load: only `?automation=1` installs it. */\nexport function shouldInstallAutomation(search: string): boolean {\n return new URLSearchParams(search).get(\"automation\") === \"1\";\n}\n\n/**\n * Install the hook on globalThis when the current URL opts in. Returns whether it installed, so\n * callers (and tests) can assert the gate.\n */\nexport function installAutomationHook(deps: AutomationDeps): boolean {\n if (!shouldInstallAutomation(location.search)) {\n return false;\n }\n (globalThis as Record<string, unknown>).__jxAutomation = createAutomationApi(deps);\n return true;\n}\n",
10
- "/**\n * Minimal semver helpers for comparing dependency versions in the UI. Deliberately tiny — we only\n * need range stripping and ordering of `x.y.z` triples, not full semver range satisfaction, so we\n * avoid pulling in a dependency.\n */\n\n/** Strip a range prefix to its base version: \"^0.19.0\" → \"0.19.0\", \"~1.2.3\" → \"1.2.3\". */\nexport function stripRange(range: string): string {\n const base = range.replace(/^[\\^~>=<v\\s]+/, \"\").trim();\n return base.split(/\\s+/)[0] ?? \"\";\n}\n\n/**\n * Whether a spec is a comparable registry semver (a plain `x.y.z` range), as opposed to\n * `workspace:`, `file:`, `link:`, a git/URL spec, or a wildcard like `*`/`latest`.\n */\nexport function isComparable(spec: string): boolean {\n if (spec.includes(\":\")) {\n return false;\n }\n return /^\\d+\\.\\d+/.test(stripRange(spec));\n}\n\n/** Parse a version into numeric [major, minor, patch], ignoring any pre-release/build suffix. */\nfunction parts(version: string): [number, number, number] {\n const core = stripRange(version).split(/[-+]/)[0] ?? \"\";\n const [major = 0, minor = 0, patch = 0] = core.split(\".\").map((n) => Math.trunc(Number(n)) || 0);\n return [major, minor, patch];\n}\n\n/**\n * Compare two versions (range prefixes tolerated). Returns -1 if a < b, 1 if a > b, 0 if equal.\n * Pre-release/build metadata is ignored.\n */\nexport function compareSemver(a: string, b: string): number {\n const pa = parts(a);\n const pb = parts(b);\n for (let i = 0; i < 3; i++) {\n const da = pa[i] ?? 0;\n const db = pb[i] ?? 0;\n if (da !== db) {\n return da < db ? -1 : 1;\n }\n }\n return 0;\n}\n\n/** Whether `latest` is strictly newer than the base version of `current` (both comparable). */\nexport function isUpgrade(current: string, latest: string): boolean {\n if (!isComparable(current) || !isComparable(latest)) {\n return false;\n }\n return compareSemver(latest, current) > 0;\n}\n",
11
- "/// <reference lib=\"dom\" />\n/**\n * On project open, offer to bring the project's `@jxsuite/*` dependencies up to their newest\n * PUBLISHED versions — each package to its own latest, asked of the npm registry.\n *\n * It used to target `VERSION`, the version this Studio build embeds, and bump every `@jxsuite/*`\n * range to `^VERSION` in one move. That was right exactly once: when the whole suite released\n * together, so \"the version Studio is\" and \"the newest version of each package\" were the same\n * string. They are not any more — the packages release on their own cadences, and `@jxsuite/parser`\n * being at 1.2.0 while Studio is 2.0.1 is the normal case, not a fault. Targeting the embedded\n * version therefore proposed a version that may never have been published, for a package whose real\n * latest it had not looked at.\n *\n * **Studio's own copies are not involved.** The app resolves `@jxsuite/*` from its own install\n * (that is the hermetic host rule the schema loader enforces), so the project's ranges govern `jx\n * build` and the project's types — not the running app. There is no reason for them to match\n * Studio, and pinning them to it was the residue of an assumption that is no longer true.\n *\n * The registry lookup is `platform.outdatedPackages()`, the same seam the dependencies editor uses.\n * A host that does not offer it (the cloud session, which manages dependencies server-side) simply\n * gets no prompt: without the registry there is no honest target, and guessing is what this\n * replaced.\n */\n\nimport { html } from \"lit-html\";\nimport { getPlatform } from \"../platform\";\nimport { shouldInstallAutomation } from \"../services/automation\";\nimport { showConfirmDialog } from \"../ui/layers\";\nimport { showProgressModal } from \"../ui/progress-modal\";\nimport { notify } from \"../services/notify\";\nimport { isUpgrade } from \"./semver\";\n\nconst JXSUITE_PREFIX = \"@jxsuite/\";\n\nexport interface JxsuiteUpdate {\n name: string;\n /** The range pinned in package.json, e.g. `^1.2.0`. */\n current: string;\n /** THIS package's newest published version — not a suite-wide number. */\n latest: string;\n dev: boolean;\n}\n\n/**\n * The project's `@jxsuite/*` dependencies that are behind their own newest published version.\n *\n * Empty when there is nothing to do, when the host cannot reach the registry, or when it offers no\n * lookup at all. Every failure path is empty rather than thrown: this runs on project open, and a\n * registry that is unreachable on a train is not an error the author needs to see.\n */\nexport async function checkJxsuiteUpdate(): Promise<JxsuiteUpdate[]> {\n const platform = getPlatform();\n if (!platform.outdatedPackages) {\n return [];\n }\n let reported;\n try {\n reported = await platform.outdatedPackages();\n } catch {\n return [];\n }\n const outdated: JxsuiteUpdate[] = [];\n for (const p of reported) {\n /*\n * `isUpgrade`, not merely \"differs from latest\". `outdatedPackages` reports any difference, and\n * a project deliberately pinned AHEAD of the registry — a prerelease, or a range bumped before\n * the publish landed — would otherwise be offered a downgrade described as an update.\n */\n if (p.name.startsWith(JXSUITE_PREFIX) && isUpgrade(p.current, p.latest)) {\n outdated.push({ current: p.current, dev: Boolean(p.dev), latest: p.latest, name: p.name });\n }\n }\n return outdated;\n}\n\n/**\n * The dismissal is remembered against the exact set of versions declined.\n *\n * It used to be keyed on the single target version, which no longer exists. Keying on the set means\n * a later publish of any one package asks again — which is the behaviour you want from \"not now\",\n * and the reason this is not keyed on the project alone.\n */\nfunction dismissKey(root: string, outdated: JxsuiteUpdate[]): string {\n const signature = outdated\n .map((p) => `${p.name}@${p.latest}`)\n .toSorted()\n .join(\",\");\n return `jx:jxsuite-update-dismissed:${root}:${signature}`;\n}\n\nfunction isDismissed(root: string, outdated: JxsuiteUpdate[]): boolean {\n try {\n return localStorage.getItem(dismissKey(root, outdated)) === \"1\";\n } catch {\n return false;\n }\n}\n\nfunction setDismissed(root: string, outdated: JxsuiteUpdate[]): void {\n try {\n localStorage.setItem(dismissKey(root, outdated), \"1\");\n } catch {\n /* Ignore storage errors */\n }\n}\n\n/** Pin each package to `^<its own latest>` and reinstall, behind a progress modal. */\nexport async function applyJxsuiteUpdate(outdated: JxsuiteUpdate[]): Promise<void> {\n const platform = getPlatform();\n if (!platform.setPackageVersions || outdated.length === 0) {\n return;\n }\n const progress = showProgressModal({\n status: \"Updating @jxsuite packages…\",\n title: \"Updating dependencies\",\n });\n try {\n const result = await platform.setPackageVersions(\n // Per package. One shared `^${target}` for all of them is the bug this module was refactored\n // To remove.\n outdated.map((p) => ({ dev: p.dev, name: p.name, version: `^${p.latest}` })),\n );\n if (result.ok) {\n progress.done();\n notify.success(`Updated ${outdated.length} @jxsuite package(s) to their latest versions.`);\n } else {\n progress.fail(result.log ?? \"Update failed\");\n }\n } catch (error) {\n progress.fail(error instanceof Error ? error.message : String(error));\n }\n}\n\n/**\n * Prompt to update on open. Skips when there is nothing to do or the user already declined this\n * exact set of versions for this project (remembered in localStorage).\n */\nexport async function maybePromptJxsuiteUpdate(projectRoot: string): Promise<void> {\n // Automation/screenshot runs open projects read-only to drive the canvas — the same rule\n // Ensure-deps.ts states, and for the same reason: confirming here calls `setPackageVersions`,\n // Which rewrites the opened project's package.json.\n //\n // It also has to hold when nobody confirms anything. `showConfirmDialog` renders an\n // `<sp-dialog-wrapper open underlay>`, and an underlay swallows every pointer event across the\n // Viewport — so a prompt raised at boot means every subsequent click in a shot lands in a scrim.\n // That is not hypothetical: it put this dialog into the middle of 33 committed screenshots,\n // Including docs/images/hero.png, which is the jxsuite.com marketing hero.\n //\n // Correct pins are NOT sufficient on their own. `outdatedPackages` compares the range's base\n // Version against the registry's `latest` (packages/server/src/packages.ts: `latest ===\n // StripRange(p.version)`), not whether the range resolves it — so a project pinned `^1.4.1` is\n // \"outdated\" the moment 1.4.2 publishes, and every starter shot would be scrimmed again by the\n // Next patch release of any @jxsuite package.\n if (shouldInstallAutomation(location.search)) {\n return;\n }\n const platform = getPlatform();\n if (!platform.setPackageVersions) {\n return;\n }\n const outdated = await checkJxsuiteUpdate();\n if (outdated.length === 0 || isDismissed(projectRoot, outdated)) {\n return;\n }\n const list = outdated.map((p) => `${p.name} ${p.current} → ^${p.latest}`).join(\"\\n\");\n const confirmed = await showConfirmDialog(\n \"Update @jxsuite packages?\",\n html`Newer versions of these packages have been published. Update the project to them?\n <br /><br /><span\n style=\"font-size:var(--spectrum-font-size-75, 12px);color:var(--fg-dim);white-space:pre-line\"\n >${list}</span\n >`,\n { cancelLabel: \"Not now\", confirmLabel: \"Update\" },\n );\n if (!confirmed) {\n setDismissed(projectRoot, outdated);\n return;\n }\n await applyJxsuiteUpdate(outdated);\n}\n",
12
- "/// <reference lib=\"dom\" />\n/**\n * Pull orchestration that keeps project sync from being blocked by Studio's own automated package\n * updates. The on-open @jxsuite update rewrites package.json and bun.lock without committing, so a\n * teammate pushing the same update makes a later `git pull` refuse to merge. Since those local\n * changes are machine-generated and reproducible, we discard them, pull, and re-run the package\n * sync (re-apply the update if the pulled project is still behind, or `bun install` if the pull\n * brought it). Detection is state-based (git status + content comparison against `@{u}`), never git\n * stderr parsing, so it works identically across backends and locales.\n */\n\nimport { errorMessage } from \"@jxsuite/schema/parse\";\nimport { getPlatform } from \"../platform\";\nimport { showConfirmDialog } from \"../ui/layers\";\nimport { showProgressModal } from \"../ui/progress-modal\";\nimport { notify } from \"../services/notify\";\nimport { applyJxsuiteUpdate, checkJxsuiteUpdate } from \"./jxsuite-update\";\nimport type { GitStatusResult } from \"../types\";\n\nconst PKG_PATHS = [\"package.json\", \"bun.lock\", \"bun.lockb\"];\n\n/** Untracked markers across backends: desktop porcelain v1 emits \"??\", server porcelain v2 \"U\". */\nconst UNTRACKED_STATUSES = new Set([\"??\", \"U\"]);\n\n/** Above this many dirty files, skip the per-file upstream comparison and leave the error as-is. */\nconst MAX_CONFLICT_SCAN = 25;\n\nconst JXSUITE_PREFIX = \"@jxsuite/\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((entry) => sortKeys(entry));\n }\n if (isRecord(value)) {\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(value).toSorted()) {\n out[key] = sortKeys(value[key]);\n }\n return out;\n }\n return value;\n}\n\n/** Replace every @jxsuite/* version in dependencies/devDependencies so they compare equal. */\nfunction maskJxsuiteVersions(pkg: Record<string, unknown>): Record<string, unknown> {\n const out = { ...pkg };\n for (const section of [\"dependencies\", \"devDependencies\"]) {\n const deps = out[section];\n if (!isRecord(deps)) {\n continue;\n }\n const masked = { ...deps };\n for (const name of Object.keys(masked)) {\n if (name.startsWith(JXSUITE_PREFIX)) {\n masked[name] = \"*\";\n }\n }\n out[section] = masked;\n }\n return out;\n}\n\n/**\n * True when the working package.json differs from the HEAD copy only in the version strings of\n * jxsuite-scoped entries — i.e. exactly what Studio's automated update writes. Added/removed deps\n * or any other edit means a human touched the file.\n */\nexport function isAutomatedPackageDiff(\n headText: string | null,\n workingText: string | null,\n): boolean {\n if (headText === null || workingText === null) {\n return false;\n }\n let head: unknown;\n let working: unknown;\n try {\n head = JSON.parse(headText);\n working = JSON.parse(workingText);\n } catch {\n return false;\n }\n if (!isRecord(head) || !isRecord(working)) {\n return false;\n }\n return (\n JSON.stringify(sortKeys(maskJxsuiteVersions(head))) ===\n JSON.stringify(sortKeys(maskJxsuiteVersions(working)))\n );\n}\n\nasync function tryShow(path: string, ref: string): Promise<string | null> {\n try {\n return await getPlatform().gitShow({ path, ref });\n } catch {\n return null;\n }\n}\n\nasync function tryRead(path: string): Promise<string | null> {\n try {\n return await getPlatform().readFile(path);\n } catch {\n return null;\n }\n}\n\nexport interface PackagePullPlan {\n /** Tracked dirty package files whose upstream (@{u}) content differs from HEAD. */\n discard: string[];\n /** Untracked package files that exist at @{u} (\"untracked would be overwritten\" case). */\n removeUntracked: string[];\n /** Whether the package.json working copy diverges from HEAD only by automated @jxsuite bumps. */\n automated: boolean;\n}\n\n/**\n * Decide which local package files stand in the way of a merge. Only files the upstream actually\n * changed can block the pull, so files whose @{u} content matches HEAD are left alone.\n */\nexport async function planPackageDiscard(status: GitStatusResult): Promise<PackagePullPlan> {\n const discard: string[] = [];\n const removeUntracked: string[] = [];\n let automated = true;\n for (const path of PKG_PATHS) {\n const entries = status.files.filter((f) => f.path === path);\n if (entries.length === 0) {\n continue;\n }\n const upstream = await tryShow(path, \"@{u}\");\n if (entries.every((f) => UNTRACKED_STATUSES.has(f.status))) {\n if (upstream !== null) {\n removeUntracked.push(path);\n }\n continue;\n }\n const head = await tryShow(path, \"HEAD\");\n if (upstream === null || upstream === head) {\n continue;\n }\n discard.push(path);\n if (path === \"package.json\") {\n automated &&= isAutomatedPackageDiff(head, await tryRead(path));\n }\n }\n return { automated, discard, removeUntracked };\n}\n\nfunction planIsEmpty(plan: PackagePullPlan): boolean {\n return plan.discard.length === 0 && plan.removeUntracked.length === 0;\n}\n\n/** True when a dirty non-package file also differs upstream — recovery can't unblock that pull. */\nasync function otherFilesConflict(status: GitStatusResult): Promise<boolean> {\n const paths = [\n ...new Set(status.files.filter((f) => !PKG_PATHS.includes(f.path)).map((f) => f.path)),\n ];\n if (paths.length > MAX_CONFLICT_SCAN) {\n return true;\n }\n for (const path of paths) {\n const upstream = await tryShow(path, \"@{u}\");\n if (upstream !== null && upstream !== (await tryShow(path, \"HEAD\"))) {\n return true;\n }\n }\n return false;\n}\n\nasync function applyDiscard(plan: PackagePullPlan): Promise<void> {\n const platform = getPlatform();\n if (plan.discard.length > 0) {\n // Unstage unconditionally: desktop porcelain v1 doesn't report a staged flag.\n // Restoring an unstaged tracked file is a no-op.\n await platform.gitUnstage(plan.discard);\n await platform.gitDiscard(plan.discard);\n }\n for (const path of plan.removeUntracked) {\n await platform.deleteFile(path);\n }\n}\n\n/**\n * Bring packages back in line after a pull that touched (or followed a discard of) package files:\n * re-apply the @jxsuite update if the pulled project is still behind, otherwise `bun install` so\n * node_modules matches the pulled lockfile. Never throws — a successful pull must not turn into an\n * error banner; failures surface through the progress modal.\n */\nasync function syncPackagesAfterPull(): Promise<void> {\n const platform = getPlatform();\n let outdated: Awaited<ReturnType<typeof checkJxsuiteUpdate>> = [];\n try {\n outdated = await checkJxsuiteUpdate();\n } catch {\n outdated = [];\n }\n if (outdated.length > 0 && platform.setPackageVersions) {\n // No re-prompt: the discarded local changes came from an update the user already accepted.\n await applyJxsuiteUpdate(outdated);\n return;\n }\n if (!platform.installDependencies) {\n return;\n }\n const progress = showProgressModal({\n status: \"Running bun install…\",\n title: \"Syncing dependencies\",\n });\n try {\n const result = await platform.installDependencies();\n if (result.ok) {\n progress.done();\n } else {\n progress.fail(result.log ?? \"bun install failed\");\n }\n } catch (error) {\n progress.fail(errorMessage(error));\n }\n}\n\n/**\n * Discard per plan, pull, and re-sync. A discard is always followed by a package re-sync — even\n * when the pull fails — so the project is never stranded without the update it had before.\n */\nasync function discardPullAndSync(plan: PackagePullPlan): Promise<void> {\n const platform = getPlatform();\n try {\n await applyDiscard(plan);\n } catch (error) {\n throw new Error(`Could not reset local package files: ${errorMessage(error)}`, {\n cause: error,\n });\n }\n try {\n await platform.gitPull();\n } catch (error) {\n await syncPackagesAfterPull();\n throw error;\n }\n notify.warn(\"Local package updates were superseded by pulled changes.\", {\n source: \"Source Control\",\n });\n await syncPackagesAfterPull();\n}\n\nasync function recoverAfterFailedPull(original: unknown): Promise<void> {\n const platform = getPlatform();\n let status: GitStatusResult;\n try {\n status = await platform.gitStatus();\n } catch {\n throw original;\n }\n if (!(status.behind > 0)) {\n throw original;\n }\n const plan = await planPackageDiscard(status);\n if (planIsEmpty(plan) || (await otherFilesConflict(status))) {\n throw original;\n }\n if (!plan.automated) {\n const confirmed = await showConfirmDialog(\n \"Discard local package changes?\",\n \"package.json / bun.lock have local edits that conflict with incoming changes. Discard them, pull, and re-sync packages?\",\n { confirmLabel: \"Discard and pull\", destructive: true },\n );\n if (!confirmed) {\n throw original;\n }\n }\n await discardPullAndSync(plan);\n}\n\n/**\n * Snapshot the package files (aligned to PKG_PATHS). Lists the root once and reads only the files\n * that exist, so absent lockfiles (cloud projects don't commit one) never trigger a console 404\n * from a blind read. Listing failure falls back to probing all paths.\n */\n/**\n * Snapshot the package files (aligned to PKG_PATHS). Lists the root once and reads only the files\n * that exist, so absent lockfiles (cloud projects don't commit one) never trigger a console 404\n * from a blind read. Listing failure falls back to probing all paths.\n */\nasync function snapshotPackageFiles(): Promise<(string | null)[]> {\n let present: Set<string>;\n try {\n const entries = await getPlatform().listDirectory(\"\");\n present = new Set(entries.filter((e) => e.type === \"file\").map((e) => e.name));\n } catch {\n present = new Set(PKG_PATHS);\n }\n return Promise.all(\n PKG_PATHS.map((path) => (present.has(path) ? tryRead(path) : Promise.resolve(null))),\n );\n}\n\n/**\n * Pull with automatic recovery from conflicts caused by Studio's own package updates. Throws only\n * when the pull genuinely fails for reasons recovery can't (or shouldn't) fix.\n */\nexport async function pullWithPackageSync(): Promise<void> {\n const platform = getPlatform();\n const before = await snapshotPackageFiles();\n\n // Preemptive: fetch so `behind` is current, then reset automated package edits that would\n // Block the merge — manual package.json edits fall through to the plain pull + confirm path.\n let status: GitStatusResult | null = null;\n try {\n await platform.gitFetch();\n status = await platform.gitStatus();\n } catch {\n status = null; // Offline or status failure — the plain pull will report the real error\n }\n if (status && status.behind > 0) {\n const plan = await planPackageDiscard(status);\n if (!planIsEmpty(plan) && plan.automated) {\n await discardPullAndSync(plan);\n return;\n }\n }\n\n try {\n await platform.gitPull();\n } catch (error) {\n await recoverAfterFailedPull(error);\n return;\n }\n const after = await snapshotPackageFiles();\n if (before.some((content, i) => content !== after[i])) {\n await syncPackagesAfterPull();\n }\n}\n\n/**\n * Pull remote changes as soon as a project opens, ahead of the install check and update prompt, so\n * a session starts from the current remote state. Never throws and never blocks the open — failures\n * (offline, no upstream, unrelated conflicts) surface as a status message only.\n */\nexport async function autoSyncProjectOnOpen(): Promise<void> {\n const platform = getPlatform();\n let status: GitStatusResult;\n try {\n status = await platform.gitStatus();\n } catch {\n return;\n }\n if (!status?.isRepo || (status.remotes?.length ?? 0) === 0) {\n return;\n }\n notify.info(\"Syncing project…\", { key: \"project.sync\", source: \"Source Control\" });\n try {\n await pullWithPackageSync();\n } catch (error) {\n // A skipped sync leaves the project behind its remote, which is a state to FIX rather than\n // A moment to read about — it stays listed until a pull succeeds.\n notify.warn(\"The project could not be synced with its remote.\", {\n detail: errorMessage(error),\n key: \"project.sync\",\n source: \"Source Control\",\n tier: \"problem\",\n });\n }\n}\n",
13
- "/// <reference lib=\"dom\" />\n/**\n * Git panel — Source control sidebar with sync status, branch selector, Local Changes / History\n * tabs, commit form, and changed-components view.\n */\n\nimport { html, nothing } from \"lit-html\";\nimport { errorMessage } from \"@jxsuite/schema/parse\";\nimport { flushAllCollab } from \"../collab/collab-session\";\nimport type { GitDiffState, GitFileStatus, StudioPlatform } from \"../types\";\nimport { live } from \"lit-html/directives/live.js\";\nimport { repeat } from \"lit-html/directives/repeat.js\";\nimport { getPlatform } from \"../platform\";\nimport { now } from \"../services/clock\";\nimport { formatForPath } from \"../format/format-host\";\nimport { projectState } from \"../store\";\nimport { activeTab } from \"../workspace/workspace\";\nimport type { Tab } from \"../tabs/tab\";\nimport { shell } from \"../shell\";\nimport type { GitLogEntry } from \"../shell\";\nimport { showConfirmDialog, showPromptDialog } from \"../ui/layers\";\nimport { POLL_GIT } from \"../ui/timing\";\nimport { renderEmptyState } from \"./empty-state\";\nimport { registerPanel } from \"./panel-registry\";\nimport { notify } from \"../services/notify\";\nimport { authenticateGithub } from \"../github/github-auth\";\nimport { createGithubRepository } from \"../github/github-publish\";\nimport { pullWithPackageSync } from \"../packages/pull-package-sync\";\nimport type { AnyCommand, CommandRegistry } from \"../commands/registry\";\n\ntype GitFileEntry = GitFileStatus;\n\nexport async function refreshGitStatus() {\n if (!projectState) {\n return;\n }\n const plat = getPlatform();\n const { git } = shell;\n git.loading = true;\n git.error = null;\n try {\n // Settled independently, not Promise.all: outside a work tree `git branch` exits non-zero\n // While `git status` answers cleanly with isRepo:false. Letting the branch lookup reject the\n // Pair discarded that status, so the panel re-rendered its \"no status yet\" branch, refreshed\n // Again, and span — a request per render for as long as the tab stayed open.\n const [status, branches] = await Promise.allSettled([plat.gitStatus(), plat.gitBranches()]);\n if (status.status === \"fulfilled\") {\n git.status = status.value;\n }\n if (branches.status === \"fulfilled\") {\n git.branches = branches.value;\n }\n // A branch lookup that fails on a repo-less project is expected, not an error worth showing;\n // Anything else (including a failed status) surfaces.\n const failure: unknown =\n status.status === \"rejected\"\n ? status.reason\n : branches.status === \"rejected\" && status.value?.isRepo\n ? branches.reason\n : null;\n if (failure) {\n git.error = errorMessage(failure);\n }\n git.lastUpdated = now();\n } catch (error) {\n git.error = errorMessage(error);\n } finally {\n git.loading = false;\n }\n}\n\n/**\n * Show a dialog to clone a git repository. Returns the cloned project root on success, or null.\n *\n * @param {{ openRecentProject: (root: string) => Promise<void> }} ctx\n */\nexport async function cloneRepository(ctx: { openRecentProject: (root: string) => Promise<void> }) {\n const platform = getPlatform();\n if (!platform.gitClone) {\n notify.warn(\"Cloning is not supported on this platform.\", { source: \"Source Control\" });\n return;\n }\n\n const url = await showPromptDialog(\"Clone Git Repository\", {\n confirmLabel: \"Clone\",\n message: \"Repository URL\",\n placeholder: \"https://github.com/user/repo.git\",\n validate: (v) => (v.trim() ? \"\" : \"Enter a repository URL.\"),\n });\n\n if (!url) {\n return;\n }\n\n try {\n notify.info(\"Cloning repository…\", { key: \"git.clone\", source: \"Source Control\" });\n const result = await platform.gitClone(url);\n if (result?.root) {\n notify.success(\"Clone complete.\", { key: \"git.clone\" });\n await ctx.openRecentProject(result.root);\n }\n } catch (error) {\n notify.error(\"Could not clone the repository.\", {\n detail: errorMessage(error),\n key: \"git.clone\",\n source: \"Source Control\",\n });\n }\n}\n\n/** @returns {boolean} */\nexport function platformSupportsClone() {\n return Boolean(getPlatform().gitClone);\n}\n\n/**\n * One file's comparison against HEAD: the committed text and the working copy.\n *\n * **One definition site, because there are now two callers.** This panel's row click has always\n * made this pair of reads; `workspace/pane-derive.ts`'s Diff lens needs the same answer for the\n * document its source pane is showing, and it must not reach `shell.git.diffState` — that slot\n * holds whatever THIS panel last opened, which is a different file (§18.4, finding 4). A second\n * copy of these five lines is how the panel and the lens would come to disagree about what \"the\n * diff of this file\" means, which is the rule {@link initRepository} is written under too.\n *\n * `A` (added) has no `HEAD` copy, so its original is the empty string rather than a `gitShow` that\n * would throw. Callers narrow to `M`/`A` before asking.\n *\n * @param {string} path\n * @param {string} fileStatus\n * @returns {Promise<GitDiffState>}\n */\nexport async function readGitDiff(path: string, fileStatus: string): Promise<GitDiffState> {\n const plat = getPlatform();\n const [originalContent, currentContent] = await Promise.all([\n fileStatus === \"A\" ? Promise.resolve(\"\") : plat.gitShow({ path, ref: \"HEAD\" }),\n plat.readFile(path),\n ]);\n return { currentContent, filePath: path, fileStatus, originalContent };\n}\n\n/**\n * The Diff lens's reader: {@link readGitDiff}, with a failure the PANE can state.\n *\n * A rejection here is not an error the shell should raise — the author asked to see a comparison\n * beside their page, and \"could not read it\" is a sentence the derived pane draws in its own empty\n * state. `applyDerivation` turns the `null` into exactly that.\n *\n * @param {string} path\n * @param {string} fileStatus\n * @returns {Promise<GitDiffState | null>}\n */\nexport async function loadDiffForLens(\n path: string,\n fileStatus: string,\n): Promise<GitDiffState | null> {\n try {\n return await readGitDiff(path, fileStatus);\n } catch (error) {\n // Reported where it can be acted on — the pane says so — rather than as a toast over a\n // Document the author did not ask about.\n console.warn(\"loadDiffForLens:\", errorMessage(error));\n return null;\n }\n}\n\n/**\n * Start tracking this project with git.\n *\n * A function rather than an inline click handler because it is now also a command ({@link\n * sourceControlCommands}) and the first step of the deploy checklist, and three call sites of the\n * same three lines is how the panel and the palette come to disagree about what a verb does.\n */\nexport async function initRepository(): Promise<void> {\n try {\n notify.info(\"Initializing repository…\", { key: \"git.init\" });\n await getPlatform().gitInit();\n notify.success(\"Repository initialized.\", { key: \"git.init\" });\n } catch (error) {\n notify.error(\"Could not initialize the repository.\", {\n action: \"git.init\",\n detail: errorMessage(error),\n key: \"git.init\",\n source: \"Source Control\",\n });\n return;\n }\n await refreshGitStatus();\n}\n\n/** Push the current branch. Same loading/error contract as every other panel verb. */\nexport async function pushCurrentBranch(): Promise<void> {\n await gitAction(\"gitPush\");\n}\n\n/**\n * Sign in to GitHub, or report why it could not.\n *\n * The report belongs to `github/github-auth.ts` — this only says what a SUCCESS was, which that\n * module cannot, because it is also called mid-flow by \"Create GitHub Repository\" where a toast\n * saying \"Signed in\" in front of a half-finished operation would be noise.\n */\nexport async function signInToGithub(): Promise<void> {\n const token = await authenticateGithub();\n if (token) {\n notify.success(\"Signed in to GitHub.\", { key: \"github.auth\" });\n }\n}\n\n/**\n * @param {string} action\n * @param {unknown} [body]\n */\nasync function gitAction(action: string, body?: unknown) {\n const plat = getPlatform() as Record<string, (...args: unknown[]) => Promise<unknown>> &\n StudioPlatform;\n shell.git.loading = true;\n shell.git.error = null;\n try {\n await plat[action]!(body);\n await refreshGitStatus();\n } catch (error) {\n shell.git.error = errorMessage(error);\n shell.git.loading = false;\n }\n}\n\n/** Pull via the package-aware orchestrator; same loading/error contract as gitAction. */\nasync function doPull() {\n shell.git.loading = true;\n shell.git.error = null;\n try {\n await pullWithPackageSync();\n await refreshGitStatus();\n } catch (error) {\n shell.git.error = errorMessage(error);\n shell.git.loading = false;\n }\n}\n\n/**\n * The background refresh handle. The interval itself is infrastructure, not state — the sub-tab and\n * the \"last updated\" stamp it used to sit beside are on `shell.git`, so opening a second project no\n * longer inherits the first one's History selection and timestamp.\n */\nlet _pollTimer = null as ReturnType<typeof setInterval> | null;\n\nasync function fetchGitLog() {\n const plat = getPlatform();\n try {\n shell.git.logEntries = await plat.gitLog(30);\n } catch (error) {\n shell.git.error = errorMessage(error);\n }\n}\n\n/**\n * Render the Source Control panel.\n *\n * Takes no state argument: everything it reads is project-level and lives on `shell.git`, which is\n * the whole point of the hoist — the panel renders identically with no document open.\n *\n * @param {{\n * setCanvasMode?: (tab: Tab | null, mode: string) => void;\n * setGitDiffState?: (state: GitDiffState | null) => void;\n * cloneRepository?: () => void;\n * }} ctx\n */\nexport function renderGitPanel(ctx: {\n setCanvasMode?: (tab: Tab | null, mode: string) => void;\n setGitDiffState?: (state: GitDiffState | null) => void;\n cloneRepository?: () => void;\n}) {\n if (!projectState) {\n return html`<div class=\"git-panel git-panel-empty\">\n ${renderEmptyState({\n actions: platformSupportsClone()\n ? [\n {\n icon: html`<sp-icon-download slot=\"icon\"></sp-icon-download>`,\n label: \"Clone Git Repository\",\n run: () => ctx.cloneRepository?.(),\n },\n ]\n : [],\n message:\n \"Source control keeps every version of a project, so any change can be undone. \" +\n \"Open a project to see its history.\",\n })}\n </div>`;\n }\n const { branches, loading, status } = shell.git;\n\n // First paint kicks off the fetch. A refresh that already failed must NOT re-arm it here, or the\n // Render it triggers becomes the next render's reason to fetch again; the Refresh button and the\n // Poll timer are the ways back.\n if (!status && !loading && !shell.git.error) {\n void refreshGitStatus();\n return html`<div class=\"git-panel\">\n <div class=\"git-loading\">Loading...</div>\n </div>`;\n }\n\n if (status && !status.isRepo) {\n return html`<div class=\"git-panel git-panel-empty\">\n ${renderEmptyState({\n actions: [\n {\n disabled: Boolean(loading),\n icon: html`<sp-icon-add slot=\"icon\"></sp-icon-add>`,\n label: \"Initialize Repository\",\n run: () => {\n void initRepository();\n },\n },\n {\n disabled: Boolean(loading),\n icon: html`<sp-icon-share slot=\"icon\"></sp-icon-share>`,\n label: \"Create GitHub repository\",\n run: () => {\n void createGithubRepository({ projectName: projectState?.name || \"my-project\" });\n },\n },\n ],\n message:\n \"This project is not tracked by git yet. Start tracking it to keep a history \" +\n \"of every change and to publish it anywhere.\",\n })}\n </div>`;\n }\n\n if (!_pollTimer) {\n _pollTimer = setInterval(() => {\n if (shell.leftTab === \"git\" && !shell.git.loading) {\n void refreshGitStatus();\n }\n }, POLL_GIT);\n }\n\n const stagedFiles = status?.files?.filter((f: GitFileEntry) => f.staged) || [];\n const unstagedFiles = status?.files?.filter((f: GitFileEntry) => !f.staged) || [];\n const totalChanges = status?.files?.length || 0;\n\n const doCommit = async () => {\n const msg = shell.git.commitMessage.trim();\n if (!msg) {\n return;\n }\n shell.git.commitMessage = \"\";\n // Fold co-editing sessions into the backend's tree first so the commit never misses\n // Trailing keystrokes (the mirror is debounced).\n await flushAllCollab();\n await gitAction(\"gitCommit\", msg);\n };\n\n const doCommitAndSync = async () => {\n const msg = shell.git.commitMessage.trim();\n if (!msg) {\n return;\n }\n shell.git.commitMessage = \"\";\n shell.git.loading = true;\n shell.git.error = null;\n await flushAllCollab();\n const plat = getPlatform();\n try {\n await plat.gitCommit(msg);\n await plat.gitPush();\n await refreshGitStatus();\n } catch (error) {\n shell.git.error = errorMessage(error);\n shell.git.loading = false;\n }\n };\n\n // ─── 1. Sync status bar ──────────────────────────────────────────────────\n const isUpToDate = !status?.ahead && !status?.behind;\n const syncLabel = isUpToDate\n ? \"Up to date\"\n : `${status?.ahead ? `${status.ahead} ahead` : \"\"}${status?.ahead && status?.behind ? \", \" : \"\"}${status?.behind ? `${status.behind} behind` : \"\"}`;\n const lastUpdatedStr = shell.git.lastUpdated\n ? new Date(shell.git.lastUpdated).toLocaleTimeString([], {\n hour: \"2-digit\",\n minute: \"2-digit\",\n })\n : \"\";\n\n const hasRemotes = (status?.remotes?.length ?? 0) > 0;\n\n const syncBarT = hasRemotes\n ? html`\n <div class=\"git-sync-bar\">\n <sp-action-button\n size=\"s\"\n quiet\n class=\"git-sync-icon\"\n title=\"Refresh\"\n @click=${() => refreshGitStatus()}\n ?disabled=${loading}\n >\n <sp-icon-refresh slot=\"icon\"></sp-icon-refresh>\n </sp-action-button>\n <div class=\"git-sync-text\">\n <span class=\"git-sync-label\">${syncLabel}</span>\n ${\n lastUpdatedStr\n ? html`<span class=\"git-sync-time\">Last updated ${lastUpdatedStr}</span>`\n : nothing\n }\n </div>\n <sp-action-group size=\"xs\" quiet class=\"git-sync-actions\">\n <sp-action-button\n title=\"Fetch\"\n @click=${() => gitAction(\"gitFetch\")}\n ?disabled=${loading}\n >\n <sp-icon-download slot=\"icon\" size=\"xs\"></sp-icon-download>\n </sp-action-button>\n <sp-action-button\n title=\"Pull${status?.behind ? ` (${status.behind} behind)` : \"\"}\"\n @click=${() => {\n void doPull();\n }}\n ?disabled=${loading}\n >\n <sp-icon-arrow-down slot=\"icon\" size=\"xs\"></sp-icon-arrow-down>\n </sp-action-button>\n <sp-action-button\n title=\"Push${status?.ahead ? ` (${status.ahead} ahead)` : \"\"}\"\n @click=${() => gitAction(\"gitPush\")}\n ?disabled=${loading}\n >\n <sp-icon-arrow-up slot=\"icon\" size=\"xs\"></sp-icon-arrow-up>\n </sp-action-button>\n </sp-action-group>\n </div>\n `\n : html`\n <div class=\"git-sync-bar git-sync-bar--no-remote\">\n <sp-action-button\n size=\"s\"\n quiet\n class=\"git-sync-icon\"\n title=\"Refresh\"\n @click=${() => refreshGitStatus()}\n ?disabled=${loading}\n >\n <sp-icon-refresh slot=\"icon\"></sp-icon-refresh>\n </sp-action-button>\n <div class=\"git-sync-text\">\n <span class=\"git-sync-label\">Local only (no remote)</span>\n </div>\n <sp-action-button\n size=\"s\"\n @click=${() =>\n createGithubRepository({\n projectName: projectState?.name || \"my-project\",\n })}\n ?disabled=${loading}\n >\n <sp-icon-share slot=\"icon\"></sp-icon-share>\n Create GitHub repository\n </sp-action-button>\n </div>\n `;\n\n // ─── 2. Branch selector ──────────────────────────────────────────────────\n const branchSelectorT = html`\n <div class=\"git-branch-row\">\n <svg\n class=\"git-branch-icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <line x1=\"6\" y1=\"3\" x2=\"6\" y2=\"15\"></line>\n <circle cx=\"18\" cy=\"6\" r=\"3\"></circle>\n <circle cx=\"6\" cy=\"18\" r=\"3\"></circle>\n <path d=\"M18 9a9 9 0 0 1-9 9\"></path>\n </svg>\n <div class=\"git-branch-text\">\n <span class=\"git-branch-label\">Active branch</span>\n <span class=\"git-branch-name\">${branches?.current || status?.branch || \"—\"}</span>\n </div>\n <sp-picker\n size=\"s\"\n quiet\n class=\"git-branch-picker\"\n .value=${live(branches?.current || \"\")}\n @change=${async (e: Event) => {\n const val = (e.target as HTMLInputElement).value;\n if (val === \"__new__\") {\n (e.target as HTMLInputElement).value = branches?.current || \"\";\n const name = await showPromptDialog(\"New Branch\", {\n confirmLabel: \"Create\",\n message: `Branching from ${branches?.current || status?.branch || \"the current branch\"}.`,\n placeholder: \"feature/my-change\",\n validate: (v) => (v.trim() ? \"\" : \"Enter a branch name.\"),\n });\n if (name) {\n await gitAction(\"gitCreateBranch\", name);\n }\n return;\n }\n if (val !== branches?.current) {\n await gitAction(\"gitCheckout\", val);\n }\n }}\n >\n ${(branches?.branches || []).map(\n (b: string) => html`<sp-menu-item value=${b}>${b}</sp-menu-item>`,\n )}\n <sp-menu-divider></sp-menu-divider>\n <sp-menu-item value=\"__new__\">+ New branch...</sp-menu-item>\n </sp-picker>\n </div>\n `;\n\n // ─── 3. Tabs: Local Changes / History ────────────────────────────────────\n const switchTab = (tab: string) => {\n shell.git.subTab = tab;\n if (tab === \"history\" && !shell.git.logEntries) {\n void fetchGitLog();\n }\n };\n\n const tabsT = html`\n <div class=\"git-tabs\">\n <button\n class=\"git-tab ${shell.git.subTab === \"changes\" ? \"active\" : \"\"}\"\n @click=${() => switchTab(\"changes\")}\n >\n Local Changes${totalChanges > 0 ? ` (${totalChanges})` : \"\"}\n </button>\n <button\n class=\"git-tab ${shell.git.subTab === \"history\" ? \"active\" : \"\"}\"\n @click=${() => switchTab(\"history\")}\n >\n History\n </button>\n </div>\n `;\n\n // ─── 4. Commit form ──────────────────────────────────────────────────────\n // `navigator/panel:git/commit` is a HAND-STAMPED leaf: the panel host derives\n // `navigator/panel:git`, but nothing derives the parts inside a panel body. Leaves are the one\n // Category of region id that is authored, and they are counted for exactly that reason.\n const commitT = html`\n <div class=\"git-commit-area\" data-jx-region=\"navigator/panel:git/commit\">\n <label class=\"git-commit-label\">Please write a commit message</label>\n <sp-textfield\n size=\"s\"\n multiline\n class=\"git-commit-input\"\n placeholder=\"Describe your changes\"\n .value=${live(shell.git.commitMessage)}\n @input=${(e: Event) => {\n shell.git.commitMessage = (e.target as HTMLInputElement).value;\n }}\n @keydown=${(e: KeyboardEvent) => {\n if ((e.ctrlKey || e.metaKey) && e.key === \"Enter\") {\n e.preventDefault();\n void doCommit();\n }\n }}\n ></sp-textfield>\n <div class=\"git-commit-actions\">\n <div class=\"git-split-btn\">\n <sp-action-button\n class=\"git-commit-btn\"\n size=\"s\"\n @click=${doCommitAndSync}\n ?disabled=${loading}\n >\n Commit and sync\n </sp-action-button>\n <sp-action-button\n class=\"git-split-trigger\"\n size=\"s\"\n @click=${(e: Event) => {\n const menu = (\n (e.currentTarget as HTMLElement).parentElement as HTMLElement\n ).querySelector(\".git-split-menu\");\n if (menu) {\n menu.toggleAttribute(\"hidden\");\n }\n }}\n >\n <sp-icon-chevron-down slot=\"icon\" size=\"xs\"></sp-icon-chevron-down>\n </sp-action-button>\n <div class=\"git-split-menu\" hidden>\n <button\n class=\"git-split-menu-item\"\n @click=${(e: Event) => {\n ((e.currentTarget as HTMLElement).parentElement as HTMLElement).setAttribute(\n \"hidden\",\n \"\",\n );\n void doCommit();\n }}\n >\n Commit (don't sync)\n </button>\n </div>\n </div>\n </div>\n </div>\n `;\n\n // ─── 5. Changed Components ───────────────────────────────────────────────\n const fileRowT = (file: GitFileEntry) => {\n const parts = file.path.split(\"/\");\n const name = parts.pop();\n const dir = parts.join(\"/\");\n\n const onFileClick = async () => {\n if (file.status !== \"M\" && file.status !== \"A\") {\n return;\n }\n if (!file.path.endsWith(\".json\") && !formatForPath(file.path)) {\n return;\n }\n\n try {\n shell.git.loading = true;\n\n const diffState = await readGitDiff(file.path, file.status);\n\n shell.git.diffState = diffState;\n\n if (ctx?.setCanvasMode) {\n if (ctx.setGitDiffState) {\n ctx.setGitDiffState(diffState);\n }\n ctx.setCanvasMode(activeTab.value, \"git-diff\");\n }\n } catch (error) {\n shell.git.error = `Failed to load diff: ${errorMessage(error)}`;\n } finally {\n shell.git.loading = false;\n }\n };\n\n return html`\n <div class=\"git-file-row\">\n <span\n class=\"git-file-info\"\n style=\"cursor: pointer; flex: 1;\"\n title=\"Click to view diff\"\n @click=${onFileClick}\n >\n <span class=\"git-file-name\" title=${file.path}>${name}</span>\n ${dir ? html`<span class=\"git-file-dir\">${dir}</span>` : nothing}\n </span>\n <span class=\"git-file-actions\">\n ${\n file.staged\n ? html`\n <sp-action-button\n size=\"xs\"\n quiet\n title=\"Unstage\"\n @click=${() => gitAction(\"gitUnstage\", [file.path])}\n >\n <sp-icon-remove slot=\"icon\" size=\"xs\"></sp-icon-remove>\n </sp-action-button>\n `\n : html`\n <sp-action-button\n size=\"xs\"\n quiet\n title=\"Discard changes\"\n @click=${async () => {\n if (file.status === \"U\") {\n return;\n }\n const confirmed = await showConfirmDialog(\n \"Discard Changes\",\n `Discard changes to ${file.path}?`,\n { confirmLabel: \"Discard\", destructive: true },\n );\n if (!confirmed) {\n return;\n }\n await gitAction(\"gitDiscard\", [file.path]);\n }}\n ?disabled=${file.status === \"U\"}\n >\n <sp-icon-undo slot=\"icon\" size=\"xs\"></sp-icon-undo>\n </sp-action-button>\n <sp-action-button\n size=\"xs\"\n quiet\n title=\"Stage\"\n @click=${() => gitAction(\"gitStage\", [file.path])}\n >\n <sp-icon-add slot=\"icon\" size=\"xs\"></sp-icon-add>\n </sp-action-button>\n `\n }\n </span>\n <span class=\"git-file-badge git-status-${file.status}\">${file.status}</span>\n </div>\n `;\n };\n\n /** Group files by component (parent directory for .json/.class.json, or \"Other\") */\n const groupFilesByComponent = (files: GitFileEntry[]) => {\n const groups = new Map<string, GitFileEntry[]>();\n for (const f of files) {\n const parts = f.path.split(\"/\");\n let component;\n if (f.path.endsWith(\".json\") || f.path.endsWith(\".class.json\") || formatForPath(f.path)) {\n component = parts.length > 1 ? `/${parts.at(-2)}` : `/${parts[0]}`;\n } else {\n component = \"Other\";\n }\n if (!groups.has(component)) {\n groups.set(component, []);\n }\n (groups.get(component) as GitFileEntry[]).push(f);\n }\n return groups;\n };\n\n const allFiles = [...stagedFiles, ...unstagedFiles];\n const componentGroups = groupFilesByComponent(allFiles);\n\n const changesT = html`\n ${\n stagedFiles.length > 0\n ? html`\n <div class=\"git-section\">\n <div class=\"git-section-header\">\n <span>Staged Changes</span>\n <span class=\"git-count\">${stagedFiles.length}</span>\n <sp-action-button\n size=\"xs\"\n quiet\n title=\"Unstage all\"\n @click=${() =>\n gitAction(\n \"gitUnstage\",\n stagedFiles.map((f: GitFileEntry) => f.path),\n )}\n >\n <sp-icon-remove slot=\"icon\" size=\"xs\"></sp-icon-remove>\n </sp-action-button>\n </div>\n ${repeat(stagedFiles, (f: GitFileEntry) => f.path, fileRowT)}\n </div>\n `\n : nothing\n }\n <div class=\"git-section\">\n <div class=\"git-section-header\">\n <span>Changed Components</span>\n <span class=\"git-count\">${allFiles.length}</span>\n ${\n unstagedFiles.length > 0\n ? html`\n <sp-action-button\n size=\"xs\"\n quiet\n title=\"Stage all\"\n @click=${() =>\n gitAction(\n \"gitStage\",\n unstagedFiles.map((f: GitFileEntry) => f.path),\n )}\n >\n <sp-icon-add slot=\"icon\" size=\"xs\"></sp-icon-add>\n </sp-action-button>\n `\n : nothing\n }\n </div>\n ${\n allFiles.length > 0\n ? html`\n ${[...componentGroups.entries()].map(\n ([comp, files]) => html`\n <div class=\"git-component-group\">\n <div class=\"git-component-header\">\n <sp-action-button\n size=\"xs\"\n quiet\n class=\"git-component-overflow\"\n title=\"Actions\"\n >\n <sp-icon-more slot=\"icon\" size=\"xs\"></sp-icon-more>\n </sp-action-button>\n <span class=\"git-component-name\">${comp}</span>\n </div>\n ${repeat(files, (f: GitFileEntry) => f.path, fileRowT)}\n </div>\n `,\n )}\n `\n : renderEmptyState({\n compact: true,\n message: \"Nothing to commit. Files you edit and save show up here.\",\n })\n }\n </div>\n `;\n\n // ─── 6. History tab content ──────────────────────────────────────────────\n const logEntries = shell.git.logEntries || [];\n const historyT = html`\n <div class=\"git-history\">\n ${\n logEntries.length === 0\n ? renderEmptyState({\n compact: true,\n message: \"No commits yet. Each commit you make is a version you can come back to.\",\n })\n : repeat(\n logEntries,\n (e: GitLogEntry) => e.hash,\n (entry: GitLogEntry) => html`\n <div class=\"git-history-entry\">\n <span class=\"git-history-hash\">${entry.hash.slice(0, 7)}</span>\n <span class=\"git-history-message\">${entry.message}</span>\n <span class=\"git-history-meta\"\n >${entry.author} · ${relativeDate(entry.date)}</span\n >\n </div>\n `,\n )\n }\n </div>\n `;\n\n return html`\n <div class=\"git-panel\">\n ${syncBarT} ${branchSelectorT} ${tabsT}\n ${shell.git.subTab === \"changes\" ? html`${commitT}${changesT}` : historyT}\n ${loading ? html`<div class=\"git-loading\">Loading...</div>` : nothing}\n ${shell.git.error ? html`<div class=\"git-error\">${shell.git.error}</div>` : nothing}\n </div>\n `;\n}\n\n/**\n * A commit age, relative to {@link now}.\n *\n * Exported so it is testable at all: reading the wall clock inline meant \"yesterday\" and the\n * locale-date fallback could only be asserted against an offset from the real present, and two\n * captures minutes apart legitimately disagreed.\n *\n * @param {string} iso\n */\nexport function relativeDate(iso: string) {\n const d = new Date(iso);\n const diff = now() - d.getTime();\n const mins = Math.floor(diff / 60_000);\n if (mins < 1) {\n return \"just now\";\n }\n if (mins < 60) {\n return `${mins}m ago`;\n }\n const hours = Math.floor(mins / 60);\n if (hours < 24) {\n return `${hours}h ago`;\n }\n const days = Math.floor(hours / 24);\n if (days < 30) {\n return `${days}d ago`;\n }\n return d.toLocaleDateString();\n}\n\n/**\n * The `Source Control:` family — the four verbs that were only ever buttons.\n *\n * Every one of them was reachable from exactly one place: two from an empty state that disappears\n * the moment the repository exists, one from a 20px icon with a `title` attribute, and the fourth —\n * signing in to GitHub — from nowhere at all, because it only ever happened as a side effect of\n * something else. That is why a failed sign-in had no Retry to name: there was no record to point\n * at. Naming them here gives the palette, `__jxAutomation`, the assistant, the deploy checklist and\n * every `notify` Retry the same four ids.\n *\n * `git.signInToGithub` is `application`-level and the other three are `project`-level, and the\n * split is the credential's: a GitHub token is one per machine and is revoked in Preferences ›\n * Accounts, while a branch, a remote and a push belong to one repository.\n */\nexport function sourceControlCommands(): AnyCommand[] {\n return [\n {\n category: \"Source Control\",\n id: \"git.init\",\n level: \"project\",\n menus: [\"commandbar/overflow\", \"palette\"],\n group: \"7_scm\",\n requires: \"an open project that git is not already tracking\",\n when: (ctx) => ctx.project.open,\n // `when` already asked about the project; an `enablement` that re-asks is the same rule\n // Written twice, and the two places drift.\n enablement: (ctx) => !ctx.project.isRepo,\n aiTool: {\n description:\n \"Run git init in the project root so the project has a history and can be pushed.\",\n name: \"init_repository\",\n },\n run: async () => {\n await initRepository();\n },\n title: \"Initialize Repository\",\n },\n {\n category: \"Source Control\",\n id: \"git.createGithubRepository\",\n level: \"project\",\n menus: [\"commandbar/overflow\", \"palette\"],\n group: \"7_scm\",\n /* THE STRICTEST OF THE THREE, because it is the one that leaves something behind on a\n server. It declared no `enablement` at all while `git.push` — which does strictly less —\n required a tracked repository, so on an untracked project Push was correctly disabled and\n this was fully live from the palette, the overflow, the deploy checklist and the\n `create_github_repository` AI tool. Its flow creates the repository on GitHub BEFORE it\n touches the local one, so `gitAddRemote` then throws and it reports \"The repository was\n created, but the remote could not be added.\" The refused verb leaves nothing behind; the\n unrefused one leaves an empty repository on the user's account. */\n requires: \"a project tracked by git\",\n when: (ctx) => ctx.project.open,\n enablement: (ctx) => ctx.project.isRepo,\n aiTool: {\n description:\n \"Create a new GitHub repository for this project, add it as the origin remote, and push. \" +\n \"This creates a repository; it does not deploy a site — that is publish.setUp.\",\n name: \"create_github_repository\",\n },\n run: async () => {\n await createGithubRepository({ projectName: projectState?.name || \"my-project\" });\n },\n title: \"Create GitHub Repository\",\n },\n {\n category: \"Source Control\",\n id: \"git.push\",\n level: \"project\",\n menus: [\"commandbar/overflow\", \"palette\"],\n group: \"7_scm\",\n requires: \"a project tracked by git\",\n when: (ctx) => ctx.project.open,\n enablement: (ctx) => ctx.project.isRepo,\n aiTool: {\n description: \"Push the current branch to its remote.\",\n name: \"git_push\",\n },\n run: async () => {\n await pushCurrentBranch();\n },\n title: \"Push\",\n },\n {\n category: \"Source Control\",\n id: \"git.signInToGithub\",\n level: \"application\",\n menus: [\"palette\"],\n group: \"7_scm\",\n run: async () => {\n await signInToGithub();\n },\n title: \"Sign In to GitHub\",\n },\n ];\n}\n\n/** Register the `Source Control:` family. */\nexport function registerSourceControlCommands(registry: CommandRegistry): void {\n registry.registerAll(sourceControlCommands());\n}\n\n/** Stop the background refresh. Called on unmount and whenever a different project is opened. */\nexport function cleanupGitPanel() {\n if (_pollTimer) {\n clearInterval(_pollTimer);\n _pollTimer = null;\n }\n}\n\n/**\n * Contribute the Source Control panel.\n *\n * `level: \"project\"` — a branch, a working tree and a commit belong to the repository, not to\n * whichever document happens to be focused. That is why the badge below reads `ctx.git.dirtyCount`\n * (sourced from the hoisted `shell.git` record) and why this panel's render ignores `ctx.doc`\n * entirely: the count used to come from `activeTab.session.ui.gitStatus`, so it vanished when the\n * last tab closed and two tabs could disagree about the branch.\n */\nexport function registerGitPanel(): void {\n registerPanel({\n id: \"git\",\n title: \"Source Control\",\n level: \"project\",\n dock: \"navigator\",\n // A KEY into `activity-bar.ts`'s `tabIcon()` map, not a tag: this one resolves to\n // `gitBranchIcon`, a hand-drawn inline SVG, because the workflow set has no Git family.\n icon: \"sp-icon-git-branch\",\n badge: (ctx) => ctx.git.dirtyCount || null,\n // Through `deps`, not the local binding: `studio.ts` owns the wiring (the clone action and the\n // Diff-state setter come from the bootstrap), and the Navigator has injected it all along.\n render: (ctx) => ctx.deps.renderGitPanel(ctx.deps),\n });\n}\n"
14
- ],
15
- "mappings": "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",
16
- "debugId": "369A489EB1E6F95564756E2164756E21",
17
- "names": []
18
- }
@@ -1,10 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../node_modules/@spectrum-web-components/overlay/sp-overlay.dev.js"],
4
- "sourcesContent": [
5
- "\"use strict\";\nimport { defineElement } from \"@spectrum-web-components/base/src/define-element.js\";\nimport { Overlay } from \"./src/Overlay.dev.js\";\ndefineElement(\"sp-overlay\", Overlay);\n//# sourceMappingURL=sp-overlay.dev.js.map\n"
6
- ],
7
- "mappings": ";;;;;;;;AAGA,cAAc,cAAc,OAAO;",
8
- "debugId": "24A9645EA10C33DD64756E2164756E21",
9
- "names": []
10
- }