slopwaresystems 0.9.0 → 0.9.2

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/index.js CHANGED
@@ -146,7 +146,7 @@ function fetchLaunchCandidate(launcher2) {
146
146
  var path = fileURLToPath(import.meta.url);
147
147
  var launcher = {
148
148
  path,
149
- bundledVersion: "0.9.0",
149
+ bundledVersion: "0.9.2",
150
150
  bundledMain: fileURLToPath(new URL("./main.js", import.meta.url)),
151
151
  installed: isInstalledLauncherPath(path)
152
152
  };
package/dist/main.js CHANGED
@@ -26542,7 +26542,7 @@ var TaskEventRecord = external_exports.object({
26542
26542
  });
26543
26543
 
26544
26544
  // ../contract/src/work/cli-release.ts
26545
- var CLI_RELEASE = "0.9.0";
26545
+ var CLI_RELEASE = "0.9.2";
26546
26546
  var CLI_VERSION_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
26547
26547
  var CLI_VERSION_MAX = 64;
26548
26548
  function parseCliVersion(version2) {
@@ -27770,7 +27770,8 @@ var SPLAT_RELAY_LIMITS = {
27770
27770
  /** Requests waiting for a place; past it: 503, retryable. */
27771
27771
  queuedRequestsPerSource: 2048,
27772
27772
  webSocketsPerSession: 16,
27773
- webSocketMessageBytes: 1024 * 1024,
27773
+ // Dev servers' hot-reload messages pass 1 MiB (Next with many pages open); Workers take up to 32 MiB since late 2025.
27774
+ webSocketMessageBytes: 16 * 1024 * 1024,
27774
27775
  headerCount: 128,
27775
27776
  headerBytes: 48 * 1024,
27776
27777
  pathLength: 8192,
@@ -29010,7 +29011,7 @@ function resolveAgentIdentity(cwd, fallback = "process") {
29010
29011
  harness: conversation?.harness ?? null,
29011
29012
  directory: repo ? basename3(repo.worktree) : basename3(cwd),
29012
29013
  branch: fetchCurrentBranch(cwd),
29013
- cliVersion: "0.9.0"
29014
+ cliVersion: "0.9.2"
29014
29015
  };
29015
29016
  }
29016
29017
 
@@ -29674,7 +29675,7 @@ function buildUpdateNotice() {
29674
29675
  }
29675
29676
  function resolveLatestCliVersion() {
29676
29677
  const deprecated = fetchDeprecatedVersions();
29677
- return sortCliVersions([CLI_RELEASE, "0.9.0", fetchUpdateStatus().latest ?? CLI_RELEASE]).filter((version2) => !deprecated.has(version2)).at(-1) ?? CLI_RELEASE;
29678
+ return sortCliVersions([CLI_RELEASE, "0.9.2", fetchUpdateStatus().latest ?? CLI_RELEASE]).filter((version2) => !deprecated.has(version2)).at(-1) ?? CLI_RELEASE;
29678
29679
  }
29679
29680
  function formatAgentCliVersion(version2, latest = resolveLatestCliVersion()) {
29680
29681
  const label = version2 ? `slop ${version2}` : "an older slop";
@@ -30110,7 +30111,7 @@ async function updateInstalledCliFromRegistry(launcher, options2) {
30110
30111
  const running = fetchLaunchCandidate(launcher).version;
30111
30112
  const action = running === previous ? "current" : isNewerVersion(running, previous) ? "updated" : "rolled-back";
30112
30113
  const latest = resolveNewestOfferedRelease(index);
30113
- deleteUnusedVersions(/* @__PURE__ */ new Set([running, previous, current, launcher.bundledVersion, "0.9.0"]));
30114
+ deleteUnusedVersions(/* @__PURE__ */ new Set([running, previous, current, launcher.bundledVersion, "0.9.2"]));
30114
30115
  persistUpdateStatus({ checkedAt: now(), latest, failures: 0, lastError: null });
30115
30116
  return { action, running, previous, latest };
30116
30117
  } catch (error62) {
@@ -30917,7 +30918,7 @@ function watchLaunchTarget(onChange) {
30917
30918
  }
30918
30919
  function runMcpRelay() {
30919
30920
  const launcher = readLauncherInfo();
30920
- const own2 = { version: "0.9.0", main: fileURLToPath(import.meta.url), downloaded: false };
30921
+ const own2 = { version: "0.9.2", main: fileURLToPath(import.meta.url), downloaded: false };
30921
30922
  const relay = new McpRelay({
30922
30923
  input: process.stdin,
30923
30924
  output: process.stdout,
@@ -31358,7 +31359,7 @@ async function waitForMessage(api, projectId, taskKey, options2 = {}) {
31358
31359
  setTimeout(() => resolve6(outcome), 50);
31359
31360
  };
31360
31361
  const held = new HeldSession(api, projectId, taskKey, {
31361
- claim: () => options2.claim ?? { harness: null, directory: null, branch: null, cliVersion: "0.9.0" },
31362
+ claim: () => options2.claim ?? { harness: null, directory: null, branch: null, cliVersion: "0.9.2" },
31362
31363
  reconnect: false,
31363
31364
  onHello: options2.onHello,
31364
31365
  onEnd: () => finishWait({ kind: "ended" }),
@@ -34388,7 +34389,7 @@ var SplatPublisherConnection = class {
34388
34389
  const helloTimer = setTimeout(() => socket.close(4e3, "hello timeout"), 2e4);
34389
34390
  let ended = null;
34390
34391
  socket.addEventListener("error", () => socket.close());
34391
- socket.addEventListener("message", (event) => {
34392
+ socket.addEventListener("message", this.buildSplatSocketListener("the relay's message", (event) => {
34392
34393
  if (this.socket !== socket) return;
34393
34394
  if (event.data === "pong") {
34394
34395
  if (pongTimer) clearTimeout(pongTimer);
@@ -34417,7 +34418,7 @@ var SplatPublisherConnection = class {
34417
34418
  }
34418
34419
  if (down.data.type === "end") ended = down.data.reason;
34419
34420
  this.receiveDown(down.data);
34420
- });
34421
+ }));
34421
34422
  socket.addEventListener("close", (event) => {
34422
34423
  clearInterval(pingTimer);
34423
34424
  clearInterval(heartbeat);
@@ -34704,27 +34705,49 @@ var SplatPublisherConnection = class {
34704
34705
  upstream.binaryType = "arraybuffer";
34705
34706
  this.upstreamSockets.set(down.id, upstream);
34706
34707
  let opened = false;
34707
- upstream.addEventListener("open", () => {
34708
+ const closeUpstream = (code, reason) => {
34709
+ try {
34710
+ upstream.close(code, reason);
34711
+ } catch {
34712
+ }
34713
+ };
34714
+ upstream.addEventListener("open", this.buildSplatSocketListener("an app socket's open", () => {
34708
34715
  opened = true;
34709
34716
  this.sendUp({ type: "ws.accept", id: down.id, protocol: upstream.protocol || null });
34710
- });
34711
- upstream.addEventListener("message", (event) => {
34717
+ }, () => closeUpstream(4011, "publisher error")));
34718
+ upstream.addEventListener("message", this.buildSplatSocketListener("an app socket's message", (event) => {
34712
34719
  const text = typeof event.data === "string";
34713
34720
  const payload = text ? new TextEncoder().encode(event.data) : new Uint8Array(event.data);
34714
34721
  if (payload.byteLength > SPLAT_RELAY_LIMITS.webSocketMessageBytes) {
34715
- upstream.close(1009, "message too large");
34722
+ this.log(`A message from localhost:${this.options.port}${down.path} is ${Math.round(payload.byteLength / 1048576)} MB, past the ${SPLAT_RELAY_LIMITS.webSocketMessageBytes / 1048576} MB a preview socket carries; closed that socket`);
34723
+ closeUpstream(4009, "message too large");
34716
34724
  return;
34717
34725
  }
34718
34726
  this.sendUp(buildSplatRelayFrame(text ? SPLAT_RELAY_FRAME.wsText : SPLAT_RELAY_FRAME.wsBinary, down.id, payload));
34719
- });
34720
- upstream.addEventListener("close", (event) => {
34727
+ }, () => closeUpstream(4011, "publisher error")));
34728
+ upstream.addEventListener("close", this.buildSplatSocketListener("an app socket's close", (event) => {
34721
34729
  if (this.upstreamSockets.get(down.id) !== upstream) return;
34722
34730
  this.upstreamSockets.delete(down.id);
34723
34731
  if (!opened) this.sendUp({ type: "ws.reject", id: down.id, status: 502, message: `localhost:${this.options.port} refused the connection` });
34724
34732
  else this.sendUp({ type: "ws.close", id: down.id, code: event.code >= 1e3 && event.code <= 4999 && event.code !== 1005 && event.code !== 1006 ? event.code : 1e3, reason: event.reason.slice(0, 123) });
34725
- });
34733
+ }));
34726
34734
  upstream.addEventListener("error", () => void 0);
34727
34735
  }
34736
+ /**
34737
+ * A socket event handler that cannot take the publisher down: a socket's handlers run outside any caller, so a throw
34738
+ * in one (a close code the runtime refuses, a frame it cannot build) would end the whole process and take every
34739
+ * preview of this source offline. It is logged, `recover` ends just the socket it came from, and publishing goes on.
34740
+ */
34741
+ buildSplatSocketListener(what, handle, recover) {
34742
+ return (event) => {
34743
+ try {
34744
+ handle(event);
34745
+ } catch (error62) {
34746
+ this.log(`Error handling ${what}: ${error62 instanceof Error ? error62.message : String(error62)}`);
34747
+ recover?.();
34748
+ }
34749
+ };
34750
+ }
34728
34751
  /** Everything in flight belonged to the connection that just closed: its requests and sockets to the app end too. */
34729
34752
  releaseStreams() {
34730
34753
  for (const id of [...this.streams.keys()]) this.closeStream(id);
@@ -34922,7 +34945,7 @@ var SplatRendererConnection = class {
34922
34945
  try {
34923
34946
  let path3;
34924
34947
  try {
34925
- const ticket = await this.api.post(`/projects/${this.projectId}/splat/renderer/ticket`, ApiResponses.ConnectTicket, { cliVersion: "0.9.0", onlyMe: this.options.onlyMe ?? false, agent: this.options.agent ?? null, capabilities: ["workspaces"] });
34948
+ const ticket = await this.api.post(`/projects/${this.projectId}/splat/renderer/ticket`, ApiResponses.ConnectTicket, { cliVersion: "0.9.2", onlyMe: this.options.onlyMe ?? false, agent: this.options.agent ?? null, capabilities: ["workspaces"] });
34926
34949
  path3 = ticket.path;
34927
34950
  } catch (error62) {
34928
34951
  if (error62 instanceof CliError && ["unauthenticated", "not_found", "forbidden", "bad_request"].includes(error62.code)) {
@@ -35342,6 +35365,7 @@ ${published.map((source2) => ` ${formatSplatSourceLine(source2)}`).join("\n")}`
35342
35365
  clearInterval(keepAlive);
35343
35366
  renderer.stop();
35344
35367
  emitOutput({ ok: true }, () => "Stopped rendering.");
35368
+ scheduleSplatServeExit();
35345
35369
  });
35346
35370
  registerProjectOption(splat.command("publications")).description("The apps this machine publishes (slop splat serve --name), by workspace.").action(async (options2) => {
35347
35371
  const api = buildAuthedApiClient();
@@ -35552,6 +35576,10 @@ async function servePublication(options2) {
35552
35576
  const reason = await Promise.race([publisher.run(), stopped]);
35553
35577
  publisher.stop(reason);
35554
35578
  emitOutput({ ok: true, sourceId: published.id, reason }, () => reason);
35579
+ scheduleSplatServeExit();
35580
+ }
35581
+ function scheduleSplatServeExit() {
35582
+ setTimeout(() => process.exit(), 250).unref();
35555
35583
  }
35556
35584
 
35557
35585
  // src/commands/mcp/splat-tools.ts
@@ -36950,17 +36978,17 @@ function hasHarnessSetup() {
36950
36978
  function syncMachineSetupAfterUpdate() {
36951
36979
  const nothing = { skills: [], retired: [], reinstalling: false };
36952
36980
  try {
36953
- if (!isUpdateCheckEnabled() || fetchMachineSetupState()?.version === "0.9.0") return nothing;
36981
+ if (!isUpdateCheckEnabled() || fetchMachineSetupState()?.version === "0.9.2") return nothing;
36954
36982
  const lock = claimFileLock(buildMachineSetupLockDirectory(), { staleAfterMs: 6e4 });
36955
36983
  if (!lock) return nothing;
36956
36984
  try {
36957
36985
  const state = fetchMachineSetupState();
36958
- if (state?.version === "0.9.0") return nothing;
36986
+ if (state?.version === "0.9.2") return nothing;
36959
36987
  const skills = hasInstalledSkills() ? installSkills() : [];
36960
36988
  const shipped = Object.keys(SKILLS);
36961
36989
  const retired = deleteRetiredSkills((state?.skills ?? []).filter((name) => !shipped.includes(name)));
36962
36990
  const setupRevision = state?.setupRevision ?? (hasHarnessSetup() ? UNRECORDED_SETUP_REVISION : null);
36963
- persistMachineSetupState({ version: "0.9.0", setupRevision, skills: hasInstalledSkills() ? shipped : [] });
36991
+ persistMachineSetupState({ version: "0.9.2", setupRevision, skills: hasInstalledSkills() ? shipped : [] });
36964
36992
  const reinstalling = setupRevision !== null && setupRevision < SETUP_REVISION && runMcpInstallInBackground();
36965
36993
  return { skills, retired, reinstalling };
36966
36994
  } finally {
@@ -37127,7 +37155,7 @@ async function trustCodexHooks(codexHome) {
37127
37155
  const sendNotification = (method, params) => server.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", method, params })}
37128
37156
  `);
37129
37157
  try {
37130
- await callCodexMethod("initialize", { clientInfo: { name: "slop", version: "0.9.0" }, capabilities: { experimentalApi: true } });
37158
+ await callCodexMethod("initialize", { clientInfo: { name: "slop", version: "0.9.2" }, capabilities: { experimentalApi: true } });
37131
37159
  sendNotification("initialized", {});
37132
37160
  const listed = await callCodexMethod("hooks/list", { cwds: [process.cwd()] });
37133
37161
  const ours = listed.data.flatMap((entry) => entry.hooks).filter((hook) => hook.command?.startsWith("slop hook "));
@@ -37392,7 +37420,7 @@ var options = optionEnd < 0 ? args : args.slice(0, optionEnd);
37392
37420
  updateJsonMode(options.includes("--json"));
37393
37421
  syncMachineSetupAfterUpdate();
37394
37422
  if (!options.includes("--background") && !options.includes("--child")) scheduleBackgroundUpdate();
37395
- var program2 = new Command().name("slop").description("Slopware Tasks from the terminal. Everything a person can do on the board, an agent can do here.").version("0.9.0").option("--json", "machine-readable output: JSON on stdout, errors as JSON on stderr").configureOutput({
37423
+ var program2 = new Command().name("slop").description("Slopware Tasks from the terminal. Everything a person can do on the board, an agent can do here.").version("0.9.2").option("--json", "machine-readable output: JSON on stdout, errors as JSON on stderr").configureOutput({
37396
37424
  outputError: (message, write) => {
37397
37425
  if (!isJsonMode()) write(message);
37398
37426
  },
@@ -37409,7 +37437,7 @@ var sessionCommand = registerSessionCommands(program2);
37409
37437
  registerThreadCommands(program2, taskCommand);
37410
37438
  registerOperationCommands(program2, taskCommand, sessionCommand);
37411
37439
  registerSplatCommands(program2);
37412
- registerMcpCommands(program2, "0.9.0");
37440
+ registerMcpCommands(program2, "0.9.2");
37413
37441
  registerGuideCommand(program2);
37414
37442
  registerSkillCommands(program2);
37415
37443
  registerUpdateCommand(program2);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slopwaresystems",
3
- "version": "0.9.0",
3
+ "version": "0.9.2",
4
4
  "private": false,
5
5
  "description": "slop: the Slopware Tasks board from the terminal, for people and coding agents.",
6
6
  "type": "module",