pinokiod 3.307.0 → 3.309.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.
@@ -587,6 +587,12 @@ const init = async (options, kernel) => {
587
587
  await fs.promises.writeFile(destination, rendered_recipe)
588
588
  }
589
589
  }
590
+ await fs.promises.writeFile(path.resolve(root, ".geminiignore"), `ENVIRONMENT
591
+ !/logs
592
+ !/GEMINI.md
593
+ !/SPEC.md
594
+ !/app
595
+ !${kernel.homedir}`)
590
596
  }
591
597
 
592
598
  const gitDir = path.resolve(root, ".git")
@@ -615,13 +621,14 @@ const init = async (options, kernel) => {
615
621
  "ENVIRONMENT",
616
622
  // ".*",
617
623
  // "~*",
618
- "/.pinokio-temp/",
619
- "/logs/",
620
- "/cache/",
624
+ "/.pinokio-temp",
625
+ "/logs",
626
+ "/cache",
621
627
  "/AGENTS.md",
622
628
  "/CLAUDE.md",
623
629
  "/GEMINI.md",
624
- "/QWEN.md"
630
+ "/QWEN.md",
631
+ "/.geminiignore"
625
632
  ]
626
633
 
627
634
  const missingEntries = entriesToEnsure.filter(entry => !existingEntries.has(entry))
package/kernel/index.js CHANGED
@@ -1035,7 +1035,7 @@ class Kernel {
1035
1035
  }
1036
1036
  }
1037
1037
  })
