spacecode 2.4.0 → 2.4.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/repl.mjs CHANGED
@@ -5000,7 +5000,7 @@ function createProfileClient({ baseUrl, apiKey, fetch: doFetch, timeoutMs = 8e3
5000
5000
  method,
5001
5001
  headers: { Authorization: `Bearer ${apiKey}`, ...init.body !== void 0 ? { "content-type": "application/json" } : {}, ...init.headers },
5002
5002
  ...init.body !== void 0 ? { body: JSON.stringify(init.body) } : {},
5003
- signal: AbortSignal.timeout(timeoutMs)
5003
+ signal: AbortSignal.timeout(init.timeoutMs ?? timeoutMs)
5004
5004
  });
5005
5005
  } catch (err) {
5006
5006
  throw new ProfileApiError(0, `profile request failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -5033,7 +5033,7 @@ function createProfileClient({ baseUrl, apiKey, fetch: doFetch, timeoutMs = 8e3
5033
5033
  },
5034
5034
  /** Asks the server-side classifier to decide keep/on_demand/drop per section (see adapt-plan.ts). */
5035
5035
  async adapt(sections) {
5036
- const res = await call("POST", "/adapt", { body: { sections } });
5036
+ const res = await call("POST", "/adapt", { body: { sections }, timeoutMs: ADAPT_TIMEOUT_MS });
5037
5037
  return await res.json();
5038
5038
  },
5039
5039
  async put(kind, name, input) {
@@ -5044,7 +5044,7 @@ function createProfileClient({ baseUrl, apiKey, fetch: doFetch, timeoutMs = 8e3
5044
5044
  }
5045
5045
  };
5046
5046
  }
5047
- var ProfileApiError;
5047
+ var ProfileApiError, ADAPT_TIMEOUT_MS;
5048
5048
  var init_profile_client = __esm({
5049
5049
  "../agent/src/import/profile-client.ts"() {
5050
5050
  "use strict";
@@ -5056,6 +5056,7 @@ var init_profile_client = __esm({
5056
5056
  this.name = "ProfileApiError";
5057
5057
  }
5058
5058
  };
5059
+ ADAPT_TIMEOUT_MS = 1e5;
5059
5060
  }
5060
5061
  });
5061
5062
 
@@ -5324,28 +5325,41 @@ function applyPlan(input, decisions, maxCoreChars = MAX_CORE_CHARS) {
5324
5325
  }
5325
5326
  const missing = input.sections.filter((s) => !seen.has(s.slug)).map((s) => s.slug);
5326
5327
  if (missing.length > 0) throw new AdaptPlanError(`plan does not decide section(s): ${missing.join(", ")}`);
5327
- const kept = [];
5328
- const onDemand = [];
5329
- const dropped = [];
5330
- const index = [];
5331
- for (const d of decisions) {
5332
- const s = bySlug.get(d.slug);
5333
- if (d.decision === "keep") kept.push(s.text);
5334
- else if (d.decision === "on_demand") {
5335
- onDemand.push({ slug: s.slug, title: s.title, text: s.text });
5336
- index.push(`- ${s.slug}: ${s.title} \u2014 ${d.summary.trim().replace(/\s+/g, " ")}`);
5337
- } else dropped.push({ slug: s.slug, title: s.title, reason: d.reason.trim(), unsupported: s.unsupported });
5338
- }
5339
- const indexBlock = index.length > 0 ? `
5328
+ const keptSlugs = new Set(decisions.filter((d) => d.decision === "keep").map((d) => d.slug));
5329
+ const summaries = new Map(decisions.map((d) => [d.slug, d.summary?.trim().replace(/\s+/g, " ") ?? ""]));
5330
+ const demoted = [];
5331
+ const assemble = () => {
5332
+ const kept = [];
5333
+ const onDemand2 = [];
5334
+ const dropped2 = [];
5335
+ const index = [];
5336
+ for (const d of decisions) {
5337
+ const s = bySlug.get(d.slug);
5338
+ if (keptSlugs.has(d.slug)) kept.push(s.text);
5339
+ else if (d.decision === "drop") dropped2.push({ slug: s.slug, title: s.title, reason: d.reason.trim(), unsupported: s.unsupported });
5340
+ else {
5341
+ onDemand2.push({ slug: s.slug, title: s.title, text: s.text });
5342
+ index.push(`- ${s.slug}: ${s.title} \u2014 ${summaries.get(s.slug) || `read when working on: ${s.title}`}`);
5343
+ }
5344
+ }
5345
+ const indexBlock = index.length > 0 ? `
5340
5346
  ## More instructions (on demand)
5341
5347
  Use the instructions_read tool with a section name to read one before acting in that area:
5342
5348
  ${index.join("\n")}
5343
5349
  ` : "";
5344
- const core = input.preamble + kept.join("") + indexBlock;
5345
- if (core.length > maxCoreChars) throw new AdaptPlanError(`core is ${core.length} chars, over the ${maxCoreChars} budget: demote larger sections to on_demand`);
5350
+ return { core: input.preamble + kept.join("") + indexBlock, onDemand: onDemand2, dropped: dropped2 };
5351
+ };
5352
+ let { core, onDemand, dropped } = assemble();
5353
+ while (core.length > maxCoreChars && keptSlugs.size > 0) {
5354
+ const largest = [...keptSlugs].map((slug) => bySlug.get(slug)).sort((a, b2) => b2.chars - a.chars)[0];
5355
+ keptSlugs.delete(largest.slug);
5356
+ demoted.push({ slug: largest.slug, title: largest.title });
5357
+ ({ core, onDemand, dropped } = assemble());
5358
+ }
5359
+ if (core.length > maxCoreChars) throw new AdaptPlanError(`core is ${core.length} chars, over the ${maxCoreChars} budget even with every section on demand`);
5346
5360
  const translated = input.preamble + input.sections.map((s) => s.text).join("");
5347
5361
  const coverage = checkCoverage(translated, [core, ...onDemand.map((o) => o.text)], dropped.map((d) => bySlug.get(d.slug).text));
5348
- return { core, onDemand, dropped, coverage, coreChars: core.length };
5362
+ return { core, onDemand, dropped, coverage, coreChars: core.length, demoted };
5349
5363
  }
5350
5364
  var AdaptPlanError, MAX_CORE_CHARS;
5351
5365
  var init_adapt_plan = __esm({
@@ -5557,6 +5571,7 @@ async function sha12(text) {
5557
5571
  function formatAdaptReport(r, before, replaced) {
5558
5572
  const lines2 = [`Adapted instructions: ${before} chars -> core ${r.coreChars} chars + ${r.onDemand.length} on-demand section(s), ${r.dropped.length} dropped.`];
5559
5573
  for (const x2 of replaced) lines2.push(` tool name ${x2.from} -> ${x2.to} (${x2.count}x)`);
5574
+ for (const d of r.demoted) lines2.push(` demoted ${d.slug}: kept by the model but moved on demand to fit the core budget`);
5560
5575
  for (const o of r.onDemand) lines2.push(` on demand ${o.slug} (${o.text.length} chars)`);
5561
5576
  for (const d of r.dropped) lines2.push(` DROPPED ${d.slug}: ${d.reason}${d.unsupported.length ? ` [${d.unsupported.join("; ")}]` : ""}`);
5562
5577
  if (r.coverage.droppedRules.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spacecode",
3
- "version": "2.4.0",
3
+ "version": "2.4.2",
4
4
  "description": "SpaceCode - launch cloud dev environments with AI coding agents",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",