midsummer-sol 0.3.8 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/package.json +1 -1
  2. package/sol-mcp.js +38 -2
  3. package/sol.js +38 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "midsummer-sol",
3
- "version": "0.3.8",
3
+ "version": "0.3.9",
4
4
  "description": "Sol — agent-native version control (a new git). CLI, MCP server, and no-filesystem SDK.",
5
5
  "bin": { "sol": "./sol.js", "sol-mcp": "./sol-mcp.js", "sol-secret-mcp": "./sol-secret-mcp.js" },
6
6
  "main": "./index.js",
package/sol-mcp.js CHANGED
@@ -4270,9 +4270,10 @@ async function exportManifest(cfg, token) {
4270
4270
  const m = await res.json();
4271
4271
  if (!Array.isArray(m.packIds))
4272
4272
  return exportStreaming(cfg, token);
4273
+ const legacyHashes = m.legacyPaged ? await collectLegacyHashes(cfg, token) : m.legacyNodes ?? [];
4273
4274
  const tasks = [
4274
4275
  ...(m.packIds ?? []).map((packId) => () => fetchPack(cfg, token, packId, false)),
4275
- ...(m.legacyNodes ?? []).map((hash) => () => fetchPack(cfg, token, hash, true))
4276
+ ...chunk(legacyHashes, LEGACY_BATCH_SIZE).map((batch) => () => fetchLegacyBatch(cfg, token, batch))
4276
4277
  ];
4277
4278
  const packNodes = await pool(tasks, CLONE_PACK_CONCURRENCY);
4278
4279
  const nodes = [];
@@ -4281,6 +4282,41 @@ async function exportManifest(cfg, token) {
4281
4282
  nodes.push(n);
4282
4283
  return { schema: m.schema, head: m.head, seq: m.seq, tip: m.tip, ops: m.ops, nodes, refs: m.refs, checkout: m.checkout };
4283
4284
  }
4285
+ async function collectLegacyHashes(cfg, token) {
4286
+ const out = [];
4287
+ let cursor;
4288
+ for (;; ) {
4289
+ const url = `/export/manifest/legacy${cursor ? `?cursor=${encodeURIComponent(cursor)}` : ""}`;
4290
+ const res = await fetch(endpoint(cfg, url), { headers: { authorization: `Bearer ${token}`, "content-type": "application/json" } });
4291
+ if (!res.ok)
4292
+ throw new Error(`remote /export/manifest/legacy -> ${res.status}: ${(await res.text().catch(() => "")).slice(0, 200)}`);
4293
+ const page = await res.json();
4294
+ for (const h of page.hashes ?? [])
4295
+ out.push(h);
4296
+ if (!page.cursor)
4297
+ break;
4298
+ cursor = page.cursor;
4299
+ }
4300
+ return out;
4301
+ }
4302
+ function chunk(xs, size) {
4303
+ const out = [];
4304
+ for (let i = 0;i < xs.length; i += size)
4305
+ out.push(xs.slice(i, i + size));
4306
+ return out;
4307
+ }
4308
+ async function fetchLegacyBatch(cfg, token, hashes) {
4309
+ return retryTransient(async () => {
4310
+ const res = await fetch(endpoint(cfg, "/pack-batch"), {
4311
+ method: "POST",
4312
+ headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
4313
+ body: JSON.stringify({ hashes })
4314
+ });
4315
+ if (!res.ok)
4316
+ throw new Error(`remote /pack-batch -> ${res.status}: ${(await res.text().catch(() => "")).slice(0, 200)}`);
4317
+ return decodePackLine((await res.text()).trim());
4318
+ });
4319
+ }
4284
4320
  async function fetchPack(cfg, token, id, legacy) {
4285
4321
  return retryTransient(async () => {
4286
4322
  const path = `/pack/${encodeURIComponent(id)}${legacy ? "?legacy=1" : ""}`;
@@ -4401,7 +4437,7 @@ async function writeBundle(solDir2, bundle, from = 0) {
4401
4437
  writeFileSync6(join6(solDir2, "HEAD"), JSON.stringify({ head: bundle.head, seq: bundle.seq, logTip: bundle.tip }));
4402
4438
  return fresh.length;
4403
4439
  }
4404
- var endpoint = (cfg, path) => `${cfg.url.replace(/\/+$/, "")}${path}${path.includes("?") ? "&" : "?"}repo=${encodeURIComponent(cfg.repo)}`, remoteHead = (cfg, token) => call(cfg, token, "/head"), remoteGate = (cfg, token, branch) => call(cfg, token, `/head?gateState=true${branch ? `&branch=${encodeURIComponent(branch)}` : ""}`), CLONE_PACK_CONCURRENCY = 12, remoteExport = (cfg, token) => exportManifest(cfg, token), remoteRefs = (cfg, token) => call(cfg, token, "/refs"), remotePush = (cfg, token, body) => call(cfg, token, "/push", { method: "POST", body: JSON.stringify(body) }), remotePromote = (cfg, token, branch) => call(cfg, token, "/promote", { method: "POST", body: JSON.stringify({ branch }) }), SMALL_PUSH_BYTES, BLOB_PACK_BYTES, BLOB_PACK_CONCURRENCY = 6, GIANT_LEAF_BYTES, nodeBytes = (n) => JSON.stringify(n).length, remotePushBlobs = (cfg, token, nodes) => retryTransient(() => call(cfg, token, "/push/blobs", { method: "POST", body: gzipSync3(JSON.stringify({ nodes })), headers: { "content-encoding": "gzip" } })), mrOpen = (cfg, token, body) => call(cfg, token, "/mr", { method: "POST", body: JSON.stringify(body) }), mrList = (cfg, token) => call(cfg, token, "/mrs"), mrDiff = (cfg, token, id) => call(cfg, token, `/mr/diff?id=${id}`), mrGet = (cfg, token, id) => call(cfg, token, `/mr?id=${id}`), mrAction = (cfg, token, action, body) => call(cfg, token, `/mr/${action}`, { method: "POST", body: JSON.stringify(body) }), accessGet = (cfg, token) => call(cfg, token, "/access"), ownerSet = (cfg, token, ownerHandle) => call(cfg, token, "/owner", { method: "POST", body: JSON.stringify({ ownerHandle }) }), accessSet = (cfg, token, body) => call(cfg, token, "/access", { method: "POST", body: JSON.stringify(body) }), policyCheck = (cfg, token, paths) => call(cfg, token, "/policy/check", { method: "POST", body: JSON.stringify({ paths }) }), policyGet = (cfg, token) => call(cfg, token, "/policy"), policyUpsert = (cfg, token, rule) => call(cfg, token, "/policy?write=1", { method: "POST", body: JSON.stringify({ op: "upsert", rule }) }), policyRemove = (cfg, token, pattern) => call(cfg, token, "/policy?write=1", { method: "POST", body: JSON.stringify({ op: "remove", pattern }) }), recipientsForPath = (cfg, token, path) => call(cfg, token, `/recipients?path=${encodeURIComponent(path)}`), recipientsForAudience = (cfg, token, audience, recovery) => call(cfg, token, `/recipients?audience=${encodeURIComponent(JSON.stringify(audience))}${recovery?.length ? `&recovery=${encodeURIComponent(recovery.join(","))}` : ""}`), remoteEnvPush = (cfg, token, bundle) => call(cfg, token, "/env/push", { method: "POST", body: JSON.stringify(bundle) }), remoteEnvAnchor = (cfg, token) => call(cfg, token, "/env/anchor"), remoteEnvPull = (cfg, token) => call(cfg, token, "/env/pull"), forkMeta = (cfg, token, parent) => call(cfg, token, "/fork-meta", { method: "POST", body: JSON.stringify({ parent }) }), forksList = (cfg, token) => call(cfg, token, "/forks"), saveRemote = (solDir2, cfg) => writeFileSync6(join6(solDir2, "remote.json"), JSON.stringify(cfg, null, 2));
4440
+ var endpoint = (cfg, path) => `${cfg.url.replace(/\/+$/, "")}${path}${path.includes("?") ? "&" : "?"}repo=${encodeURIComponent(cfg.repo)}`, remoteHead = (cfg, token) => call(cfg, token, "/head"), remoteGate = (cfg, token, branch) => call(cfg, token, `/head?gateState=true${branch ? `&branch=${encodeURIComponent(branch)}` : ""}`), CLONE_PACK_CONCURRENCY = 12, LEGACY_BATCH_SIZE = 500, remoteExport = (cfg, token) => exportManifest(cfg, token), remoteRefs = (cfg, token) => call(cfg, token, "/refs"), remotePush = (cfg, token, body) => call(cfg, token, "/push", { method: "POST", body: JSON.stringify(body) }), remotePromote = (cfg, token, branch) => call(cfg, token, "/promote", { method: "POST", body: JSON.stringify({ branch }) }), SMALL_PUSH_BYTES, BLOB_PACK_BYTES, BLOB_PACK_CONCURRENCY = 6, GIANT_LEAF_BYTES, nodeBytes = (n) => JSON.stringify(n).length, remotePushBlobs = (cfg, token, nodes) => retryTransient(() => call(cfg, token, "/push/blobs", { method: "POST", body: gzipSync3(JSON.stringify({ nodes })), headers: { "content-encoding": "gzip" } })), mrOpen = (cfg, token, body) => call(cfg, token, "/mr", { method: "POST", body: JSON.stringify(body) }), mrList = (cfg, token) => call(cfg, token, "/mrs"), mrDiff = (cfg, token, id) => call(cfg, token, `/mr/diff?id=${id}`), mrGet = (cfg, token, id) => call(cfg, token, `/mr?id=${id}`), mrAction = (cfg, token, action, body) => call(cfg, token, `/mr/${action}`, { method: "POST", body: JSON.stringify(body) }), accessGet = (cfg, token) => call(cfg, token, "/access"), ownerSet = (cfg, token, ownerHandle) => call(cfg, token, "/owner", { method: "POST", body: JSON.stringify({ ownerHandle }) }), accessSet = (cfg, token, body) => call(cfg, token, "/access", { method: "POST", body: JSON.stringify(body) }), policyCheck = (cfg, token, paths) => call(cfg, token, "/policy/check", { method: "POST", body: JSON.stringify({ paths }) }), policyGet = (cfg, token) => call(cfg, token, "/policy"), policyUpsert = (cfg, token, rule) => call(cfg, token, "/policy?write=1", { method: "POST", body: JSON.stringify({ op: "upsert", rule }) }), policyRemove = (cfg, token, pattern) => call(cfg, token, "/policy?write=1", { method: "POST", body: JSON.stringify({ op: "remove", pattern }) }), recipientsForPath = (cfg, token, path) => call(cfg, token, `/recipients?path=${encodeURIComponent(path)}`), recipientsForAudience = (cfg, token, audience, recovery) => call(cfg, token, `/recipients?audience=${encodeURIComponent(JSON.stringify(audience))}${recovery?.length ? `&recovery=${encodeURIComponent(recovery.join(","))}` : ""}`), remoteEnvPush = (cfg, token, bundle) => call(cfg, token, "/env/push", { method: "POST", body: JSON.stringify(bundle) }), remoteEnvAnchor = (cfg, token) => call(cfg, token, "/env/anchor"), remoteEnvPull = (cfg, token) => call(cfg, token, "/env/pull"), forkMeta = (cfg, token, parent) => call(cfg, token, "/fork-meta", { method: "POST", body: JSON.stringify({ parent }) }), forksList = (cfg, token) => call(cfg, token, "/forks"), saveRemote = (solDir2, cfg) => writeFileSync6(join6(solDir2, "remote.json"), JSON.stringify(cfg, null, 2));
4405
4441
  var init_remote = __esm(() => {
4406
4442
  init_file_store2();
4407
4443
  init_store();
package/sol.js CHANGED
@@ -3503,9 +3503,10 @@ async function exportManifest(cfg, token) {
3503
3503
  const m = await res.json();
3504
3504
  if (!Array.isArray(m.packIds))
3505
3505
  return exportStreaming(cfg, token);
3506
+ const legacyHashes = m.legacyPaged ? await collectLegacyHashes(cfg, token) : m.legacyNodes ?? [];
3506
3507
  const tasks = [
3507
3508
  ...(m.packIds ?? []).map((packId) => () => fetchPack(cfg, token, packId, false)),
3508
- ...(m.legacyNodes ?? []).map((hash) => () => fetchPack(cfg, token, hash, true))
3509
+ ...chunk(legacyHashes, LEGACY_BATCH_SIZE).map((batch) => () => fetchLegacyBatch(cfg, token, batch))
3509
3510
  ];
3510
3511
  const packNodes = await pool(tasks, CLONE_PACK_CONCURRENCY);
3511
3512
  const nodes = [];
@@ -3514,6 +3515,41 @@ async function exportManifest(cfg, token) {
3514
3515
  nodes.push(n);
3515
3516
  return { schema: m.schema, head: m.head, seq: m.seq, tip: m.tip, ops: m.ops, nodes, refs: m.refs, checkout: m.checkout };
3516
3517
  }
3518
+ async function collectLegacyHashes(cfg, token) {
3519
+ const out = [];
3520
+ let cursor;
3521
+ for (;; ) {
3522
+ const url = `/export/manifest/legacy${cursor ? `?cursor=${encodeURIComponent(cursor)}` : ""}`;
3523
+ const res = await fetch(endpoint(cfg, url), { headers: { authorization: `Bearer ${token}`, "content-type": "application/json" } });
3524
+ if (!res.ok)
3525
+ throw new Error(`remote /export/manifest/legacy -> ${res.status}: ${(await res.text().catch(() => "")).slice(0, 200)}`);
3526
+ const page = await res.json();
3527
+ for (const h of page.hashes ?? [])
3528
+ out.push(h);
3529
+ if (!page.cursor)
3530
+ break;
3531
+ cursor = page.cursor;
3532
+ }
3533
+ return out;
3534
+ }
3535
+ function chunk(xs, size) {
3536
+ const out = [];
3537
+ for (let i = 0;i < xs.length; i += size)
3538
+ out.push(xs.slice(i, i + size));
3539
+ return out;
3540
+ }
3541
+ async function fetchLegacyBatch(cfg, token, hashes) {
3542
+ return retryTransient(async () => {
3543
+ const res = await fetch(endpoint(cfg, "/pack-batch"), {
3544
+ method: "POST",
3545
+ headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
3546
+ body: JSON.stringify({ hashes })
3547
+ });
3548
+ if (!res.ok)
3549
+ throw new Error(`remote /pack-batch -> ${res.status}: ${(await res.text().catch(() => "")).slice(0, 200)}`);
3550
+ return decodePackLine((await res.text()).trim());
3551
+ });
3552
+ }
3517
3553
  async function fetchPack(cfg, token, id, legacy) {
3518
3554
  return retryTransient(async () => {
3519
3555
  const path = `/pack/${encodeURIComponent(id)}${legacy ? "?legacy=1" : ""}`;
@@ -3634,7 +3670,7 @@ async function writeBundle(solDir2, bundle, from = 0) {
3634
3670
  writeFileSync5(join5(solDir2, "HEAD"), JSON.stringify({ head: bundle.head, seq: bundle.seq, logTip: bundle.tip }));
3635
3671
  return fresh.length;
3636
3672
  }
3637
- var endpoint = (cfg, path) => `${cfg.url.replace(/\/+$/, "")}${path}${path.includes("?") ? "&" : "?"}repo=${encodeURIComponent(cfg.repo)}`, remoteHead = (cfg, token) => call(cfg, token, "/head"), remoteGate = (cfg, token, branch) => call(cfg, token, `/head?gateState=true${branch ? `&branch=${encodeURIComponent(branch)}` : ""}`), CLONE_PACK_CONCURRENCY = 12, remoteExport = (cfg, token) => exportManifest(cfg, token), remoteRefs = (cfg, token) => call(cfg, token, "/refs"), remotePush = (cfg, token, body) => call(cfg, token, "/push", { method: "POST", body: JSON.stringify(body) }), remotePromote = (cfg, token, branch) => call(cfg, token, "/promote", { method: "POST", body: JSON.stringify({ branch }) }), SMALL_PUSH_BYTES, BLOB_PACK_BYTES, BLOB_PACK_CONCURRENCY = 6, GIANT_LEAF_BYTES, nodeBytes = (n) => JSON.stringify(n).length, remotePushBlobs = (cfg, token, nodes) => retryTransient(() => call(cfg, token, "/push/blobs", { method: "POST", body: gzipSync2(JSON.stringify({ nodes })), headers: { "content-encoding": "gzip" } })), mrOpen = (cfg, token, body) => call(cfg, token, "/mr", { method: "POST", body: JSON.stringify(body) }), mrList = (cfg, token) => call(cfg, token, "/mrs"), mrDiff = (cfg, token, id) => call(cfg, token, `/mr/diff?id=${id}`), mrGet = (cfg, token, id) => call(cfg, token, `/mr?id=${id}`), mrAction = (cfg, token, action, body) => call(cfg, token, `/mr/${action}`, { method: "POST", body: JSON.stringify(body) }), accessGet = (cfg, token) => call(cfg, token, "/access"), ownerSet = (cfg, token, ownerHandle) => call(cfg, token, "/owner", { method: "POST", body: JSON.stringify({ ownerHandle }) }), accessSet = (cfg, token, body) => call(cfg, token, "/access", { method: "POST", body: JSON.stringify(body) }), policyCheck = (cfg, token, paths) => call(cfg, token, "/policy/check", { method: "POST", body: JSON.stringify({ paths }) }), policyGet = (cfg, token) => call(cfg, token, "/policy"), policyUpsert = (cfg, token, rule) => call(cfg, token, "/policy?write=1", { method: "POST", body: JSON.stringify({ op: "upsert", rule }) }), policyRemove = (cfg, token, pattern) => call(cfg, token, "/policy?write=1", { method: "POST", body: JSON.stringify({ op: "remove", pattern }) }), recipientsForPath = (cfg, token, path) => call(cfg, token, `/recipients?path=${encodeURIComponent(path)}`), recipientsForAudience = (cfg, token, audience, recovery) => call(cfg, token, `/recipients?audience=${encodeURIComponent(JSON.stringify(audience))}${recovery?.length ? `&recovery=${encodeURIComponent(recovery.join(","))}` : ""}`), remoteEnvPush = (cfg, token, bundle) => call(cfg, token, "/env/push", { method: "POST", body: JSON.stringify(bundle) }), remoteEnvAnchor = (cfg, token) => call(cfg, token, "/env/anchor"), remoteEnvPull = (cfg, token) => call(cfg, token, "/env/pull"), forkMeta = (cfg, token, parent) => call(cfg, token, "/fork-meta", { method: "POST", body: JSON.stringify({ parent }) }), forksList = (cfg, token) => call(cfg, token, "/forks"), saveRemote = (solDir2, cfg) => writeFileSync5(join5(solDir2, "remote.json"), JSON.stringify(cfg, null, 2));
3673
+ var endpoint = (cfg, path) => `${cfg.url.replace(/\/+$/, "")}${path}${path.includes("?") ? "&" : "?"}repo=${encodeURIComponent(cfg.repo)}`, remoteHead = (cfg, token) => call(cfg, token, "/head"), remoteGate = (cfg, token, branch) => call(cfg, token, `/head?gateState=true${branch ? `&branch=${encodeURIComponent(branch)}` : ""}`), CLONE_PACK_CONCURRENCY = 12, LEGACY_BATCH_SIZE = 500, remoteExport = (cfg, token) => exportManifest(cfg, token), remoteRefs = (cfg, token) => call(cfg, token, "/refs"), remotePush = (cfg, token, body) => call(cfg, token, "/push", { method: "POST", body: JSON.stringify(body) }), remotePromote = (cfg, token, branch) => call(cfg, token, "/promote", { method: "POST", body: JSON.stringify({ branch }) }), SMALL_PUSH_BYTES, BLOB_PACK_BYTES, BLOB_PACK_CONCURRENCY = 6, GIANT_LEAF_BYTES, nodeBytes = (n) => JSON.stringify(n).length, remotePushBlobs = (cfg, token, nodes) => retryTransient(() => call(cfg, token, "/push/blobs", { method: "POST", body: gzipSync2(JSON.stringify({ nodes })), headers: { "content-encoding": "gzip" } })), mrOpen = (cfg, token, body) => call(cfg, token, "/mr", { method: "POST", body: JSON.stringify(body) }), mrList = (cfg, token) => call(cfg, token, "/mrs"), mrDiff = (cfg, token, id) => call(cfg, token, `/mr/diff?id=${id}`), mrGet = (cfg, token, id) => call(cfg, token, `/mr?id=${id}`), mrAction = (cfg, token, action, body) => call(cfg, token, `/mr/${action}`, { method: "POST", body: JSON.stringify(body) }), accessGet = (cfg, token) => call(cfg, token, "/access"), ownerSet = (cfg, token, ownerHandle) => call(cfg, token, "/owner", { method: "POST", body: JSON.stringify({ ownerHandle }) }), accessSet = (cfg, token, body) => call(cfg, token, "/access", { method: "POST", body: JSON.stringify(body) }), policyCheck = (cfg, token, paths) => call(cfg, token, "/policy/check", { method: "POST", body: JSON.stringify({ paths }) }), policyGet = (cfg, token) => call(cfg, token, "/policy"), policyUpsert = (cfg, token, rule) => call(cfg, token, "/policy?write=1", { method: "POST", body: JSON.stringify({ op: "upsert", rule }) }), policyRemove = (cfg, token, pattern) => call(cfg, token, "/policy?write=1", { method: "POST", body: JSON.stringify({ op: "remove", pattern }) }), recipientsForPath = (cfg, token, path) => call(cfg, token, `/recipients?path=${encodeURIComponent(path)}`), recipientsForAudience = (cfg, token, audience, recovery) => call(cfg, token, `/recipients?audience=${encodeURIComponent(JSON.stringify(audience))}${recovery?.length ? `&recovery=${encodeURIComponent(recovery.join(","))}` : ""}`), remoteEnvPush = (cfg, token, bundle) => call(cfg, token, "/env/push", { method: "POST", body: JSON.stringify(bundle) }), remoteEnvAnchor = (cfg, token) => call(cfg, token, "/env/anchor"), remoteEnvPull = (cfg, token) => call(cfg, token, "/env/pull"), forkMeta = (cfg, token, parent) => call(cfg, token, "/fork-meta", { method: "POST", body: JSON.stringify({ parent }) }), forksList = (cfg, token) => call(cfg, token, "/forks"), saveRemote = (solDir2, cfg) => writeFileSync5(join5(solDir2, "remote.json"), JSON.stringify(cfg, null, 2));
3638
3674
  var init_remote = __esm(() => {
3639
3675
  init_file_store();
3640
3676
  init_store();