1038
- if (this.bin.installed.conda.has("git")) {
1038
+ if (this.bin.installed && this.bin.installed.conda && this.bin.installed.conda.has("git")) {
1039
1039
  await Promise.all([
1040
1040
  this.proto.init(),
1041
1041
  this.plugin.init(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "3.307.0",
3
+ "version": "3.309.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/server/index.js CHANGED
@@ -178,6 +178,46 @@ class Server {
178
178
  process.on('unhandledRejection', (reason) => invoke(reason, 'unhandledRejection'))
179
179
  this.fatalHandlersInstalled = true
180
180
  }
181
+
182
+ async ensureGitconfigDefaults(home) {
183
+ const gitconfigPath = path.resolve(home, "gitconfig")
184
+ const templatePath = path.resolve(__dirname, "..", "kernel", "gitconfig_template")
185
+ const required = [
186
+ { section: "init", key: "defaultBranch", value: "main" },
187
+ { section: "push", key: "autoSetupRemote", value: true },
188
+ ]
189
+
190
+ const exists = await this.kernel.exists(gitconfigPath)
191
+ if (!exists) {
192
+ await fs.promises.copyFile(templatePath, gitconfigPath)
193
+ return
194
+ }
195
+
196
+ let config
197
+ let dirty = false
198
+ try {
199
+ const content = await fs.promises.readFile(gitconfigPath, "utf8")
200
+ config = ini.parse(content)
201
+ } catch (e) {
202
+ config = {}
203
+ dirty = true
204
+ }
205
+
206
+ for (const { section, key, value } of required) {
207
+ if (!config[section]) {
208
+ config[section] = {}
209
+ }
210
+ const current = config[section][key]
211
+ if (String(current) !== String(value)) {
212
+ config[section][key] = value
213
+ dirty = true
214
+ }
215
+ }
216
+
217
+ if (dirty) {
218
+ await fs.promises.writeFile(gitconfigPath, ini.stringify(config))
219
+ }
220
+ }
181
221
  async handleFatalError(error, origin) {
182
222
  if (this.handlingFatalError) {
183
223
  console.error(`[Pinokiod] Additional fatal (${origin})`, (error && error.stack) ? error.stack : error)
@@ -219,20 +259,6 @@ class Server {
219
259
  } catch (err) {
220
260
  console.error('Failed to emit fatal notification:', err)
221
261
  }
222
- if (!this.fatalExitTimer) {
223
- this.fatalExitTimer = setTimeout(() => {
224
- try {
225
- this.shutdown('Fatal Error')
226
- } catch (shutdownErr) {
227
- console.error('Failed to shutdown after fatal error:', shutdownErr)
228
- }
229
- try {
230
- process.exit(1)
231
- } catch (_) {
232
- // ignore
233
- }
234
- }, 500)
235
- }
236
262
  }
237
263
  stop() {
238
264
  this.server.close()
@@ -4155,12 +4181,7 @@ class Server {
4155
4181
  let p4 = path.resolve(home, "network/system")
4156
4182
  await fse.remove(p4)
4157
4183
 
4158
- let gitconfig = path.resolve(home, "gitconfig")
4159
- await fse.remove(gitconfig)
4160
- await fs.promises.copyFile(
4161
- path.resolve(__dirname, "..", "kernel", "gitconfig_template"),
4162
- gitconfig
4163
- )
4184
+ await this.ensureGitconfigDefaults(home)
4164
4185
 
4165
4186
  let prototype_path = path.resolve(home, "prototype")
4166
4187
  await fse.remove(prototype_path)
@@ -2177,6 +2177,10 @@ body.dark {
2177
2177
  padding-top: 12px;
2178
2178
  }
2179
2179
 
2180
+ .pinokio-modal-footer--create {
2181
+ padding-top: 12px;
2182
+ }
2183
+
2180
2184
  .pinokio-modal-footer.pinokio-modal-footer--publish {
2181
2185
  display: none;
2182
2186
  padding-top: 12px;
@@ -2200,6 +2204,21 @@ body.dark {
2200
2204
  background: rgba(127, 91, 243, 1) !important;
2201
2205
  }
2202
2206
 
2207
+ .pinokio-modal-secondary-btn {
2208
+ padding: 10px 22px;
2209
+ border-radius: 999px;
2210
+ border: 1px solid rgba(127, 91, 243, 0.35);
2211
+ background: transparent;
2212
+ color: var(--pinokio-modal-body-text-color);
2213
+ font-weight: 600;
2214
+ cursor: pointer;
2215
+ }
2216
+
2217
+ .pinokio-modal-secondary-btn:hover {
2218
+ border-color: rgba(127, 91, 243, 0.6);
2219
+ color: #fff;
2220
+ }
2221
+
2203
2222
  .pinokio-modal-body--fork {
2204
2223
  display: flex;
2205
2224
  flex-direction: column;
@@ -5699,6 +5718,30 @@ const rerenderMenuSection = (container, html) => {
5699
5718
  return { owner: null, name: null, full: null }
5700
5719
  }
5701
5720
 
5721
+ function buildRemoteWebUrl(remoteUrl) {
5722
+ if (!remoteUrl || typeof remoteUrl !== 'string') {
5723
+ return null
5724
+ }
5725
+ const trimmed = remoteUrl.trim()
5726
+ if (!trimmed) {
5727
+ return null
5728
+ }
5729
+ if (/^https?:\/\//i.test(trimmed)) {
5730
+ return trimmed
5731
+ }
5732
+ const slug = parseRemoteSlug(trimmed)
5733
+ if (slug && slug.full) {
5734
+ return `https://github.com/${slug.full}`
5735
+ }
5736
+ if (trimmed.startsWith('git@')) {
5737
+ const sshSlug = parseRemoteSlug(trimmed.replace(/^git@/, '').replace(/:/, '/'))
5738
+ if (sshSlug && sshSlug.full) {
5739
+ return `https://github.com/${sshSlug.full}`
5740
+ }
5741
+ }
5742
+ return trimmed
5743
+ }
5744
+
5702
5745
  function deriveForkDefaultName(repo) {
5703
5746
  if (!repo) {
5704
5747
  return workspaceName || 'fork'
@@ -5986,16 +6029,30 @@ const rerenderMenuSection = (container, html) => {
5986
6029
  return repoData
5987
6030
  }
5988
6031
 
6032
+ const getRepoChangeCount = (repo) => {
6033
+ if (!repo) {
6034
+ return 0
6035
+ }
6036
+ if (typeof repo.changeCount === 'number') {
6037
+ return repo.changeCount
6038
+ }
6039
+ if (Array.isArray(repo.changes)) {
6040
+ return repo.changes.length
6041
+ }
6042
+ return 0
6043
+ }
6044
+
5989
6045
  async function ensureRemoteForPublish({ repoParam, repoName }) {
5990
6046
  const label = repoName || repoParam || 'Repository'
5991
6047
  const initialRepo = await getRepoData(repoParam)
5992
6048
  if (hasRemoteConfigured(initialRepo)) {
5993
- return true
6049
+ return { remoteReady: true, shouldOpenPublish: true }
5994
6050
  }
5995
6051
 
5996
- const creationResult = await showCreateModal({ skipReload: true })
5997
- if (!creationResult || creationResult.completed === false) {
5998
- return false
6052
+ const creationResult = await showCreateModal({ skipReload: true, repoParam, repoName })
6053
+ const action = creationResult && creationResult.action ? creationResult.action : null
6054
+ if (!creationResult || creationResult.completed === false || action === 'cancel') {
6055
+ return { remoteReady: false, shouldOpenPublish: false }
5999
6056
  }
6000
6057
 
6001
6058
  if (typeof check_git === 'function') {
@@ -6003,7 +6060,7 @@ const rerenderMenuSection = (container, html) => {
6003
6060
  }
6004
6061
  const refreshedRepo = await getRepoData(repoParam)
6005
6062
  if (hasRemoteConfigured(refreshedRepo)) {
6006
- return true
6063
+ return { remoteReady: true, shouldOpenPublish: true }
6007
6064
  }
6008
6065
 
6009
6066
  Swal.fire({
@@ -6011,7 +6068,7 @@ const rerenderMenuSection = (container, html) => {
6011
6068
  title: `${escapeHtml(label)} still needs a Git remote`,
6012
6069
  text: 'Add a remote (for example, origin) and try publishing again.'
6013
6070
  })
6014
- return false
6071
+ return { remoteReady: false, shouldOpenPublish: false }
6015
6072
  }
6016
6073
 
6017
6074
  const buildPublishPreflightCopy = (repoName, reason) => {
@@ -6037,6 +6094,65 @@ const rerenderMenuSection = (container, html) => {
6037
6094
  }
6038
6095
  }
6039
6096
 
6097
+ const promptCommitBeforePublish = async ({ repoParam, repoName }) => {
6098
+ const repoData = await getRepoData(repoParam)
6099
+ const changeCount = getRepoChangeCount(repoData)
6100
+ if (changeCount <= 0) {
6101
+ return { proceed: true, action: 'skip', changeCount }
6102
+ }
6103
+
6104
+ const displayName = repoName || (repoData && repoData.name) || repoParam || 'Repository'
6105
+ const safeName = escapeHtml(displayName)
6106
+ const result = await Swal.fire({
6107
+ html: `
6108
+ <div class="pinokio-modal-surface">
6109
+ <div class="pinokio-modal-header">
6110
+ <div class="pinokio-modal-icon"><i class="fa-solid fa-code-commit"></i></div>
6111
+ <div class="pinokio-modal-heading">
6112
+ <div class="pinokio-modal-title">Commit changes before publishing?</div>
6113
+ <div class="pinokio-modal-subtitle">${safeName} has ${changeCount} uncommitted change${changeCount === 1 ? '' : 's'}.</div>
6114
+ </div>
6115
+ </div>
6116
+ </div>
6117
+ `,
6118
+ customClass: {
6119
+ popup: 'pinokio-modern-modal',
6120
+ htmlContainer: 'pinokio-modern-html',
6121
+ confirmButton: 'pinokio-modern-confirm',
6122
+ cancelButton: 'pinokio-modern-cancel',
6123
+ closeButton: 'pinokio-modern-close'
6124
+ },
6125
+ backdrop: 'rgba(9,11,15,0.65)',
6126
+ width: 'min(520px, 92vw)',
6127
+ showCloseButton: true,
6128
+ showCancelButton: true,
6129
+ showConfirmButton: true,
6130
+ buttonsStyling: false,
6131
+ allowOutsideClick: false,
6132
+ allowEscapeKey: false,
6133
+ reverseButtons: true,
6134
+ confirmButtonText: 'Review & Commit',
6135
+ cancelButtonText: 'Continue without committing',
6136
+ focusConfirm: false
6137
+ })
6138
+
6139
+ if (result.isConfirmed) {
6140
+ try {
6141
+ await showGitDiffModal({ repoParam, repoName: displayName, forceRefresh: true })
6142
+ } catch (error) {
6143
+ console.error('Failed to open commit modal before publish:', error)
6144
+ }
6145
+ if (typeof check_git === 'function') {
6146
+ await check_git()
6147
+ }
6148
+ return { proceed: true, action: 'commit', changeCount }
6149
+ }
6150
+ if (result.dismiss === Swal.DismissReason.cancel) {
6151
+ return { proceed: true, action: 'skip', changeCount }
6152
+ }
6153
+ return { proceed: false, action: 'dismiss', changeCount }
6154
+ }
6155
+
6040
6156
  const showPublishPreflightModal = ({ title, message, actionLabel, onAction }) => {
6041
6157
  const safeTitle = escapeHtml(title || 'Repository is not ready to publish')
6042
6158
  const safeMessage = escapeHtml(message || 'Resolve the issue and try again.')
@@ -6081,6 +6197,59 @@ const rerenderMenuSection = (container, html) => {
6081
6197
  })
6082
6198
  }
6083
6199
 
6200
+ const handlePreflightFailure = ({ preflight, repoParam, repoName }) => {
6201
+ if (!preflight) {
6202
+ return
6203
+ }
6204
+ if (preflight.reason === 'network') {
6205
+ Swal.fire({
6206
+ icon: 'error',
6207
+ title: 'Unable to check repository state',
6208
+ text: 'Please try again in a moment.'
6209
+ })
6210
+ return
6211
+ }
6212
+ const copy = buildPublishPreflightCopy(repoName, preflight.reason)
6213
+ showPublishPreflightModal({
6214
+ title: copy.title,
6215
+ message: copy.message,
6216
+ actionLabel: copy.actionLabel,
6217
+ onAction: () => launchPublishPreflightDiffFlow({ repoParam, repoName })
6218
+ })
6219
+ }
6220
+
6221
+ const runPublishFlow = async ({ repoParam, repoName }) => {
6222
+ let preflight = await fetchPublishPreflightState(repoParam)
6223
+ if (!preflight.ok) {
6224
+ handlePreflightFailure({ preflight, repoParam, repoName })
6225
+ return
6226
+ }
6227
+
6228
+ const commitDecision = await promptCommitBeforePublish({ repoParam, repoName })
6229
+ if (!commitDecision || commitDecision.proceed !== true) {
6230
+ return
6231
+ }
6232
+
6233
+ if (commitDecision.action === 'commit') {
6234
+ preflight = await fetchPublishPreflightState(repoParam)
6235
+ if (!preflight.ok) {
6236
+ handlePreflightFailure({ preflight, repoParam, repoName })
6237
+ return
6238
+ }
6239
+ }
6240
+
6241
+ const remoteOutcome = await ensureRemoteForPublish({ repoParam, repoName })
6242
+ const remoteReady = typeof remoteOutcome === 'object'
6243
+ ? remoteOutcome.remoteReady
6244
+ : Boolean(remoteOutcome)
6245
+ const shouldOpenPublish = typeof remoteOutcome === 'object'
6246
+ ? remoteOutcome.shouldOpenPublish !== false
6247
+ : remoteReady
6248
+ if (remoteReady && shouldOpenPublish) {
6249
+ showPublishModal({ repoParam, repoName })
6250
+ }
6251
+ }
6252
+
6084
6253
  const launchPublishPreflightDiffFlow = async ({ repoParam, repoName }) => {
6085
6254
  try {
6086
6255
  await showGitDiffModal({ repoParam, repoName, forceRefresh: true })
@@ -6092,10 +6261,7 @@ const rerenderMenuSection = (container, html) => {
6092
6261
  const retryState = await fetchPublishPreflightState(repoParam)
6093
6262
  if (retryState.ok) {
6094
6263
  closeStatusDropdowns()
6095
- const remoteReady = await ensureRemoteForPublish({ repoParam, repoName })
6096
- if (remoteReady) {
6097
- showPublishModal({ repoParam, repoName })
6098
- }
6264
+ await runPublishFlow({ repoParam, repoName })
6099
6265
  }
6100
6266
  } catch (error) {
6101
6267
  console.error('Failed to retry publish after diff:', error)
@@ -6104,29 +6270,7 @@ const rerenderMenuSection = (container, html) => {
6104
6270
 
6105
6271
  const handlePublishDropdownClick = async ({ repoParam, repoName }) => {
6106
6272
  closeStatusDropdowns()
6107
- const preflight = await fetchPublishPreflightState(repoParam)
6108
- if (preflight.ok) {
6109
- const remoteReady = await ensureRemoteForPublish({ repoParam, repoName })
6110
- if (remoteReady) {
6111
- showPublishModal({ repoParam, repoName })
6112
- }
6113
- return
6114
- }
6115
- if (preflight.reason === 'network') {
6116
- Swal.fire({
6117
- icon: 'error',
6118
- title: 'Unable to check repository state',
6119
- text: 'Please try again in a moment.'
6120
- })
6121
- return
6122
- }
6123
- const copy = buildPublishPreflightCopy(repoName, preflight.reason)
6124
- showPublishPreflightModal({
6125
- title: copy.title,
6126
- message: copy.message,
6127
- actionLabel: copy.actionLabel,
6128
- onAction: () => launchPublishPreflightDiffFlow({ repoParam, repoName })
6129
- })
6273
+ await runPublishFlow({ repoParam, repoName })
6130
6274
  }
6131
6275
 
6132
6276
  const renderPublishDropdown = (repos, options = {}) => {
@@ -7302,10 +7446,28 @@ const rerenderMenuSection = (container, html) => {
7302
7446
  const iframe = popup.querySelector('iframe')
7303
7447
  const footer = popup.querySelector('[data-publish-footer]')
7304
7448
  const closeBtn = popup.querySelector('[data-publish-close]')
7449
+ const viewBtn = popup.querySelector('[data-publish-view-remote]')
7450
+ const remoteHref = viewBtn ? viewBtn.getAttribute('data-remote-url') : null
7305
7451
 
7306
7452
  if (closeBtn) {
7307
7453
  closeBtn.addEventListener('click', () => Swal.close())
7308
7454
  }
7455
+ if (viewBtn) {
7456
+ if (remoteHref) {
7457
+ viewBtn.addEventListener('click', (event) => {
7458
+ event.preventDefault()
7459
+ event.stopPropagation()
7460
+ try {
7461
+ window.open(remoteHref, '_blank', 'browser')
7462
+ } catch (error) {
7463
+ console.error('Failed to open remote URL:', error)
7464
+ }
7465
+ })
7466
+ } else {
7467
+ viewBtn.disabled = true
7468
+ viewBtn.setAttribute('title', 'Remote URL not available')
7469
+ }
7470
+ }
7309
7471
 
7310
7472
  if (iframe) {
7311
7473
  iframe.dataset.forceVisible = 'true'
@@ -7388,12 +7550,17 @@ const rerenderMenuSection = (container, html) => {
7388
7550
  return
7389
7551
  }
7390
7552
 
7391
- const remoteDisplay = repoData && repoData.url ? escapeHtml(repoData.url) : null
7553
+ const remoteUrl = repoData && typeof repoData.url === 'string' ? repoData.url.trim() : ''
7554
+ const remoteWebUrl = buildRemoteWebUrl(remoteUrl)
7555
+ const remoteDisplay = remoteUrl ? escapeHtml(remoteUrl) : null
7392
7556
  const subtitle = `${escapeHtml(repoLabel)} — review your latest changes before publishing.`
7393
7557
  const remoteHtml = remoteDisplay ? `<div class="pinokio-fork-item-url">${remoteDisplay}</div>` : ''
7394
7558
  const timestampedUri = pushUri.includes('?')
7395
7559
  ? `${pushUri}&ts=${Date.now()}`
7396
7560
  : `${pushUri}?ts=${Date.now()}`
7561
+ const viewRemoteButton = remoteWebUrl
7562
+ ? `<button type="button" class="pinokio-modal-secondary-btn" data-publish-view-remote data-remote-url="${escapeHtml(remoteWebUrl)}">View on GitHub</button>`
7563
+ : ''
7397
7564
 
7398
7565
  const modalHtml = `
7399
7566
  <div class="pinokio-modal-surface">
@@ -7409,6 +7576,7 @@ const rerenderMenuSection = (container, html) => {
7409
7576
  <iframe src="${timestampedUri}"></iframe>
7410
7577
  </div>
7411
7578
  <div class="pinokio-modal-footer pinokio-modal-footer--publish" data-publish-footer>
7579
+ ${viewRemoteButton}
7412
7580
  <button type="button" class="pinokio-publish-close-btn" data-publish-close>Close</button>
7413
7581
  </div>
7414
7582
  </div>
@@ -7598,11 +7766,13 @@ const rerenderMenuSection = (container, html) => {
7598
7766
  backdrop: 'rgba(9,11,15,0.65)',
7599
7767
  width: 'min(520px, 90vw)',
7600
7768
  buttonsStyling: false,
7601
- showCloseButton: true,
7769
+ showCloseButton: false,
7602
7770
  showConfirmButton: true,
7603
7771
  showCancelButton: true,
7604
7772
  confirmButtonText: 'Create on GitHub',
7605
7773
  cancelButtonText: 'Cancel',
7774
+ allowOutsideClick: false,
7775
+ allowEscapeKey: false,
7606
7776
  focusConfirm: false,
7607
7777
  preConfirm: () => {
7608
7778
  const repoName = document.getElementById('create-repo-name-input').value.trim()
@@ -7623,21 +7793,14 @@ const rerenderMenuSection = (container, html) => {
7623
7793
 
7624
7794
  return createRepoModalPromise.then((result) => {
7625
7795
  if (!result || !result.isConfirmed) {
7626
- return { completed: false, result }
7796
+ return { completed: false, action: 'cancel', result }
7627
7797
  }
7628
7798
  const { name, isPrivate } = result.value
7629
- return showCreateRepoIframeModal(name, isPrivate, opts).then((iframeResult) => {
7630
- if (iframeResult && iframeResult.completed === false) {
7631
- return { completed: false, result: iframeResult }
7632
- }
7633
- return { completed: true, result: iframeResult }
7634
- })
7799
+ return showCreateRepoIframeModal(name, isPrivate, opts)
7635
7800
  })
7636
7801
  }
7637
7802
 
7638
7803
  const showCreateRepoIframeModal = (name, isPrivate, options = {}) => {
7639
- const opts = typeof options === 'object' && options !== null ? options : {}
7640
- const skipReload = Boolean(opts.skipReload)
7641
7804
  const createUri = document.querySelector('#fs-status').getAttribute('data-create-uri')
7642
7805
 
7643
7806
  if (!createUri) {
@@ -7654,40 +7817,71 @@ const rerenderMenuSection = (container, html) => {
7654
7817
  urlParams.append('visibility', isPrivate ? 'private' : 'public')
7655
7818
 
7656
7819
  const finalUri = `${createUri}${createUri.includes('?') ? '&' : '?'}${urlParams.toString()}`
7657
-
7658
- const createRepoIframePromise = Swal.fire({
7659
- html: `
7660
- <div class="pinokio-modal-surface">
7661
- <div class="pinokio-modal-header">
7662
- <div class="pinokio-modal-icon"><i class="fa-brands fa-github"></i></div>
7663
- <div class="pinokio-modal-heading">
7664
- <div class="pinokio-modal-title">Create GitHub repository</div>
7665
- <div class="pinokio-modal-subtitle">${name} · ${isPrivate ? 'Private' : 'Public'}</div>
7820
+
7821
+ return new Promise((resolve) => {
7822
+ let resolved = false
7823
+ const finalize = (payload) => {
7824
+ if (resolved) {
7825
+ return
7826
+ }
7827
+ resolved = true
7828
+ resolve(payload)
7829
+ }
7830
+
7831
+ Swal.fire({
7832
+ html: `
7833
+ <div class="pinokio-modal-surface">
7834
+ <div class="pinokio-modal-header">
7835
+ <div class="pinokio-modal-icon"><i class="fa-brands fa-github"></i></div>
7836
+ <div class="pinokio-modal-heading">
7837
+ <div class="pinokio-modal-title">Create GitHub repository</div>
7838
+ <div class="pinokio-modal-subtitle">${name} · ${isPrivate ? 'Private' : 'Public'}</div>
7839
+ </div>
7840
+ </div>
7841
+ <div class="pinokio-modal-body pinokio-modal-body--iframe">
7842
+ <iframe src="${finalUri}"></iframe>
7843
+ </div>
7844
+ <div class="pinokio-modal-footer pinokio-modal-footer--create">
7845
+ <button type="button" class="pinokio-modal-secondary-btn" data-create-cancel>Cancel</button>
7846
+ <button type="button" class="pinokio-publish-close-btn" data-create-next>Next</button>
7666
7847
  </div>
7667
7848
  </div>
7668
- <div class="pinokio-modal-body pinokio-modal-body--iframe">
7669
- <iframe src="${finalUri}"></iframe>
7670
- </div>
7671
- </div>
7672
- `,
7673
- customClass: {
7674
- popup: 'pinokio-modern-modal',
7675
- htmlContainer: 'pinokio-modern-html',
7676
- closeButton: 'pinokio-modern-close'
7677
- },
7678
- backdrop: 'rgba(9,11,15,0.65)',
7679
- width: 'min(760px, 90vw)',
7680
- showConfirmButton: false,
7681
- showCloseButton: true,
7682
- buttonsStyling: false,
7683
- focusConfirm: false
7849
+ `,
7850
+ customClass: {
7851
+ popup: 'pinokio-modern-modal',
7852
+ htmlContainer: 'pinokio-modern-html',
7853
+ closeButton: 'pinokio-modern-close'
7854
+ },
7855
+ backdrop: 'rgba(9,11,15,0.65)',
7856
+ width: 'min(760px, 90vw)',
7857
+ showConfirmButton: false,
7858
+ showCancelButton: false,
7859
+ showCloseButton: false,
7860
+ buttonsStyling: false,
7861
+ allowOutsideClick: false,
7862
+ allowEscapeKey: false,
7863
+ focusConfirm: false,
7864
+ didOpen: (popup) => {
7865
+ const nextBtn = popup.querySelector('[data-create-next]')
7866
+ const cancelBtn = popup.querySelector('[data-create-cancel]')
7867
+ if (nextBtn) {
7868
+ nextBtn.addEventListener('click', () => {
7869
+ finalize({ completed: true, action: 'next', name, isPrivate })
7870
+ Swal.close()
7871
+ })
7872
+ }
7873
+ if (cancelBtn) {
7874
+ cancelBtn.addEventListener('click', () => {
7875
+ finalize({ completed: false, action: 'cancel', name, isPrivate })
7876
+ Swal.close()
7877
+ })
7878
+ }
7879
+ },
7880
+ willClose: () => {
7881
+ finalize({ completed: false, action: 'dismissed', name, isPrivate })
7882
+ }
7883
+ }).then(() => {})
7684
7884
  })
7685
-
7686
- if (!skipReload) {
7687
- reloadOnModalClose(createRepoIframePromise)
7688
- }
7689
-
7690
- return createRepoIframePromise
7691
7885
  }
7692
7886
 
7693
7887
  async function showForkModalForRepo(repoParam) {