midsummer-sol 0.3.6 → 0.3.7
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/package.json +1 -1
- package/sol-mcp.js +77 -20
- package/sol.js +115 -32
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "midsummer-sol",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
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
|
@@ -3036,6 +3036,7 @@ __export(exports_lib, {
|
|
|
3036
3036
|
allLocalNodes: () => allLocalNodes,
|
|
3037
3037
|
addInclude: () => addInclude,
|
|
3038
3038
|
actor: () => actor,
|
|
3039
|
+
acquireLockAt: () => acquireLockAt,
|
|
3039
3040
|
acquireLock: () => acquireLock,
|
|
3040
3041
|
LazyStore: () => LazyStore,
|
|
3041
3042
|
DEFAULT_IGNORE: () => DEFAULT_IGNORE
|
|
@@ -3269,9 +3270,9 @@ function pidAlive(pid) {
|
|
|
3269
3270
|
return e?.code === "EPERM";
|
|
3270
3271
|
}
|
|
3271
3272
|
}
|
|
3272
|
-
function
|
|
3273
|
-
const
|
|
3274
|
-
const
|
|
3273
|
+
function acquireLockAt(lockFile, opts = {}) {
|
|
3274
|
+
const deadline = Date.now() + (opts.timeoutMs ?? 15000);
|
|
3275
|
+
const onTimeout = opts.onTimeout ?? "die";
|
|
3275
3276
|
for (;; ) {
|
|
3276
3277
|
try {
|
|
3277
3278
|
writeFileSync5(lockFile, String(process.pid), { flag: "wx" });
|
|
@@ -3294,8 +3295,11 @@ function acquireLock() {
|
|
|
3294
3295
|
} catch {
|
|
3295
3296
|
continue;
|
|
3296
3297
|
}
|
|
3297
|
-
if (Date.now() > deadline)
|
|
3298
|
-
|
|
3298
|
+
if (Date.now() > deadline) {
|
|
3299
|
+
if (onTimeout === "undefined")
|
|
3300
|
+
return;
|
|
3301
|
+
die(opts.timeoutMsg ?? "repo is locked by another sol process (timed out)");
|
|
3302
|
+
}
|
|
3299
3303
|
sleepSync(25);
|
|
3300
3304
|
}
|
|
3301
3305
|
}
|
|
@@ -3311,6 +3315,9 @@ function acquireLock() {
|
|
|
3311
3315
|
process.on("exit", release);
|
|
3312
3316
|
return release;
|
|
3313
3317
|
}
|
|
3318
|
+
function acquireLock() {
|
|
3319
|
+
return acquireLockAt(join5(lockDir(), "lock"));
|
|
3320
|
+
}
|
|
3314
3321
|
function loadStore() {
|
|
3315
3322
|
return new LazyStore(objectsDir());
|
|
3316
3323
|
}
|
|
@@ -4160,6 +4167,7 @@ __export(exports_remote, {
|
|
|
4160
4167
|
saveRemote: () => saveRemote,
|
|
4161
4168
|
remoteRefs: () => remoteRefs,
|
|
4162
4169
|
remotePushPack: () => remotePushPack,
|
|
4170
|
+
remotePushGiantLeaf: () => remotePushGiantLeaf,
|
|
4163
4171
|
remotePushBlobs: () => remotePushBlobs,
|
|
4164
4172
|
remotePush: () => remotePush,
|
|
4165
4173
|
remotePromote: () => remotePromote,
|
|
@@ -4307,13 +4315,34 @@ async function retryTransient(fn, attempts = 5) {
|
|
|
4307
4315
|
}
|
|
4308
4316
|
throw last;
|
|
4309
4317
|
}
|
|
4318
|
+
function canonicalPackBytesClient(entries) {
|
|
4319
|
+
const sorted = [...entries].sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0);
|
|
4320
|
+
const obj = {};
|
|
4321
|
+
for (const [h, n] of sorted)
|
|
4322
|
+
obj[h] = n;
|
|
4323
|
+
return JSON.stringify(obj);
|
|
4324
|
+
}
|
|
4325
|
+
async function remotePushGiantLeaf(cfg, token, node) {
|
|
4326
|
+
const hash = hashNode(node);
|
|
4327
|
+
const body = canonicalPackBytesClient([[hash, node]]);
|
|
4328
|
+
const packId = hashString(body);
|
|
4329
|
+
const packBody = gzipSync3(Buffer.from(body, "utf8")).toString("base64");
|
|
4330
|
+
const path = `/push/blobs?giant=${encodeURIComponent(hash)}&packId=${encodeURIComponent(packId)}`;
|
|
4331
|
+
return retryTransient(() => call(cfg, token, path, { method: "POST", body: packBody }));
|
|
4332
|
+
}
|
|
4310
4333
|
async function remotePushPack(cfg, token, body) {
|
|
4311
4334
|
const { trees, leaves, total } = classifyNodes(body.nodes);
|
|
4312
4335
|
if (total <= SMALL_PUSH_BYTES) {
|
|
4313
4336
|
return retryTransient(() => call(cfg, token, "/push/pack", { method: "POST", body: gzipSync3(JSON.stringify(body)), headers: { "content-encoding": "gzip" } }));
|
|
4314
4337
|
}
|
|
4315
|
-
const
|
|
4316
|
-
|
|
4338
|
+
const giants = leaves.filter((n) => nodeBytes(n) > GIANT_LEAF_BYTES);
|
|
4339
|
+
const normal = leaves.filter((n) => nodeBytes(n) <= GIANT_LEAF_BYTES);
|
|
4340
|
+
const blobPacks = splitLeafPacks(normal, BLOB_PACK_BYTES);
|
|
4341
|
+
const tasks = [
|
|
4342
|
+
...blobPacks.map((pack) => () => remotePushBlobs(cfg, token, pack)),
|
|
4343
|
+
...giants.map((node) => () => remotePushGiantLeaf(cfg, token, node))
|
|
4344
|
+
];
|
|
4345
|
+
await pool(tasks, BLOB_PACK_CONCURRENCY);
|
|
4317
4346
|
return retryTransient(() => call(cfg, token, "/push/pack", {
|
|
4318
4347
|
method: "POST",
|
|
4319
4348
|
body: gzipSync3(JSON.stringify({ ...body, nodes: trees })),
|
|
@@ -4340,11 +4369,13 @@ async function writeBundle(solDir2, bundle, from = 0) {
|
|
|
4340
4369
|
writeFileSync6(join6(solDir2, "HEAD"), JSON.stringify({ head: bundle.head, seq: bundle.seq, logTip: bundle.tip }));
|
|
4341
4370
|
return fresh.length;
|
|
4342
4371
|
}
|
|
4343
|
-
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)}` : ""}`), remoteExport = (cfg, token) => exportStreaming(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 =
|
|
4372
|
+
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)}` : ""}`), remoteExport = (cfg, token) => exportStreaming(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));
|
|
4344
4373
|
var init_remote = __esm(() => {
|
|
4345
4374
|
init_file_store2();
|
|
4375
|
+
init_store();
|
|
4346
4376
|
SMALL_PUSH_BYTES = 24 * 1024 * 1024;
|
|
4347
4377
|
BLOB_PACK_BYTES = 16 * 1024 * 1024;
|
|
4378
|
+
GIANT_LEAF_BYTES = 24 * 1024 * 1024;
|
|
4348
4379
|
});
|
|
4349
4380
|
|
|
4350
4381
|
// src/bin/test-gate.ts
|
|
@@ -9745,21 +9776,41 @@ function tokenClaims(token) {
|
|
|
9745
9776
|
return {};
|
|
9746
9777
|
}
|
|
9747
9778
|
}
|
|
9748
|
-
|
|
9749
|
-
if (!existsSync20(CRED_PATH))
|
|
9750
|
-
return;
|
|
9751
|
-
let creds;
|
|
9779
|
+
function readCreds() {
|
|
9752
9780
|
try {
|
|
9753
|
-
|
|
9781
|
+
return JSON.parse(readFileSync20(CRED_PATH, "utf8"));
|
|
9754
9782
|
} catch {
|
|
9755
9783
|
return;
|
|
9756
9784
|
}
|
|
9757
|
-
|
|
9785
|
+
}
|
|
9786
|
+
function accessTokenFresh(accessToken) {
|
|
9787
|
+
if (!accessToken)
|
|
9788
|
+
return false;
|
|
9789
|
+
const exp = tokenClaims(accessToken).exp;
|
|
9790
|
+
return typeof exp === "number" && exp * 1000 > Date.now() + 30000;
|
|
9791
|
+
}
|
|
9792
|
+
async function loadStoredToken() {
|
|
9793
|
+
if (!existsSync20(CRED_PATH))
|
|
9758
9794
|
return;
|
|
9759
|
-
|
|
9760
|
-
if (
|
|
9795
|
+
let creds = readCreds();
|
|
9796
|
+
if (!creds?.accessToken)
|
|
9797
|
+
return;
|
|
9798
|
+
if (accessTokenFresh(creds.accessToken))
|
|
9799
|
+
return creds.accessToken;
|
|
9800
|
+
if (!(creds.refreshToken && creds.webUrl))
|
|
9761
9801
|
return creds.accessToken;
|
|
9762
|
-
|
|
9802
|
+
const release = acquireLockAt(join19(dirname5(CRED_PATH), "credentials.lock"), {
|
|
9803
|
+
timeoutMs: 1e4,
|
|
9804
|
+
onTimeout: "undefined"
|
|
9805
|
+
});
|
|
9806
|
+
try {
|
|
9807
|
+
if (release) {
|
|
9808
|
+
const fresh = readCreds();
|
|
9809
|
+
if (fresh?.accessToken && accessTokenFresh(fresh.accessToken))
|
|
9810
|
+
return fresh.accessToken;
|
|
9811
|
+
if (fresh)
|
|
9812
|
+
creds = fresh;
|
|
9813
|
+
}
|
|
9763
9814
|
try {
|
|
9764
9815
|
const res = await fetch(`${creds.webUrl}/api/auth/refresh`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ refreshToken: creds.refreshToken }) });
|
|
9765
9816
|
if (res.ok) {
|
|
@@ -9770,8 +9821,10 @@ async function loadStoredToken() {
|
|
|
9770
9821
|
}
|
|
9771
9822
|
}
|
|
9772
9823
|
} catch {}
|
|
9824
|
+
return creds.accessToken;
|
|
9825
|
+
} finally {
|
|
9826
|
+
release?.();
|
|
9773
9827
|
}
|
|
9774
|
-
return creds.accessToken;
|
|
9775
9828
|
}
|
|
9776
9829
|
function authExpired() {
|
|
9777
9830
|
return die("session expired — run `sol auth login` (or set SOL_TOKEN)");
|
|
@@ -12514,8 +12567,12 @@ WARNING: "${path}" was committed as PLAINTEXT before this seal — the pre-seal
|
|
|
12514
12567
|
const days = Number(patAction) || 90;
|
|
12515
12568
|
const name = (Number(patAction) ? args[2] : patAction) || undefined;
|
|
12516
12569
|
const res = await fetch(`${creds.webUrl}/api/auth/pat`, { method: "POST", headers: { authorization: `Bearer ${token}`, "content-type": "application/json" }, body: JSON.stringify({ days, ...name ? { name } : {} }) });
|
|
12517
|
-
if (!res.ok)
|
|
12518
|
-
|
|
12570
|
+
if (!res.ok) {
|
|
12571
|
+
const reason = await res.json().then((b) => b?.error?.detail || b?.error?.message).catch(() => {
|
|
12572
|
+
return;
|
|
12573
|
+
});
|
|
12574
|
+
die(`could not mint a PAT (${res.status})${reason ? `: ${reason}` : ""}`);
|
|
12575
|
+
}
|
|
12519
12576
|
const out = await res.json();
|
|
12520
12577
|
console.log(`
|
|
12521
12578
|
Personal Access Token "${out.name}" (id ${out.id}, expires in ${days} days) — store it now, it is not shown again:
|
package/sol.js
CHANGED
|
@@ -2269,6 +2269,7 @@ __export(exports_lib, {
|
|
|
2269
2269
|
allLocalNodes: () => allLocalNodes,
|
|
2270
2270
|
addInclude: () => addInclude,
|
|
2271
2271
|
actor: () => actor,
|
|
2272
|
+
acquireLockAt: () => acquireLockAt,
|
|
2272
2273
|
acquireLock: () => acquireLock,
|
|
2273
2274
|
LazyStore: () => LazyStore,
|
|
2274
2275
|
DEFAULT_IGNORE: () => DEFAULT_IGNORE
|
|
@@ -2502,9 +2503,9 @@ function pidAlive(pid) {
|
|
|
2502
2503
|
return e?.code === "EPERM";
|
|
2503
2504
|
}
|
|
2504
2505
|
}
|
|
2505
|
-
function
|
|
2506
|
-
const
|
|
2507
|
-
const
|
|
2506
|
+
function acquireLockAt(lockFile, opts = {}) {
|
|
2507
|
+
const deadline = Date.now() + (opts.timeoutMs ?? 15000);
|
|
2508
|
+
const onTimeout = opts.onTimeout ?? "die";
|
|
2508
2509
|
for (;; ) {
|
|
2509
2510
|
try {
|
|
2510
2511
|
writeFileSync4(lockFile, String(process.pid), { flag: "wx" });
|
|
@@ -2527,8 +2528,11 @@ function acquireLock() {
|
|
|
2527
2528
|
} catch {
|
|
2528
2529
|
continue;
|
|
2529
2530
|
}
|
|
2530
|
-
if (Date.now() > deadline)
|
|
2531
|
-
|
|
2531
|
+
if (Date.now() > deadline) {
|
|
2532
|
+
if (onTimeout === "undefined")
|
|
2533
|
+
return;
|
|
2534
|
+
die(opts.timeoutMsg ?? "repo is locked by another sol process (timed out)");
|
|
2535
|
+
}
|
|
2532
2536
|
sleepSync(25);
|
|
2533
2537
|
}
|
|
2534
2538
|
}
|
|
@@ -2544,6 +2548,9 @@ function acquireLock() {
|
|
|
2544
2548
|
process.on("exit", release);
|
|
2545
2549
|
return release;
|
|
2546
2550
|
}
|
|
2551
|
+
function acquireLock() {
|
|
2552
|
+
return acquireLockAt(join4(lockDir(), "lock"));
|
|
2553
|
+
}
|
|
2547
2554
|
function loadStore() {
|
|
2548
2555
|
return new LazyStore(objectsDir());
|
|
2549
2556
|
}
|
|
@@ -3393,6 +3400,7 @@ __export(exports_remote, {
|
|
|
3393
3400
|
saveRemote: () => saveRemote,
|
|
3394
3401
|
remoteRefs: () => remoteRefs,
|
|
3395
3402
|
remotePushPack: () => remotePushPack,
|
|
3403
|
+
remotePushGiantLeaf: () => remotePushGiantLeaf,
|
|
3396
3404
|
remotePushBlobs: () => remotePushBlobs,
|
|
3397
3405
|
remotePush: () => remotePush,
|
|
3398
3406
|
remotePromote: () => remotePromote,
|
|
@@ -3540,13 +3548,34 @@ async function retryTransient(fn, attempts = 5) {
|
|
|
3540
3548
|
}
|
|
3541
3549
|
throw last;
|
|
3542
3550
|
}
|
|
3551
|
+
function canonicalPackBytesClient(entries) {
|
|
3552
|
+
const sorted = [...entries].sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0);
|
|
3553
|
+
const obj = {};
|
|
3554
|
+
for (const [h, n] of sorted)
|
|
3555
|
+
obj[h] = n;
|
|
3556
|
+
return JSON.stringify(obj);
|
|
3557
|
+
}
|
|
3558
|
+
async function remotePushGiantLeaf(cfg, token, node) {
|
|
3559
|
+
const hash = hashNode(node);
|
|
3560
|
+
const body = canonicalPackBytesClient([[hash, node]]);
|
|
3561
|
+
const packId = hashString(body);
|
|
3562
|
+
const packBody = gzipSync2(Buffer.from(body, "utf8")).toString("base64");
|
|
3563
|
+
const path = `/push/blobs?giant=${encodeURIComponent(hash)}&packId=${encodeURIComponent(packId)}`;
|
|
3564
|
+
return retryTransient(() => call(cfg, token, path, { method: "POST", body: packBody }));
|
|
3565
|
+
}
|
|
3543
3566
|
async function remotePushPack(cfg, token, body) {
|
|
3544
3567
|
const { trees, leaves, total } = classifyNodes(body.nodes);
|
|
3545
3568
|
if (total <= SMALL_PUSH_BYTES) {
|
|
3546
3569
|
return retryTransient(() => call(cfg, token, "/push/pack", { method: "POST", body: gzipSync2(JSON.stringify(body)), headers: { "content-encoding": "gzip" } }));
|
|
3547
3570
|
}
|
|
3548
|
-
const
|
|
3549
|
-
|
|
3571
|
+
const giants = leaves.filter((n) => nodeBytes(n) > GIANT_LEAF_BYTES);
|
|
3572
|
+
const normal = leaves.filter((n) => nodeBytes(n) <= GIANT_LEAF_BYTES);
|
|
3573
|
+
const blobPacks = splitLeafPacks(normal, BLOB_PACK_BYTES);
|
|
3574
|
+
const tasks = [
|
|
3575
|
+
...blobPacks.map((pack) => () => remotePushBlobs(cfg, token, pack)),
|
|
3576
|
+
...giants.map((node) => () => remotePushGiantLeaf(cfg, token, node))
|
|
3577
|
+
];
|
|
3578
|
+
await pool(tasks, BLOB_PACK_CONCURRENCY);
|
|
3550
3579
|
return retryTransient(() => call(cfg, token, "/push/pack", {
|
|
3551
3580
|
method: "POST",
|
|
3552
3581
|
body: gzipSync2(JSON.stringify({ ...body, nodes: trees })),
|
|
@@ -3573,11 +3602,13 @@ async function writeBundle(solDir2, bundle, from = 0) {
|
|
|
3573
3602
|
writeFileSync5(join5(solDir2, "HEAD"), JSON.stringify({ head: bundle.head, seq: bundle.seq, logTip: bundle.tip }));
|
|
3574
3603
|
return fresh.length;
|
|
3575
3604
|
}
|
|
3576
|
-
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)}` : ""}`), remoteExport = (cfg, token) => exportStreaming(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 =
|
|
3605
|
+
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)}` : ""}`), remoteExport = (cfg, token) => exportStreaming(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));
|
|
3577
3606
|
var init_remote = __esm(() => {
|
|
3578
3607
|
init_file_store();
|
|
3608
|
+
init_store();
|
|
3579
3609
|
SMALL_PUSH_BYTES = 24 * 1024 * 1024;
|
|
3580
3610
|
BLOB_PACK_BYTES = 16 * 1024 * 1024;
|
|
3611
|
+
GIANT_LEAF_BYTES = 24 * 1024 * 1024;
|
|
3581
3612
|
});
|
|
3582
3613
|
|
|
3583
3614
|
// src/bin/test-gate.ts
|
|
@@ -9513,21 +9544,41 @@ function tokenClaims(token) {
|
|
|
9513
9544
|
return {};
|
|
9514
9545
|
}
|
|
9515
9546
|
}
|
|
9516
|
-
|
|
9517
|
-
if (!existsSync19(CRED_PATH))
|
|
9518
|
-
return;
|
|
9519
|
-
let creds;
|
|
9547
|
+
function readCreds() {
|
|
9520
9548
|
try {
|
|
9521
|
-
|
|
9549
|
+
return JSON.parse(readFileSync19(CRED_PATH, "utf8"));
|
|
9522
9550
|
} catch {
|
|
9523
9551
|
return;
|
|
9524
9552
|
}
|
|
9525
|
-
|
|
9553
|
+
}
|
|
9554
|
+
function accessTokenFresh(accessToken) {
|
|
9555
|
+
if (!accessToken)
|
|
9556
|
+
return false;
|
|
9557
|
+
const exp = tokenClaims(accessToken).exp;
|
|
9558
|
+
return typeof exp === "number" && exp * 1000 > Date.now() + 30000;
|
|
9559
|
+
}
|
|
9560
|
+
async function loadStoredToken() {
|
|
9561
|
+
if (!existsSync19(CRED_PATH))
|
|
9562
|
+
return;
|
|
9563
|
+
let creds = readCreds();
|
|
9564
|
+
if (!creds?.accessToken)
|
|
9526
9565
|
return;
|
|
9527
|
-
|
|
9528
|
-
|
|
9566
|
+
if (accessTokenFresh(creds.accessToken))
|
|
9567
|
+
return creds.accessToken;
|
|
9568
|
+
if (!(creds.refreshToken && creds.webUrl))
|
|
9529
9569
|
return creds.accessToken;
|
|
9530
|
-
|
|
9570
|
+
const release = acquireLockAt(join18(dirname5(CRED_PATH), "credentials.lock"), {
|
|
9571
|
+
timeoutMs: 1e4,
|
|
9572
|
+
onTimeout: "undefined"
|
|
9573
|
+
});
|
|
9574
|
+
try {
|
|
9575
|
+
if (release) {
|
|
9576
|
+
const fresh = readCreds();
|
|
9577
|
+
if (fresh?.accessToken && accessTokenFresh(fresh.accessToken))
|
|
9578
|
+
return fresh.accessToken;
|
|
9579
|
+
if (fresh)
|
|
9580
|
+
creds = fresh;
|
|
9581
|
+
}
|
|
9531
9582
|
try {
|
|
9532
9583
|
const res = await fetch(`${creds.webUrl}/api/auth/refresh`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ refreshToken: creds.refreshToken }) });
|
|
9533
9584
|
if (res.ok) {
|
|
@@ -9538,8 +9589,10 @@ async function loadStoredToken() {
|
|
|
9538
9589
|
}
|
|
9539
9590
|
}
|
|
9540
9591
|
} catch {}
|
|
9592
|
+
return creds.accessToken;
|
|
9593
|
+
} finally {
|
|
9594
|
+
release?.();
|
|
9541
9595
|
}
|
|
9542
|
-
return creds.accessToken;
|
|
9543
9596
|
}
|
|
9544
9597
|
function authExpired() {
|
|
9545
9598
|
return die("session expired — run `sol auth login` (or set SOL_TOKEN)");
|
|
@@ -12282,8 +12335,12 @@ WARNING: "${path}" was committed as PLAINTEXT before this seal — the pre-seal
|
|
|
12282
12335
|
const days = Number(patAction) || 90;
|
|
12283
12336
|
const name = (Number(patAction) ? args[2] : patAction) || undefined;
|
|
12284
12337
|
const res = await fetch(`${creds.webUrl}/api/auth/pat`, { method: "POST", headers: { authorization: `Bearer ${token}`, "content-type": "application/json" }, body: JSON.stringify({ days, ...name ? { name } : {} }) });
|
|
12285
|
-
if (!res.ok)
|
|
12286
|
-
|
|
12338
|
+
if (!res.ok) {
|
|
12339
|
+
const reason = await res.json().then((b) => b?.error?.detail || b?.error?.message).catch(() => {
|
|
12340
|
+
return;
|
|
12341
|
+
});
|
|
12342
|
+
die(`could not mint a PAT (${res.status})${reason ? `: ${reason}` : ""}`);
|
|
12343
|
+
}
|
|
12287
12344
|
const out = await res.json();
|
|
12288
12345
|
console.log(`
|
|
12289
12346
|
Personal Access Token "${out.name}" (id ${out.id}, expires in ${days} days) — store it now, it is not shown again:
|
|
@@ -13797,21 +13854,41 @@ function tokenClaims2(token) {
|
|
|
13797
13854
|
return {};
|
|
13798
13855
|
}
|
|
13799
13856
|
}
|
|
13800
|
-
|
|
13801
|
-
if (!existsSync20(CRED_PATH2))
|
|
13802
|
-
return;
|
|
13803
|
-
let creds;
|
|
13857
|
+
function readCreds2() {
|
|
13804
13858
|
try {
|
|
13805
|
-
|
|
13859
|
+
return JSON.parse(readFileSync20(CRED_PATH2, "utf8"));
|
|
13806
13860
|
} catch {
|
|
13807
13861
|
return;
|
|
13808
13862
|
}
|
|
13809
|
-
|
|
13863
|
+
}
|
|
13864
|
+
function accessTokenFresh2(accessToken) {
|
|
13865
|
+
if (!accessToken)
|
|
13866
|
+
return false;
|
|
13867
|
+
const exp = tokenClaims2(accessToken).exp;
|
|
13868
|
+
return typeof exp === "number" && exp * 1000 > Date.now() + 30000;
|
|
13869
|
+
}
|
|
13870
|
+
async function loadStoredToken2() {
|
|
13871
|
+
if (!existsSync20(CRED_PATH2))
|
|
13810
13872
|
return;
|
|
13811
|
-
|
|
13812
|
-
if (
|
|
13873
|
+
let creds = readCreds2();
|
|
13874
|
+
if (!creds?.accessToken)
|
|
13875
|
+
return;
|
|
13876
|
+
if (accessTokenFresh2(creds.accessToken))
|
|
13877
|
+
return creds.accessToken;
|
|
13878
|
+
if (!(creds.refreshToken && creds.webUrl))
|
|
13813
13879
|
return creds.accessToken;
|
|
13814
|
-
|
|
13880
|
+
const release = acquireLockAt(join20(dirname7(CRED_PATH2), "credentials.lock"), {
|
|
13881
|
+
timeoutMs: 1e4,
|
|
13882
|
+
onTimeout: "undefined"
|
|
13883
|
+
});
|
|
13884
|
+
try {
|
|
13885
|
+
if (release) {
|
|
13886
|
+
const fresh = readCreds2();
|
|
13887
|
+
if (fresh?.accessToken && accessTokenFresh2(fresh.accessToken))
|
|
13888
|
+
return fresh.accessToken;
|
|
13889
|
+
if (fresh)
|
|
13890
|
+
creds = fresh;
|
|
13891
|
+
}
|
|
13815
13892
|
try {
|
|
13816
13893
|
const res = await fetch(`${creds.webUrl}/api/auth/refresh`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ refreshToken: creds.refreshToken }) });
|
|
13817
13894
|
if (res.ok) {
|
|
@@ -13822,8 +13899,10 @@ async function loadStoredToken2() {
|
|
|
13822
13899
|
}
|
|
13823
13900
|
}
|
|
13824
13901
|
} catch {}
|
|
13902
|
+
return creds.accessToken;
|
|
13903
|
+
} finally {
|
|
13904
|
+
release?.();
|
|
13825
13905
|
}
|
|
13826
|
-
return creds.accessToken;
|
|
13827
13906
|
}
|
|
13828
13907
|
function authExpired2() {
|
|
13829
13908
|
return die("session expired — run `sol auth login` (or set SOL_TOKEN)");
|
|
@@ -16566,8 +16645,12 @@ WARNING: "${path}" was committed as PLAINTEXT before this seal — the pre-seal
|
|
|
16566
16645
|
const days = Number(patAction) || 90;
|
|
16567
16646
|
const name = (Number(patAction) ? args[2] : patAction) || undefined;
|
|
16568
16647
|
const res = await fetch(`${creds.webUrl}/api/auth/pat`, { method: "POST", headers: { authorization: `Bearer ${token}`, "content-type": "application/json" }, body: JSON.stringify({ days, ...name ? { name } : {} }) });
|
|
16569
|
-
if (!res.ok)
|
|
16570
|
-
|
|
16648
|
+
if (!res.ok) {
|
|
16649
|
+
const reason = await res.json().then((b) => b?.error?.detail || b?.error?.message).catch(() => {
|
|
16650
|
+
return;
|
|
16651
|
+
});
|
|
16652
|
+
die(`could not mint a PAT (${res.status})${reason ? `: ${reason}` : ""}`);
|
|
16653
|
+
}
|
|
16571
16654
|
const out = await res.json();
|
|
16572
16655
|
console.log(`
|
|
16573
16656
|
Personal Access Token "${out.name}" (id ${out.id}, expires in ${days} days) — store it now, it is not shown again:
|