@jxsuite/studio 9.0.0 → 10.1.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 (190) hide show
  1. package/dist/chunks/{2020-89fz3pfy.js → 2020-mkb0qa6p.js} +3 -3
  2. package/dist/chunks/adapter-xcpsmecx.js +4 -0
  3. package/dist/chunks/{add-new-flow-nmkqpjym.js → add-new-flow-ptmhmzr9.js} +3 -3
  4. package/dist/chunks/{cf-account-picker-2e06qxey.js → cf-account-picker-z1sgwpwd.js} +3 -3
  5. package/dist/chunks/cf-settings-xqvhxxe9.js +4 -0
  6. package/dist/chunks/components-whsc81a7.js +4 -0
  7. package/dist/chunks/content-source-jwtxg78w.js +4 -0
  8. package/dist/chunks/{convert-to-repeater-j9hfcj4f.js → convert-to-repeater-f92ey3kp.js} +3 -3
  9. package/dist/chunks/editor-zdqdpq1x.js +4 -0
  10. package/dist/chunks/entry-commands-w8p2fbpt.js +4 -0
  11. package/dist/chunks/{extension-sections-thfke054.js → extension-sections-y2p1te2r.js} +3 -3
  12. package/dist/chunks/file-ops-13ab4swj.js +4 -0
  13. package/dist/chunks/files-zbc8p6v1.js +4 -0
  14. package/dist/chunks/format-host-zjsbktbx.js +4 -0
  15. package/dist/chunks/fs-events-t6x0hch6.js +4 -0
  16. package/dist/chunks/grid-open-fyzdwpkh.js +4 -0
  17. package/dist/chunks/{grid-view-7d2nx83y.js → grid-view-r22jsqht.js} +5 -5
  18. package/dist/chunks/iframe-host-kbyqc7pt.js +4 -0
  19. package/dist/chunks/index-6nvj89vb.js +4 -0
  20. package/dist/chunks/{index-jxmt7vh8.js → index-pxwwf00y.js} +3 -3
  21. package/dist/chunks/{javascript-vmqp56ke.js → javascript-pzqryby6.js} +2 -2
  22. package/dist/chunks/{jsonMode-n3wmpant.js → jsonMode-tcnyxyap.js} +5 -5
  23. package/dist/chunks/jx-validate-5sp8a4rm.js +4 -0
  24. package/dist/chunks/layers-panel-qrxj9vr2.js +4 -0
  25. package/dist/chunks/layers-tpzayggx.js +4 -0
  26. package/dist/chunks/lit-html-x6nrxsx3.js +4 -0
  27. package/dist/chunks/media-library-ywppnjrz.js +4 -0
  28. package/dist/chunks/media-picker-etxgc8qq.js +4 -0
  29. package/dist/chunks/{monaco-binding-wfhmz89d.js → monaco-binding-bqpge64f.js} +3 -3
  30. package/dist/chunks/monaco-buffer-qrnqhk0b.js +4 -0
  31. package/dist/chunks/{monaco-setup-fty7a8vg.js → monaco-setup-1mkab762.js} +3 -3
  32. package/dist/chunks/notify-kcv38wwe.js +4 -0
  33. package/dist/chunks/parse-df2kkmhc.js +4 -0
  34. package/dist/chunks/platform-dtsysmyd.js +4 -0
  35. package/dist/chunks/publish-panel-evb1rcxt.js +4 -0
  36. package/dist/chunks/{publish-quick-12hh8926.js → publish-quick-m9vkhahq.js} +3 -3
  37. package/dist/chunks/publish-workspace-ktk9h536.js +4 -0
  38. package/dist/chunks/quick-search-2f47fxcw.js +4 -0
  39. package/dist/chunks/references-5w6ajjv7.js +4 -0
  40. package/dist/chunks/right-panel-kz0a6byf.js +4 -0
  41. package/dist/chunks/source-control-1phx90zk.js +4 -0
  42. package/dist/chunks/{studio-qevf5z9d.js → studio-07k0geap.js} +4 -4
  43. package/dist/chunks/{studio-k5n4es74.js → studio-0g2sm01j.js} +4 -4
  44. package/dist/chunks/{studio-7q6jdd4h.js → studio-0hr000ba.js} +4 -4
  45. package/dist/chunks/{studio-e4rq6x0q.js → studio-1wyp7dt5.js} +4 -4
  46. package/dist/chunks/{studio-vtey9w98.js → studio-20ap8dds.js} +4 -4
  47. package/dist/chunks/studio-291gqh98.js +5 -0
  48. package/dist/chunks/{studio-32d8wyxq.js → studio-37twdaf7.js} +30 -30
  49. package/dist/chunks/{studio-8pne0rx4.js → studio-4nkm4404.js} +4 -4
  50. package/dist/chunks/{studio-z1p91z5a.js → studio-4smcnv33.js} +4 -4
  51. package/dist/chunks/{studio-s4fq9jht.js → studio-4zqfw5ha.js} +4 -4
  52. package/dist/chunks/{studio-n4qq1n57.js → studio-56egy6vf.js} +4 -4
  53. package/dist/chunks/{studio-t6dqnnft.js → studio-5dmgmyw4.js} +4 -4
  54. package/dist/chunks/{studio-9ff0vqff.js → studio-5e7p1vgd.js} +4 -4
  55. package/dist/chunks/{studio-4qg61g9j.js → studio-5m0w815d.js} +4 -4
  56. package/dist/chunks/{studio-0rg30pvs.js → studio-695k95bw.js} +4 -4
  57. package/dist/chunks/{studio-spza69tb.js → studio-6vwvshw8.js} +5 -5
  58. package/dist/chunks/{studio-ae7a69jc.js → studio-76t560kn.js} +5 -5
  59. package/dist/chunks/{studio-9gzvypw4.js → studio-7823f0g8.js} +4 -4
  60. package/dist/chunks/{studio-gskkgfe3.js → studio-7vb997ff.js} +4 -4
  61. package/dist/chunks/{studio-sc35ttdk.js → studio-8486jn4r.js} +4 -4
  62. package/dist/chunks/{studio-a6e5fzve.js → studio-848rk4p1.js} +4 -4
  63. package/dist/chunks/{studio-tyzgte21.js → studio-8jb31dcf.js} +4 -4
  64. package/dist/chunks/{studio-jr30g4ae.js → studio-8qejv8yf.js} +4 -4
  65. package/dist/chunks/studio-8x8616xd.js +5 -0
  66. package/dist/chunks/{studio-kyw47pet.js → studio-9b7177jq.js} +4 -4
  67. package/dist/chunks/{studio-gk9yk8dj.js → studio-9cp96v90.js} +6 -6
  68. package/dist/chunks/{studio-h4jbgne2.js → studio-9rcbvksg.js} +6 -6
  69. package/dist/chunks/{studio-3hpcawh8.js → studio-a3s6frde.js} +3 -3
  70. package/dist/chunks/{studio-tfmhnwyr.js → studio-ahf3cspq.js} +3 -3
  71. package/dist/chunks/{studio-6rbaedw2.js → studio-bkmv1h3e.js} +6 -6
  72. package/dist/chunks/{studio-4j35hgsw.js → studio-brdp85q7.js} +4 -4
  73. package/dist/chunks/{studio-hcy9zeac.js → studio-cgb97rwv.js} +4 -4
  74. package/dist/chunks/{studio-gczve8zf.js → studio-ch8gt8vt.js} +3 -3
  75. package/dist/chunks/studio-cqf1k4qk.js +5 -0
  76. package/dist/chunks/{studio-myb4mf0h.js → studio-cvz0e00f.js} +4 -4
  77. package/dist/chunks/{studio-nqexty8x.js → studio-dbgv4fv9.js} +14 -14
  78. package/dist/chunks/{studio-8hf8qcm1.js → studio-dy2xtt7a.js} +4 -4
  79. package/dist/chunks/{studio-c88gq88j.js → studio-eesyjg7h.js} +5 -5
  80. package/dist/chunks/studio-et6t8g4m.js +4 -0
  81. package/dist/chunks/{studio-qs5fmhtj.js → studio-f2j9et3h.js} +8 -8
  82. package/dist/chunks/{studio-79r8msnr.js → studio-fep7hr66.js} +4 -4
  83. package/dist/chunks/{studio-1cfyd1ys.js → studio-fyf7j57j.js} +3 -3
  84. package/dist/chunks/{studio-mkw17ngg.js → studio-g5prntab.js} +4 -4
  85. package/dist/chunks/{studio-x2trkhk5.js → studio-ga77mf07.js} +4 -4
  86. package/dist/chunks/{studio-yjh9gddd.js → studio-ggm7zf70.js} +5 -5
  87. package/dist/chunks/studio-h7gy12h2.js +5 -0
  88. package/dist/chunks/{studio-qd0cycm4.js → studio-hsr3k06v.js} +5 -5
  89. package/dist/chunks/{studio-ztppbam0.js → studio-j933k8nr.js} +4 -4
  90. package/dist/chunks/studio-jgbvqcgh.js +5 -0
  91. package/dist/chunks/{studio-xzgp0cp7.js → studio-jh6t5qz4.js} +4 -4
  92. package/dist/chunks/{studio-k6hbx2fc.js → studio-jw0q5j6k.js} +4 -4
  93. package/dist/chunks/studio-k4xc5g6h.js +5 -0
  94. package/dist/chunks/{studio-fg4fj9ec.js → studio-mwnmzx7g.js} +6 -6
  95. package/dist/chunks/{studio-ekzbgnjp.js → studio-nf0pqpbj.js} +4 -4
  96. package/dist/chunks/{studio-sm2f0sc6.js → studio-p0nf2e1f.js} +5 -5
  97. package/dist/chunks/{studio-by8x0jvc.js → studio-pd9dsqpq.js} +4 -4
  98. package/dist/chunks/{studio-cg54vtet.js → studio-pmzg17fj.js} +4 -4
  99. package/dist/chunks/{studio-ht81xjkr.js → studio-pzfa2vmb.js} +4 -4
  100. package/dist/chunks/{studio-9179bsm7.js → studio-qyb5bebs.js} +7 -7
  101. package/dist/chunks/{studio-aghsg0ds.js → studio-rf8d6p9f.js} +6 -6
  102. package/dist/chunks/{studio-9ra9e7m4.js → studio-rt498t2v.js} +4 -4
  103. package/dist/chunks/{studio-trcfer2b.js → studio-s0fg2wav.js} +4 -4
  104. package/dist/chunks/studio-sd07xva5.js +6 -0
  105. package/dist/chunks/{studio-apapy17g.js → studio-skynbac3.js} +2 -2
  106. package/dist/chunks/{studio-nvfa137z.js → studio-t3j8htp7.js} +5 -5
  107. package/dist/chunks/{studio-ry4789ng.js → studio-thj81e98.js} +6 -6
  108. package/dist/chunks/{studio-nfwacw31.js → studio-tpy3rdxn.js} +4 -4
  109. package/dist/chunks/{studio-g45r5vm8.js → studio-va0e63sk.js} +4 -4
  110. package/dist/chunks/{studio-kqh7fxn6.js → studio-vcz63n42.js} +4 -4
  111. package/dist/chunks/studio-vffwe9k7.js +5 -0
  112. package/dist/chunks/{studio-nm86874b.js → studio-vjhej0w5.js} +123 -123
  113. package/dist/chunks/{studio-ws2r1d7e.js → studio-vxjap704.js} +4 -4
  114. package/dist/chunks/{studio-9ndgd55w.js → studio-w67vfgy5.js} +4 -4
  115. package/dist/chunks/{studio-ajw4k8hp.js → studio-x2metr13.js} +3 -3
  116. package/dist/chunks/{studio-14hh60j8.js → studio-xebavr9s.js} +4 -4
  117. package/dist/chunks/{studio-4rgem12q.js → studio-yg5n49za.js} +4 -4
  118. package/dist/chunks/{studio-6k9djnxw.js → studio-yhz5b313.js} +4 -4
  119. package/dist/chunks/{studio-nfmpmkqb.js → studio-zacvfm31.js} +4 -4
  120. package/dist/chunks/{studio-ywf9y1e2.js → studio-zsjpsw08.js} +4 -4
  121. package/dist/chunks/{studio-0nefxhar.js → studio-zxm98z2m.js} +6 -6
  122. package/dist/chunks/{tsMode-byje4a01.js → tsMode-6vwhy6ty.js} +5 -5
  123. package/dist/chunks/workspace-d65bz1qk.js +4 -0
  124. package/dist/chunks/workspace-home-vbg9b3jh.js +4 -0
  125. package/dist/chunks/{ws-client-h09h6sqg.js → ws-client-zcxkfgmf.js} +3 -3
  126. package/dist/iframe-entry.js +8 -8
  127. package/dist/manifest.json +74 -74
  128. package/dist/studio.js +86 -84
  129. package/package.json +11 -11
  130. package/src/canvas/iframe-editable-root.ts +32 -2
  131. package/src/format/format-host.ts +1 -1
  132. package/src/github/github-auth-status.ts +2 -2
  133. package/src/media/media-library.ts +73 -3
  134. package/src/packages/ensure-deps.ts +5 -5
  135. package/src/packages/pull-package-sync.ts +4 -4
  136. package/src/panels/activity-panel.ts +1 -1
  137. package/src/platform-errors.ts +17 -1
  138. package/src/platforms/cloud.ts +62 -34
  139. package/src/publish/publish-changes.ts +136 -4
  140. package/src/settings/extension-commands.ts +1 -1
  141. package/src/settings/extension-rows.ts +1 -6
  142. package/src/settings/extensions-section.ts +3 -6
  143. package/src/surfaces/block-action-bar.json +1 -3
  144. package/src/surfaces/media-library.json +35 -0
  145. package/src/surfaces/media-library.ts +2 -0
  146. package/src/surfaces/menu.ts +62 -1
  147. package/src/surfaces/settings-packages.ts +1 -1
  148. package/src/types.ts +24 -8
  149. package/src/ui/layers.ts +1 -1
  150. package/src/ui/progress-modal.ts +3 -3
  151. package/dist/chunks/adapter-ay13gema.js +0 -4
  152. package/dist/chunks/cf-settings-5y04810c.js +0 -4
  153. package/dist/chunks/components-3vf75n83.js +0 -4
  154. package/dist/chunks/content-source-4f2raf4a.js +0 -4
  155. package/dist/chunks/editor-645krvtz.js +0 -4
  156. package/dist/chunks/entry-commands-3qmv8wkr.js +0 -4
  157. package/dist/chunks/file-ops-kkhp9ma7.js +0 -4
  158. package/dist/chunks/files-yswdhxrf.js +0 -4
  159. package/dist/chunks/format-host-4g8ex6bz.js +0 -4
  160. package/dist/chunks/fs-events-z9gpvc6t.js +0 -4
  161. package/dist/chunks/grid-open-fm4j183c.js +0 -4
  162. package/dist/chunks/iframe-host-q7fedsmr.js +0 -4
  163. package/dist/chunks/index-pt4wh98x.js +0 -4
  164. package/dist/chunks/jx-validate-19y62knt.js +0 -4
  165. package/dist/chunks/layers-panel-1qvc83y9.js +0 -4
  166. package/dist/chunks/layers-qf0bc7ze.js +0 -4
  167. package/dist/chunks/lit-html-wyqw04y2.js +0 -4
  168. package/dist/chunks/media-library-f9d5qcjb.js +0 -4
  169. package/dist/chunks/media-picker-rsb1fmk2.js +0 -4
  170. package/dist/chunks/monaco-buffer-ak0raadw.js +0 -4
  171. package/dist/chunks/notify-4qj70q0x.js +0 -4
  172. package/dist/chunks/parse-n8dfxnqf.js +0 -4
  173. package/dist/chunks/platform-ehg6t9vd.js +0 -4
  174. package/dist/chunks/publish-panel-yhmda3cd.js +0 -4
  175. package/dist/chunks/publish-workspace-hx8qdv9p.js +0 -4
  176. package/dist/chunks/quick-search-r955m3q1.js +0 -4
  177. package/dist/chunks/references-8gxv0x7t.js +0 -4
  178. package/dist/chunks/right-panel-jarwqjpy.js +0 -4
  179. package/dist/chunks/source-control-84qt25m9.js +0 -4
  180. package/dist/chunks/studio-2bq7hheq.js +0 -5
  181. package/dist/chunks/studio-a9k86nq6.js +0 -5
  182. package/dist/chunks/studio-dvhxxxbd.js +0 -5
  183. package/dist/chunks/studio-fj6jzgxw.js +0 -5
  184. package/dist/chunks/studio-ge08zwpv.js +0 -5
  185. package/dist/chunks/studio-nr0kcqc6.js +0 -5
  186. package/dist/chunks/studio-psh8mwnw.js +0 -4
  187. package/dist/chunks/studio-tn7v8gey.js +0 -6
  188. package/dist/chunks/studio-y47090vq.js +0 -5
  189. package/dist/chunks/workspace-7q4arnt3.js +0 -4
  190. package/dist/chunks/workspace-home-ge027kr6.js +0 -4
