@crowdedkingdoms/crowdyjs 16.2.0 → 17.0.1-dev.1

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 (47) hide show
  1. package/MIGRATION.md +79 -0
  2. package/README.md +1 -1
  3. package/dist/crowdy-dsh/bridge.d.ts +1 -0
  4. package/dist/crowdy-dsh/bridge.d.ts.map +1 -1
  5. package/dist/crowdy-dsh/bridge.js +37 -12
  6. package/dist/crowdy-dsh/protocol.d.ts +25 -5
  7. package/dist/crowdy-dsh/protocol.d.ts.map +1 -1
  8. package/dist/crowdy-dsh/protocol.js +9 -1
  9. package/dist/crowdy-studio/controller.d.ts +22 -16
  10. package/dist/crowdy-studio/controller.d.ts.map +1 -1
  11. package/dist/crowdy-studio/controller.js +55 -72
  12. package/dist/crowdy-studio/dom-shell.d.ts +1 -2
  13. package/dist/crowdy-studio/dom-shell.d.ts.map +1 -1
  14. package/dist/crowdy-studio/dom-shell.js +35 -29
  15. package/dist/crowdy-studio/embed/panel.d.ts +10 -0
  16. package/dist/crowdy-studio/embed/panel.d.ts.map +1 -1
  17. package/dist/crowdy-studio/embed/panel.js +3 -1
  18. package/dist/crowdy-studio/github/index.d.ts +2 -2
  19. package/dist/crowdy-studio/github/index.d.ts.map +1 -1
  20. package/dist/crowdy-studio/github/index.js +1 -1
  21. package/dist/crowdy-studio/github/layout.d.ts +22 -0
  22. package/dist/crowdy-studio/github/layout.d.ts.map +1 -0
  23. package/dist/crowdy-studio/github/layout.js +66 -0
  24. package/dist/crowdy-studio/github/transport.d.ts +67 -9
  25. package/dist/crowdy-studio/github/transport.d.ts.map +1 -1
  26. package/dist/crowdy-studio/github/transport.js +61 -17
  27. package/dist/crowdy-studio/models.d.ts +29 -0
  28. package/dist/crowdy-studio/models.d.ts.map +1 -1
  29. package/dist/crowdy-studio/models.js +1 -0
  30. package/dist/default-origin.d.ts +6 -6
  31. package/dist/default-origin.d.ts.map +1 -1
  32. package/dist/default-origin.js +6 -6
  33. package/dist/domains/crowdyStudio.d.ts +25 -3
  34. package/dist/domains/crowdyStudio.d.ts.map +1 -1
  35. package/dist/domains/crowdyStudio.js +183 -10
  36. package/dist/generated/graphql.d.ts +148 -30
  37. package/dist/generated/graphql.d.ts.map +1 -1
  38. package/dist/generated/graphql.js +25 -9
  39. package/dist/index.d.ts +1 -1
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +1 -1
  42. package/dist/kit/npcs.d.ts.map +1 -1
  43. package/dist/kit/social.d.ts.map +1 -1
  44. package/package.json +1 -1
  45. package/dist/crowdy-studio/github/sync.d.ts +0 -49
  46. package/dist/crowdy-studio/github/sync.d.ts.map +0 -1
  47. package/dist/crowdy-studio/github/sync.js +0 -200
@@ -1,7 +1,6 @@
1
1
  import { PlayerCodeBroker, } from '../player-runtime/player-code-broker.js';
2
2
  import { digestCanonicalJson, sha256Digest, } from '../player-host/json-schema.js';
3
3
  import { parseRustcDiagnostics } from './diagnostics.js';
4
- import { mergeStudioFilesFromGitHub, pullStudioFilesFromGitHub, pushStudioFilesToGitHub, } from './github/sync.js';
5
4
  import { cloneCrowdyStudioProject, crowdyStudioFileKey, normalizeCrowdyStudioPath, projectTargets, CrowdyStudioOfflineError, CrowdyStudioRevisionConflictError, } from './models.js';
6
5
  import { createCrowdyStudioStarterProject, } from './starter-projects.js';
7
6
  class OperationCancelledError extends Error {
@@ -52,9 +51,8 @@ export class CrowdyStudioController {
52
51
  this.surfaceTimers = new Map();
53
52
  this.pageVisible = true;
54
53
  this.destroyed = false;
55
- // ----- GitHub repository loop ------------------------------------------
54
+ // ----- GitHub repository card ------------------------------------------
56
55
  this.githubStatusGeneration = 0;
57
- this.suppressGitHubPush = false;
58
56
  if (options.onStateChange)
59
57
  this.listeners.add(options.onStateChange);
60
58
  }
@@ -445,7 +443,7 @@ export class CrowdyStudioController {
445
443
  this.savePromise = null;
446
444
  }
447
445
  }
