gamesteel 0.5.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -4,8 +4,8 @@ Copyright (c) 2026 Ricardo Ramos. All rights reserved.
4
4
  This package (the "Software") is proprietary. It is not open source.
5
5
 
6
6
  You may install and run the Software, unchanged, only to use Gamesteel
7
- (https://gamesteel.onrender.com) with your own AI agent on your own machine, under
8
- Gamesteel's Terms (https://gamesteel.onrender.com/terms).
7
+ (https://gamesteel.studio) with your own AI agent on your own machine, under
8
+ Gamesteel's Terms (https://gamesteel.studio/terms).
9
9
 
10
10
  Except as the law allows despite this restriction, you may not:
11
11
 
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # gamesteel
2
2
 
3
- The [Gamesteel](https://gamesteel.onrender.com) program, and the command that sets it up in your AI agent. Gamesteel makes 2D games that play in the browser, and your own agent builds them through its tools. Your agent starts this program on your machine, where the work runs (painting, sound, playtests, app builds), and the website keeps your games. The program signs in to it once.
3
+ The [Gamesteel](https://gamesteel.studio) program, and the command that sets it up in your AI agent. Gamesteel makes 2D games that play in the browser, and your own agent builds them through its tools. Your agent starts this program on your machine, where the work runs (painting, sound, playtests, app builds), and the website keeps your games. The program signs in to it once.
4
4
 
5
5
  ```
6
6
  npx gamesteel@latest connect # the agents it sets up, and how each stands
package/dist/gamesteel.js CHANGED
@@ -64315,7 +64315,7 @@ function agentFile(id, place) {
64315
64315
  function agentById(id) {
64316
64316
  return AGENTS.find((agent) => agent.id === id);
64317
64317
  }
64318
- var LIVE_SITE = "https://gamesteel.onrender.com";
64318
+ var LIVE_SITE = "https://gamesteel.studio";
64319
64319
  var CONNECT_COMMAND = "npx gamesteel@latest connect";
64320
64320
  var SIGN_IN_SAID = "The first time your agent asks it for something, the program opens Gamesteel's sign-in in your browser: log in and Allow.";
64321
64321
 
@@ -86206,6 +86206,7 @@ var PLANS = [
86206
86206
  monthly: 999,
86207
86207
  seats: 1,
86208
86208
  extraSeat: null,
86209
+ storageBlock: 499,
86209
86210
  everythingIn: null,
86210
86211
  pick: false,
86211
86212
  storage: 10 * GB,
@@ -86213,7 +86214,7 @@ var PLANS = [
86213
86214
  includes: [
86214
86215
  room(10 * GB, 500 * MB),
86215
86216
  line("Everything Gamesteel does, with your own agent"),
86216
- line("The agent's 15 tools"),
86217
+ line("The agent's 16 tools"),
86217
86218
  line("Export to the web"),
86218
86219
  line("Phone app builds")
86219
86220
  ]
@@ -86224,6 +86225,7 @@ var PLANS = [
86224
86225
  monthly: 1999,
86225
86226
  seats: 3,
86226
86227
  extraSeat: 1e3,
86228
+ storageBlock: 399,
86227
86229
  everythingIn: "starter",
86228
86230
  pick: true,
86229
86231
  storage: 50 * GB,
@@ -86231,11 +86233,12 @@ var PLANS = [
86231
86233
  includes: [room(50 * GB, GB), line("An organization with shared games and roles")]
86232
86234
  },
86233
86235
  {
86234
- id: "enterprise",
86235
- name: "Enterprise",
86236
+ id: "business",
86237
+ name: "Business",
86236
86238
  monthly: 3999,
86237
86239
  seats: 20,
86238
- extraSeat: 1e3,
86240
+ extraSeat: 800,
86241
+ storageBlock: 299,
86239
86242
  everythingIn: "pro",
86240
86243
  pick: false,
86241
86244
  storage: 250 * GB,
@@ -86243,6 +86246,12 @@ var PLANS = [
86243
86246
  includes: [room(250 * GB, 2 * GB), line("Invoices instead of cards"), line("Priority support")]
86244
86247
  }
86245
86248
  ];
86249
+ var ENTERPRISE = {
86250
+ name: "Enterprise",
86251
+ everythingIn: "business",
86252
+ includes: [line("Seats and storage sized for your team"), line("Terms and invoicing agreed with you"), line("A direct line to the team")],
86253
+ email: "business@gamesteel.studio"
86254
+ };
86246
86255
  var TRIAL = {
86247
86256
  days: 7,
86248
86257
  games: 1,
@@ -86252,11 +86261,17 @@ var TRIAL = {
86252
86261
  gameBytes: 200 * MB,
86253
86262
  rules: ["One week, free", "One game", "No export", "A watermark on the game"]
86254
86263
  };
86255
- var STORAGE_BLOCK = { bytes: 10 * GB, monthly: 499 };
86264
+ var STORAGE_BLOCK = { bytes: 10 * GB };
86256
86265
  var STORAGE_FULL = (site, allowed) => `this workspace's ${sizeText(allowed)} are full: delete something it keeps, or its owner can add storage or choose a bigger plan at ${site}/editor#plan`;
86257
86266
  var GAME_FULL = (site, allowed) => `a game may hold at most ${sizeText(allowed)} on this plan: delete something in it, or its owner can choose a bigger plan at ${site}/editor#plan`;
86258
86267
  var NEARLY_FULL = 0.8;
86259
86268
  var UNLIMITED_GAME_BYTES = 2 * GB;
86269
+ function planById(id) {
86270
+ const plan = PLANS.find((one2) => one2.id === id);
86271
+ if (plan === void 0)
86272
+ throw new Error(`no plan called ${id}`);
86273
+ return plan;
86274
+ }
86260
86275
 
86261
86276
  // ../edit/dist/model.js
86262
86277
  var TILE_LAYERS = ["back", "front"];
@@ -107276,7 +107291,8 @@ var NEEDS_PROGRAM6 = "exporting to a file runs in the Gamesteel program on your
107276
107291
  var EXPORT_TOOLS = [
107277
107292
  {
107278
107293
  name: "export_game",
107279
- description: "write the game's export, a zip that plays anywhere, on this machine, and say where it is: unzipped, its index.html plays in a browser. A plan exports games up to its cap; a game of gigabytes takes minutes, and as much of this machine's memory.",
107294
+ // Its words cut to make room under Cursor's list size for the website's own tool (2026-10-26).
107295
+ description: "write the game's export, a zip that plays anywhere, on this machine, and say where it is: unzipped, its index.html plays in a browser. A plan exports games up to its cap; a large game takes minutes, and memory.",
107280
107296
  inputSchema: object2({ game: GAME }, ["game"]),
107281
107297
  handle: async (args2, ctx) => {
107282
107298
  const slug = textArg(args2, "game");
@@ -111289,7 +111305,7 @@ var DEFAULT_SERVE = { schemas: "full" };
111289
111305
  var SINGLES2 = ["guide", "edit", "write_code", "team"];
111290
111306
  var fam = (name2, about, actions) => ({ name: name2, about, actions: Object.entries(actions).map(([action, tool]) => ({ action, tool })) });
111291
111307
  var FAMILIES2 = [
111292
- fam("games", "the games in the library: list them, open one, start or import one, export one, keep one on GitHub; and game text given as source, checked, run or replayed as it is", {
111308
+ fam("games", "the games in the library, and game text given as source", {
111293
111309
  list: "list_games",
111294
111310
  open: "open_game",
111295
111311
  new: "new_game",
@@ -111316,7 +111332,7 @@ var FAMILIES2 = [
111316
111332
  redo: "redo",
111317
111333
  art: "undo_art"
111318
111334
  }),
111319
- fam("playtest", "play the game yourself, headless: play a track, play until something happens, look at it, inspect it, start over, and save or return to a moment", {
111335
+ fam("playtest", "play the game yourself, headless, and look at it", {
111320
111336
  play: "playtest_play",
111321
111337
  until: "playtest_until",
111322
111338
  look: "playtest_look",
@@ -111325,13 +111341,13 @@ var FAMILIES2 = [
111325
111341
  snapshot: "playtest_snapshot",
111326
111342
  restore: "playtest_restore"
111327
111343
  }),
111328
- fam("art", "a game's pictures: paint one, model one in 3D, read one, list them", {
111344
+ fam("art", "a game's pictures, painted or modelled in 3D", {
111329
111345
  paint: "paint_art",
111330
111346
  model: "model_art",
111331
111347
  read: "read_art",
111332
111348
  list: "list_art"
111333
111349
  }),
111334
- fam("sound", "a game's sound: design an effect, compose music, listen to them, list them", {
111350
+ fam("sound", "a game's sound effects and music", {
111335
111351
  design: "design_sound",
111336
111352
  compose: "compose_music",
111337
111353
  listen: "listen",
@@ -111357,6 +111373,14 @@ var FAMILIES2 = [
111357
111373
  online: "app_online",
111358
111374
  online_logs: "app_online_logs",
111359
111375
  online_query: "app_online_query"
111376
+ }),
111377
+ // The 16th (the owner, 2026-10-26): what is the website's, not a game's.
111378
+ fam("website", "your Gamesteel account on the website", {
111379
+ account: "website_account",
111380
+ workspaces: "website_workspaces",
111381
+ members: "website_members",
111382
+ storage: "website_storage",
111383
+ sign_in: "sign_in"
111360
111384
  })
111361
111385
  ];
111362
111386
  function nowCalled(tool) {
@@ -111447,7 +111471,7 @@ function listingOf(family2, tools) {
111447
111471
  };
111448
111472
  for (const [key, { shape, uses }] of options)
111449
111473
  properties[key] = { ...shape, description: saidOf(uses, present2.length) };
111450
- const description = [`${family2.about}. Each action is one of:`, ...present2.map((a4) => `- ${a4.action}: ${a4.def.description}`)].join("\n");
111474
+ const description = [`${family2.about}. Actions:`, ...present2.map((a4) => `- ${a4.action}: ${a4.def.description}`)].join("\n");
111451
111475
  return { name: family2.name, description, inputSchema: { type: "object", additionalProperties: false, required: ["action"], properties } };
111452
111476
  }
111453
111477
  var ORDER = [
@@ -111465,7 +111489,8 @@ var ORDER = [
111465
111489
  "library",
111466
111490
  "film",
111467
111491
  "team",
111468
- "app"
111492
+ "app",
111493
+ "website"
111469
111494
  ];
111470
111495
  function familyListing(tools) {
111471
111496
  const singles = SINGLES2.flatMap((name2) => tools.filter((t2) => t2.name === name2));
@@ -111513,6 +111538,20 @@ var WAIT_TOOL = {
111513
111538
  description: `wait up to ${String(JOB_MS / 1e3)} seconds for a call of yours still going, and answer with what it said`,
111514
111539
  inputSchema: { type: "object", additionalProperties: false, properties: {} }
111515
111540
  };
111541
+ var WEBSITE_READS = { account: "website_account", workspaces: "website_workspaces", members: "website_members", storage: "website_storage" };
111542
+ var NO_OPTIONS = { type: "object", additionalProperties: false, properties: {} };
111543
+ var WEBSITE_TOOLS = [
111544
+ { name: WEBSITE_READS.account, description: "which account and workspace this works in, its plan, limits and pages", inputSchema: NO_OPTIONS },
111545
+ { name: WEBSITE_READS.workspaces, description: "the person's workspaces, their role in each, and which this works in", inputSchema: NO_OPTIONS },
111546
+ { name: WEBSITE_READS.members, description: "the workspace's people and their roles", inputSchema: NO_OPTIONS },
111547
+ { name: WEBSITE_READS.storage, description: "what the workspace keeps: by kind, the largest files, what no game uses", inputSchema: NO_OPTIONS }
111548
+ ];
111549
+ var WEBSITE_NAMES = new Set(Object.values(WEBSITE_READS));
111550
+ var SIGN_IN_TOOL = {
111551
+ name: "sign_in",
111552
+ description: "sign in again, as another account or workspace",
111553
+ inputSchema: { type: "object", additionalProperties: false, properties: {} }
111554
+ };
111516
111555
  var NOTHING_GOING = "no call of yours is going on";
111517
111556
  function guideAnswer(raw) {
111518
111557
  const name2 = typeof raw["topic"] === "string" ? raw["topic"] : "";
@@ -111549,6 +111588,10 @@ function schemaFor(tool) {
111549
111588
  return GUIDE_TOOL.inputSchema;
111550
111589
  if (tool === WAIT_TOOL.name)
111551
111590
  return WAIT_TOOL.inputSchema;
111591
+ if (tool === SIGN_IN_TOOL.name)
111592
+ return SIGN_IN_TOOL.inputSchema;
111593
+ if (WEBSITE_NAMES.has(tool))
111594
+ return NO_OPTIONS;
111552
111595
  const editing = EDITING.get(tool);
111553
111596
  if (editing !== void 0)
111554
111597
  return editing.inputSchema;
@@ -111570,6 +111613,8 @@ async function callToolAsync(tool, args2, ctx, label = nowCalled(tool)) {
111570
111613
  return { content: [{ type: "text", text: refused3 }], isError: true };
111571
111614
  return { content: [{ type: "text", text: NOTHING_GOING }] };
111572
111615
  }
111616
+ if (tool === SIGN_IN_TOOL.name || WEBSITE_NAMES.has(tool))
111617
+ return { content: [{ type: "text", text: ON_YOUR_MACHINE }], isError: true };
111573
111618
  const editing = EDITING.get(tool);
111574
111619
  if (editing !== void 0) {
111575
111620
  const refused3 = admitArgs(editing.inputSchema, raw, label);
@@ -111637,13 +111682,18 @@ function toolList() {
111637
111682
  return [
111638
111683
  GUIDE_TOOL,
111639
111684
  WAIT_TOOL,
111685
+ ...WEBSITE_TOOLS,
111686
+ SIGN_IN_TOOL,
111640
111687
  ...EDIT_TOOLS.map((tool) => ({ name: tool.name, description: tool.description, inputSchema: tool.inputSchema })),
111641
111688
  ...CORE_TOOLS.map((name2) => ({ name: name2, description: CORE_LINES.get(name2) ?? name2, inputSchema: schemaFor(name2) }))
111642
111689
  ];
111643
111690
  }
111644
111691
  var READING_TOOLS = /* @__PURE__ */ new Set([
111692
+ // The account read and signed in again too, so an agent in a read-only workspace can still move to another.
111645
111693
  "guide",
111646
111694
  "wait_for_calls",
111695
+ ...Object.values(WEBSITE_READS),
111696
+ "sign_in",
111647
111697
  "open_game",
111648
111698
  "read_scene",
111649
111699
  "read_type",
@@ -111668,6 +111718,7 @@ var READING_TOOLS = /* @__PURE__ */ new Set([
111668
111718
  "app_online_logs",
111669
111719
  "app_online_query"
111670
111720
  ]);
111721
+ var ON_YOUR_MACHINE = "This runs on your own machine, not on the website. Add Gamesteel to your agent with `npx gamesteel@latest connect`, or `claude mcp add --scope user gamesteel -- npx -y gamesteel@latest`, then ask again.";
111671
111722
  function makesGame(name2, args2, exists) {
111672
111723
  if (name2 === "new_game")
111673
111724
  return true;
@@ -116168,6 +116219,18 @@ var FONT_FILES = {
116168
116219
  ui: resolve2("@fontsource-variable/geist/files/geist-latin-wght-normal.woff2")
116169
116220
  };
116170
116221
 
116222
+ // ../design/dist/roles.js
116223
+ var PERMISSIONS = ["play", "edit", "publish", "servers", "members", "billing", "workspace"];
116224
+ var GRANTS = {
116225
+ owner: new Set(PERMISSIONS),
116226
+ admin: /* @__PURE__ */ new Set(["play", "edit", "publish", "servers", "members"]),
116227
+ member: /* @__PURE__ */ new Set(["play", "edit"]),
116228
+ viewer: /* @__PURE__ */ new Set(["play"])
116229
+ };
116230
+ function can(role, permission) {
116231
+ return role != null && GRANTS[role].has(permission);
116232
+ }
116233
+
116171
116234
  // ../i18n/dist/index.js
116172
116235
  function chooseLanguage(header2) {
116173
116236
  const best = { en: { q: 0, at: Infinity }, es: { q: 0, at: Infinity } };
@@ -116214,6 +116277,8 @@ var SITE = resolve3(dirname8(__gamesteelResolve("@gamesteel/site/package.json"))
116214
116277
  var WORDS = resolve3(SITE, "..", "i18n");
116215
116278
  var KEEP_LANGUAGE = 365 * 24 * 60 * 60;
116216
116279
  var KEEP_FONT = 7 * 24 * 60 * 60;
116280
+ var PUBLIC_PAGES = ["/", "/engine", "/updates", "/demo", "/connect", "/pricing", "/docs", "/terms", "/privacy"];
116281
+ var PUBLIC = new Set(PUBLIC_PAGES);
116217
116282
  var gzipped = promisify(gzip);
116218
116283
 
116219
116284
  // ../studio/dist/server/export.js
@@ -121879,7 +121944,7 @@ function hostedAppRoutes(options) {
121879
121944
  const mayExport = options.mayExport ?? ((req2) => requestPlaces.get(req2)?.export !== false);
121880
121945
  const mayKeepKeys = options.mayKeepKeys ?? ((req2) => {
121881
121946
  const role = requestPlaces.get(req2)?.role;
121882
- return !agentRequests.has(req2) && (role === "owner" || role === "admin");
121947
+ return !agentRequests.has(req2) && can(role, "publish");
121883
121948
  });
121884
121949
  const gameOf = (params) => {
121885
121950
  const slug = params["slug"] ?? "";
@@ -127834,6 +127899,7 @@ var HOUR = 36e5;
127834
127899
  var DAY = 24 * HOUR;
127835
127900
  var SESSION_LIFE = 30 * DAY;
127836
127901
  var FREE_WEEK = 7 * DAY;
127902
+ var PICTURE_MOST = 512 * 1024;
127837
127903
 
127838
127904
  // ../accounts/dist/limits.js
127839
127905
  var MINUTE = 6e4;
@@ -127847,6 +127913,8 @@ var LIMITS2 = {
127847
127913
  loginAddress: { tries: 30, per: 15 * MINUTE },
127848
127914
  /** Sign-ups from one address. */
127849
127915
  signup: { tries: 5, per: HOUR2 },
127916
+ /** Google log-ins started from one address, each keeping a state until it comes back (the Google log-in spec). */
127917
+ googleStart: { tries: 30, per: 15 * MINUTE },
127850
127918
  /** Requests that can email an address (sign up, send again, forgot), counted whether or not one goes out. */
127851
127919
  emails: { tries: 3, per: HOUR2 },
127852
127920
  /** Apps registering to sign agents in, from one address (the agents by address spec, part 2). */
@@ -127858,6 +127926,9 @@ var LIMITS2 = {
127858
127926
  oauthTokenAll: { tries: 600, per: MINUTE }
127859
127927
  };
127860
127928
 
127929
+ // ../accounts/dist/mail.js
127930
+ var INK = { band: PALETTE2.bg, red: PALETTE2.forge, link: "#C81516", page: "#F2F2F3", card: "#FFFFFF", heading: "#0B0B0C", text: "#3F3F46", small: "#52525B", faint: "#A1A1AA", foot: "#FAFAFA", rule: "#ECECEE" };
127931
+
127861
127932
  // ../accounts/dist/workspaces.js
127862
127933
  var DAY2 = 864e5;
127863
127934
  var INVITE_LIFE = 7 * DAY2;
@@ -134850,6 +134921,11 @@ var SiteRefusal = class extends Error {
134850
134921
  status;
134851
134922
  body;
134852
134923
  };
134924
+ var SignInMoved = class extends SiteRefusal {
134925
+ constructor() {
134926
+ super(409, "this program's sign-in moved to another account or workspace: ask again", { error: "workspace" });
134927
+ }
134928
+ };
134853
134929
  var pathOf3 = (path) => path.split("/").map(encodeURIComponent).join("/");
134854
134930
  var sha2562 = (bytes2) => createHash5("sha256").update(bytes2).digest("hex");
134855
134931
  var DeviceSite = class {
@@ -134862,11 +134938,19 @@ var DeviceSite = class {
134862
134938
  get site() {
134863
134939
  return this.options.site;
134864
134940
  }
134941
+ /** The workspace the program started in, named in each request once it is known, so a sign-in that moved under the
134942
+ * program to another workspace is refused there, and nothing of this one is ever sent into it. */
134943
+ pinned = null;
134944
+ pin(workspaceId) {
134945
+ this.pinned = workspaceId;
134946
+ }
134865
134947
  async request(method, path, init2 = {}) {
134948
+ const pinned = init2.unpinned === true ? null : this.pinned;
134866
134949
  const headers = {
134867
134950
  authorization: `Bearer ${await this.options.token()}`,
134868
134951
  "x-gamesteel-engine": ENGINE_VERSION,
134869
134952
  "x-gamesteel-session": init2.session ?? this.options.session(),
134953
+ ...pinned === null ? {} : { "x-gamesteel-workspace": pinned },
134870
134954
  ...init2.headers
134871
134955
  };
134872
134956
  if (init2.json !== void 0) headers["content-type"] = "application/json";
@@ -134883,6 +134967,13 @@ var DeviceSite = class {
134883
134967
  await response.body?.cancel();
134884
134968
  throw new SiteRefusal(401, `this program is signed out of ${this.options.site}: sign in again`, null);
134885
134969
  }
134970
+ if (response.status === 409 && pinned !== null) {
134971
+ const said4 = await response.clone().json().catch(() => null);
134972
+ if (said4?.error === "workspace") {
134973
+ await response.body?.cancel();
134974
+ throw new SignInMoved();
134975
+ }
134976
+ }
134886
134977
  return response;
134887
134978
  }
134888
134979
  /** The answer's body when its status is one the route answers with, else thrown in its words. */
@@ -134930,8 +135021,21 @@ var DeviceSite = class {
134930
135021
  async githubConfirmed(confirmation) {
134931
135022
  return (await this.answer(await this.request("POST", "github/confirmed", { json: confirmation }), [200])).confirmed;
134932
135023
  }
135024
+ /** Who the sign-in is now, whatever workspace the program started in. */
134933
135025
  async standing() {
134934
- return this.answer(await this.request("GET", "standing"), [200]);
135026
+ return this.answer(await this.request("GET", "standing", { unpinned: true }), [200]);
135027
+ }
135028
+ /** The person's workspaces, their role in each, and the one this works in (the website tool). */
135029
+ async workspaces() {
135030
+ return (await this.answer(await this.request("GET", "workspaces"), [200])).workspaces;
135031
+ }
135032
+ /** The workspace's people and their roles. */
135033
+ async members() {
135034
+ return (await this.answer(await this.request("GET", "members"), [200])).members;
135035
+ }
135036
+ /** What the workspace keeps, game by game: each item, its size, and whether its game uses it. */
135037
+ async storage() {
135038
+ return this.answer(await this.request("GET", "storage"), [200]);
134935
135039
  }
134936
135040
  /** A person of the workspace by name, or their agent. */
134937
135041
  async name(user, grant) {
@@ -136966,6 +137070,7 @@ var GitHubClient = class {
136966
137070
  }
136967
137071
  const response = await this.fetch(`${this.api}${path}`, {
136968
137072
  method,
137073
+ cache: "no-cache",
136969
137074
  headers: {
136970
137075
  authorization: `Bearer ${await this.options.token()}`,
136971
137076
  accept: accept2,
@@ -137581,6 +137686,26 @@ var SignIn = class {
137581
137686
  signedIn() {
137582
137687
  return this.options.key !== null || this.read() !== null;
137583
137688
  }
137689
+ /** The sign-in the program holds now, by its client (each sign-in registers its own), or the key; null for none.
137690
+ * Another sign-in on this machine changes it under every program running. */
137691
+ current() {
137692
+ return this.options.key !== null ? "key" : this.read()?.clientId ?? null;
137693
+ }
137694
+ /** This machine's sign-in ended for every program on it, and revoked on the website, so it leaves the account's
137695
+ * connected apps; the next call signs in afresh, as another account or into another workspace (a person with two
137696
+ * accounts, 2026-10-26). A website that cannot be reached now keeps the grant, which is forgotten here all the same. */
137697
+ async forget() {
137698
+ this.close();
137699
+ const held = await this.locked(async () => {
137700
+ const was = this.read();
137701
+ if (was !== null) this.write(null);
137702
+ return was;
137703
+ });
137704
+ if (held === null) return;
137705
+ await this.form("/oauth/revoke", { token: held.refresh }).then(async (answer3) => {
137706
+ await answer3.body?.cancel();
137707
+ }, () => void 0);
137708
+ }
137584
137709
  /** A live token: the key, or the access token, refreshed when it ends within a minute. Throws SignInNeeded. */
137585
137710
  async token() {
137586
137711
  if (this.options.key !== null) return this.options.key;
@@ -139163,6 +139288,90 @@ function processLink() {
139163
139288
  };
139164
139289
  }
139165
139290
 
139291
+ // src/program/website.ts
139292
+ var ANOTHER = "For another account or workspace: website { action: 'sign_in' }.";
139293
+ var whoOf = (standing2) => `${standing2.email == null ? "" : ` as ${standing2.email}`}${standing2.workspaceName === void 0 ? "" : ` in the workspace ${standing2.workspaceName}`}`;
139294
+ function planSaid(standing2) {
139295
+ const plan = standing2.plan === null ? null : planById(standing2.plan).name;
139296
+ switch (standing2.state) {
139297
+ case "unlimited":
139298
+ return "has every feature on";
139299
+ case "free-week":
139300
+ return "is in its free week";
139301
+ case "active":
139302
+ return `is on the ${plan ?? ""} plan`;
139303
+ case "past-due":
139304
+ return `is on the ${plan ?? ""} plan, its payment past due`;
139305
+ case "ended":
139306
+ return "is read-only: its free week or plan has ended";
139307
+ default:
139308
+ return `is ${standing2.state}`;
139309
+ }
139310
+ }
139311
+ function accountSaid(standing2, site) {
139312
+ const { used, allowed } = standing2.storage ?? { used: 0, allowed: null };
139313
+ const keeps = allowed === null ? `${sizeText(used)}, with no limit` : `${sizeText(used)} of ${sizeText(allowed)}`;
139314
+ const { games, gameBytes } = standing2.limits;
139315
+ const makes = [
139316
+ games === null ? "any number of games" : `${String(games)} game${games === 1 ? "" : "s"}`,
139317
+ gameBytes === void 0 ? null : `each up to ${sizeText(gameBytes)}`
139318
+ ].filter((part2) => part2 !== null).join(", ");
139319
+ return [
139320
+ `Signed in${whoOf(standing2)}, as its ${standing2.role}.`,
139321
+ `The workspace ${planSaid(standing2)}, and keeps ${keeps}. Its plan makes ${makes}${standing2.limits.export ? "" : ", and does not export"}.`,
139322
+ `The person's pages: their games ${site}/editor, what the workspace keeps ${site}/editor#storage, the plan ${site}/editor#plan.`,
139323
+ ANOTHER
139324
+ ].join(" ");
139325
+ }
139326
+ function workspacesSaid(workspaces) {
139327
+ const lines = workspaces.map((one2) => `- ${one2.name}: ${one2.role}${one2.here ? " (this works in it)" : ""}`);
139328
+ return [`The person's workspaces, ${String(workspaces.length)}:`, ...lines, `To work in another: website { action: 'sign_in' }, and choose it on the page.`].join("\n");
139329
+ }
139330
+ function membersSaid(members, site) {
139331
+ const lines = members.map((one2) => `- ${one2.name === one2.email ? one2.email : `${one2.name} (${one2.email})`}: ${one2.role}${one2.you ? " (the person)" : ""}`);
139332
+ return [`The workspace's people, ${String(members.length)}:`, ...lines, `Its owner and admins invite and remove people at ${site}/editor#organization.`].join("\n");
139333
+ }
139334
+ var KINDS3 = {
139335
+ picture: "picture",
139336
+ sound: "sound",
139337
+ music: "music",
139338
+ font: "font",
139339
+ film: "film",
139340
+ replay: "replay",
139341
+ store: "store picture",
139342
+ game: "game text and settings",
139343
+ other: "file"
139344
+ };
139345
+ var PLURAL = {
139346
+ picture: "pictures",
139347
+ sound: "sounds",
139348
+ music: "music",
139349
+ font: "fonts",
139350
+ film: "films",
139351
+ replay: "replays",
139352
+ store: "store pictures",
139353
+ game: "game text and settings",
139354
+ other: "other files"
139355
+ };
139356
+ var LARGEST = 10;
139357
+ function storageSaid(storage, standing2, site) {
139358
+ const items = storage.games.flatMap((game) => game.items.map((item) => ({ ...item, game: game.title ?? game.slug })));
139359
+ const used = standing2.storage?.used ?? items.reduce((sum, item) => sum + item.bytes, 0) + storage.styles.bytes;
139360
+ const allowed = standing2.storage?.allowed ?? null;
139361
+ const kinds = /* @__PURE__ */ new Map();
139362
+ for (const item of items) kinds.set(item.kind, (kinds.get(item.kind) ?? 0) + item.bytes);
139363
+ const largest = [...items].sort((a4, b5) => b5.bytes - a4.bytes).slice(0, LARGEST);
139364
+ const unused = items.filter((item) => item.used === false && !item.kept);
139365
+ const useOf = (item) => item.kept ? "part of the game" : item.used === null ? "not checked" : item.used ? "in use" : "not in use";
139366
+ return [
139367
+ `The workspace keeps ${sizeText(used)}${allowed === null ? ", with no limit" : ` of ${sizeText(allowed)}`}, in ${String(storage.games.length)} game${storage.games.length === 1 ? "" : "s"}.`,
139368
+ kinds.size === 0 ? null : `By kind: ${[...kinds].sort((a4, b5) => b5[1] - a4[1]).map(([kind, bytes2]) => `${PLURAL[kind] ?? kind} ${sizeText(bytes2)}`).join(", ")}.`,
139369
+ largest.length === 0 ? null : "Largest:",
139370
+ ...largest.map((item) => `- ${item.kind === "game" ? "the game itself" : item.name}, ${KINDS3[item.kind] ?? item.kind} of ${item.game}: ${sizeText(item.bytes)}, ${useOf(item)}`),
139371
+ unused.length === 0 ? "No game is known not to use anything it keeps." : `Not in use by their games: ${String(unused.length)}, ${sizeText(unused.reduce((sum, item) => sum + item.bytes, 0))}. The person deletes them at ${site}/editor#storage, where each says its game and whether it is used.`
139372
+ ].filter((line2) => line2 !== null).join("\n");
139373
+ }
139374
+
139166
139375
  // src/program/program.ts
139167
139376
  var STANDING_MS = 3e4;
139168
139377
  var OLD_EXPORT_BYTES = 100 * MB;
@@ -139172,6 +139381,7 @@ var signInFirst = (needed) => ({
139172
139381
  ${needed.message}` }]
139173
139382
  });
139174
139383
  var clientName = (name2) => (name2 ?? "agent").toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40) || "agent";
139384
+ var movedFrom = (was, now) => was.workspaceId !== now.workspaceId || was.userId !== now.userId || was.grantId !== now.grantId;
139175
139385
  async function startProgram(options) {
139176
139386
  const { settings, signIn } = options;
139177
139387
  const log = options.log ?? ((line2) => {
@@ -139200,9 +139410,11 @@ async function startProgram(options) {
139200
139410
  let standingAt = 0;
139201
139411
  let standing2 = null;
139202
139412
  const start2 = async () => {
139413
+ const signedWith = signIn.current();
139203
139414
  const known2 = await site.standing();
139204
139415
  standing2 = known2;
139205
139416
  standingAt = Date.now();
139417
+ site.pin(known2.workspaceId);
139206
139418
  const grantId = known2.grantId ?? "";
139207
139419
  session = `${settings.programId}:${clientName(server.getClientVersion()?.name)}`;
139208
139420
  const author = `ai:${grantId}:${session}`;
@@ -139369,6 +139581,7 @@ async function startProgram(options) {
139369
139581
  madeStores = publishing;
139370
139582
  return {
139371
139583
  standing: known2,
139584
+ signedWith,
139372
139585
  copy,
139373
139586
  uploader: sending,
139374
139587
  follower,
@@ -139396,9 +139609,24 @@ async function startProgram(options) {
139396
139609
  const listen = () => {
139397
139610
  if (signIn.signedIn()) desk.start();
139398
139611
  };
139612
+ let ending = Promise.resolve();
139613
+ const restart = (from = running) => {
139614
+ if (from === null || running !== from) return ending;
139615
+ const was = running;
139616
+ running = null;
139617
+ standing2 = null;
139618
+ current = null;
139619
+ told = false;
139620
+ storageTold = false;
139621
+ nearTold.clear();
139622
+ if (was !== null) ending = ending.then(async () => {
139623
+ await (await was.catch(() => null))?.close();
139624
+ });
139625
+ return ending;
139626
+ };
139399
139627
  const prepared = () => {
139400
139628
  if (running === null) {
139401
- const starting = start2();
139629
+ const starting = ending.then(start2);
139402
139630
  running = starting;
139403
139631
  starting.catch(() => {
139404
139632
  if (running === starting) running = null;
@@ -139426,20 +139654,67 @@ async function startProgram(options) {
139426
139654
  return `${slug} holds ${sizeText(bytes2)} of the ${sizeText(cap)} a game may hold on this plan. Past that it takes no new files, though it still saves; its owner can choose a bigger plan at ${settings.site}/editor#plan.`;
139427
139655
  };
139428
139656
  const gamesHere = (root2) => new Set(readdirSync17(root2).filter((slug) => existsSync26(join40(root2, slug, "game.json"))));
139657
+ const signInAgain = async () => {
139658
+ if (settings.key !== null) {
139659
+ return refusal3("this program signs in with a personal key (GAMESTEEL_KEY), which is of one account and workspace: to work as another, give it a key made there, on the editor's Agents page");
139660
+ }
139661
+ const was = (await running?.catch(() => null))?.standing ?? standing2;
139662
+ await restart();
139663
+ await signIn.forget();
139664
+ const needed = new SignInNeeded(await signIn.address());
139665
+ const from = was === null ? "" : whoOf(was);
139666
+ return { content: [{ type: "text", text: `Gamesteel signed out${from}, so nothing else was done. On the page, the person can use another account and chooses the workspace.
139667
+ ${needed.message}` }] };
139668
+ };
139669
+ const websiteSaid = async (name2, now) => {
139670
+ switch (name2) {
139671
+ case WEBSITE_READS.account:
139672
+ return accountSaid(now, settings.site);
139673
+ case WEBSITE_READS.workspaces:
139674
+ return workspacesSaid(await site.workspaces());
139675
+ case WEBSITE_READS.members:
139676
+ return membersSaid(await site.members(), settings.site);
139677
+ case WEBSITE_READS.storage:
139678
+ return storageSaid(await site.storage(), now, settings.site);
139679
+ default:
139680
+ return null;
139681
+ }
139682
+ };
139429
139683
  const around2 = async (name2, args2, call) => {
139684
+ if (name2 === SIGN_IN_TOOL.name) return signInAgain();
139430
139685
  let program;
139431
139686
  let now;
139687
+ let switched = null;
139688
+ let on2 = null;
139432
139689
  try {
139433
139690
  if (!signIn.signedIn()) throw new SignInNeeded(await signIn.address());
139434
- program = await prepared();
139691
+ on2 = prepared();
139692
+ program = await on2;
139693
+ if (signIn.current() !== program.signedWith || name2 === WEBSITE_READS.account || name2 === WEBSITE_READS.storage) standing2 = null;
139435
139694
  now = await plan();
139695
+ if (movedFrom(program.standing, now)) {
139696
+ await restart(on2);
139697
+ on2 = prepared();
139698
+ program = await on2;
139699
+ now = await plan();
139700
+ switched = `Gamesteel's sign-in on this computer changed: it works${whoOf(now)} now.`;
139701
+ }
139436
139702
  listen();
139437
139703
  } catch (error2) {
139438
139704
  if (error2 instanceof SignInNeeded) return signInFirst(error2);
139439
139705
  if (error2 instanceof SiteRefusal && error2.status === 401) return signInFirst(new SignInNeeded(await signIn.address()));
139706
+ if (error2 instanceof SignInMoved) {
139707
+ await restart(on2);
139708
+ return refusal3(error2.message);
139709
+ }
139440
139710
  return refusal3(`the website could not be reached: ${error2.message}. Ask again in a moment`);
139441
139711
  }
139442
139712
  current = program.ctx;
139713
+ const website = await websiteSaid(name2, now).catch((error2) => ({ refused: error2.message }));
139714
+ if (typeof website === "object" && website !== null) return refusal3(website.refused);
139715
+ if (website !== null) return { content: [{ type: "text", text: switched === null ? website : `${switched}
139716
+
139717
+ ${website}` }] };
139443
139718
  const { copy, follower, team: team2, author, uploader, moves: moves2 } = program;
139444
139719
  const reading = READING_TOOLS.has(name2) || name2 === "team" && args2["action"] === "read";
139445
139720
  if (!reading && !now.limits.writes) {
@@ -139486,6 +139761,7 @@ async function startProgram(options) {
139486
139761
  }
139487
139762
  if (unsaved.length > 0) pending.push(...(await uploader.send(unsaved)).pending);
139488
139763
  } catch (error2) {
139764
+ if (error2 instanceof SignInMoved) await restart(on2);
139489
139765
  return refusal3(error2.message);
139490
139766
  }
139491
139767
  const cap = now.limits.exportBytes;
@@ -139532,6 +139808,11 @@ ${line2}` }] };
139532
139808
  ${line2}` }] };
139533
139809
  }
139534
139810
  }
139811
+ if (name2 === "list_games" && answer3.isError !== true && now.email != null) {
139812
+ answer3 = { ...answer3, content: [...answer3.content, { type: "text", text: `
139813
+
139814
+ Signed in${whoOf(now)}. For another account or workspace: website { action: 'sign_in' }.` }] };
139815
+ }
139535
139816
  if (name2 === "list_games" && unread.length > 0) {
139536
139817
  answer3 = { ...answer3, content: [...answer3.content, { type: "text", text: `
139537
139818
 
@@ -139550,6 +139831,9 @@ Not on the website yet: ${pending.join("; ")}.` }] };
139550
139831
  const team3 = program.standing.team;
139551
139832
  answer3 = withFirstWords(answer3, team3 === null ? null : teamInstructions({ agent: team3.agent, workspace: team3.workspace, people: [...team3.people] }));
139552
139833
  }
139834
+ if (switched !== null) answer3 = { ...answer3, content: [{ type: "text", text: `${switched}
139835
+
139836
+ ` }, ...answer3.content] };
139553
139837
  return answer3;
139554
139838
  };
139555
139839
  serveTools(server, {
@@ -139572,6 +139856,7 @@ Not on the website yet: ${pending.join("; ")}.` }] };
139572
139856
  await desk.close();
139573
139857
  signIn.close();
139574
139858
  if (running !== null) await (await running.catch(() => null))?.close();
139859
+ await ending;
139575
139860
  })();
139576
139861
  return closing;
139577
139862
  }
@@ -85761,6 +85761,7 @@ var PLANS = [
85761
85761
  monthly: 999,
85762
85762
  seats: 1,
85763
85763
  extraSeat: null,
85764
+ storageBlock: 499,
85764
85765
  everythingIn: null,
85765
85766
  pick: false,
85766
85767
  storage: 10 * GB,
@@ -85768,7 +85769,7 @@ var PLANS = [
85768
85769
  includes: [
85769
85770
  room(10 * GB, 500 * MB2),
85770
85771
  line("Everything Gamesteel does, with your own agent"),
85771
- line("The agent's 15 tools"),
85772
+ line("The agent's 16 tools"),
85772
85773
  line("Export to the web"),
85773
85774
  line("Phone app builds")
85774
85775
  ]
@@ -85779,6 +85780,7 @@ var PLANS = [
85779
85780
  monthly: 1999,
85780
85781
  seats: 3,
85781
85782
  extraSeat: 1e3,
85783
+ storageBlock: 399,
85782
85784
  everythingIn: "starter",
85783
85785
  pick: true,
85784
85786
  storage: 50 * GB,
@@ -85786,11 +85788,12 @@ var PLANS = [
85786
85788
  includes: [room(50 * GB, GB), line("An organization with shared games and roles")]
85787
85789
  },
85788
85790
  {
85789
- id: "enterprise",
85790
- name: "Enterprise",
85791
+ id: "business",
85792
+ name: "Business",
85791
85793
  monthly: 3999,
85792
85794
  seats: 20,
85793
- extraSeat: 1e3,
85795
+ extraSeat: 800,
85796
+ storageBlock: 299,
85794
85797
  everythingIn: "pro",
85795
85798
  pick: false,
85796
85799
  storage: 250 * GB,
@@ -85798,6 +85801,12 @@ var PLANS = [
85798
85801
  includes: [room(250 * GB, 2 * GB), line("Invoices instead of cards"), line("Priority support")]
85799
85802
  }
85800
85803
  ];
85804
+ var ENTERPRISE = {
85805
+ name: "Enterprise",
85806
+ everythingIn: "business",
85807
+ includes: [line("Seats and storage sized for your team"), line("Terms and invoicing agreed with you"), line("A direct line to the team")],
85808
+ email: "business@gamesteel.studio"
85809
+ };
85801
85810
  var TRIAL = {
85802
85811
  days: 7,
85803
85812
  games: 1,
@@ -85807,7 +85816,7 @@ var TRIAL = {
85807
85816
  gameBytes: 200 * MB2,
85808
85817
  rules: ["One week, free", "One game", "No export", "A watermark on the game"]
85809
85818
  };
85810
- var STORAGE_BLOCK = { bytes: 10 * GB, monthly: 499 };
85819
+ var STORAGE_BLOCK = { bytes: 10 * GB };
85811
85820
  var UNLIMITED_GAME_BYTES = 2 * GB;
85812
85821
 
85813
85822
  // ../agent/dist/export-tools.js
@@ -85815,7 +85824,8 @@ var NEEDS_PROGRAM6 = "exporting to a file runs in the Gamesteel program on your
85815
85824
  var EXPORT_TOOLS = [
85816
85825
  {
85817
85826
  name: "export_game",
85818
- description: "write the game's export, a zip that plays anywhere, on this machine, and say where it is: unzipped, its index.html plays in a browser. A plan exports games up to its cap; a game of gigabytes takes minutes, and as much of this machine's memory.",
85827
+ // Its words cut to make room under Cursor's list size for the website's own tool (2026-10-26).
85828
+ description: "write the game's export, a zip that plays anywhere, on this machine, and say where it is: unzipped, its index.html plays in a browser. A plan exports games up to its cap; a large game takes minutes, and memory.",
85819
85829
  inputSchema: object({ game: GAME }, ["game"]),
85820
85830
  handle: async (args, ctx) => {
85821
85831
  const slug = textArg(args, "game");
@@ -91546,7 +91556,7 @@ var import_ajv_formats = __toESM(require_dist3(), 1);
91546
91556
  // ../agent/dist/families.js
91547
91557
  var fam = (name, about, actions) => ({ name, about, actions: Object.entries(actions).map(([action, tool]) => ({ action, tool })) });
91548
91558
  var FAMILIES2 = [
91549
- fam("games", "the games in the library: list them, open one, start or import one, export one, keep one on GitHub; and game text given as source, checked, run or replayed as it is", {
91559
+ fam("games", "the games in the library, and game text given as source", {
91550
91560
  list: "list_games",
91551
91561
  open: "open_game",
91552
91562
  new: "new_game",
@@ -91573,7 +91583,7 @@ var FAMILIES2 = [
91573
91583
  redo: "redo",
91574
91584
  art: "undo_art"
91575
91585
  }),
91576
- fam("playtest", "play the game yourself, headless: play a track, play until something happens, look at it, inspect it, start over, and save or return to a moment", {
91586
+ fam("playtest", "play the game yourself, headless, and look at it", {
91577
91587
  play: "playtest_play",
91578
91588
  until: "playtest_until",
91579
91589
  look: "playtest_look",
@@ -91582,13 +91592,13 @@ var FAMILIES2 = [
91582
91592
  snapshot: "playtest_snapshot",
91583
91593
  restore: "playtest_restore"
91584
91594
  }),
91585
- fam("art", "a game's pictures: paint one, model one in 3D, read one, list them", {
91595
+ fam("art", "a game's pictures, painted or modelled in 3D", {
91586
91596
  paint: "paint_art",
91587
91597
  model: "model_art",
91588
91598
  read: "read_art",
91589
91599
  list: "list_art"
91590
91600
  }),
91591
- fam("sound", "a game's sound: design an effect, compose music, listen to them, list them", {
91601
+ fam("sound", "a game's sound effects and music", {
91592
91602
  design: "design_sound",
91593
91603
  compose: "compose_music",
91594
91604
  listen: "listen",
@@ -91614,6 +91624,14 @@ var FAMILIES2 = [
91614
91624
  online: "app_online",
91615
91625
  online_logs: "app_online_logs",
91616
91626
  online_query: "app_online_query"
91627
+ }),
91628
+ // The 16th (the owner, 2026-10-26): what is the website's, not a game's.
91629
+ fam("website", "your Gamesteel account on the website", {
91630
+ account: "website_account",
91631
+ workspaces: "website_workspaces",
91632
+ members: "website_members",
91633
+ storage: "website_storage",
91634
+ sign_in: "sign_in"
91617
91635
  })
91618
91636
  ];
91619
91637
 
@@ -91648,6 +91666,15 @@ var WAIT_TOOL = {
91648
91666
  description: `wait up to ${String(JOB_MS / 1e3)} seconds for a call of yours still going, and answer with what it said`,
91649
91667
  inputSchema: { type: "object", additionalProperties: false, properties: {} }
91650
91668
  };
91669
+ var WEBSITE_READS = { account: "website_account", workspaces: "website_workspaces", members: "website_members", storage: "website_storage" };
91670
+ var NO_OPTIONS = { type: "object", additionalProperties: false, properties: {} };
91671
+ var WEBSITE_TOOLS = [
91672
+ { name: WEBSITE_READS.account, description: "which account and workspace this works in, its plan, limits and pages", inputSchema: NO_OPTIONS },
91673
+ { name: WEBSITE_READS.workspaces, description: "the person's workspaces, their role in each, and which this works in", inputSchema: NO_OPTIONS },
91674
+ { name: WEBSITE_READS.members, description: "the workspace's people and their roles", inputSchema: NO_OPTIONS },
91675
+ { name: WEBSITE_READS.storage, description: "what the workspace keeps: by kind, the largest files, what no game uses", inputSchema: NO_OPTIONS }
91676
+ ];
91677
+ var WEBSITE_NAMES = new Set(Object.values(WEBSITE_READS));
91651
91678
  var EDITING = new Map(EDIT_TOOLS.map((tool) => [tool.name, tool]));
91652
91679
  var CORE_LINES = /* @__PURE__ */ new Map([
91653
91680
  ["list_games", "the saved games in the library, newest first"],
@@ -91657,6 +91684,36 @@ var CORE_LINES = /* @__PURE__ */ new Map([
91657
91684
  ["create_game", "generate a seeded platform maze from a design; with save, keep it in the library as a game you can edit"]
91658
91685
  ]);
91659
91686
  var CORE_TOOLS = TOOL_NAMES.filter((name) => !EDITING.has(name) && CORE_LINES.has(name));
91687
+ var READING_TOOLS = /* @__PURE__ */ new Set([
91688
+ // The account read and signed in again too, so an agent in a read-only workspace can still move to another.
91689
+ "guide",
91690
+ "wait_for_calls",
91691
+ ...Object.values(WEBSITE_READS),
91692
+ "sign_in",
91693
+ "open_game",
91694
+ "read_scene",
91695
+ "read_type",
91696
+ "read_code",
91697
+ "changes_since",
91698
+ "list_art",
91699
+ "list_components",
91700
+ "describe_component",
91701
+ "list_sounds",
91702
+ "list_fonts",
91703
+ "read_art",
91704
+ "list_made",
91705
+ "search_code",
91706
+ "find_references",
91707
+ "list_games",
91708
+ "validate",
91709
+ "simulate",
91710
+ "replay",
91711
+ "github_status",
91712
+ // A game's online, its server's logs and its data, read only (the online services spec).
91713
+ "app_online",
91714
+ "app_online_logs",
91715
+ "app_online_query"
91716
+ ]);
91660
91717
  var EDIT_OPS = Object.keys(OP_FIELDS);
91661
91718
 
91662
91719
  // ../core/dist/render/index.js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gamesteel",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "description": "The Gamesteel program your AI agent starts, and the command that sets it up in Claude Code, Codex, Gemini CLI, Cursor, VS Code and 25 more. The work runs on your machine; the website keeps your games.",
5
5
  "keywords": [
6
6
  "gamesteel",
@@ -13,7 +13,7 @@
13
13
  "cursor",
14
14
  "games"
15
15
  ],
16
- "homepage": "https://gamesteel.onrender.com/connect",
16
+ "homepage": "https://gamesteel.studio/connect",
17
17
  "license": "SEE LICENSE IN LICENSE",
18
18
  "type": "module",
19
19
  "bin": {
@@ -39,23 +39,23 @@
39
39
  "@modelcontextprotocol/sdk": "^1.0.0",
40
40
  "esbuild": "0.28.2",
41
41
  "miniflare": "4.20260730.0",
42
- "@gamesteel/billing": "0.1.0",
43
42
  "@gamesteel/accounts": "0.1.0",
44
- "@gamesteel/connect": "0.1.0",
45
43
  "@gamesteel/builder": "0.1.0",
46
- "@gamesteel/core": "0.1.0",
44
+ "@gamesteel/billing": "0.1.0",
47
45
  "@gamesteel/agent": "0.1.0",
48
- "@gamesteel/github": "0.1.0",
46
+ "@gamesteel/connect": "0.1.0",
49
47
  "@gamesteel/cloud": "0.1.0",
48
+ "@gamesteel/i18n": "0.1.0",
50
49
  "@gamesteel/edit": "0.1.0",
50
+ "@gamesteel/model": "0.1.0",
51
+ "@gamesteel/core": "0.1.0",
51
52
  "@gamesteel/service": "0.1.0",
52
- "@gamesteel/store": "0.1.0",
53
53
  "@gamesteel/online": "0.1.0",
54
- "@gamesteel/model": "0.1.0",
55
54
  "@gamesteel/studio": "0.1.0",
56
- "@gamesteel/design": "0.1.0",
57
55
  "@gamesteel/stores": "0.1.0",
58
- "@gamesteel/i18n": "0.1.0"
56
+ "@gamesteel/github": "0.1.0",
57
+ "@gamesteel/design": "0.1.0",
58
+ "@gamesteel/store": "0.1.0"
59
59
  },
60
60
  "scripts": {
61
61
  "pretest": "pnpm --filter \"gamesteel^...\" --filter \"!@gamesteel/studio\" build && pnpm --filter @gamesteel/studio exec tsc -p tsconfig.json && pnpm build",