@@ -10,8 +10,16 @@
10
10
  * a host that opens pull requests (`createPullRequest`); on one that does not (the dev server and
11
11
  * the desktop app today) it is drawn disabled with that sentence rather than falling back to a
12
12
  * branch push that opens nothing. On a host whose branches are sessions (`gitHosted`, the cloud) a
13
- * branch cannot be made and committed to mid-flow, so review there commits to the session's own
14
- * branch and opens the pull request from it, and the destination's note says so.
13
+ * branch cannot be checked out mid-flow, so review there commits to the session's own branch and
14
+ * opens the pull request from it; on the default branch, where every commit is live, the change set
15
+ * is committed as a branch of its own instead (`gitCommitBranch`), and the destination's note says
16
+ * which.
17
+ *
18
+ * **A remote that moved is not a dead end.** On such a host a commit the remote's newer changes
19
+ * overlap is refused with the files they share ({@link remoteConflictsOf}). The author is then
20
+ * offered the same branch of its own: {@link publishAsBranch} commits the change set onto the base
21
+ * it was edited against, which cannot conflict, and opens a pull request into the branch that
22
+ * moved, where GitHub reconciles the two.
15
23
  *
16
24
  * **Every word a control shows is decided here**, so the workspace and the dialog cannot disagree
17
25
  * about what a button does: {@link destinationChoices}, {@link publishLabel} and