448
- /** Re-read connection + bind for the open project. Never pulls on its own. */
446
+ /** Re-read connection + bind for the open project. Never changes files on its own. */
449
447
  async refreshGitHubStatus() {
450
448
  if (!this.options.github)
451
449
  return;
@@ -479,13 +477,22 @@ export class CrowdyStudioController {
479
477
  this.update({ githubMessage: 'Finish installing on GitHub in the new tab, then Refresh.' });
480
478
  return connectUrl;
481
479
  }
482
- /** `owner/repo` or `owner/repo@branch`. */
483
- async bindGitHubRepo(slug) {
480
+ /**
481
+ * Bind the open project to `owner/repo` or `owner/repo@branch`, choosing
482
+ * which side is the truth for the first commit. Refuses over unsaved edits
483
+ * so what is pushed (or replaced) is exactly what the server holds. The
484
+ * project is re-read afterwards: TAKE_REPOSITORY replaced its files, and
485
+ * both paths gave it a `github.sha`.
486
+ */
487
+ async bindGitHubRepo(slug, initial = 'PUSH_PROJECT') {
484
488
  if (!this.options.github)
485
489
  throw new Error('GitHub is not available in this Studio.');
486
490
  const scope = this.githubScope();
487
491
  if (!scope)
488
492
  throw new Error('Open a Studio project before binding a repository.');
493
+ if (this.editGeneration !== this.persistedGeneration) {
494
+ throw new Error('Save Studio edits before binding a repository.');
495
+ }
489
496
  const trimmed = slug.trim();
490
497
  const at = trimmed.lastIndexOf('@');
491
498
  const repoPath = at > 0 ? trimmed.slice(0, at) : trimmed;
@@ -501,98 +508,73 @@ export class CrowdyStudioController {
501
508
  owner: repoPath.slice(0, slash),
502
509
  repo: repoPath.slice(slash + 1),
503
510
  ...(branch ? { branch } : {}),
511
+ initial,
512
+ });
513
+ await this.reloadProject();
514
+ this.update({
515
+ github,
516
+ githubMessage: initial === 'PUSH_PROJECT'
517
+ ? `Pushed the project to ${github.owner}/${github.repo}@${github.branch}. It is the working tree now; edits commit as you save.`
518
+ : `Took ${github.owner}/${github.repo}@${github.branch} as the project. Edits commit as you save.`,
504
519
  });
505
- this.update({ github, githubMessage: `Bound ${github.owner}/${github.repo}@${github.branch}. Autosave push is off until you turn it on.` });
506
520
  }
507
521
  finally {
508
522
  this.update({ githubBusy: false });
509
523
  }
510
524
  }
