gamesteel 0.4.0 → 0.4.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.
- package/dist/gamesteel.js +185 -46
- package/dist/pkgs/studio/dist/server/playtest-worker.js +27 -12
- package/package.json +9 -8
package/dist/gamesteel.js
CHANGED
|
@@ -64163,12 +64163,52 @@ function write(file, before2, after, paste) {
|
|
|
64163
64163
|
return { kind: "refused", why: `${file} could not be written: ${error2.message}`, text: paste };
|
|
64164
64164
|
}
|
|
64165
64165
|
}
|
|
64166
|
-
|
|
64166
|
+
var CODEX_SCHEMA_BYTES = 131072;
|
|
64167
|
+
var CODEX_SETTINGS = [
|
|
64168
|
+
"JAVA_HOME",
|
|
64169
|
+
"ANDROID_HOME",
|
|
64170
|
+
"ANDROID_SDK_ROOT",
|
|
64171
|
+
"BLENDER",
|
|
64172
|
+
"GAMESTEEL_KEY",
|
|
64173
|
+
"GAMESTEEL_SITE",
|
|
64174
|
+
"GAMESTEEL_ANDROID_TEMPLATE",
|
|
64175
|
+
"HTTP_PROXY",
|
|
64176
|
+
"HTTPS_PROXY",
|
|
64177
|
+
"NO_PROXY",
|
|
64178
|
+
"http_proxy",
|
|
64179
|
+
"https_proxy",
|
|
64180
|
+
"no_proxy"
|
|
64181
|
+
];
|
|
64182
|
+
var isTable = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
64183
|
+
var OWN_TOML_KEYS = /* @__PURE__ */ new Set([
|
|
64184
|
+
"command",
|
|
64185
|
+
"args",
|
|
64186
|
+
"env",
|
|
64187
|
+
"startup_timeout_sec",
|
|
64188
|
+
"tool_timeout_sec",
|
|
64189
|
+
"default_tools_approval_mode",
|
|
64190
|
+
"tool_input_schema_max_bytes",
|
|
64191
|
+
"omit_tools_from",
|
|
64192
|
+
"env_vars"
|
|
64193
|
+
]);
|
|
64194
|
+
var tomlKey = (key) => /^[A-Za-z0-9_-]+$/.test(key) ? key : tomlString(key);
|
|
64195
|
+
function tomlBody(agent, launch, before2 = {}) {
|
|
64196
|
+
const theirs = Object.entries(isTable(before2["env"]) ? before2["env"] : {}).filter(([name2]) => !name2.startsWith("GAMESTEEL_"));
|
|
64197
|
+
const env = theirs.length === 0 ? launch.env : { ...Object.fromEntries(theirs), ...launch.env };
|
|
64198
|
+
const approval = typeof before2["default_tools_approval_mode"] === "string" ? before2["default_tools_approval_mode"] : "approve";
|
|
64167
64199
|
return [
|
|
64168
64200
|
`command = ${tomlString(launch.command)}`,
|
|
64169
64201
|
`args = [${launch.args.map(tomlString).join(", ")}]`,
|
|
64170
|
-
...
|
|
64171
|
-
...agent.id === "codex" ? [
|
|
64202
|
+
...env === void 0 ? [] : [`env = ${tomlValue(env)}`],
|
|
64203
|
+
...agent.id === "codex" ? [
|
|
64204
|
+
`startup_timeout_sec = ${String(START_SECONDS)}`,
|
|
64205
|
+
`tool_timeout_sec = ${String(CALL_SECONDS)}`,
|
|
64206
|
+
`default_tools_approval_mode = ${tomlString(approval)}`,
|
|
64207
|
+
`tool_input_schema_max_bytes = ${String(CODEX_SCHEMA_BYTES)}`,
|
|
64208
|
+
'omit_tools_from = ["deferred"]',
|
|
64209
|
+
`env_vars = [${CODEX_SETTINGS.map(tomlString).join(", ")}]`
|
|
64210
|
+
] : [],
|
|
64211
|
+
...Object.entries(before2).filter(([key]) => !OWN_TOML_KEYS.has(key)).map(([key, value]) => `${tomlKey(key)} = ${tomlValue(value)}`)
|
|
64172
64212
|
];
|
|
64173
64213
|
}
|
|
64174
64214
|
function jsonEntry(agent, launch) {
|
|
@@ -64356,7 +64396,7 @@ function launchOrNull(agent, env) {
|
|
|
64356
64396
|
return null;
|
|
64357
64397
|
}
|
|
64358
64398
|
}
|
|
64359
|
-
var tomlFor = (agent, form) => tomlBody(agent, form.launch);
|
|
64399
|
+
var tomlFor = (agent, form, before2) => tomlBody(agent, form.launch, before2);
|
|
64360
64400
|
var tomlListFor = (form) => [
|
|
64361
64401
|
`name = ${tomlString(NAME)}`,
|
|
64362
64402
|
'transport = "stdio"',
|
|
@@ -64420,7 +64460,8 @@ function connectWith(agent, env, print, launch) {
|
|
|
64420
64460
|
}
|
|
64421
64461
|
}
|
|
64422
64462
|
if (agent.way === "toml") {
|
|
64423
|
-
const
|
|
64463
|
+
const there2 = before2 === null ? void 0 : tomlTable(before2, NAME);
|
|
64464
|
+
const body3 = tomlFor(agent, form, isTable(there2) ? there2 : void 0);
|
|
64424
64465
|
const paste2 = [`[mcp_servers.${NAME}]`, ...body3].join("\n");
|
|
64425
64466
|
try {
|
|
64426
64467
|
return viaFile(file, before2, setTomlServer(withoutOld(agent, env, before2) ?? "", NAME, body3), print, paste2);
|
|
@@ -82098,6 +82139,10 @@ function admit(bound, value, at5) {
|
|
|
82098
82139
|
return refuse2("unknown-argument", `${at5}.${key}`, raw[key], known2.join(", "), null, `${at5} does not take '${key}'; it takes ${known2.join(", ")}. unknown arguments are refused rather than ignored, because an ignored one is how a call comes to look stronger than it was`);
|
|
82099
82140
|
}
|
|
82100
82141
|
}
|
|
82142
|
+
const missing2 = known2.filter((key) => raw[key] === void 0 && bound.required.includes(key));
|
|
82143
|
+
if (missing2.length > 1) {
|
|
82144
|
+
return refuse2("missing-argument", `${at5}.${missing2[0] ?? ""}`, void 0, "required", null, `${at5} needs ${missing2.slice(0, -1).join(", ")} and ${missing2[missing2.length - 1] ?? ""}`);
|
|
82145
|
+
}
|
|
82101
82146
|
const out2 = {};
|
|
82102
82147
|
for (const key of known2.sort()) {
|
|
82103
82148
|
const field2 = bound.fields[key];
|
|
@@ -95653,7 +95698,7 @@ var START = [
|
|
|
95653
95698
|
"## Read as you go",
|
|
95654
95699
|
"",
|
|
95655
95700
|
"- game: the game text. Read it before writing one.",
|
|
95656
|
-
"- scripts, then api: how scripts run, and the exact TypeScript they are checked against. Most of a good game",
|
|
95701
|
+
"- scripts, then api and api-game: how scripts run, and the exact TypeScript they are checked against. Most of a good game",
|
|
95657
95702
|
" lives in its scripts.",
|
|
95658
95703
|
"- drawing: art drawn in code: shapes, gradients, soft light, curves, panels, every option.",
|
|
95659
95704
|
"- style: craft -- palette, light, texture, depth, UI and type, and the tells that make art look generated.",
|
|
@@ -95692,6 +95737,9 @@ var START = [
|
|
|
95692
95737
|
" the title, a menu, a hit, the ending. Words are cheap; pictures cost more, so look on purpose.",
|
|
95693
95738
|
"6. Polish until it is a game you would show someone.",
|
|
95694
95739
|
"",
|
|
95740
|
+
"games new and games open answer with the game's link, where the person sees and plays it in the editor: give it to",
|
|
95741
|
+
"the person whenever there is something to see, the first time above all. A look with shaders is drawn there too.",
|
|
95742
|
+
"",
|
|
95695
95743
|
"## Made for this game, never repeated",
|
|
95696
95744
|
"",
|
|
95697
95745
|
"Before a character, a creature, a vehicle, a building, or any song:",
|
|
@@ -96028,16 +96076,27 @@ var MODEL = [
|
|
|
96028
96076
|
];
|
|
96029
96077
|
var SCRIPTS = [
|
|
96030
96078
|
...SCRIPTS_PRIMER,
|
|
96031
|
-
"The exact declarations every script is checked against are the api
|
|
96079
|
+
"The exact declarations every script is checked against are the api and api-game topics."
|
|
96032
96080
|
];
|
|
96033
|
-
function agentApi() {
|
|
96081
|
+
function agentApi(part) {
|
|
96034
96082
|
const own3 = (what, name2) => `/** ${what}: one of the game's own, own:<name>, made for it. */
|
|
96035
96083
|
type ${name2} = \`own:\${string}\`
|
|
96036
96084
|
`;
|
|
96037
|
-
|
|
96038
|
-
|
|
96039
|
-
|
|
96040
|
-
|
|
96085
|
+
const whole3 = SCRIPT_API.trimEnd().replace(/(?:\/\*\*[^\n]*\*\/\n)?type SoundName = [^\n]*\n/, () => own3("A sound", "SoundName")).replace(/(?:\/\*\*[^\n]*\*\/\n)?type MusicName = [^\n]*\n/, () => own3("A song", "MusicName"));
|
|
96086
|
+
const at5 = whole3.indexOf("\ninterface Game {");
|
|
96087
|
+
if (at5 < 0)
|
|
96088
|
+
throw new Error("the script API has no interface Game to split it at");
|
|
96089
|
+
return part === "objects" ? [
|
|
96090
|
+
"// The script API, part one, as the type checker holds scripts to it: the shared types, tweens and sequences, Thing,",
|
|
96091
|
+
"// sounds, songs and the Mixer, Turns, the UI, spawning, Behaviour, Bot, Check, GameScript, input, rays, the camera",
|
|
96092
|
+
"// and bursts. A sound and a song are the game's own (own:<name>); the stock names older games still use are left",
|
|
96093
|
+
"// out here. this.game, drawing, noise and console are part two, the api-game topic.",
|
|
96094
|
+
whole3.slice(0, at5).trimEnd()
|
|
96095
|
+
].join("\n") : [
|
|
96096
|
+
"// The script API, part two, as the type checker holds scripts to it: this.game (interface Game), drawing (Draw,",
|
|
96097
|
+
"// its layers, paints and shaders), noise and console. The types it names, Thing, Point and Colour among them, are",
|
|
96098
|
+
"// part one, the api topic.",
|
|
96099
|
+
whole3.slice(at5 + 1)
|
|
96041
96100
|
].join("\n");
|
|
96042
96101
|
}
|
|
96043
96102
|
var TEAM = [
|
|
@@ -96291,18 +96350,19 @@ var GUIDE_TOPICS = [
|
|
|
96291
96350
|
{ name: "start", about: "how to work, and the bar for a finished game -- read it first", text: () => START.join("\n") },
|
|
96292
96351
|
{ name: "game", about: "the game text: settings, types, bodies, levels and tiles, the camera, rules, controls", text: () => [...quickWay(), ...gameText()].join("\n") },
|
|
96293
96352
|
{ name: "scripts", about: "how scripts run: hooks, state, timers, tweens, screens, sound, with ready-made UI", text: () => SCRIPTS.join("\n") },
|
|
96294
|
-
{ name: "api", about: "the script API,
|
|
96353
|
+
{ name: "api", about: "the script API, part one: Thing, scripts, sound, UI, input", text: () => agentApi("objects") },
|
|
96354
|
+
{ name: "api-game", about: "the script API, part two: this.game and drawing", text: () => agentApi("game") },
|
|
96295
96355
|
{ name: "drawing", about: "art drawn in code: layers and units, shapes, gradients, soft light, curves, panels, push and pop, screens that scale", text: () => DRAWING.join("\n") },
|
|
96296
|
-
{ name: "shaders", about: "drawing with the graphics card: boxes
|
|
96356
|
+
{ name: "shaders", about: "drawing with the graphics card: shaded boxes, shaders over the picture, passes, inputs", text: () => SHADERS.join("\n") },
|
|
96297
96357
|
{ name: "style", about: "craft: palette, light, texture, depth, UI and type, and the tells that make art look generated", text: () => STYLE.join("\n") },
|
|
96298
96358
|
{ name: "feel", about: "screens, transitions, juice, sound and music", text: () => FEEL.join("\n") },
|
|
96299
96359
|
{ name: "sound", about: "designed sound effects and composed music: layers, variants, instruments, loudness, and listening", text: () => SOUND_TOPIC.join("\n") },
|
|
96300
96360
|
{ name: "playtest", about: "playing it yourself with tracks and bots, and looking at it", text: () => playtestGuide().join("\n") },
|
|
96301
96361
|
{ name: "edit", about: "ids, the edit operations, and write_code against edit", text: () => howToEdit().join("\n") },
|
|
96302
96362
|
{ name: "art", about: "art paint: pictures, animations and tilesets painted against the 2D canvas", text: () => ART.join("\n") },
|
|
96303
|
-
{ name: "model", about: "art model: 3D art Blender builds from a short script
|
|
96304
|
-
{ name: "team", about: "working beside teammates and their agents: the board,
|
|
96305
|
-
{ name: "film", about: "films: levels that play themselves, cutscenes, chapters, endFilm, and film render
|
|
96363
|
+
{ name: "model", about: "art model: 3D art Blender builds from a short script, when the person asks for 3D", text: () => MODEL.join("\n") },
|
|
96364
|
+
{ name: "team", about: "working beside teammates and their agents: the board, parts, claims, notes", text: () => TEAM.join("\n") },
|
|
96365
|
+
{ name: "film", about: "films: levels that play themselves, cutscenes, chapters, endFilm, and film render to MP4", text: () => FILM.join("\n") }
|
|
96306
96366
|
];
|
|
96307
96367
|
function guideTopic(name2) {
|
|
96308
96368
|
return GUIDE_TOPICS.find((topic) => topic.name === name2);
|
|
@@ -96398,9 +96458,11 @@ function admitArgs(schema, value, at5) {
|
|
|
96398
96458
|
}
|
|
96399
96459
|
}
|
|
96400
96460
|
const required2 = Array.isArray(schema["required"]) ? schema["required"] : [];
|
|
96401
|
-
|
|
96402
|
-
|
|
96403
|
-
|
|
96461
|
+
const missing2 = [...Object.keys(properties), ...required2.filter((key) => !(key in properties))].filter((key) => required2.includes(key) && raw[key] === void 0);
|
|
96462
|
+
if (missing2.length === 1)
|
|
96463
|
+
return `${at5}.${missing2[0] ?? ""} is required`;
|
|
96464
|
+
if (missing2.length > 1)
|
|
96465
|
+
return `${at5} needs ${missing2.slice(0, -1).join(", ")} and ${missing2[missing2.length - 1] ?? ""}`;
|
|
96404
96466
|
for (const key of known2) {
|
|
96405
96467
|
const property = properties[key];
|
|
96406
96468
|
if (raw[key] === void 0 || property === void 0)
|
|
@@ -107566,13 +107628,15 @@ function guideAnswer(raw) {
|
|
|
107566
107628
|
}
|
|
107567
107629
|
return { content: [{ type: "text", text: topic.text() }] };
|
|
107568
107630
|
}
|
|
107631
|
+
var NAMED_PEOPLE = 4;
|
|
107569
107632
|
function teamInstructions(who) {
|
|
107570
|
-
const
|
|
107633
|
+
const more2 = who.people.length > NAMED_PEOPLE ? ` and ${String(who.people.length - NAMED_PEOPLE)} more` : "";
|
|
107634
|
+
const people = who.people.length === 0 ? "" : ` (${who.people.slice(0, NAMED_PEOPLE).join(", ")}${more2})`;
|
|
107571
107635
|
return [
|
|
107572
|
-
`You are ${who.agent}, in the workspace '${who.workspace}'${people}.
|
|
107573
|
-
"
|
|
107574
|
-
"on the game's board (team), with the parts it touches
|
|
107575
|
-
"the rest."
|
|
107636
|
+
`You are ${who.agent}, in the workspace '${who.workspace}'${people}. Teammates may work on the same games at once:`,
|
|
107637
|
+
"every answer about a game says what they are doing. Before you start something, take it",
|
|
107638
|
+
"on the game's board (team), with the parts it touches, and leave a note when you finish. The guide's team topic",
|
|
107639
|
+
"has the rest."
|
|
107576
107640
|
].join("\n");
|
|
107577
107641
|
}
|
|
107578
107642
|
function createServer(more2) {
|
|
@@ -107700,9 +107764,13 @@ function makesGame(name2, args2, exists) {
|
|
|
107700
107764
|
return false;
|
|
107701
107765
|
}
|
|
107702
107766
|
function servedTools(options = DEFAULT_SERVE, leaveOut = /* @__PURE__ */ new Set()) {
|
|
107703
|
-
const families = familyListing(underlyingTools(options, leaveOut));
|
|
107767
|
+
const families = familyListing(underlyingTools(options, leaveOut)).map((tool) => ({ ...tool, annotations: marksOf(tool.name) }));
|
|
107704
107768
|
return options.schemas === "portable" ? families.map((tool) => ({ ...tool, inputSchema: portableSchema(tool.inputSchema) })) : families;
|
|
107705
107769
|
}
|
|
107770
|
+
var READING_FAMILIES = /* @__PURE__ */ new Set(["guide", "read", "search", "library"]);
|
|
107771
|
+
function marksOf(name2) {
|
|
107772
|
+
return READING_FAMILIES.has(name2) ? { readOnlyHint: true, idempotentHint: true, openWorldHint: false } : { readOnlyHint: false, openWorldHint: name2 === "app" };
|
|
107773
|
+
}
|
|
107706
107774
|
function underlyingTools(_options, leaveOut) {
|
|
107707
107775
|
return toolList().filter((tool) => !leaveOut.has(tool.name));
|
|
107708
107776
|
}
|
|
@@ -111801,7 +111869,7 @@ var FONT_FILES = {
|
|
|
111801
111869
|
};
|
|
111802
111870
|
|
|
111803
111871
|
// ../design/dist/plans.js
|
|
111804
|
-
var line = (text3
|
|
111872
|
+
var line = (text3) => ({ text: text3 });
|
|
111805
111873
|
var PLANS = [
|
|
111806
111874
|
{
|
|
111807
111875
|
id: "starter",
|
|
@@ -111826,7 +111894,7 @@ var PLANS = [
|
|
|
111826
111894
|
extraSeat: 1e3,
|
|
111827
111895
|
everythingIn: "starter",
|
|
111828
111896
|
pick: true,
|
|
111829
|
-
includes: [line("An organization with shared games and roles"
|
|
111897
|
+
includes: [line("An organization with shared games and roles")]
|
|
111830
111898
|
},
|
|
111831
111899
|
{
|
|
111832
111900
|
id: "enterprise",
|
|
@@ -111836,10 +111904,29 @@ var PLANS = [
|
|
|
111836
111904
|
extraSeat: 1e3,
|
|
111837
111905
|
everythingIn: "pro",
|
|
111838
111906
|
pick: false,
|
|
111839
|
-
includes: [line("Invoices instead of cards"
|
|
111907
|
+
includes: [line("Invoices instead of cards"), line("Priority support")]
|
|
111840
111908
|
}
|
|
111841
111909
|
];
|
|
111842
111910
|
|
|
111911
|
+
// ../i18n/dist/index.js
|
|
111912
|
+
function chooseLanguage(header2) {
|
|
111913
|
+
const best = { en: { q: 0, at: Infinity }, es: { q: 0, at: Infinity } };
|
|
111914
|
+
for (const [at5, part] of (header2 ?? "").split(",").entries()) {
|
|
111915
|
+
const [tag = "", ...params] = part.trim().split(";");
|
|
111916
|
+
const primary = tag.trim().toLowerCase().split("-")[0] ?? "";
|
|
111917
|
+
if (primary !== "en" && primary !== "es")
|
|
111918
|
+
continue;
|
|
111919
|
+
const qParam = params.map((param) => param.trim()).find((param) => param.startsWith("q="));
|
|
111920
|
+
const q2 = qParam === void 0 ? 1 : Number(qParam.slice(2));
|
|
111921
|
+
if (!Number.isFinite(q2) || q2 <= 0)
|
|
111922
|
+
continue;
|
|
111923
|
+
if (q2 > best[primary].q || q2 === best[primary].q && at5 < best[primary].at)
|
|
111924
|
+
best[primary] = { q: q2, at: at5 };
|
|
111925
|
+
}
|
|
111926
|
+
const { en: en2, es } = best;
|
|
111927
|
+
return es.q > en2.q || es.q > 0 && es.q === en2.q && es.at < en2.at ? "es" : "en";
|
|
111928
|
+
}
|
|
111929
|
+
|
|
111843
111930
|
// ../studio/dist/server/static.js
|
|
111844
111931
|
function rangeOf(header2, size2) {
|
|
111845
111932
|
if (header2 === void 0)
|
|
@@ -114817,7 +114904,7 @@ function keepSettings(store, doc, slug, prefix, settings) {
|
|
|
114817
114904
|
var isObject5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
114818
114905
|
var TARGETS2 = "android-debug, android-release or ios-project";
|
|
114819
114906
|
var KEY_ROLES = "the upload key is for the workspace's owner and admins";
|
|
114820
|
-
var NO_EXPORT =
|
|
114907
|
+
var NO_EXPORT = (plans) => `this workspace's plan does not export, so it builds no apps: the workspace's owner can choose a plan ${plans === void 0 ? "on the Plan page" : `at ${plans}`}`;
|
|
114821
114908
|
var sizeOf4 = (bytes2) => bytes2 < 1024 * 1024 ? `${String(Math.max(1, Math.round(bytes2 / 1024)))} KB` : `${(bytes2 / (1024 * 1024)).toFixed(1)} MB`;
|
|
114822
114909
|
function stepNow(job) {
|
|
114823
114910
|
return (job.steps.find((step2) => step2.state === "running") ?? job.steps.find((step2) => step2.state === "failed") ?? job.steps.at(-1))?.name ?? "";
|
|
@@ -115009,7 +115096,7 @@ function hostedAppRoutes(options) {
|
|
|
115009
115096
|
}
|
|
115010
115097
|
if (call.action === "build") {
|
|
115011
115098
|
if (!await mayExport(req2))
|
|
115012
|
-
throw new AppRefused(402, NO_EXPORT);
|
|
115099
|
+
throw new AppRefused(402, NO_EXPORT(options.plans));
|
|
115013
115100
|
const job = await builds.build(workspaceId, slug, call.target, source);
|
|
115014
115101
|
return { text: `${job.target} started (build ${job.id}): ${builds.started}. app status says how it goes.` };
|
|
115015
115102
|
}
|
|
@@ -123019,16 +123106,35 @@ Open it, allow Gamesteel, then ask again.`);
|
|
|
123019
123106
|
};
|
|
123020
123107
|
var EARLY_MS = 6e4;
|
|
123021
123108
|
var STALE_LOCK_MS = 12e4;
|
|
123109
|
+
function browserCommand(platform, address) {
|
|
123110
|
+
return platform === "darwin" ? ["open", [address]] : platform === "win32" ? ["rundll32", ["url.dll,FileProtocolHandler", address]] : ["xdg-open", [address]];
|
|
123111
|
+
}
|
|
123022
123112
|
function openInBrowser(address) {
|
|
123023
|
-
const [command2,
|
|
123113
|
+
const [command2, args2] = browserCommand(process.platform, address);
|
|
123024
123114
|
try {
|
|
123025
|
-
const child = spawn4(command2
|
|
123115
|
+
const child = spawn4(command2, args2, { stdio: "ignore", detached: true });
|
|
123026
123116
|
child.on("error", () => void 0);
|
|
123027
123117
|
child.unref();
|
|
123028
123118
|
} catch {
|
|
123029
123119
|
}
|
|
123030
123120
|
}
|
|
123031
|
-
var
|
|
123121
|
+
var SAID = {
|
|
123122
|
+
en: {
|
|
123123
|
+
done: "Gamesteel is signed in. Go back to your agent and ask it again, for example: \u201Ctry again\u201D. You can close this tab.",
|
|
123124
|
+
denied: "You did not allow Gamesteel, so your agent cannot use it yet. To sign in, ask your agent again.",
|
|
123125
|
+
stranger: "This sign-in is not the one Gamesteel asked for. Ask your agent again.",
|
|
123126
|
+
failed: "Gamesteel could not finish signing in. Ask your agent again."
|
|
123127
|
+
},
|
|
123128
|
+
es: {
|
|
123129
|
+
done: "Gamesteel inici\xF3 sesi\xF3n. Vuelve a tu agente y p\xEDdeselo de nuevo, por ejemplo: \xABint\xE9ntalo de nuevo\xBB. Puedes cerrar esta pesta\xF1a.",
|
|
123130
|
+
denied: "No le diste permiso a Gamesteel, as\xED que tu agente a\xFAn no puede usarlo. Para iniciar sesi\xF3n, p\xEDdeselo de nuevo a tu agente.",
|
|
123131
|
+
stranger: "Este inicio de sesi\xF3n no es el que pidi\xF3 Gamesteel. P\xEDdeselo de nuevo a tu agente.",
|
|
123132
|
+
failed: "Gamesteel no pudo terminar de iniciar sesi\xF3n. P\xEDdeselo de nuevo a tu agente."
|
|
123133
|
+
}
|
|
123134
|
+
};
|
|
123135
|
+
var languageOf3 = (req2) => chooseLanguage(req2.headers["accept-language"]);
|
|
123136
|
+
var page = (lang, said4) => `<!doctype html><html lang="${lang}"><meta charset="utf-8"><title>Gamesteel</title><p style="font:16px system-ui;margin:3em">${SAID[lang][said4]}</p></html>`;
|
|
123137
|
+
var REOPEN_MS = 3e4;
|
|
123032
123138
|
var SignIn = class {
|
|
123033
123139
|
constructor(options) {
|
|
123034
123140
|
this.options = options;
|
|
@@ -123040,6 +123146,8 @@ var SignIn = class {
|
|
|
123040
123146
|
clock;
|
|
123041
123147
|
flow = null;
|
|
123042
123148
|
server = null;
|
|
123149
|
+
/** When the sign-in's page was last opened in the browser. */
|
|
123150
|
+
opened = 0;
|
|
123043
123151
|
get file() {
|
|
123044
123152
|
return join33(this.options.home, "credentials.json");
|
|
123045
123153
|
}
|
|
@@ -123078,13 +123186,22 @@ var SignIn = class {
|
|
|
123078
123186
|
/** The address the person opens to sign in: the website's own sign-in, opened in their browser once. */
|
|
123079
123187
|
address() {
|
|
123080
123188
|
if (this.flow === null) {
|
|
123081
|
-
const
|
|
123082
|
-
this.flow =
|
|
123083
|
-
|
|
123084
|
-
if (this.flow ===
|
|
123189
|
+
const flow2 = this.begin();
|
|
123190
|
+
this.flow = flow2;
|
|
123191
|
+
flow2.catch(() => {
|
|
123192
|
+
if (this.flow === flow2) this.flow = null;
|
|
123085
123193
|
});
|
|
123194
|
+
return flow2;
|
|
123086
123195
|
}
|
|
123087
|
-
|
|
123196
|
+
const flow = this.flow;
|
|
123197
|
+
void flow.then((address) => {
|
|
123198
|
+
if (this.flow === flow && this.clock() - this.opened >= REOPEN_MS) this.open(address);
|
|
123199
|
+
}, () => void 0);
|
|
123200
|
+
return flow;
|
|
123201
|
+
}
|
|
123202
|
+
open(address) {
|
|
123203
|
+
this.opened = this.clock();
|
|
123204
|
+
(this.options.openBrowser ?? openInBrowser)(address);
|
|
123088
123205
|
}
|
|
123089
123206
|
/** Ends the sign-in under way: the next one, if the person must sign in again, begins afresh. */
|
|
123090
123207
|
close() {
|
|
@@ -123135,17 +123252,26 @@ var SignIn = class {
|
|
|
123135
123252
|
return;
|
|
123136
123253
|
}
|
|
123137
123254
|
const code = url.searchParams.get("code");
|
|
123255
|
+
const lang = languageOf3(req2);
|
|
123256
|
+
const error2 = url.searchParams.get("error");
|
|
123257
|
+
if (url.searchParams.get("state") === state && error2 !== null) {
|
|
123258
|
+
const denied = error2 === "access_denied";
|
|
123259
|
+
res.writeHead(denied ? 200 : 502, { "content-type": "text/html; charset=utf-8" }).end(page(lang, denied ? "denied" : "failed"));
|
|
123260
|
+
if (denied) this.opened = 0;
|
|
123261
|
+
else this.close();
|
|
123262
|
+
return;
|
|
123263
|
+
}
|
|
123138
123264
|
if (url.searchParams.get("state") !== state || code === null) {
|
|
123139
|
-
res.writeHead(400, { "content-type": "text/html" }).end(page(
|
|
123265
|
+
res.writeHead(400, { "content-type": "text/html; charset=utf-8" }).end(page(lang, "stranger"));
|
|
123140
123266
|
return;
|
|
123141
123267
|
}
|
|
123142
123268
|
void this.form("/oauth/token", { grant_type: "authorization_code", code, redirect_uri: redirectUri, code_verifier: verifier, client_id: clientId, resource }).then(async (answer3) => {
|
|
123143
123269
|
if (answer3.status !== 200) throw new Error(String(answer3.status));
|
|
123144
123270
|
await this.keepLocked(clientId, await answer3.json());
|
|
123145
|
-
res.writeHead(200, { "content-type": "text/html" }).end(page(
|
|
123271
|
+
res.writeHead(200, { "content-type": "text/html; charset=utf-8" }).end(page(lang, "done"));
|
|
123146
123272
|
this.close();
|
|
123147
123273
|
}).catch(() => {
|
|
123148
|
-
res.writeHead(502, { "content-type": "text/html" }).end(page(
|
|
123274
|
+
res.writeHead(502, { "content-type": "text/html; charset=utf-8" }).end(page(lang, "failed"));
|
|
123149
123275
|
});
|
|
123150
123276
|
});
|
|
123151
123277
|
this.server = server;
|
|
@@ -123164,7 +123290,7 @@ var SignIn = class {
|
|
|
123164
123290
|
code_challenge_method: "S256",
|
|
123165
123291
|
resource
|
|
123166
123292
|
}).toString()}`;
|
|
123167
|
-
|
|
123293
|
+
this.open(address);
|
|
123168
123294
|
return address;
|
|
123169
123295
|
}
|
|
123170
123296
|
/** A new token, made by one program on the machine at a time: the others find it made. */
|
|
@@ -123695,7 +123821,7 @@ async function startProgram(options) {
|
|
|
123695
123821
|
models: machineModels(options.models),
|
|
123696
123822
|
// The plan's rule for an app build is the website's, read here; the key is downloaded only from the App tab.
|
|
123697
123823
|
apps,
|
|
123698
|
-
appOptions: { mayExport: async () => (await plan()).limits.export, mayKeepKeys: () => false },
|
|
123824
|
+
appOptions: { mayExport: async () => (await plan()).limits.export, mayKeepKeys: () => false, plans: `${settings.site}/editor#plan` },
|
|
123699
123825
|
// An agent's film render and a look with shaders, drawn by the editors with the game open on the website.
|
|
123700
123826
|
relays: { renders: remoteRenders(site), looks: remoteLooks(site) }
|
|
123701
123827
|
});
|
|
@@ -123805,7 +123931,9 @@ async function startProgram(options) {
|
|
|
123805
123931
|
const listed5 = await site.games();
|
|
123806
123932
|
const names2 = new Set(listed5.map((game) => game.slug));
|
|
123807
123933
|
if (makesGame(name2, args2, (one2) => names2.has(one2) || copy.has(one2)) && listed5.length >= now.limits.games) {
|
|
123808
|
-
|
|
123934
|
+
const slugs = listed5.map((game) => game.slug);
|
|
123935
|
+
const has = slugs.length === 1 ? `${slugs[0] ?? ""}: work on it` : `${slugs.slice(0, -1).join(", ")} and ${slugs.at(-1) ?? ""}: work on one of them`;
|
|
123936
|
+
return refusal3(`the free week makes one game, and this workspace has ${has}, or its owner can choose a plan at ${settings.site}/editor#plan`);
|
|
123809
123937
|
}
|
|
123810
123938
|
}
|
|
123811
123939
|
const named3 = typeof args2["game"] === "string" ? args2["game"] : name2 === "save_game" && typeof args2["name"] === "string" ? args2["name"] : null;
|
|
@@ -123840,8 +123968,9 @@ async function startProgram(options) {
|
|
|
123840
123968
|
const answered2 = await call();
|
|
123841
123969
|
const said4 = team2 !== null && slug !== null && here ? await team2.notes(slug, author) : "";
|
|
123842
123970
|
let answer3 = said4 === "" ? answered2 : { ...answered2, content: [...answered2.content, { type: "text", text: said4 }] };
|
|
123971
|
+
let made2 = [];
|
|
123843
123972
|
if (!reading) {
|
|
123844
|
-
|
|
123973
|
+
made2 = [...gamesHere(copy.root)].filter((one2) => !before2.has(one2));
|
|
123845
123974
|
pending.push(...(await uploader.send([...slug === null ? [] : [slug], ...made2])).pending);
|
|
123846
123975
|
if (slug !== null) moves2.wrote(slug);
|
|
123847
123976
|
}
|
|
@@ -123850,6 +123979,13 @@ async function startProgram(options) {
|
|
|
123850
123979
|
if (report !== null) answer3 = { ...answer3, content: [...answer3.content, { type: "text", text: `
|
|
123851
123980
|
|
|
123852
123981
|
${report}` }] };
|
|
123982
|
+
}
|
|
123983
|
+
const shown3 = (answer3.isError === true ? [] : name2 === "open_game" && slug !== null ? [slug] : made2).filter((one2) => copy.onWebsite(one2));
|
|
123984
|
+
for (const one2 of shown3) {
|
|
123985
|
+
answer3 = { ...answer3, content: [...answer3.content, { type: "text", text: `
|
|
123986
|
+
|
|
123987
|
+
Give the person this link to see and play it: ${settings.site}/editor?game=${one2}&workspace=${now.workspaceId}
|
|
123988
|
+
` }] };
|
|
123853
123989
|
}
|
|
123854
123990
|
if (slug !== null) moves2.settled(slug);
|
|
123855
123991
|
const recorded = slug === null ? null : moves2.said(slug);
|
|
@@ -124299,6 +124435,9 @@ ${lines.join("\n")}` }] } };
|
|
|
124299
124435
|
toolNotices.set("playtest", "The Gamesteel program updated itself: playtests started over at the first tick, and their saved moments were forgotten.");
|
|
124300
124436
|
if (old.tools === null) await old.listing?.catch(() => void 0);
|
|
124301
124437
|
if (initialized && (old.tools === null || old.tools !== next2.tools)) toClient({ jsonrpc: "2.0", method: "notifications/tools/list_changed" });
|
|
124438
|
+
if (old.tools !== null && old.tools !== next2.tools) {
|
|
124439
|
+
say(`Gamesteel updated itself to ${next2.version}, and its tools changed: if your agent's client does not show the new ones, restart it.`);
|
|
124440
|
+
}
|
|
124302
124441
|
try {
|
|
124303
124442
|
options.versions.sweep([next2.version, old.version]);
|
|
124304
124443
|
} catch (error2) {
|
|
@@ -76534,7 +76534,7 @@ var START = [
|
|
|
76534
76534
|
"## Read as you go",
|
|
76535
76535
|
"",
|
|
76536
76536
|
"- game: the game text. Read it before writing one.",
|
|
76537
|
-
"- scripts, then api: how scripts run, and the exact TypeScript they are checked against. Most of a good game",
|
|
76537
|
+
"- scripts, then api and api-game: how scripts run, and the exact TypeScript they are checked against. Most of a good game",
|
|
76538
76538
|
" lives in its scripts.",
|
|
76539
76539
|
"- drawing: art drawn in code: shapes, gradients, soft light, curves, panels, every option.",
|
|
76540
76540
|
"- style: craft -- palette, light, texture, depth, UI and type, and the tells that make art look generated.",
|
|
@@ -76573,6 +76573,9 @@ var START = [
|
|
|
76573
76573
|
" the title, a menu, a hit, the ending. Words are cheap; pictures cost more, so look on purpose.",
|
|
76574
76574
|
"6. Polish until it is a game you would show someone.",
|
|
76575
76575
|
"",
|
|
76576
|
+
"games new and games open answer with the game's link, where the person sees and plays it in the editor: give it to",
|
|
76577
|
+
"the person whenever there is something to see, the first time above all. A look with shaders is drawn there too.",
|
|
76578
|
+
"",
|
|
76576
76579
|
"## Made for this game, never repeated",
|
|
76577
76580
|
"",
|
|
76578
76581
|
"Before a character, a creature, a vehicle, a building, or any song:",
|
|
@@ -76909,16 +76912,27 @@ var MODEL = [
|
|
|
76909
76912
|
];
|
|
76910
76913
|
var SCRIPTS = [
|
|
76911
76914
|
...SCRIPTS_PRIMER,
|
|
76912
|
-
"The exact declarations every script is checked against are the api
|
|
76915
|
+
"The exact declarations every script is checked against are the api and api-game topics."
|
|
76913
76916
|
];
|
|
76914
|
-
function agentApi() {
|
|
76917
|
+
function agentApi(part) {
|
|
76915
76918
|
const own3 = (what, name) => `/** ${what}: one of the game's own, own:<name>, made for it. */
|
|
76916
76919
|
type ${name} = \`own:\${string}\`
|
|
76917
76920
|
`;
|
|
76918
|
-
|
|
76919
|
-
|
|
76920
|
-
|
|
76921
|
-
|
|
76921
|
+
const whole = SCRIPT_API.trimEnd().replace(/(?:\/\*\*[^\n]*\*\/\n)?type SoundName = [^\n]*\n/, () => own3("A sound", "SoundName")).replace(/(?:\/\*\*[^\n]*\*\/\n)?type MusicName = [^\n]*\n/, () => own3("A song", "MusicName"));
|
|
76922
|
+
const at2 = whole.indexOf("\ninterface Game {");
|
|
76923
|
+
if (at2 < 0)
|
|
76924
|
+
throw new Error("the script API has no interface Game to split it at");
|
|
76925
|
+
return part === "objects" ? [
|
|
76926
|
+
"// The script API, part one, as the type checker holds scripts to it: the shared types, tweens and sequences, Thing,",
|
|
76927
|
+
"// sounds, songs and the Mixer, Turns, the UI, spawning, Behaviour, Bot, Check, GameScript, input, rays, the camera",
|
|
76928
|
+
"// and bursts. A sound and a song are the game's own (own:<name>); the stock names older games still use are left",
|
|
76929
|
+
"// out here. this.game, drawing, noise and console are part two, the api-game topic.",
|
|
76930
|
+
whole.slice(0, at2).trimEnd()
|
|
76931
|
+
].join("\n") : [
|
|
76932
|
+
"// The script API, part two, as the type checker holds scripts to it: this.game (interface Game), drawing (Draw,",
|
|
76933
|
+
"// its layers, paints and shaders), noise and console. The types it names, Thing, Point and Colour among them, are",
|
|
76934
|
+
"// part one, the api topic.",
|
|
76935
|
+
whole.slice(at2 + 1)
|
|
76922
76936
|
].join("\n");
|
|
76923
76937
|
}
|
|
76924
76938
|
var TEAM = [
|
|
@@ -77172,18 +77186,19 @@ var GUIDE_TOPICS = [
|
|
|
77172
77186
|
{ name: "start", about: "how to work, and the bar for a finished game -- read it first", text: () => START.join("\n") },
|
|
77173
77187
|
{ name: "game", about: "the game text: settings, types, bodies, levels and tiles, the camera, rules, controls", text: () => [...quickWay(), ...gameText()].join("\n") },
|
|
77174
77188
|
{ name: "scripts", about: "how scripts run: hooks, state, timers, tweens, screens, sound, with ready-made UI", text: () => SCRIPTS.join("\n") },
|
|
77175
|
-
{ name: "api", about: "the script API,
|
|
77189
|
+
{ name: "api", about: "the script API, part one: Thing, scripts, sound, UI, input", text: () => agentApi("objects") },
|
|
77190
|
+
{ name: "api-game", about: "the script API, part two: this.game and drawing", text: () => agentApi("game") },
|
|
77176
77191
|
{ name: "drawing", about: "art drawn in code: layers and units, shapes, gradients, soft light, curves, panels, push and pop, screens that scale", text: () => DRAWING.join("\n") },
|
|
77177
|
-
{ name: "shaders", about: "drawing with the graphics card: boxes
|
|
77192
|
+
{ name: "shaders", about: "drawing with the graphics card: shaded boxes, shaders over the picture, passes, inputs", text: () => SHADERS.join("\n") },
|
|
77178
77193
|
{ name: "style", about: "craft: palette, light, texture, depth, UI and type, and the tells that make art look generated", text: () => STYLE.join("\n") },
|
|
77179
77194
|
{ name: "feel", about: "screens, transitions, juice, sound and music", text: () => FEEL.join("\n") },
|
|
77180
77195
|
{ name: "sound", about: "designed sound effects and composed music: layers, variants, instruments, loudness, and listening", text: () => SOUND_TOPIC.join("\n") },
|
|
77181
77196
|
{ name: "playtest", about: "playing it yourself with tracks and bots, and looking at it", text: () => playtestGuide().join("\n") },
|
|
77182
77197
|
{ name: "edit", about: "ids, the edit operations, and write_code against edit", text: () => howToEdit().join("\n") },
|
|
77183
77198
|
{ name: "art", about: "art paint: pictures, animations and tilesets painted against the 2D canvas", text: () => ART.join("\n") },
|
|
77184
|
-
{ name: "model", about: "art model: 3D art Blender builds from a short script
|
|
77185
|
-
{ name: "team", about: "working beside teammates and their agents: the board,
|
|
77186
|
-
{ name: "film", about: "films: levels that play themselves, cutscenes, chapters, endFilm, and film render
|
|
77199
|
+
{ name: "model", about: "art model: 3D art Blender builds from a short script, when the person asks for 3D", text: () => MODEL.join("\n") },
|
|
77200
|
+
{ name: "team", about: "working beside teammates and their agents: the board, parts, claims, notes", text: () => TEAM.join("\n") },
|
|
77201
|
+
{ name: "film", about: "films: levels that play themselves, cutscenes, chapters, endFilm, and film render to MP4", text: () => FILM.join("\n") }
|
|
77187
77202
|
];
|
|
77188
77203
|
|
|
77189
77204
|
// ../agent/dist/artgen-tools.js
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gamesteel",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
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 26 more. The work runs on your machine; the website keeps your games.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"gamesteel",
|
|
@@ -37,18 +37,19 @@
|
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
39
39
|
"esbuild": "0.28.2",
|
|
40
|
+
"@gamesteel/billing": "0.1.0",
|
|
41
|
+
"@gamesteel/agent": "0.1.0",
|
|
42
|
+
"@gamesteel/connect": "0.1.0",
|
|
40
43
|
"@gamesteel/builder": "0.1.0",
|
|
41
|
-
"@gamesteel/accounts": "0.1.0",
|
|
42
|
-
"@gamesteel/design": "0.1.0",
|
|
43
44
|
"@gamesteel/cloud": "0.1.0",
|
|
44
|
-
"@gamesteel/edit": "0.1.0",
|
|
45
45
|
"@gamesteel/core": "0.1.0",
|
|
46
|
-
"@gamesteel/
|
|
47
|
-
"@gamesteel/
|
|
48
|
-
"@gamesteel/connect": "0.1.0",
|
|
46
|
+
"@gamesteel/edit": "0.1.0",
|
|
47
|
+
"@gamesteel/accounts": "0.1.0",
|
|
49
48
|
"@gamesteel/service": "0.1.0",
|
|
49
|
+
"@gamesteel/i18n": "0.1.0",
|
|
50
50
|
"@gamesteel/studio": "0.1.0",
|
|
51
|
-
"@gamesteel/
|
|
51
|
+
"@gamesteel/store": "0.1.0",
|
|
52
|
+
"@gamesteel/design": "0.1.0",
|
|
52
53
|
"@gamesteel/model": "0.1.0"
|
|
53
54
|
},
|
|
54
55
|
"scripts": {
|