@@ -24,6 +32,8 @@
24
32
  import { errorMessage } from "@jxsuite/schema/parse";
25
33
  import { flushAllCollab } from "../collab/collab-session";
26
34
  import { getPlatform, hasPlatform } from "../platform";
35
+ import { remoteConflictsOf } from "../platform-errors";
36
+ import { showPromptDialog } from "../ui/layers";
27
37
  import { notify } from "../services/notify";
28
38
  import { shell } from "../shell";
29
39
  import { projectState } from "../store";
@@ -71,6 +81,21 @@ export function reviewBranchName(summary: string): string {
71
81
  return `studio/${slug.replace(/-$/, "") || "changes"}`;
72
82
  }
73
83
 
84
+ /**
85
+ * Whether this host can commit a change set as a branch of its own without checking it out
86
+ * (`StudioPlatform.gitCommitBranch`): what lets the cloud send a review from the default branch and
87
+ * publish a change set the remote has conflicted with.
88
+ */
89
+ export function platformCommitsBranches(): boolean {
90
+ return hasPlatform() && getPlatform().gitCommitBranch !== undefined;
91
+ }
92
+
93
+ /** Whether review on this host commits a branch of its own rather than the session's branch. */
94
+ function reviewBranchesOff(): boolean {
95
+ const base = defaultBranch();
96
+ return platformHostsGit() && platformCommitsBranches() && base !== "" && currentBranch() === base;
97
+ }
98
+
74
99
  /** One destination, as a radio card draws it. */