525
+ /** Clear the bind. The files stay; the project is a Studio project again. */
511
526
  async unbindGitHub() {
512
527
  if (!this.options.github)
513
528
  return;
514
529
  const scope = this.githubScope();
515
530
  if (!scope)
516
531
  return;
517
- const github = await this.options.github.unbind(scope);
518
- this.update({ github, githubMessage: 'Repository unbound. Files in Studio are unchanged.' });
519
- }
520
- /** Opt the open project into (or out of) pushing autosaves. Default off. */
521
- async setGitHubAutosave(autosave) {
522
- if (!this.options.github)
523
- return;
524
- const scope = this.githubScope();
525
- if (!scope)
532
+ if (this.editGeneration !== this.persistedGeneration) {
533
+ this.update({ githubMessage: 'Save edits before unbinding.' });
526
534
  return;
527
- const github = await this.options.github.setAutosave({ ...scope, autosave });
528
- this.update({
529
- github,
530
- githubMessage: autosave ? 'Autosave now also pushes to GitHub.' : 'Autosave push is off.',
531
- });
532
- }
533
- /** Explicit push of the current files (or a subset) to the bound repository. */
534
- async pushToGitHub(files, opts = {}) {
535
- if (!this.options.github)
536
- return 0;
537
- const scope = this.githubScope();
538
- if (!scope || !this.state.github?.owner) {
539
- if (!opts.quiet)
540
- this.update({ githubMessage: 'Bind a repository first.' });
541
- return 0;
542
535
  }
543
- const toPush = files ?? this.state.project?.files ?? [];
544
536
  this.update({ githubBusy: true });
545
537
  try {
546
- const pushed = await pushStudioFilesToGitHub(this.options.github, scope, toPush);
547
- this.update({
548
- githubMessage: pushed > 0 ? `Pushed ${pushed} file${pushed === 1 ? '' : 's'} to GitHub.` : 'GitHub already has these files.',
549
- });
550
- return pushed;
551
- }
552
- catch (error) {
553
- this.update({ githubMessage: `GitHub push failed: ${errorMessage(error)}` });
554
- return 0;
538
+ const github = await this.options.github.unbind(scope);
539
+ await this.reloadProject();
540
+ this.update({ github, githubMessage: 'Repository unbound. The files stay in Studio.' });
555
541
  }
556
542
  finally {
557
543
  this.update({ githubBusy: false });
558
544
  }
559
545
  }
560
- /** Explicit pull: overlay the repository onto the project, then save. Refuses over unsaved edits. */
561
- async pullFromGitHub() {
546
+ /**
547
+ * Bring the project to the branch head after a push made outside Studio.
548
+ * Refuses over unsaved edits (they would be committed against the old head
549
+ * and refused anyway, less legibly).
550
+ */
551
+ async refreshFromGitHub() {
562
552
  if (!this.options.github)
563
553
  return false;
564
554
  const scope = this.githubScope();
565
- const project = this.state.project;
566
- if (!scope || !project || !this.state.github?.owner) {
555
+ if (!scope || !this.state.project?.github) {
567
556
  this.update({ githubMessage: 'Bind a repository first.' });
568
557
  return false;
569
558
  }
570
559
  if (this.editGeneration !== this.persistedGeneration) {
571
- this.update({ githubMessage: 'Save Studio edits before pulling from GitHub.' });
560
+ this.update({ githubMessage: 'Save Studio edits before refreshing from GitHub.' });
572
561
  return false;
573
562
  }
574
563
  this.update({ githubBusy: true });
575
564
  try {
576
- const incoming = await pullStudioFilesFromGitHub(this.options.github, scope);
577
- const { files, changed } = mergeStudioFilesFromGitHub(project.files, incoming.files);
578
- if (!changed) {
579
- this.update({ githubMessage: 'GitHub is in sync.' });
580
- return true;
581
- }
582
- project.files = files;
583
- this.editGeneration += 1;
584
- this.update({ project, githubMessage: 'Pulled from GitHub.' });
585
- this.suppressGitHubPush = true;
586
- try {
587
- await this.saveNow();
588
- }
589
- finally {
590
- this.suppressGitHubPush = false;
591
- }
565
+ const before = this.state.project.github.sha;
566
+ const github = await this.options.github.refresh(scope);
567
+ await this.reloadProject();
568
+ this.update({
569
+ github,
570
+ githubMessage: github.githubSha === before
571
+ ? 'Already at the branch head.'
572
+ : `Refreshed to ${github.githubSha?.slice(0, 7) ?? 'head'}.`,
573
+ });
592
574
  return true;
593
575
  }
594
576
  catch (error) {
595
- this.update({ githubMessage: `GitHub pull failed: ${errorMessage(error)}` });
577
+ this.update({ githubMessage: `GitHub refresh failed: ${errorMessage(error)}` });
596
578
  return false;
597
579
  }
598
580
  finally {
@@ -937,16 +919,15 @@ export class CrowdyStudioController {
937
919
  message: `Submitting ${name}`,
938
920
  },
939
921
  });
940
- // This is the sole project→legacy wire conversion. Project state, provider
941
- // contracts, editors, and templates all use typed files.
942
- const sourceFilesJson = JSON.stringify(Object.fromEntries(files.map((file) => [file.path, file.content])));
922
+ // The server resolves the source from the project itself: the saved
923
+ // files at the project revision, or — for a GITHUB project — the rust at
924
+ // the commit the mirror is at. No file bodies travel with a deploy.
943
925
  const deployed = await this.options.playerCompute.deploy({
944
926
  ...this.scope(),
927
+ projectId: project.projectId,
945
928
  name,
946
929
  target: target,
947
- sourceFilesJson,
948
- sdkVersion: project.sdkVersion,
949
- abiVersion: project.abiVersion,
930
+ ...(project.github?.sha ? { commitSha: project.github.sha } : {}),
950
931
  tickHz: target === 'SERVER' ? 1 : undefined,
951
932
  draft,
952
933
  });
@@ -1199,9 +1180,6 @@ export class CrowdyStudioController {
1199
1180
  this.state.project.revision = { ...saved.revision };
1200
1181
  this.state.project.updatedAt = saved.updatedAt;
1201
1182
  }
1202
- if (this.state.github?.autosave && !this.suppressGitHubPush) {
1203
- void this.pushToGitHub(snapshot.files, { quiet: true });
1204
- }
1205
1183
  this.update({
1206
1184
  projects: upsertSummary(this.state.projects, summaryOf(saved)),
1207
1185
  saveState: this.persistedGeneration === this.editGeneration ? 'SAVED' : 'SAVING',
@@ -1434,6 +1412,11 @@ function summaryOf(project) {
1434
1412
  name: project.metadata.name,
1435
1413
  kind: project.kind,
1436
1414
  revisionId: project.revision.id,
1415
+ source: project.source,
1416
+ ...(project.github
1417
+ ? { github: `${project.github.owner}/${project.github.repo}@${project.github.branch}` }
1418
+ : {}),
1419
+ githubSha: project.github?.sha ?? null,
1437
1420
  ...(project.metadata.serverModuleName
1438
1421
  ? { serverModuleName: project.metadata.serverModuleName }
1439
1422
  : {}),
@@ -61,8 +61,7 @@ export declare class CrowdyStudioDomShell {
61
61
  private readonly githubBindInput;
62
62
  private readonly githubBind;
63
63
  private readonly githubUnbind;
64
- private readonly githubAutosave;
65
- private readonly githubPush;
64
+ private readonly githubInitial;
66
65
  private readonly githubPull;
67
66
  private readonly githubRefresh;
68
67
  private readonly githubMessage;
@@ -1 +1 @@
1
- {"version":3,"file":"dom-shell.d.ts","sourceRoot":"","sources":["../../src/crowdy-studio/dom-shell.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dom-shell.d.ts","sourceRoot":"","sources":["../../src/crowdy-studio/dom-shell.ts"],"names":[],"mappings":"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"}
@@ -123,9 +123,12 @@ export class CrowdyStudioDomShell {
123
123
  ]);
124
124
  this.settings.append(settingsTitle, labeled('Name', this.settingsName), labeled('Description', this.settingsDescription), labeled('Server module', this.serverModuleName), labeled('Client module', this.clientModuleName), labeled('Pairing', this.pairing));
125
125
  // ----- GitHub repository card -------------------------------------------
126
- // Bring-your-own repo. The repository is resolved server-side from the
127
- // project's bind; the card never learns a token. Autosave push is off
128
- // until the owner turns it on here.
126
+ // Bring-your-own repo, never required. The repository is resolved
127
+ // server-side from the project's bind; the card never learns a token.
128
+ // Once bound the repository IS the working tree: every save commits, so
129
+ // there is no push, no pull and no autosave toggle here — only bind (with
130
+ // a choice of which side is the truth on day one), unbind, and a refresh
131
+ // that brings the project to the branch head after a push made elsewhere.
129
132
  this.github = element('section', 'ck-crowdy-studio-github');
130
133
  const githubTitle = element('h3');
131
134
  githubTitle.textContent = 'GitHub repository';
@@ -135,10 +138,21 @@ export class CrowdyStudioDomShell {
135
138
  void this.controller.connectGitHub().catch((error) => this.githubNote(error));
136
139
  });
137
140
  this.githubBindInput = input('owner/repo or owner/repo@branch');
141
+ this.githubInitial = document.createElement('select');
142
+ this.githubInitial.className = 'ck-crowdy-studio-github-initial';
143
+ for (const [value, label] of [
144
+ ['PUSH_PROJECT', 'Push this project into the repository'],
145
+ ['TAKE_REPOSITORY', 'Take the repository as this project'],
146
+ ]) {
147
+ const option = document.createElement('option');
148
+ option.value = value;
149
+ option.textContent = label;
150
+ this.githubInitial.append(option);
151
+ }
138
152
  this.githubBind = button('Bind');
139
153
  this.githubBind.addEventListener('click', () => {
140
154
  void this.controller
141
- .bindGitHubRepo(this.githubBindInput.value)
155
+ .bindGitHubRepo(this.githubBindInput.value, this.githubInitial.value === 'TAKE_REPOSITORY' ? 'TAKE_REPOSITORY' : 'PUSH_PROJECT')
142
156
  .then(() => {
143
157
  this.githubBindInput.value = '';
144
158
  })
@@ -148,31 +162,20 @@ export class CrowdyStudioDomShell {
148
162
  this.githubUnbind.addEventListener('click', () => {
149
163
  void this.controller.unbindGitHub().catch((error) => this.githubNote(error));
150
164
  });
151
- this.githubAutosave = document.createElement('input');
152
- this.githubAutosave.type = 'checkbox';
153
- this.githubAutosave.addEventListener('change', () => {
154
- void this.controller
155
- .setGitHubAutosave(this.githubAutosave.checked)
156
- .catch((error) => this.githubNote(error));
157
- });
158
- this.githubPush = button('Push to GitHub');
159
- this.githubPush.addEventListener('click', () => {
160
- void this.controller.pushToGitHub();
161
- });
162
- this.githubPull = button('Pull from GitHub');
165
+ this.githubPull = button('Refresh from GitHub');
163
166
  this.githubPull.addEventListener('click', () => {
164
- void this.controller.pullFromGitHub();
167
+ void this.controller.refreshFromGitHub();
165
168
  });
166
- this.githubRefresh = button('Refresh');
169
+ this.githubRefresh = button('Refresh status');
167
170
  this.githubRefresh.addEventListener('click', () => {
168
171
  void this.controller.refreshGitHubStatus();
169
172
  });
170
173
  this.githubMessage = element('p', 'ck-crowdy-studio-github-message');
171
174
  const bindRow = element('div', 'ck-crowdy-studio-github-row');
172
- bindRow.append(this.githubBindInput, this.githubBind, this.githubUnbind);
175
+ bindRow.append(this.githubBindInput, this.githubInitial, this.githubBind, this.githubUnbind);
173
176
  const syncRow = element('div', 'ck-crowdy-studio-github-row');
174
- syncRow.append(this.githubPush, this.githubPull, this.githubRefresh);
175
- this.github.append(githubTitle, this.githubStatus, this.githubConnect, bindRow, labeled('Also push autosaves to GitHub', this.githubAutosave), syncRow, this.githubMessage);
177
+ syncRow.append(this.githubPull, this.githubRefresh);
178
+ this.github.append(githubTitle, this.githubStatus, this.githubConnect, bindRow, syncRow, this.githubMessage);
176
179
  this.github.hidden = true;
177
180
  this.settings.append(this.github);
178
181
  this.workspace.append(rail, this.explorer, this.paneSplitter('explorer', 'vertical', 'before', 'Resize the file explorer'), this.editorColumn, this.paneSplitter('settings', 'vertical', 'after', 'Resize project settings'), this.settings);
@@ -836,22 +839,25 @@ export class CrowdyStudioDomShell {
836
839
  }
837
840
  this.github.hidden = false;
838
841
  const bound = Boolean(github.owner && github.repo);
842
+ const sha = github.githubSha ? ` @ ${github.githubSha.slice(0, 7)}` : '';
839
843
  this.githubStatus.textContent = !github.connected
840
- ? 'Not connected. Install the Crowdy Studio app on your GitHub account to bind a repository you own.'
844
+ ? 'Not connected. Install the Crowdy Studio app on your GitHub account to bind a repository you own. GitHub is optional; the project saves in Studio either way.'
841
845
  : bound
842
- ? `${github.accountLogin ?? 'GitHub'} · bound to ${github.owner}/${github.repo}@${github.branch}`
846
+ ? `${github.accountLogin ?? 'GitHub'} · ${github.owner}/${github.repo}@${github.branch}${sha} is the working tree; saves commit to it.`
843
847
  : `${github.accountLogin ?? 'GitHub'} connected · no repository bound`;
844
848
  this.githubConnect.hidden = github.connected;
845
849
  this.githubConnect.disabled = state.githubBusy;
846
- const canBind = github.connected && Boolean(state.project) && !state.githubBusy;
850
+ const canBind = github.connected && Boolean(state.project) && !bound && !state.githubBusy && state.saveState === 'SAVED';
851
+ this.githubBindInput.hidden = bound;
852
+ this.githubInitial.hidden = bound;
853
+ this.githubBind.hidden = bound;
847
854
  this.githubBindInput.disabled = !canBind;
855
+ this.githubInitial.disabled = !canBind;
848
856
  this.githubBind.disabled = !canBind;
849
857
  this.githubUnbind.hidden = !bound;
850
- this.githubUnbind.disabled = state.githubBusy;
851
- this.githubAutosave.disabled = !bound || state.githubBusy;
852
- this.githubAutosave.checked = github.autosave;
853
- this.githubPush.disabled = !bound || state.githubBusy;
854
- this.githubPull.disabled = !bound || state.githubBusy || state.saveState !== 'SAVED';
858
+ this.githubUnbind.disabled = state.githubBusy || state.saveState !== 'SAVED';
859
+ this.githubPull.hidden = !bound;
860
+ this.githubPull.disabled = state.githubBusy || state.saveState !== 'SAVED';
855
861
  this.githubRefresh.disabled = state.githubBusy;
856
862
  this.githubMessage.textContent = state.githubMessage ?? '';
857
863
  }
@@ -57,6 +57,16 @@ export interface CrowdyStudioEmbedOptions {
57
57
  closeKeyCode?: string | null;
58
58
  /** Studio agent pane (DeepSeek Harness in the browser); omission hides it. */
59
59
  dsh?: CrowdyStudioEmbedDshOptions;
60
+ /**
61
+ * GitHub repository card transport. Defaults to `client.crowdyStudioGitHub`
62
+ * — the same app-token client that plays, which is what every game should
63
+ * use: the API scopes every GitHub field to projects that token's user owns
64
+ * and needs no identity session for them. Hosted first-party Studio, which
65
+ * does hold an identity session, may pass its own. Omit both to hide the
66
+ * card. Persistence of a bound project's files does not go through this;
67
+ * the project provider commits them.
68
+ */
69
+ github?: CrowdyStudioGitHubTransport;
60
70
  /**
61
71
  * Suppress gameplay input and return a restoration callback. Used only by
62
72
  * the narrow-screen modal; the desktop dock remains non-modal.
@@ -1 +1 @@
1
- {"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../../src/crowdy-studio/embed/panel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../../src/crowdy-studio/embed/panel.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC9B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EACV,sBAAsB,EACtB,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAKL,KAAK,4BAA4B,EAClC,MAAM,WAAW,CAAC;AAEnB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAO1D,MAAM,MAAM,4BAA4B,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEnE;;;GAGG;AACH,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,2BAA2B,CAAC;IAC1C,aAAa,EAAE,yBAAyB,CAAC;IACzC,YAAY,CAAC,EAAE,wBAAwB,CAAC;IACxC,mFAAmF;IACnF,kBAAkB,CAAC,EAAE,2BAA2B,CAAC;CAClD;AAED,MAAM,WAAW,iCAAiC;IAChD,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,kCAAkC;IACjD,MAAM,EAAE,iCAAiC,CAAC;IAC1C,MAAM,EAAE,iCAAiC,CAAC;CAC3C;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,sBAAsB,CAAC;IAC5C,6DAA6D;IAC7D,QAAQ,CAAC,GAAG,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACzC,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,MAAM,2BAA2B,GAAG,IAAI,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC;AAEpF,+DAA+D;AAC/D,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,yBAAyB,CAAC;IAClC,KAAK,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IAC/B,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,8EAA8E;IAC9E,GAAG,CAAC,EAAE,2BAA2B,CAAC;IAClC;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,2BAA2B,CAAC;IACrC;;;OAGG;IACH,qBAAqB,CAAC,IAAI,MAAM,IAAI,CAAC;IACrC,sEAAsE;IACtE,cAAc,CAAC,IAAI,IAAI,CAAC;IACxB,sFAAsF;IACtF,cAAc,CAAC,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI,CAAC;IACvD,kBAAkB,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,gBAAgB,CAAC,IAAI,IAAI,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,IAAI,CAAC;IAClB,WAAW,CAAC,EAAE,4BAA4B,GAAG,IAAI,CAAC;IAClD,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,OAAO,CAAC,wBAAwB,CAAC,CAAC;CACtD;AAED,6EAA6E;AAC7E,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B,iBAAiB,EAAE,kCAAkC,CAAC;IACtD,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,UAAU,CAAC,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,wEAAwE;IACxE,GAAG,CAAC,EAAE,mBAAmB,CAAC;IAC1B,mEAAmE;IACnE,cAAc,CAAC,CAAC,YAAY,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC5D,+DAA+D;IAC/D,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,8EAA8E;IAC9E,OAAO,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,YAAY,CAAC,CAAC;CACnD;AAED;;;;GAIG;AACH,qBAAa,iBAAiB;IAehB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAdpC,OAAO,CAAC,IAAI,CAA+B;IAC3C,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,OAAO,CAAyC;IACxD,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,oBAAoB,CAA6B;IACzD,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,WAAW,CAA6C;IAChE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAwB;gBAEhB,OAAO,EAAE,wBAAwB;IAS9D,IAAI,IAAI,IAAI,OAAO,CAElB;IAED,IAAI,KAAK,IAAI,OAAO,CAEnB;IAED,IAAI,IAAI,IAAI,4BAA4B,GAAG,IAAI,CAE9C;IAED,MAAM,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI;IAK/C,OAAO,IAAI,IAAI;IAKf,KAAK,IAAI,IAAI;IAqCb,OAAO,CAAC,IAAI;IA6DZ;;;;OAIG;IACH,OAAO,CAAC,MAAM;IAqCd;;;;OAIG;IACH,OAAO,CAAC,MAAM;IAmEd,OAAO,CAAC,YAAY;YAgBN,WAAW;IAkDzB,sEAAsE;YACxD,cAAc;IA6D5B,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,qBAAqB;IAS7B,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAE7B;IAEF,OAAO,CAAC,iBAAiB;IAyCzB,OAAO,CAAC,cAAc;IAgBtB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAEtB;IAEF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAG9B;IAEF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAO5B;IAEF,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,OAAO;IAsBf,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAEhC;IAEF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAI5B;IAEF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAK9B;CACH;AAED,2DAA2D;AAC3D,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,wBAAwB,GAChC,iBAAiB,CAEnB"}
@@ -362,7 +362,9 @@ export class CrowdyStudioEmbed {
362
362
  const handle = await mountCrowdyStudio(element, {
363
363
  projectProvider: client.crowdyStudio,
364
364
  playerCompute: client.playerCompute,
365
- ...(client.crowdyStudioGitHub ? { github: client.crowdyStudioGitHub } : {}),
365
+ ...((this.options.github ?? client.crowdyStudioGitHub)
366
+ ? { github: this.options.github ?? client.crowdyStudioGitHub }
367
+ : {}),
366
368
  playerWallet: client.playerWallet,
367
369
  appId,
368
370
  gridId: context.gridId,
@@ -1,3 +1,3 @@
1
- export { CrowdyStudioGitHubTransport, type CrowdyStudioGitHubFile, type CrowdyStudioGitHubProjectScope, type CrowdyStudioGitHubRepo, type CrowdyStudioGitHubStatus, type CrowdyStudioGitHubTreeEntry, } from './transport.js';
2
- export { DEFAULT_FULL_STACK_CROWDY_JSON, layoutFromTree, mergeStudioFilesFromGitHub, parseCrowdyJson, pullStudioFilesFromGitHub, pushStudioFilesToGitHub, repoPathToStudioFile, resolveGitHubLayout, studioFileToRepoPath, studioFilesMissingOnGitHub, type GitHubFiles, type GitHubLayout, } from './sync.js';
1
+ export { CrowdyStudioGitHubTransport, type CrowdyStudioGitHubBindInitial, type CrowdyStudioGitHubFile, type CrowdyStudioGitHubLayout, type CrowdyStudioGitHubProjectScope, type CrowdyStudioGitHubRepo, type CrowdyStudioGitHubStatus, type CrowdyStudioGitHubTree, type CrowdyStudioGitHubTreeEntry, } from './transport.js';
2
+ export { isRustAuthoringPath, joinRepo, repoPathToStudioFile, studioFileToRepoPath, trimSlash, underRoot, } from './layout.js';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/crowdy-studio/github/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,8BAA8B,EACnC,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,GACjC,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,8BAA8B,EAC9B,cAAc,EACd,0BAA0B,EAC1B,eAAe,EACf,yBAAyB,EACzB,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,KAAK,WAAW,EAChB,KAAK,YAAY,GAClB,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/crowdy-studio/github/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,KAAK,6BAA6B,EAClC,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,8BAA8B,EACnC,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,2BAA2B,GACjC,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,mBAAmB,EACnB,QAAQ,EACR,oBAAoB,EACpB,oBAAoB,EACpB,SAAS,EACT,SAAS,GACV,MAAM,aAAa,CAAC"}
@@ -1,2 +1,2 @@
1
1
  export { CrowdyStudioGitHubTransport, } from './transport.js';
2
- export { DEFAULT_FULL_STACK_CROWDY_JSON, layoutFromTree, mergeStudioFilesFromGitHub, parseCrowdyJson, pullStudioFilesFromGitHub, pushStudioFilesToGitHub, repoPathToStudioFile, resolveGitHubLayout, studioFileToRepoPath, studioFilesMissingOnGitHub, } from './sync.js';
2
+ export { isRustAuthoringPath, joinRepo, repoPathToStudioFile, studioFileToRepoPath, trimSlash, underRoot, } from './layout.js';
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Path arithmetic between a Crowdy Studio project (per-target files such as
3
+ * `SERVER src/lib.rs`) and the bound repository, driven by the layout the
4
+ * game API resolved (`crowdyStudioGitHubLayout`). This module does NOT parse
5
+ * `crowdy.json`: the API is the only layout grammar, and the three client
6
+ * copies that existed until 17.0.0 had already begun to disagree.
7
+ */
8
+ import type { CrowdyStudioTarget } from '../models.js';
9
+ import type { CrowdyStudioGitHubLayout } from './transport.js';
10
+ export declare function trimSlash(path: string): string;
11
+ export declare function joinRepo(root: string, rel: string): string;
12
+ export declare function underRoot(path: string, root: string | null): string | null;
13
+ /** The repository path of a project file, or null when the layout has no root for its target. */
14
+ export declare function studioFileToRepoPath(layout: Pick<CrowdyStudioGitHubLayout, 'server' | 'client'>, target: CrowdyStudioTarget, path: string): string | null;
15
+ /** The project file a repository path is, or null when it is not one (README, assets, …). */
16
+ export declare function repoPathToStudioFile(layout: Pick<CrowdyStudioGitHubLayout, 'server' | 'client'>, repoPath: string): {
17
+ target: CrowdyStudioTarget;
18
+ path: string;
19
+ } | null;
20
+ /** `Cargo.toml` or a `.rs` under `src/`, no traversal — what Crowdy Studio compiles. */
21
+ export declare function isRustAuthoringPath(rel: string): boolean;
22
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/crowdy-studio/github/layout.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAE/D,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM9C;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAK1D;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAO1E;AAED,iGAAiG;AACjG,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,IAAI,CAAC,wBAAwB,EAAE,QAAQ,GAAG,QAAQ,CAAC,EAC3D,MAAM,EAAE,kBAAkB,EAC1B,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,IAAI,CAIf;AAED,6FAA6F;AAC7F,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,IAAI,CAAC,wBAAwB,EAAE,QAAQ,GAAG,QAAQ,CAAC,EAC3D,QAAQ,EAAE,MAAM,GACf;IAAE,MAAM,EAAE,kBAAkB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAWrD;AAED,wFAAwF;AACxF,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAKxD"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Path arithmetic between a Crowdy Studio project (per-target files such as
3
+ * `SERVER src/lib.rs`) and the bound repository, driven by the layout the
4
+ * game API resolved (`crowdyStudioGitHubLayout`). This module does NOT parse
5
+ * `crowdy.json`: the API is the only layout grammar, and the three client
6
+ * copies that existed until 17.0.0 had already begun to disagree.
7
+ */
8
+ export function trimSlash(path) {
9
+ let start = 0;
10
+ let end = path.length;
11
+ while (start < end && path.charCodeAt(start) === 47)
12
+ start += 1;
13
+ while (end > start && path.charCodeAt(end - 1) === 47)
14
+ end -= 1;
15
+ return start === 0 && end === path.length ? path : path.slice(start, end);
16
+ }
17
+ export function joinRepo(root, rel) {
18
+ const base = trimSlash(root);
19
+ const rest = trimSlash(rel);
20
+ if (!base || base === '.')
21
+ return rest;
22
+ return rest ? `${base}/${rest}` : base;
23
+ }
24
+ export function underRoot(path, root) {
25
+ if (root == null)
26
+ return null;
27
+ const base = trimSlash(root);
28
+ if (!base || base === '.')
29
+ return path;
30
+ if (path === base)
31
+ return '';
32
+ if (path.startsWith(`${base}/`))
33
+ return path.slice(base.length + 1);
34
+ return null;
35
+ }
36
+ /** The repository path of a project file, or null when the layout has no root for its target. */
37
+ export function studioFileToRepoPath(layout, target, path) {
38
+ const root = target === 'SERVER' ? layout.server : layout.client;
39
+ if (root == null)
40
+ return null;
41
+ return joinRepo(root, path);
42
+ }
43
+ /** The project file a repository path is, or null when it is not one (README, assets, …). */
44
+ export function repoPathToStudioFile(layout, repoPath) {
45
+ const client = underRoot(repoPath, layout.client);
46
+ if (client != null && isRustAuthoringPath(client))
47
+ return { target: 'CLIENT', path: client };
48
+ const server = underRoot(repoPath, layout.server);
49
+ if (server != null && isRustAuthoringPath(server)) {
50
+ if (layout.client && (layout.server === '.' || layout.server === '') && server.startsWith(`${trimSlash(layout.client)}/`)) {
51
+ return null;
52
+ }
53
+ return { target: 'SERVER', path: server };
54
+ }
55
+ return null;
56
+ }
57
+ /** `Cargo.toml` or a `.rs` under `src/`, no traversal — what Crowdy Studio compiles. */
58
+ export function isRustAuthoringPath(rel) {
59
+ if (!rel || rel.includes('..') || rel.startsWith('/'))
60
+ return false;
61
+ if (rel === 'Cargo.toml')
62
+ return true;
63
+ if (rel === 'Cargo.lock' || rel === 'build.rs' || rel.endsWith('/build.rs'))
64
+ return false;
65
+ return rel.startsWith('src/') && rel.endsWith('.rs');
66
+ }