75
100
  export interface DestinationChoice {
76
101
  value: PublishDestination;
@@ -108,6 +133,9 @@ export function reviewRefusal(): string {
108
133
  publish by accident. */
109
134
  const base = defaultBranch();
110
135
  const branch = currentBranch();
136
+ if (reviewBranchesOff()) {
137
+ return "";
138
+ }
111
139
  if (!base || !branch || branch === base) {
112
140
  return (
113
141
  `Every commit to ${base || "the default branch"} on this host is live. Create a branch ` +
@@ -140,14 +168,17 @@ function liveNote(): string {
140
168
  /** What Send for review does, said before it runs. */
141
169
  function reviewNote(): string {
142
170
  const branch = currentBranch() || "the current branch";
171
+ const summary = shell.git.commitMessage.trim();
172
+ const head = summary ? reviewBranchName(summary) : "a new studio/ branch";
173
+ if (reviewBranchesOff()) {
174
+ return `Saves to ${head} on GitHub and opens a pull request into ${branch}.`;
175
+ }
143
176
  if (platformHostsGit()) {
144
177
  return (
145
178
  `Commits to ${branch} and opens a pull request from it into ` +
146
179
  `${defaultBranch() || "the default branch"}.`
147
180
  );
148
181
  }
149
- const summary = shell.git.commitMessage.trim();
150
- const head = summary ? reviewBranchName(summary) : "a new studio/ branch";
151
182
  return `Saves to ${head}, pushes it and opens a pull request into ${branch}.`;
152
183
  }
153
184
 
@@ -424,6 +455,16 @@ export async function publishChanges(
424
455
  await refreshGitStatus();
425
456
  return shipped;
426
457
  } catch (error) {
458
+ const conflicts = committed ? null : remoteConflictsOf(error);
459
+ if (conflicts && platformCommitsBranches()) {
460
+ shell.git.loading = false;
461
+ if (await publishAsBranch(message, conflicts)) {
462
+ return true;
463
+ }
464
+ // Declined: the refusal still stands, and it is what the author must read.
465
+ shell.git.error ??= errorMessage(error);
466
+ return false;
467
+ }
427
468
  shell.git.error = errorMessage(error);
428
469
  shell.git.loading = false;
429
470
  // A push that failed after the commit landed must not offer the same summary again.
@@ -434,6 +475,89 @@ export async function publishChanges(
434
475
  }
435
476
  }
436
477
 
478
+ /** Up to three paths, then how many more: what a sentence can name of a list of files. */
479
+ function namePaths(paths: readonly string[]): string {
480
+ const shown = paths.slice(0, 3).join(", ");
481
+ return paths.length > 3 ? `${shown} and ${paths.length - 3} more` : shown;
482
+ }
483
+
484
+ /**
485
+ * Offer to publish a change set the remote has conflicted with as a branch of its own, and do it.
486
+ *
487
+ * Asked, never assumed: the author named a destination, and this is a different one. The dialog
488
+ * says which files collided and what will happen, and the branch name it proposes is the one Send
489
+ * for review would use, editable. Confirming commits the change set onto the base it was edited
490
+ * against (`gitCommitBranch`, which cannot conflict), opens a pull request from it into the branch
491
+ * that moved, and pulls that branch up to date now that the colliding changes have left it.
492
+ * Cancelling puts the summary back, as any publish that never committed does.
493
+ *
494
+ * @param message The summary the refused commit was made with.
495
+ * @param conflicts The files the remote changed that this change set changes too.
496
+ * @returns Whether the change set reached the new branch.
497
+ */
498
+ export async function publishAsBranch(
499
+ message: string,
500
+ conflicts: readonly string[],
501
+ ): Promise<boolean> {
502
+ const plat = getPlatform();
503
+ const commitBranch = plat.gitCommitBranch;
504
+ if (!commitBranch) {
505
+ return false;
506
+ }
507
+ const current = currentBranch() || "this branch";
508
+ const count = conflicts.length === 1 ? "1 file" : `${conflicts.length} files`;
509
+ const name = await showPromptDialog("Publish to a New Branch", {
510
+ confirmLabel: "Publish to branch",
511
+ message:
512
+ `${current} changed on GitHub after these edits began, and ${count} changed on both sides ` +
513
+ `(${namePaths(conflicts)}). Publish your changes to a branch of their own instead, and a ` +
514
+ `pull request will bring them into ${current}.`,
515
+ value: reviewBranchName(message),
516
+ validate: (value) => (value.trim() ? "" : "Enter a branch name."),
517
+ });
518
+ if (!name) {
519
+ restoreSummary(message);
520
+ return false;
521
+ }
522
+ shell.git.loading = true;
523
+ shell.git.error = null;
524
+ let committed = false;
525
+ try {
526
+ const result = await commitBranch({ branch: name, message });
527
+ committed = true;
528
+ const open = plat.createPullRequest;
529
+ const base = currentBranch();
530
+ const pr = open && base ? await open({ base, head: result.branch, title: message }) : null;
531
+ if (pr) {
532
+ shell.publish.review.number = pr.number;
533
+ shell.publish.review.url = pr.url;
534
+ }
535
+ notify.success(
536
+ pr
537
+ ? `Published to ${result.branch}. Pull request #${pr.number} brings it into ${base}.`
538
+ : `Published to ${result.branch}.`,
539
+ { detail: pr?.url ?? "", key: "publish.branch", source: "Publish" },
540
+ );
541
+ /* The colliding edits have left this session, so it can fast-forward to the remote now. A
542
+ pull that still cannot (another collaborator's edit overlaps too) is not this publish's
543
+ failure: the status says the branch is behind, and Pull says why. */
544
+ try {
545
+ await plat.gitPull();
546
+ } catch {
547
+ // Reported by the next Pull, where it can be acted on.
548
+ }
549
+ await refreshGitStatus();
550
+ return true;
551
+ } catch (error) {
552
+ shell.git.error = errorMessage(error);
553
+ shell.git.loading = false;
554
+ if (!committed) {
555
+ restoreSummary(message);
556
+ }
557
+ return false;
558
+ }
559
+ }
560
+
437
561
  /** What a pull request is opened with: its title, and the branches when the flow chose them. */
438
562
  interface PullRequestRequest {
439
563
  title: string;
@@ -454,6 +578,14 @@ async function commitForReview(
454
578
  message: string,
455
579
  onCommitted: () => void,
456
580
  ): Promise<PullRequestRequest> {
581
+ if (reviewBranchesOff() && plat.gitCommitBranch) {
582
+ /* Every commit to the default branch here is live, so the change set goes to a branch of its
583
+ own, parented on the session's base, and leaves the session: it is the pull request's now. */
584
+ const base = currentBranch();
585
+ const { branch } = await plat.gitCommitBranch({ branch: reviewBranchName(message), message });
586
+ onCommitted();
587
+ return { base, head: branch, title: message };
588
+ }
457
589
  if (platformHostsGit()) {
458
590
  // `reviewRefusal` has already refused the default branch, so this commit is not a live one.
459
591
  await plat.gitCommit(message);
@@ -135,7 +135,7 @@ export async function enableExtension(specifier: string): Promise<void> {
135
135
  let installed = false;
136
136
  notifySettingsDocument();
137
137
  try {
138
- if (!row.installed && !row.bundled) {
138
+ if (!row.installed) {
139
139
  /*
140
140
  * `beginActivity`, not `showProgressModal`. `studio-ui-guidelines.md` §13.3 reserves blocking
141
141
  * for an operation that cannot proceed while the author edits, and this one can — the only
@@ -32,8 +32,6 @@ export interface ExtensionRow {
32
32
  origin: ExtensionOrigin;
33
33
  enabled: boolean;
34
34
  installed: boolean;
35
- /** The host resolves it without a project install, so enabling is a config write alone. */
36
- bundled: boolean;
37
35
  /** Why this backend cannot run it, as one sentence. Absent means it can. */
38
36
  unavailable?: string | undefined;
39
37
  /** Enabled but not installed — the state that fails the next build. */
@@ -69,11 +67,9 @@ export function buildRows(packages: PackageInfo[] | null = null): ExtensionRow[]
69
67
  for (const entry of getExtensionCatalog()) {
70
68
  const specifier = entry.specifier ?? entry.name;
71
69
  const here = entry.installed ?? installed.has(entry.name);
72
- const bundled = entry.bundled ?? false;
73
70
  const info = resolved.get(entry.name);
74
71
  const row: ExtensionRow = {
75
- broken: enabled.has(specifier) && !here && !bundled,
76
- bundled,
72
+ broken: enabled.has(specifier) && !here,
77
73
  enabled: enabled.has(specifier),
78
74
  installed: here,
79
75
  name: entry.name,
@@ -102,7 +98,6 @@ export function buildRows(packages: PackageInfo[] | null = null): ExtensionRow[]
102
98
  const info = resolved.get(specifier);
103
99
  const row: ExtensionRow = {
104
100
  broken: !installed.has(specifier) && info === undefined,
105
- bundled: false,
106
101
  enabled: true,
107
102
  installed: installed.has(specifier),
108
103
  name: specifier,
@@ -105,12 +105,9 @@ function noteFor(row: ExtensionRow): RowNote {
105
105
  noteTone: "warn",
106
106
  };
107
107
  }
108
- if (!row.installed && !row.bundled) {
108
+ if (!row.installed) {
109
109
  return { note: "Not installed. Turning this on installs it first.", noteTone: "note" };
110
110
  }
111
- if (row.bundled) {
112
- return { note: "Ships with this backend, so it needs no install.", noteTone: "note" };
113
- }
114
111
  return { note: "", noteTone: "none" };
115
112
  }
116
113
 
@@ -131,7 +128,7 @@ function blockedReason(row: ExtensionRow): string {
131
128
  * Refused while the extension is still enabled, and DISABLED with the reason rather than hidden
132
129
  * (`studio-ui-guidelines.md` §10): removing the package while `project.json` still names it
133
130
  * manufactures exactly the broken state this section exists to eliminate. It is absent only when
134
- * there is nothing to remove — a package the project never installed, or one the backend bundles.
131
+ * there is nothing to remove — a package the project never installed.
135
132
  */
136
133
  function removeFor(
137
134
  row: ExtensionRow,
@@ -140,7 +137,7 @@ function removeFor(
140
137
  ? `Turn ${row.title} off first. Removing the package while project.json still names it would fail the next build.`
141
138
  : "";
142
139
  return {
143
- canRemove: row.installed && !row.bundled,
140
+ canRemove: row.installed,
144
141
  removeDisabled: refusal !== "" || extensionOpInFlight() !== null,
145
142
  removeHint: refusal === "" ? `Remove ${row.name}` : refusal,
146
143
  removeLabel: `Remove ${row.name}`,
@@ -104,9 +104,7 @@
104
104
  "display": "contents"
105
105
  },
106
106
  "& [part=\"link\"]": {
107
- "display": "flex",
108
- "gap": "var(--jx-space-2)",
109
- "alignItems": "center",
107
+ "$description": "No display here. A closed popover is hidden by the platform's own `[popover]:not(:popover-open)` rule, which the kit lets through with `display: revert-layer`; a `display` declared on the part beats it, and the closed panel stayed laid out at the viewport origin, invisible at opacity 0 and still taking every click and the text cursor meant for the workspace tabs beneath it.",
110
108
  "padding": "var(--jx-space-3)"
111
109
  },
112
110
  "& [part=\"link-field\"]": {
@@ -1027,6 +1027,41 @@
1027
1027
  }
1028
1028
  ]
1029
1029
  },
1030
+ "oncontextmenu": {
1031
+ "$prototype": "Function",
1032
+ "body": [
1033
+ {
1034
+ "$switch": {
1035
+ "$ref": "#/state/mode"
1036
+ },
1037
+ "cases": {
1038
+ "manage": [
1039
+ {
1040
+ "preventDefault": true
1041
+ },
1042
+ {
1043
+ "operator": "call",
1044
+ "target": {
1045
+ "$ref": "#/state/contextMenu"
1046
+ },
1047
+ "value": [
1048
+ {
1049
+ "$ref": "$map/item/file"
1050
+ },
1051
+ {
1052
+ "$ref": "event#/clientX"
1053
+ },
1054
+ {
1055
+ "$ref": "event#/clientY"
1056
+ }
1057
+ ]
1058
+ }
1059
+ ]
1060
+ }
1061
+ }
1062
+ ],
1063
+ "description": "Manage mode only: the detail pane's actions at the pointer. Pick mode's dialog is modal, and a menu in the popover layer outside it would be inert, so its right-click is left to the platform."
1064
+ },
1030
1065
  "children": [
1031
1066
  {
1032
1067
  "tagName": "div",
@@ -118,6 +118,8 @@ export interface MediaLibraryActions {
118
118
  activate: (file: string) => void;
119
119
  /** Enter on the grid: the same, for the selected file. */
120
120
  activateSelected: () => void;
121
+ /** A right-click on a tile in manage mode: select it and open its actions at the pointer. */
122
+ contextMenu: (file: string, x: number, y: number) => void;
121
123
  key: (key: string, ctrl: boolean) => void;
122
124
  measure: (file: string, width: number, height: number) => void;
123
125
  copyRef: () => void;
@@ -5,7 +5,8 @@
5
5
  * `menu.json` is the markup, ARIA and style, and this adapter is the decisions — which records,
6
6
  * what they print, where the panel opens, what runs on select. The kit owns the menu contract
7
7
  * (roving focus, typeahead, submenus, light dismissal, Escape) through the platform's own popover,
8
- * so nothing here binds a key or a document listener.
8
+ * so nothing here binds a key, and the one window listener is the record of which pointers are held
9
+ * ({@link pointersReleased}): a menu asked for mid-press is shown on the release.
9
10
  *
10
11
  * Every menu opens in a `getLayerSlot("popover", id)` slot, which is what carries the
11
12
  * `overlay.menu:<id>` region the screenshot pipeline addresses, and is torn down when the popover
@@ -309,6 +310,10 @@ export function openMenu(options: OpenMenuOptions): MenuHandle {
309
310
  if (aborted()) {
310
311
  return;
311
312
  }
313
+ await pointersReleased(controller.signal);
314
+ if (aborted()) {
315
+ return;
316
+ }
312
317
  const source =
313
318
  options.opener instanceof HTMLElement && options.opener !== document.body
314
319
  ? options.opener
@@ -368,6 +373,62 @@ export function openMenu(options: OpenMenuOptions): MenuHandle {
368
373
  return handle;
369
374
  }
370
375
 
376
+ /**
377
+ * The pointers pressed in this document and not yet released, by `pointerId`.
378
+ *
379
+ * Read by {@link pointersReleased}. Window listeners in the capture phase, so the record is current
380
+ * before any handler in the document runs, a `contextmenu` handler included. A press in the canvas
381
+ * iframe is never seen here, and needs not be: that release lands in the iframe's document, which
382
+ * cannot light-dismiss a popover in this one. Bound at load, so the press that asks for the first
383
+ * menu is already recorded; not at all without a window, where the docs build imports this module
384
+ * for the command catalog and nothing is ever pressed.
385
+ */
386
+ const pressedPointers = new Set<number>();
387
+ if (typeof window !== "undefined") {
388
+ window.addEventListener("pointerdown", (event) => pressedPointers.add(event.pointerId), true);
389
+ window.addEventListener("pointerup", (event) => pressedPointers.delete(event.pointerId), true);
390
+ window.addEventListener(
391
+ "pointercancel",
392
+ (event) => pressedPointers.delete(event.pointerId),
393
+ true,
394
+ );
395
+ // A release outside a window that lost focus may never arrive.
396
+ window.addEventListener("blur", () => pressedPointers.clear());
397
+ }
398
+
399
+ /**
400
+ * Settle once no pointer is held down in this document, or when `signal` aborts.
401
+ *
402
+ * A menu shown while the button that asked for it is still down is light-dismissed by that button's
403
+ * release. On Linux and macOS `contextmenu` fires on the PRESS, so every right-click menu opened
404
+ * with the button held, and the release that followed is a `pointerup` outside the popover. The
405
+ * HTML light-dismiss algorithm hides every `auto` popover on it, before the event reaches any
406
+ * listener, so it cannot be cancelled. Chromium 156 exempts a non-primary button and Electron 43's
407
+ * Chromium does not: in the desktop app the menu flashed and vanished. Waiting for the release is
408
+ * what Windows does natively, where `contextmenu` fires on it; a menu opened by a click or a key
409
+ * has nothing held and is shown at once.
410
+ */
411
+ function pointersReleased(signal: AbortSignal): Promise<void> {
412
+ if (pressedPointers.size === 0 || signal.aborted) {
413
+ return Promise.resolve();
414
+ }
415
+ return new Promise((resolve) => {
416
+ const waiting = new AbortController();
417
+ const settle = (): void => {
418
+ if (pressedPointers.size === 0 || signal.aborted) {
419
+ waiting.abort();
420
+ resolve();
421
+ }
422
+ };
423
+ // Registered after the record's own listeners, so each sees the record already updated.
424
+ const options = { capture: true, signal: waiting.signal };
425
+ window.addEventListener("pointerup", settle, options);
426
+ window.addEventListener("pointercancel", settle, options);
427
+ window.addEventListener("blur", settle, { signal: waiting.signal });
428
+ signal.addEventListener("abort", settle, { signal: waiting.signal });
429
+ });
430
+ }
431
+
371
432
  /**
372
433
  * Give the keyboard back to the opener BEFORE a chosen row runs, while the menu still holds it.
373
434
  *
@@ -73,7 +73,7 @@ export interface PackagesActions {
73
73
  /** Move every package that is behind one. */
74
74
  updateAll: () => void;
75
75
  remove: (name: string) => void;
76
- /** Run `bun install` over the project as it stands. */
76
+ /** Install the project's dependencies as it stands. */
77
77
  reinstall: () => void;
78
78
  }
79
79
 
package/src/types.ts CHANGED
@@ -34,6 +34,7 @@ import type {
34
34
  ExtensionsInfo,
35
35
  FsEvent,
36
36
  GitBranchesResult,
37
+ GitCommitBranchResult,
37
38
  GitLogEntry,
38
39
  GitStatusResult,
39
40
  ImportProgressEvent,
@@ -88,6 +89,7 @@ export type {
88
89
  ExtensionsInfo,
89
90
  FsEvent,
90
91
  GitBranchesResult,
92
+ GitCommitBranchResult,
91
93
  GitFileStatus,
92
94
  GitLogEntry,
93
95
  GitStatusResult,
@@ -472,8 +474,9 @@ export interface StudioPlatform {
472
474
  removePackage: (name: string) => Promise<void>;
473
475
  listPackages: () => Promise<PackageInfo[]>;
474
476
  /**
475
- * Run `bun install` in the project root. Optional: platforms without a Bun-capable backend omit
476
- * it and the install-on-open / reinstall affordances are skipped.
477
+ * Install the project's dependencies (npm's installer, writing `package-lock.json`). Optional:
478
+ * platforms with no `node_modules` to install into (the cloud) omit it and the install-on-open /
479
+ * reinstall affordances are skipped.
477
480
  */
478
481
  installDependencies?: () => Promise<PackageOpResult>;
479
482
  /** Whether the project has uninstalled dependencies (node_modules missing). */
@@ -486,7 +489,7 @@ export interface StudioPlatform {
486
489
  packageVersions?: () => Promise<PackageVersionInfo[]>;
487
490
  /**
488
491
  * Rewrite the version range of each named package (preserving its dependencies/devDependencies
489
- * placement) and run `bun install`. Used by the @jxsuite bump and per-dependency updates.
492
+ * placement) and install. Used by the @jxsuite bump and per-dependency updates.
490
493
  */
491
494
  setPackageVersions?: (
492
495
  updates: { name: string; version: string; dev?: boolean }[],
@@ -522,11 +525,12 @@ export interface StudioPlatform {
522
525
  * is dropped from the registry before composition rather than passed to it. A studio that
523
526
  * advertised a shipped list would offer rows the host would refuse.
524
527
  *
525
- * Each entry additionally carries two facts only a backend holds: whether THIS host resolves the
526
- * package without a project install (`bundled`), and whether the project has it installed
527
- * (`installed`) — the latter because `listPackages` does not mean one thing across backends.
528
- * `enabled` is deliberately absent: it is `projectConfig.extensions.includes(name)`, which Studio
529
- * already owns and rewrites through the `updateSiteConfig` chokepoint.
528
+ * Each entry additionally carries one fact only a backend holds: whether the project has it
529
+ * installed (`installed`), because `listPackages` does not mean one thing across backends. No
530
+ * host answers for an extension the project lacks (specs/extensions.md §3), so a row that is not
531
+ * installed is always install-then-enable. `enabled` is deliberately absent: it is
532
+ * `projectConfig.extensions.includes(name)`, which Studio already owns and rewrites through the
533
+ * `updateSiteConfig` chokepoint.
530
534
  *
531
535
  * Optional: platforms without it offer no catalogue, and adding an extension stays a typed
532
536
  * package name.
@@ -578,6 +582,18 @@ export interface StudioPlatform {
578
582
  gitFetch: () => Promise<void>;
579
583
  gitCheckout: (branch: string) => Promise<void>;
580
584
  gitCreateBranch: (name: string) => Promise<void>;
585
+ /**
586
+ * Commit the change set as a NEW branch, parented on the commit this session's edits were made
587
+ * against, and take the committed files out of this session. Rejects with code `branch_exists`
588
+ * when the name is taken (the ref is created, never moved).
589
+ *
590
+ * The way out on a host where a branch is a session (`gitHosted`): a commit to the session's own
591
+ * branch that the remote conflicts with can still be published, as a branch of its own the pull
592
+ * request then reconciles, and a change set on a branch whose every commit is live can be sent
593
+ * for review without landing there first. An ordinary working tree has no need of it: there a
594
+ * branch is created and checked out with the changes still in it (studio.md §22.8).
595
+ */
596
+ gitCommitBranch?: (opts: { branch: string; message: string }) => Promise<GitCommitBranchResult>;
581
597
  gitDiff: (path?: string) => Promise<string>;
582
598
  gitShow: (opts: { path: string; ref?: string }) => Promise<string>;
583
599
  gitDiscard: (files: string[]) => Promise<void>;
package/src/ui/layers.ts CHANGED
@@ -523,7 +523,7 @@ function reducedMotion(): boolean {
523
523
  /**
524
524
  * **One of the three exceptions §13.5 lists** — behaviour that differs under `?automation=1` beyond
525
525
  * installing the hook, pinning the clock and selecting a profile. The other two are both refusals
526
- * to touch the project on disk: `packages/ensure-deps.ts` declines to run `bun install`, and
526
+ * to touch the project on disk: `packages/ensure-deps.ts` declines to run an install, and
527
527
  * `packages/jxsuite-update.ts` declines to prompt for a dependency update. This one is the only
528
528
  * exception that changes what a picture SHOWS rather than what it avoids doing.
529
529
  *
@@ -4,8 +4,8 @@
4
4
  *
5
5
  * What changed. This modal used to be four things at once: the running state, the error view, the
6
6
  * log and the operation's entire memory. It blocked the whole app, offered no way out, and took all
7
- * four with it when it closed — so a failed `bun install` could be read exactly once, and a hung
8
- * one could not be escaped at all. §16.4 splits those apart:
7
+ * four with it when it closed — so a failed install could be read exactly once, and a hung one
8
+ * could not be escaped at all. §16.4 splits those apart:
9
9
  *
10
10
  * - The **record** moves to `panels/activity-panel.ts`, which keeps the entry, its steps and its log
11
11
  * after the modal is gone;
@@ -120,7 +120,7 @@ export function showProgressModal(opts: ProgressModalOptions): ProgressModalHand
120
120
  fail(message: string) {
121
121
  // The error view is not rendered here any more: it is the Problems row, with the log as its
122
122
  // `detail`, and it is still on screen tomorrow. Three of the four call sites hand over a
123
- // CAPTURED LOG as their message — `result.log ?? "bun install failed"` — so a multi-line one
123
+ // CAPTURED LOG as their message — `result.log ?? "Install failed"` — so a multi-line one
124
124
  // Is split the way the old view split it: "<title> failed" as the headline, the whole text
125
125
  // As the detail. A Problems list whose first row is 400 lines of `bun` output is not a list.
126
126
  const text = message.trim();
@@ -1,4 +0,0 @@
1
- import{qs,Gs,Wr}from"./studio-g45r5vm8.js";export{Wr as draggable,qs as dropTargetForElements,Gs as monitorForElements};
2
-
3
- //# debugId=6706B48D5462E95E64756E2164756E21
4
- //# sourceMappingURL=adapter-ay13gema.js.map
@@ -1,4 +0,0 @@
1
- import{cb,DE,NE,Z2,AE}from"./studio-nr0kcqc6.js";import"./studio-14hh60j8.js";import"./studio-tfmhnwyr.js";import"./studio-9ndgd55w.js";export{AE as clearCfConnection,NE as getCfAccountId,cb as getCfToken,Z2 as setCfAccountId,DE as setCfToken};
2
-
3
- //# debugId=9B842315B780DEB864756E2164756E21
4
- //# sourceMappingURL=cf-settings-5y04810c.js.map
@@ -1,4 +0,0 @@
1
- import{Ne,Zw,xa,Ob,Fc,jc}from"./studio-ekzbgnjp.js";import"./studio-9ndgd55w.js";export{Zw as _componentRegistryLoaded,Fc as buildComponentInstance,Ne as componentRegistry,jc as computeRelativePath,xa as loadComponentRegistry,Ob as noteComponentSaved};
2
-
3
- //# debugId=FCFBCB13AFA3037764756E2164756E21
4
- //# sourceMappingURL=components-3vf75n83.js.map
@@ -1,4 +0,0 @@
1
- import{fb,rS,sS,mb,tT,nT,iT}from"./studio-fg4fj9ec.js";import"./studio-x2trkhk5.js";import"./studio-spza69tb.js";import"./studio-9179bsm7.js";import"./studio-0nefxhar.js";import"./studio-yjh9gddd.js";import"./studio-0rg30pvs.js";import"./studio-ekzbgnjp.js";import"./studio-nqexty8x.js";import"./studio-g45r5vm8.js";import"./studio-vtey9w98.js";import"./studio-t6dqnnft.js";import"./studio-y47090vq.js";import"./studio-14hh60j8.js";import"./studio-myb4mf0h.js";import"./studio-ajw4k8hp.js";import"./studio-qs5fmhtj.js";import"./studio-8hf8qcm1.js";import"./studio-7q6jdd4h.js";import"./studio-by8x0jvc.js";import"./studio-ztppbam0.js";import"./studio-4rgem12q.js";import"./studio-8pne0rx4.js";import"./studio-tfmhnwyr.js";import"./studio-psh8mwnw.js";import"./studio-a6e5fzve.js";import"./studio-9ndgd55w.js";export{rS as collectionDirs,fb as collectionInfo,sS as collectionSourceDirs,nT as createCollectionSource,iT as createPagesSource,mb as listCollectionEntryIds,tT as reloadDraftAwareGrids};
2
-
3
- //# debugId=5EDD101C20492A8A64756E2164756E21
4
- //# sourceMappingURL=content-source-4f2raf4a.js.map
@@ -1,4 +0,0 @@
1
- import{H2,Wf,B2,z2,W2,np,V2,U2,ga,Y0,vd,q2,Wn,we}from"./studio-nm86874b.js";export{H2 as CancellationTokenSource,Wf as Emitter,B2 as KeyCode,z2 as KeyMod,ga as MarkerSeverity,Y0 as MarkerTag,W2 as Position,np as Range,V2 as Selection,U2 as SelectionDirection,q2 as Token,vd as Uri,Wn as editor,we as languages};
2
-
3
- //# debugId=0ABAF5272BD2763564756E2164756E21
4
- //# sourceMappingURL=editor-645krvtz.js.map
@@ -1,4 +0,0 @@
1
- import{B_,Y2,bE}from"./studio-mkw17ngg.js";import"./studio-ge08zwpv.js";import"./studio-ht81xjkr.js";import"./studio-6rbaedw2.js";import"./studio-k6hbx2fc.js";import"./studio-nfmpmkqb.js";import"./studio-n4qq1n57.js";import"./studio-9ff0vqff.js";import"./studio-fg4fj9ec.js";import"./studio-cg54vtet.js";import"./studio-x2trkhk5.js";import"./studio-spza69tb.js";import"./studio-kqh7fxn6.js";import"./studio-9179bsm7.js";import"./studio-0nefxhar.js";import"./studio-yjh9gddd.js";import"./studio-0rg30pvs.js";import"./studio-ekzbgnjp.js";import"./studio-nqexty8x.js";import"./studio-g45r5vm8.js";import"./studio-vtey9w98.js";import"./studio-t6dqnnft.js";import"./studio-y47090vq.js";import"./studio-14hh60j8.js";import"./studio-myb4mf0h.js";import"./studio-ajw4k8hp.js";import"./studio-qs5fmhtj.js";import"./studio-8hf8qcm1.js";import"./studio-7q6jdd4h.js";import"./studio-by8x0jvc.js";import"./studio-ztppbam0.js";import"./studio-4rgem12q.js";import"./studio-8pne0rx4.js";import"./studio-tfmhnwyr.js";import"./studio-psh8mwnw.js";import"./studio-a6e5fzve.js";import"./studio-9ndgd55w.js";import"./studio-k1wvtp03.js";export{Y2 as createEntry,B_ as entryFormatName,bE as registerContentCommands};
2
-
3
- //# debugId=B3F7191EB41FD41A64756E2164756E21
4
- //# sourceMappingURL=entry-commands-3qmv8wkr.js.map
@@ -1,4 +0,0 @@
1
- import{QD,jr,AT,rP,OT,wp,MT,wb,xb}from"./studio-x2trkhk5.js";import"./studio-spza69tb.js";import"./studio-9179bsm7.js";import"./studio-0nefxhar.js";import"./studio-yjh9gddd.js";import"./studio-0rg30pvs.js";import"./studio-ekzbgnjp.js";import"./studio-nqexty8x.js";import"./studio-g45r5vm8.js";import"./studio-vtey9w98.js";import"./studio-t6dqnnft.js";import"./studio-y47090vq.js";import"./studio-14hh60j8.js";import"./studio-myb4mf0h.js";import"./studio-ajw4k8hp.js";import"./studio-qs5fmhtj.js";import"./studio-8hf8qcm1.js";import"./studio-7q6jdd4h.js";import"./studio-by8x0jvc.js";import"./studio-ztppbam0.js";import"./studio-4rgem12q.js";import"./studio-8pne0rx4.js";import"./studio-tfmhnwyr.js";import"./studio-psh8mwnw.js";import"./studio-a6e5fzve.js";import"./studio-9ndgd55w.js";export{wb as confirmFileDelete,MT as exportFile,rP as openFile,AT as parseCollabSource,QD as parseFormatSource,jr as parseSourceForPath,xb as renamePromptMessage,wp as saveFile,OT as setDocumentSavedListener};
2
-
3
- //# debugId=12B19E983D3681CC64756E2164756E21
4
- //# sourceMappingURL=file-ops-kkhp9ma7.js.map
@@ -1,4 +0,0 @@
1
- import{Bs,pm,OE,ME,E2,PE,FE,jE,Z_,T2,hb,HE,L2,$2,BE,OD,I2,R2,pw,X_,MD,zE,D2,yi,Q_,WE,VE,fm,UE,N2,A2}from"./studio-ry4789ng.js";import"./studio-s4fq9jht.js";import"./studio-n4qq1n57.js";import"./studio-1cfyd1ys.js";import"./studio-9ff0vqff.js";import"./studio-fg4fj9ec.js";import"./studio-ws2r1d7e.js";import"./studio-79r8msnr.js";import"./studio-x2trkhk5.js";import"./studio-spza69tb.js";import"./studio-4qg61g9j.js";import"./studio-kqh7fxn6.js";import"./studio-9179bsm7.js";import"./studio-0nefxhar.js";import"./studio-yjh9gddd.js";import"./studio-0rg30pvs.js";import"./studio-ekzbgnjp.js";import"./studio-nqexty8x.js";import"./studio-g45r5vm8.js";import"./studio-vtey9w98.js";import"./studio-t6dqnnft.js";import"./studio-y47090vq.js";import"./studio-14hh60j8.js";import"./studio-myb4mf0h.js";import"./studio-ajw4k8hp.js";import"./studio-qs5fmhtj.js";import"./studio-8hf8qcm1.js";import"./studio-7q6jdd4h.js";import"./studio-by8x0jvc.js";import"./studio-ztppbam0.js";import"./studio-4rgem12q.js";import"./studio-8pne0rx4.js";import"./studio-tfmhnwyr.js";import"./studio-psh8mwnw.js";import"./studio-a6e5fzve.js";import"./studio-9ndgd55w.js";export{L2 as FILE_ROW_HEIGHT,BE as canMoveInto,R2 as createFileIn,Z_ as findHomePage,jE as initProjectRepo,$2 as isFileDrag,pw as listTakenNames,Bs as loadDirectory,PE as loadProject,pm as loadProjectDirectories,N2 as mountFilesPanel,MD as notifyMoveOutcome,Q_ as openFileInPane,yi as openFileInTab,T2 as openHomePage,hb as openLastSessionOrHome,FE as openProject,zE as parentDirOf,I2 as pickAndUploadTo,OE as refreshProjectDirectoriesFor,UE as registerFilesPanel,WE as reloadCleanTab,fm as reloadFileInTab,VE as reloadTabsIfChanged,HE as setSessionWorkspaceShow,E2 as setShowIgnoredFiles,D2 as settleRename,ME as showIgnoredFiles,A2 as unmountFilesPanel,OD as uploadFilesToDir,X_ as writeNewFile};
2
-
3
- //# debugId=6E30048FC4EC2D3564756E2164756E21
4
- //# sourceMappingURL=files-yswdhxrf.js.map
@@ -1,4 +0,0 @@
1
- import{Ht,Lh,Qc,Cv,Ux,ec,Xd,Na,Wi,of,fn,ul,kv,lr,oI,Aa,rI}from"./studio-a6e5fzve.js";import"./studio-9ndgd55w.js";export{lr as defaultContentFormat,ul as documentExtensions,Na as formatByExtension,Wi as formatByName,fn as formatForPath,oI as formatParse,Aa as formatSerialize,Ux as getExtensionCatalog,Cv as getExtensions,Xd as getFormats,Qc as loadExtensions,Ht as loadFormats,of as noFormatError,ec as refreshExtensionUi,Lh as refreshFormats,kv as routedPageExtensions,rI as splitFormatDocument};
2
-
3
- //# debugId=C90299CC3464784B64756E2164756E21
4
- //# sourceMappingURL=format-host-4g8ex6bz.js.map
@@ -1,4 +0,0 @@
1
- import{Ta,Hd,C$}from"./studio-8hf8qcm1.js";import"./studio-7q6jdd4h.js";import"./studio-by8x0jvc.js";import"./studio-ztppbam0.js";import"./studio-4rgem12q.js";import"./studio-8pne0rx4.js";import"./studio-tfmhnwyr.js";import"./studio-psh8mwnw.js";import"./studio-a6e5fzve.js";import"./studio-9ndgd55w.js";export{Hd as isRecentLocal,Ta as markLocalMutation,C$ as startFsSync};
2
-
3
- //# debugId=488DC9A47953DD8E64756E2164756E21
4
- //# sourceMappingURL=fs-events-z9gpvc6t.js.map
@@ -1,4 +0,0 @@
1
- import{ZE,zD,oS,XE,QE}from"./studio-1cfyd1ys.js";import"./studio-fg4fj9ec.js";import"./studio-x2trkhk5.js";import"./studio-spza69tb.js";import"./studio-9179bsm7.js";import"./studio-0nefxhar.js";import"./studio-yjh9gddd.js";import"./studio-0rg30pvs.js";import"./studio-ekzbgnjp.js";import"./studio-nqexty8x.js";import"./studio-g45r5vm8.js";import"./studio-vtey9w98.js";import"./studio-t6dqnnft.js";import"./studio-y47090vq.js";import"./studio-14hh60j8.js";import"./studio-myb4mf0h.js";import"./studio-ajw4k8hp.js";import"./studio-qs5fmhtj.js";import"./studio-8hf8qcm1.js";import"./studio-7q6jdd4h.js";import"./studio-by8x0jvc.js";import"./studio-ztppbam0.js";import"./studio-4rgem12q.js";import"./studio-8pne0rx4.js";import"./studio-tfmhnwyr.js";import"./studio-psh8mwnw.js";import"./studio-a6e5fzve.js";import"./studio-9ndgd55w.js";export{zD as openCollectionGrid,ZE as openCsvGridTab,XE as openGridSourcePicker,oS as openPagesGrid,QE as registerGridCommands};
2
-
3
- //# debugId=AD25A9B3B968468764756E2164756E21
4
- //# sourceMappingURL=grid-open-fm4j183c.js.map
@@ -1,4 +0,0 @@
1
- import{cL,dL,uL,hL,qS,Rb,Db,GS,Ul,pL,fL,mL,Nb,j2,sP,gL,Pc,Gw,Kw,bL,vL,yL,wL,xL,_L,SL,CL,kL,EL,TL,LL,KS,$L,Ab,IL,RL,DL,NL,AL,OL,Jw,ML,ql,PL,ih,FL,Yw,JS}from"./studio-0rg30pvs.js";import"./studio-ekzbgnjp.js";import"./studio-nqexty8x.js";import"./studio-g45r5vm8.js";import"./studio-t6dqnnft.js";import"./studio-14hh60j8.js";import"./studio-qs5fmhtj.js";import"./studio-by8x0jvc.js";import"./studio-ztppbam0.js";import"./studio-4rgem12q.js";import"./studio-8pne0rx4.js";import"./studio-tfmhnwyr.js";import"./studio-psh8mwnw.js";import"./studio-a6e5fzve.js";import"./studio-9ndgd55w.js";export{gL as adoptCanvasPreviewMode,dL as allowAutoRequestsOnNextRender,Db as beginDragSession,pL as canvasIdleBlockers,mL as canvasPointAt,Kw as clearDropIndicator,Yw as commitActiveEditSession,GS as currentDragSession,$L as dragHostTab,Gw as endDragSession,hL as flushCanvasEdits,JS as getEditBarAnchorRect,ql as getEditSnapshot,Ul as hostDragGeometry,qS as hostForCanvas,SL as isCaretActive,Rb as liveDragHostAt,sP as measureInCanvas,IL as mountIframeCanvas,RL as mountStylebookCanvas,ML as panToStylebookTag,fL as pointerAnchor,ih as postApplyFormat,DL as postColorSchemeToLiveHosts,LL as postDialogOpen,Pc as postDragMessage,NL as postLocaleToLiveHosts,FL as postOpenSlash,KS as postPatchToHosts,TL as postPopoverOpen,AL as postRedefineElementToLiveHosts,OL as postSiteStyleToLiveHosts,Jw as postStyleUpdateToStylebookHosts,Ab as releaseCanvasHosts,uL as requestCanvasEval,Nb as revealCanvasPath,j2 as revealCanvasPathIn,cL as sawIframeDragOver,xL as setCanvasContextMenuHandler,kL as setCanvasPointerDownHandler,wL as setCanvasSlashHandler,yL as setFileDropHandler,EL as setIframePatchEscalation,vL as setInsertZoneClickHandler,PL as setKeymapSource,bL as setNativeDragEnterHandler,_L as setStylebookHitHandler,CL as setToolbarRefresh};
2
-
3
- //# debugId=9F3DF202CEAD816064756E2164756E21
4
- //# sourceMappingURL=iframe-host-q7fedsmr.js.map
@@ -1,4 +0,0 @@
1
- import{HI,BI,zI,WI,VI,wu,UI,Og,qI,Vf,GI,Uf,d2,X0,ck,u2,h2,p2,f2,xu,m2,g2,b2,dk,uk,v2,y2,w2,x2,hk,_2}from"./studio-3hpcawh8.js";import{yd,Q0,Mg,S2,ZI,XI,QI,eR,Pg,mk,gk}from"./studio-h4jbgne2.js";import{zs,eP}from"./studio-qevf5z9d.js";import{Se,oe,Tv,Lv}from"./studio-nfwacw31.js";export{VI as COLLAB_SCHEMA_VERSION,xu as CollabPathError,Pg as EnvelopeError,XI as FRAME_AWARENESS,eR as FRAME_CONTROL,QI as FRAME_DOC_CLOSE,ZI as FRAME_DOC_SYNC,BI as FRONTMATTER_KEY,h2 as LOCAL_ORIGIN,HI as META_KEY,p2 as MIRROR_ORIGIN,hk as PRESENCE_PALETTE,f2 as SEED_ORIGIN,WI as SOURCE_KEY,zI as STRUCTURE_KEY,S2 as UndoManager,yd as YDoc,v2 as acquireSourceCanonical,Lv as applyDocOpToDoc,m2 as applyDocOpsToY,dk as canonicalOf,uk as canonicalRevOf,Tv as childArray,Se as cloneValue,_2 as colorForKey,Mg as createAbsolutePositionFromRelativePosition,Q0 as createRelativePositionFromTypeIndex,gk as decodeFrame,zs as deepEqual,eP as diffDocs,mk as encodeFrame,UI as frontmatterMap,oe as getNodeAtPath,x2 as isSourceReconciler,wu as metaMap,w2 as otherSourceEditors,y2 as releaseSourceCanonical,b2 as replaceYStructure,X0 as resolveYPath,u2 as seedStructure,qI as sourceText,Og as structureMap,Vf as toYChildren,GI as toYNode,ck as updateSourceText,d2 as yDocToJson,g2 as yEventsToDocOps,Uf as yValueToJson};
2
-
3
- //# debugId=9E25003D3A34DBB764756E2164756E21
4
- //# sourceMappingURL=index-pt4wh98x.js.map
@@ -1,4 +0,0 @@
1
- import{X2,hm,Q2,Bu}from"./studio-jr30g4ae.js";export{X2 as applyProjectSchemas,hm as validateDoc,Q2 as validateDocOrNull,Bu as validateProjectConfig};
2
-
3
- //# debugId=A95888877705833464756E2164756E21
4
- //# sourceMappingURL=jx-validate-19y62knt.js.map