midsummer-sol 0.2.0 → 0.2.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/package.json +1 -1
- package/sol-secret-mcp.js +8 -7
- package/sol.js +536 -168
package/sol.js
CHANGED
|
@@ -2034,6 +2034,52 @@ var init_seal_audience = __esm(() => {
|
|
|
2034
2034
|
init_identity_store();
|
|
2035
2035
|
});
|
|
2036
2036
|
|
|
2037
|
+
// src/bin/keyring-at-rest.ts
|
|
2038
|
+
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes4, scryptSync as scryptSync3 } from "node:crypto";
|
|
2039
|
+
function deriveWrapKey2(recoveryCode, accountId, salt) {
|
|
2040
|
+
return scryptSync3(recoveryCode.normalize("NFKD"), Buffer.concat([Buffer.from(`sol/keyring/v2\x00${accountId}\x00`), salt]), 32, KDF);
|
|
2041
|
+
}
|
|
2042
|
+
function isEnvelope(parsed) {
|
|
2043
|
+
return !!parsed && typeof parsed === "object" && parsed.v === 2 && parsed.enc === "scrypt-aes-256-gcm";
|
|
2044
|
+
}
|
|
2045
|
+
function wrapContext() {
|
|
2046
|
+
const id = loadIdentity();
|
|
2047
|
+
const recoveryCode = process.env.SOL_RECOVERY_CODE;
|
|
2048
|
+
if (!id || !recoveryCode)
|
|
2049
|
+
return;
|
|
2050
|
+
return { accountId: id.accountId, recoveryCode };
|
|
2051
|
+
}
|
|
2052
|
+
function encryptKeyRing(serialized) {
|
|
2053
|
+
const ctx = wrapContext();
|
|
2054
|
+
if (!ctx)
|
|
2055
|
+
return;
|
|
2056
|
+
const salt = randomBytes4(16);
|
|
2057
|
+
const key = deriveWrapKey2(ctx.recoveryCode, ctx.accountId, salt);
|
|
2058
|
+
const iv = randomBytes4(12);
|
|
2059
|
+
const c = createCipheriv3("aes-256-gcm", key, iv);
|
|
2060
|
+
const ct = Buffer.concat([c.update(Buffer.from(JSON.stringify(serialized), "utf8")), c.final()]);
|
|
2061
|
+
return { v: 2, enc: "scrypt-aes-256-gcm", accountId: ctx.accountId, salt: salt.toString("base64"), iv: iv.toString("base64"), ct: ct.toString("base64"), tag: c.getAuthTag().toString("base64") };
|
|
2062
|
+
}
|
|
2063
|
+
function decryptKeyRing(env) {
|
|
2064
|
+
const recoveryCode = process.env.SOL_RECOVERY_CODE;
|
|
2065
|
+
if (!recoveryCode)
|
|
2066
|
+
throw new Error("keys.json is encrypted at rest but SOL_RECOVERY_CODE is unset — set it to unlock the local keyring.");
|
|
2067
|
+
const key = deriveWrapKey2(recoveryCode, env.accountId, Buffer.from(env.salt, "base64"));
|
|
2068
|
+
const d = createDecipheriv3("aes-256-gcm", key, Buffer.from(env.iv, "base64"));
|
|
2069
|
+
d.setAuthTag(Buffer.from(env.tag, "base64"));
|
|
2070
|
+
try {
|
|
2071
|
+
const pt = Buffer.concat([d.update(Buffer.from(env.ct, "base64")), d.final()]).toString("utf8");
|
|
2072
|
+
return JSON.parse(pt);
|
|
2073
|
+
} catch {
|
|
2074
|
+
throw new Error("failed to decrypt keys.json — wrong SOL_RECOVERY_CODE for this keyring, or the file was tampered.");
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
var KDF;
|
|
2078
|
+
var init_keyring_at_rest = __esm(() => {
|
|
2079
|
+
init_identity_store();
|
|
2080
|
+
KDF = { N: 1 << 15, r: 8, p: 1, maxmem: 64 * 1024 * 1024 };
|
|
2081
|
+
});
|
|
2082
|
+
|
|
2037
2083
|
// src/bin/lib.ts
|
|
2038
2084
|
import {
|
|
2039
2085
|
appendFileSync as appendFileSync2,
|
|
@@ -2221,6 +2267,16 @@ async function snapshotTree(repo) {
|
|
|
2221
2267
|
if (!onDisk.has(t) && lexists(join4(cwd, t)))
|
|
2222
2268
|
onDisk.add(t);
|
|
2223
2269
|
const hidden = hiddenPathSet(solDir);
|
|
2270
|
+
const sealedProtected = new Set;
|
|
2271
|
+
for (const t of tracked) {
|
|
2272
|
+
if (lexists(join4(cwd, t)))
|
|
2273
|
+
continue;
|
|
2274
|
+
const leaf = await repo.read(t).catch(() => {
|
|
2275
|
+
return;
|
|
2276
|
+
});
|
|
2277
|
+
if (leaf?.kind === "sealed")
|
|
2278
|
+
sealedProtected.add(t);
|
|
2279
|
+
}
|
|
2224
2280
|
const changes = [];
|
|
2225
2281
|
for (const f of onDisk) {
|
|
2226
2282
|
if (hidden.has(f))
|
|
@@ -2229,9 +2285,12 @@ async function snapshotTree(repo) {
|
|
|
2229
2285
|
if (c)
|
|
2230
2286
|
changes.push(c);
|
|
2231
2287
|
}
|
|
2232
|
-
for (const t of tracked)
|
|
2233
|
-
if (
|
|
2288
|
+
for (const t of tracked) {
|
|
2289
|
+
if (hidden.has(t) || isReservedSegment(t) || sealedProtected.has(t))
|
|
2290
|
+
continue;
|
|
2291
|
+
if (!lexists(join4(cwd, t)))
|
|
2234
2292
|
changes.push({ path: t, delete: true });
|
|
2293
|
+
}
|
|
2235
2294
|
return repo.applyBatch(changes);
|
|
2236
2295
|
}
|
|
2237
2296
|
function sleepSync(ms) {
|
|
@@ -3041,12 +3100,15 @@ async function appendCapture(log, root) {
|
|
|
3041
3100
|
}
|
|
3042
3101
|
function loadKeyRing() {
|
|
3043
3102
|
const ring = new KeyRing;
|
|
3044
|
-
if (existsSync4(keysPath()))
|
|
3045
|
-
ring
|
|
3103
|
+
if (!existsSync4(keysPath()))
|
|
3104
|
+
return ring;
|
|
3105
|
+
const parsed = JSON.parse(readFileSync4(keysPath(), "utf8"));
|
|
3106
|
+
ring.load(isEnvelope(parsed) ? decryptKeyRing(parsed) : parsed);
|
|
3046
3107
|
return ring;
|
|
3047
3108
|
}
|
|
3048
3109
|
function saveKeyRing(ring) {
|
|
3049
|
-
|
|
3110
|
+
const env = encryptKeyRing(ring.serialize());
|
|
3111
|
+
writeFileSync4(keysPath(), JSON.stringify(env ?? ring.serialize(), null, 2), { mode: 384 });
|
|
3050
3112
|
try {
|
|
3051
3113
|
chmodSync3(keysPath(), 384);
|
|
3052
3114
|
} catch {}
|
|
@@ -3066,6 +3128,7 @@ var init_lib = __esm(() => {
|
|
|
3066
3128
|
init_struct();
|
|
3067
3129
|
init_tree();
|
|
3068
3130
|
init_seal_audience();
|
|
3131
|
+
init_keyring_at_rest();
|
|
3069
3132
|
procCwd = process.cwd();
|
|
3070
3133
|
repoRoot = findRepoRoot(procCwd);
|
|
3071
3134
|
cwd = repoRoot ?? procCwd;
|
|
@@ -3499,7 +3562,7 @@ __export(exports_anchor, {
|
|
|
3499
3562
|
creatorPinPath: () => creatorPinPath,
|
|
3500
3563
|
creatorFingerprint: () => creatorFingerprint
|
|
3501
3564
|
});
|
|
3502
|
-
import { existsSync as existsSync9, readFileSync as readFileSync9, writeFileSync as writeFileSync9 } from "node:fs";
|
|
3565
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync5, readdirSync as readdirSync3, readFileSync as readFileSync9, writeFileSync as writeFileSync9 } from "node:fs";
|
|
3503
3566
|
import { join as join9 } from "node:path";
|
|
3504
3567
|
function repoSolDir(solDir2) {
|
|
3505
3568
|
return solDir2;
|
|
@@ -3690,26 +3753,74 @@ function validateGenesisAnchor(solDir2) {
|
|
|
3690
3753
|
}
|
|
3691
3754
|
return out;
|
|
3692
3755
|
}
|
|
3756
|
+
function readEnvFiles(solDir2) {
|
|
3757
|
+
const dir = envDir(solDir2);
|
|
3758
|
+
const out = {};
|
|
3759
|
+
if (!existsSync9(dir))
|
|
3760
|
+
return out;
|
|
3761
|
+
for (const name of readdirSync3(dir, { withFileTypes: true })) {
|
|
3762
|
+
if (!name.isFile() || ENVSTATE_SKIP_FILES.has(name.name))
|
|
3763
|
+
continue;
|
|
3764
|
+
try {
|
|
3765
|
+
out[name.name] = readFileSync9(join9(dir, name.name), "utf8");
|
|
3766
|
+
} catch {}
|
|
3767
|
+
}
|
|
3768
|
+
return out;
|
|
3769
|
+
}
|
|
3770
|
+
function readSealStanzas(solDir2) {
|
|
3771
|
+
const dir = sealDir(solDir2);
|
|
3772
|
+
const out = {};
|
|
3773
|
+
if (!existsSync9(dir))
|
|
3774
|
+
return out;
|
|
3775
|
+
for (const name of readdirSync3(dir, { withFileTypes: true })) {
|
|
3776
|
+
if (!name.isFile() || !name.name.endsWith(".stanzas"))
|
|
3777
|
+
continue;
|
|
3778
|
+
try {
|
|
3779
|
+
out[name.name] = readFileSync9(join9(dir, name.name), "utf8");
|
|
3780
|
+
} catch {}
|
|
3781
|
+
}
|
|
3782
|
+
return out;
|
|
3783
|
+
}
|
|
3693
3784
|
function readEnvStateBundle(solDir2) {
|
|
3694
3785
|
const journal = readJournal(solDir2);
|
|
3695
3786
|
const creatorPin = readCreatorPin(solDir2);
|
|
3696
|
-
|
|
3787
|
+
const files = readEnvFiles(solDir2);
|
|
3788
|
+
const seals = readSealStanzas(solDir2);
|
|
3789
|
+
if (!journal.length && !creatorPin && !Object.keys(files).length && !Object.keys(seals).length)
|
|
3697
3790
|
return;
|
|
3698
3791
|
const journalHead = journal.length ? journal[journal.length - 1].entryHash : undefined;
|
|
3699
|
-
return { v: 1, creatorPin, journal, journalHead, journalLen: journal.length };
|
|
3792
|
+
return { v: 1, creatorPin, journal, journalHead, journalLen: journal.length, files, seals };
|
|
3700
3793
|
}
|
|
3701
3794
|
function writeEnvStateBundle(solDir2, bundle) {
|
|
3795
|
+
mkdirSync5(envDir(solDir2), { recursive: true });
|
|
3702
3796
|
writeJournal(solDir2, bundle.journal);
|
|
3703
3797
|
if (bundle.creatorPin) {
|
|
3704
3798
|
writeFileSync9(creatorPinPath(solDir2), JSON.stringify(bundle.creatorPin, null, 2), { mode: 420 });
|
|
3705
3799
|
}
|
|
3800
|
+
mkdirSync5(envDir(solDir2), { recursive: true });
|
|
3801
|
+
for (const [name, contents] of Object.entries(bundle.files ?? {})) {
|
|
3802
|
+
if (name.includes("/") || name.includes("\\") || name.includes("\x00"))
|
|
3803
|
+
continue;
|
|
3804
|
+
if (ENVSTATE_SKIP_FILES.has(name))
|
|
3805
|
+
continue;
|
|
3806
|
+
writeFileSync9(join9(envDir(solDir2), name), contents, { mode: 420 });
|
|
3807
|
+
}
|
|
3808
|
+
const seals = bundle.seals ?? {};
|
|
3809
|
+
if (Object.keys(seals).length)
|
|
3810
|
+
mkdirSync5(sealDir(solDir2), { recursive: true });
|
|
3811
|
+
for (const [name, box] of Object.entries(seals)) {
|
|
3812
|
+
if (!name.endsWith(".stanzas") || name.includes("/") || name.includes("\\") || name.includes("\x00"))
|
|
3813
|
+
continue;
|
|
3814
|
+
writeFileSync9(join9(sealDir(solDir2), name), box, { mode: 384 });
|
|
3815
|
+
}
|
|
3706
3816
|
updateHeadPin(solDir2);
|
|
3707
3817
|
}
|
|
3708
|
-
var creatorPinPath = (solDir2) => join9(envDir(solDir2), "creator.pin"), headPinPath = (solDir2) => join9(envDir(solDir2), "head.pin");
|
|
3818
|
+
var creatorPinPath = (solDir2) => join9(envDir(solDir2), "creator.pin"), headPinPath = (solDir2) => join9(envDir(solDir2), "head.pin"), ENVSTATE_SKIP_FILES;
|
|
3709
3819
|
var init_anchor = __esm(() => {
|
|
3710
3820
|
init_store2();
|
|
3711
3821
|
init_journal();
|
|
3712
3822
|
init_sign();
|
|
3823
|
+
ENVSTATE_SKIP_FILES = new Set(["journal.jsonl", "creator.pin", "head.pin"]);
|
|
3713
3824
|
});
|
|
3714
3825
|
|
|
3715
3826
|
// src/secret/toml.ts
|
|
@@ -4325,7 +4436,7 @@ var init_authz = __esm(() => {
|
|
|
4325
4436
|
});
|
|
4326
4437
|
|
|
4327
4438
|
// src/secret/model.ts
|
|
4328
|
-
import { existsSync as existsSync10, mkdirSync as
|
|
4439
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync6, readdirSync as readdirSync4, readFileSync as readFileSync10, statSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync10 } from "node:fs";
|
|
4329
4440
|
import { join as join10 } from "node:path";
|
|
4330
4441
|
function envInitialized(solDir2) {
|
|
4331
4442
|
return existsSync10(manifestPath(solDir2));
|
|
@@ -4362,8 +4473,8 @@ function audienceFor(world, env, entryAud) {
|
|
|
4362
4473
|
return world.files[env]?.audience ?? [];
|
|
4363
4474
|
}
|
|
4364
4475
|
function ensureEnvDir(solDir2) {
|
|
4365
|
-
|
|
4366
|
-
|
|
4476
|
+
mkdirSync6(envDir(solDir2), { recursive: true });
|
|
4477
|
+
mkdirSync6(sealDir(solDir2), { recursive: true });
|
|
4367
4478
|
}
|
|
4368
4479
|
function writeEnvFile(solDir2, f) {
|
|
4369
4480
|
ensureEnvDir(solDir2);
|
|
@@ -4641,7 +4752,7 @@ function collectStaleStanzas(solDir2) {
|
|
|
4641
4752
|
referenced.add(stanzaFileFor(e.newSeal));
|
|
4642
4753
|
}
|
|
4643
4754
|
const orphans = [];
|
|
4644
|
-
for (const name of
|
|
4755
|
+
for (const name of readdirSync4(dir)) {
|
|
4645
4756
|
if (!name.endsWith(".stanzas"))
|
|
4646
4757
|
continue;
|
|
4647
4758
|
if (!referenced.has(name))
|
|
@@ -5015,6 +5126,201 @@ var init_sealed_client = __esm(() => {
|
|
|
5015
5126
|
init_crypto();
|
|
5016
5127
|
});
|
|
5017
5128
|
|
|
5129
|
+
// src/bin/secret-scrub.ts
|
|
5130
|
+
var exports_secret_scrub = {};
|
|
5131
|
+
__export(exports_secret_scrub, {
|
|
5132
|
+
scrubHistory: () => scrubHistory,
|
|
5133
|
+
pendingScrubPaths: () => pendingScrubPaths,
|
|
5134
|
+
historyHasCleartext: () => historyHasCleartext,
|
|
5135
|
+
gcAfterScrub: () => gcAfterScrub,
|
|
5136
|
+
clearPendingScrub: () => clearPendingScrub,
|
|
5137
|
+
addPendingScrub: () => addPendingScrub
|
|
5138
|
+
});
|
|
5139
|
+
import { existsSync as existsSync11, readdirSync as readdirSync5, readFileSync as readFileSync11, unlinkSync as unlinkSync4, writeFileSync as writeFileSync11 } from "node:fs";
|
|
5140
|
+
import { join as join11 } from "node:path";
|
|
5141
|
+
function pendingScrubPaths(solDir2) {
|
|
5142
|
+
const p = pendingPath(solDir2);
|
|
5143
|
+
if (!existsSync11(p))
|
|
5144
|
+
return [];
|
|
5145
|
+
try {
|
|
5146
|
+
const v = JSON.parse(readFileSync11(p, "utf8"));
|
|
5147
|
+
return Array.isArray(v) ? v : [];
|
|
5148
|
+
} catch {
|
|
5149
|
+
return [];
|
|
5150
|
+
}
|
|
5151
|
+
}
|
|
5152
|
+
function addPendingScrub(solDir2, path) {
|
|
5153
|
+
const set = new Set(pendingScrubPaths(solDir2));
|
|
5154
|
+
set.add(path);
|
|
5155
|
+
writeFileSync11(pendingPath(solDir2), JSON.stringify([...set], null, 2), { mode: 384 });
|
|
5156
|
+
}
|
|
5157
|
+
function clearPendingScrub(solDir2) {
|
|
5158
|
+
try {
|
|
5159
|
+
writeFileSync11(pendingPath(solDir2), JSON.stringify([], null, 2), { mode: 384 });
|
|
5160
|
+
} catch {}
|
|
5161
|
+
}
|
|
5162
|
+
function historyHasCleartext(solDir2, ops, path) {
|
|
5163
|
+
const store2 = new LazyStore(join11(solDir2, "objects"));
|
|
5164
|
+
for (const op of ops) {
|
|
5165
|
+
try {
|
|
5166
|
+
if (entryKindAt(store2, op.rootAfter, path) === "blob")
|
|
5167
|
+
return true;
|
|
5168
|
+
} catch {}
|
|
5169
|
+
}
|
|
5170
|
+
return false;
|
|
5171
|
+
}
|
|
5172
|
+
function currentSealedBox(store2, head, path) {
|
|
5173
|
+
try {
|
|
5174
|
+
return sealedBoxAt(store2, head, path);
|
|
5175
|
+
} catch {
|
|
5176
|
+
return;
|
|
5177
|
+
}
|
|
5178
|
+
}
|
|
5179
|
+
function replaceWithSealed(store2, treeHash, segs, sealedHash, mode, put) {
|
|
5180
|
+
const tree = store2.getTree(treeHash);
|
|
5181
|
+
const [head, ...rest] = segs;
|
|
5182
|
+
const entry = tree.entries[head];
|
|
5183
|
+
if (!entry)
|
|
5184
|
+
return treeHash;
|
|
5185
|
+
const entries = { ...tree.entries };
|
|
5186
|
+
if (rest.length === 0) {
|
|
5187
|
+
if (entry.kind !== "blob")
|
|
5188
|
+
return treeHash;
|
|
5189
|
+
entries[head] = mode === undefined ? { kind: "sealed", hash: sealedHash } : { kind: "sealed", hash: sealedHash, mode };
|
|
5190
|
+
} else {
|
|
5191
|
+
if (entry.kind !== "tree")
|
|
5192
|
+
return treeHash;
|
|
5193
|
+
const child = replaceWithSealed(store2, entry.hash, rest, sealedHash, mode, put);
|
|
5194
|
+
if (child === entry.hash)
|
|
5195
|
+
return treeHash;
|
|
5196
|
+
entries[head] = { kind: "tree", hash: child };
|
|
5197
|
+
}
|
|
5198
|
+
return put({ kind: "tree", entries });
|
|
5199
|
+
}
|
|
5200
|
+
async function scrubHistory(solDir2, ops, paths) {
|
|
5201
|
+
const objDir = join11(solDir2, "objects");
|
|
5202
|
+
const store2 = new LazyStore(objDir);
|
|
5203
|
+
const put = (n) => {
|
|
5204
|
+
const h = hashNode(n);
|
|
5205
|
+
store2.objects.set(h, n);
|
|
5206
|
+
writeFileSync11(join11(objDir, h), encodeObject(n));
|
|
5207
|
+
return h;
|
|
5208
|
+
};
|
|
5209
|
+
const head = (() => {
|
|
5210
|
+
const hp = join11(solDir2, "HEAD");
|
|
5211
|
+
return existsSync11(hp) ? JSON.parse(readFileSync11(hp, "utf8")).head : undefined;
|
|
5212
|
+
})();
|
|
5213
|
+
const sealedHashFor = new Map;
|
|
5214
|
+
for (const p of paths) {
|
|
5215
|
+
const box = head ? currentSealedBox(store2, head, p) : undefined;
|
|
5216
|
+
if (box === undefined)
|
|
5217
|
+
continue;
|
|
5218
|
+
const node = { kind: "sealed", box };
|
|
5219
|
+
const hash = put(node);
|
|
5220
|
+
let mode;
|
|
5221
|
+
try {
|
|
5222
|
+
mode = headMode(store2, head, p);
|
|
5223
|
+
} catch {}
|
|
5224
|
+
sealedHashFor.set(p, { hash, mode });
|
|
5225
|
+
}
|
|
5226
|
+
const rootMap = new Map;
|
|
5227
|
+
const newOps = [];
|
|
5228
|
+
let prevTip;
|
|
5229
|
+
let rewritten = 0;
|
|
5230
|
+
for (const op of ops) {
|
|
5231
|
+
let root = op.rootAfter;
|
|
5232
|
+
for (const [p, s] of sealedHashFor) {
|
|
5233
|
+
const segs = p.split("/").filter(Boolean);
|
|
5234
|
+
const next = replaceWithSealed(store2, root, segs, s.hash, s.mode, put);
|
|
5235
|
+
root = next;
|
|
5236
|
+
}
|
|
5237
|
+
const rootChanged = root !== op.rootAfter;
|
|
5238
|
+
rootMap.set(op.rootAfter, root);
|
|
5239
|
+
const remapped = { ...op, rootAfter: root };
|
|
5240
|
+
if (op.parent !== undefined && rootMap.has(op.parent))
|
|
5241
|
+
remapped.parent = rootMap.get(op.parent);
|
|
5242
|
+
if (op.parent2 !== undefined && rootMap.has(op.parent2))
|
|
5243
|
+
remapped.parent2 = rootMap.get(op.parent2);
|
|
5244
|
+
if (rootChanged) {
|
|
5245
|
+
delete remapped.sig;
|
|
5246
|
+
delete remapped.pub;
|
|
5247
|
+
delete remapped.att;
|
|
5248
|
+
rewritten++;
|
|
5249
|
+
}
|
|
5250
|
+
const { prevHash: _p, entryHash: _e, ...bare } = remapped;
|
|
5251
|
+
const chained = chainOp(prevTip, bare);
|
|
5252
|
+
newOps.push(chained);
|
|
5253
|
+
prevTip = chained.entryHash;
|
|
5254
|
+
}
|
|
5255
|
+
const last = newOps[newOps.length - 1];
|
|
5256
|
+
return {
|
|
5257
|
+
scrubbedPaths: [...sealedHashFor.keys()],
|
|
5258
|
+
rewrittenOps: rewritten,
|
|
5259
|
+
ops: newOps,
|
|
5260
|
+
newHead: last?.rootAfter,
|
|
5261
|
+
newSeq: last?.seq ?? 0,
|
|
5262
|
+
newLogTip: last?.entryHash,
|
|
5263
|
+
rootMap
|
|
5264
|
+
};
|
|
5265
|
+
}
|
|
5266
|
+
function gcAfterScrub(solDir2, ops) {
|
|
5267
|
+
const objDir = join11(solDir2, "objects");
|
|
5268
|
+
if (!existsSync11(objDir))
|
|
5269
|
+
return 0;
|
|
5270
|
+
const store2 = new LazyStore(objDir);
|
|
5271
|
+
const reachable = new Set;
|
|
5272
|
+
const walk = (h) => {
|
|
5273
|
+
if (reachable.has(h))
|
|
5274
|
+
return;
|
|
5275
|
+
const node = store2.get(h);
|
|
5276
|
+
if (!node)
|
|
5277
|
+
return;
|
|
5278
|
+
reachable.add(h);
|
|
5279
|
+
if (node.kind === "tree")
|
|
5280
|
+
for (const e of Object.values(node.entries))
|
|
5281
|
+
walk(e.hash);
|
|
5282
|
+
};
|
|
5283
|
+
for (const op of ops) {
|
|
5284
|
+
walk(op.rootAfter);
|
|
5285
|
+
if (op.prov)
|
|
5286
|
+
walk(op.prov);
|
|
5287
|
+
}
|
|
5288
|
+
let removed = 0;
|
|
5289
|
+
for (const name of readdirSync5(objDir)) {
|
|
5290
|
+
if (name.endsWith(".tmp") || !reachable.has(name)) {
|
|
5291
|
+
try {
|
|
5292
|
+
unlinkSync4(join11(objDir, name));
|
|
5293
|
+
removed++;
|
|
5294
|
+
} catch {}
|
|
5295
|
+
}
|
|
5296
|
+
}
|
|
5297
|
+
return removed;
|
|
5298
|
+
}
|
|
5299
|
+
function headMode(store2, root, path) {
|
|
5300
|
+
const segs = path.split("/").filter(Boolean);
|
|
5301
|
+
let cur = root;
|
|
5302
|
+
for (let i = 0;i < segs.length; i++) {
|
|
5303
|
+
const t = store2.getTree(cur);
|
|
5304
|
+
const e = t.entries[segs[i]];
|
|
5305
|
+
if (!e)
|
|
5306
|
+
return;
|
|
5307
|
+
if (i === segs.length - 1)
|
|
5308
|
+
return e.mode;
|
|
5309
|
+
if (e.kind !== "tree")
|
|
5310
|
+
return;
|
|
5311
|
+
cur = e.hash;
|
|
5312
|
+
}
|
|
5313
|
+
return;
|
|
5314
|
+
}
|
|
5315
|
+
var pendingPath = (solDir2) => join11(solDir2, "scrub-pending.json");
|
|
5316
|
+
var init_secret_scrub = __esm(() => {
|
|
5317
|
+
init_chain();
|
|
5318
|
+
init_file_store();
|
|
5319
|
+
init_store();
|
|
5320
|
+
init_tree();
|
|
5321
|
+
init_lib();
|
|
5322
|
+
});
|
|
5323
|
+
|
|
5018
5324
|
// src/text-merge.ts
|
|
5019
5325
|
function lines(s) {
|
|
5020
5326
|
return s.split(`
|
|
@@ -5233,24 +5539,24 @@ __export(exports_local_peer, {
|
|
|
5233
5539
|
openPeer: () => openPeer,
|
|
5234
5540
|
localPeerSolDir: () => localPeerSolDir
|
|
5235
5541
|
});
|
|
5236
|
-
import { existsSync as
|
|
5237
|
-
import { join as
|
|
5542
|
+
import { existsSync as existsSync12, readFileSync as readFileSync12 } from "node:fs";
|
|
5543
|
+
import { join as join12, resolve as resolve2 } from "node:path";
|
|
5238
5544
|
function localPeerSolDir(arg, base) {
|
|
5239
5545
|
if (/^https?:\/\//.test(arg))
|
|
5240
5546
|
return;
|
|
5241
5547
|
const p = resolve2(base, arg);
|
|
5242
|
-
if (
|
|
5243
|
-
return
|
|
5244
|
-
if (
|
|
5548
|
+
if (existsSync12(join12(p, ".sol")))
|
|
5549
|
+
return join12(p, ".sol");
|
|
5550
|
+
if (existsSync12(join12(p, "objects")) && existsSync12(join12(p, "HEAD")))
|
|
5245
5551
|
return p;
|
|
5246
5552
|
return;
|
|
5247
5553
|
}
|
|
5248
5554
|
function openPeer(peerSolDir) {
|
|
5249
|
-
const metaPath =
|
|
5250
|
-
if (
|
|
5555
|
+
const metaPath = join12(peerSolDir, "view.json");
|
|
5556
|
+
if (existsSync12(metaPath)) {
|
|
5251
5557
|
try {
|
|
5252
|
-
const parent = resolve2(peerSolDir, JSON.parse(
|
|
5253
|
-
return { store: new FileStore(peerSolDir,
|
|
5558
|
+
const parent = resolve2(peerSolDir, JSON.parse(readFileSync12(metaPath, "utf8")).parent);
|
|
5559
|
+
return { store: new FileStore(peerSolDir, join12(parent, "objects")), log: new FileOpLog(peerSolDir) };
|
|
5254
5560
|
} catch {}
|
|
5255
5561
|
}
|
|
5256
5562
|
return { store: new FileStore(peerSolDir), log: new FileOpLog(peerSolDir) };
|
|
@@ -5515,9 +5821,9 @@ __export(exports_runtime, {
|
|
|
5515
5821
|
hydrate: () => hydrate2,
|
|
5516
5822
|
capture: () => capture
|
|
5517
5823
|
});
|
|
5518
|
-
import { chmodSync as chmodSync4, existsSync as
|
|
5824
|
+
import { chmodSync as chmodSync4, existsSync as existsSync13, lstatSync as lstatSync2, mkdirSync as mkdirSync7, readdirSync as readdirSync6, readFileSync as readFileSync13, readlinkSync as readlinkSync2, symlinkSync as symlinkSync2, unlinkSync as unlinkSync5, writeFileSync as writeFileSync12 } from "node:fs";
|
|
5519
5825
|
import { platform } from "node:os";
|
|
5520
|
-
import { dirname as dirname3, join as
|
|
5826
|
+
import { dirname as dirname3, join as join13, relative as relative2 } from "node:path";
|
|
5521
5827
|
function isolateCommand(command, scratch) {
|
|
5522
5828
|
if (platform() === "darwin") {
|
|
5523
5829
|
const profile = [
|
|
@@ -5539,16 +5845,16 @@ function hydrate2(store2, head, dir) {
|
|
|
5539
5845
|
const blob = fileAt(store2, head, p);
|
|
5540
5846
|
if (!blob)
|
|
5541
5847
|
continue;
|
|
5542
|
-
const abs =
|
|
5543
|
-
|
|
5848
|
+
const abs = join13(dir, p);
|
|
5849
|
+
mkdirSync7(dirname3(abs), { recursive: true });
|
|
5544
5850
|
const mode = modeAt(store2, head, p);
|
|
5545
5851
|
if (mode === SYMLINK_MODE2) {
|
|
5546
5852
|
try {
|
|
5547
|
-
|
|
5853
|
+
unlinkSync5(abs);
|
|
5548
5854
|
} catch {}
|
|
5549
5855
|
symlinkSync2(blob.content, abs);
|
|
5550
5856
|
} else {
|
|
5551
|
-
|
|
5857
|
+
writeFileSync12(abs, blob.encoding === "base64" ? Buffer.from(blob.content, "base64") : blob.content);
|
|
5552
5858
|
if (mode === EXEC_MODE2) {
|
|
5553
5859
|
try {
|
|
5554
5860
|
chmodSync4(abs, EXEC_MODE2);
|
|
@@ -5560,8 +5866,8 @@ function hydrate2(store2, head, dir) {
|
|
|
5560
5866
|
return n;
|
|
5561
5867
|
}
|
|
5562
5868
|
function walkDir(dir, base, pats, out = []) {
|
|
5563
|
-
for (const name of
|
|
5564
|
-
const p =
|
|
5869
|
+
for (const name of readdirSync6(dir)) {
|
|
5870
|
+
const p = join13(dir, name);
|
|
5565
5871
|
const rel = relative2(base, p);
|
|
5566
5872
|
if (isIgnored(rel, pats))
|
|
5567
5873
|
continue;
|
|
@@ -5579,11 +5885,11 @@ async function capture(repo, dir, keep = []) {
|
|
|
5579
5885
|
const pats = ignorePatterns();
|
|
5580
5886
|
const files = new Set(walkDir(dir, dir, pats));
|
|
5581
5887
|
for (const k of keep)
|
|
5582
|
-
if (
|
|
5888
|
+
if (existsSync13(join13(dir, k)))
|
|
5583
5889
|
files.add(k);
|
|
5584
5890
|
const written = [];
|
|
5585
5891
|
for (const f of files) {
|
|
5586
|
-
const abs =
|
|
5892
|
+
const abs = join13(dir, f);
|
|
5587
5893
|
const st = lstatSync2(abs);
|
|
5588
5894
|
if (st.isSymbolicLink()) {
|
|
5589
5895
|
const target = readlinkSync2(abs);
|
|
@@ -5594,7 +5900,7 @@ async function capture(repo, dir, keep = []) {
|
|
|
5594
5900
|
}
|
|
5595
5901
|
continue;
|
|
5596
5902
|
}
|
|
5597
|
-
const buf =
|
|
5903
|
+
const buf = readFileSync13(abs);
|
|
5598
5904
|
if (buf.includes(0)) {
|
|
5599
5905
|
const cur = await repo.readBytes(f);
|
|
5600
5906
|
if (cur === undefined || cur === SEALED || !Buffer.from(cur).equals(buf)) {
|
|
@@ -5611,7 +5917,7 @@ async function capture(repo, dir, keep = []) {
|
|
|
5611
5917
|
}
|
|
5612
5918
|
const deleted = [];
|
|
5613
5919
|
for (const t of await repo.list()) {
|
|
5614
|
-
if (!
|
|
5920
|
+
if (!existsSync13(join13(dir, t))) {
|
|
5615
5921
|
await repo.deleteFile(t);
|
|
5616
5922
|
deleted.push(t);
|
|
5617
5923
|
}
|
|
@@ -5725,8 +6031,8 @@ __export(exports_git_adapter, {
|
|
|
5725
6031
|
exportHistoryToGit: () => exportHistoryToGit
|
|
5726
6032
|
});
|
|
5727
6033
|
import { execFileSync } from "node:child_process";
|
|
5728
|
-
import { existsSync as
|
|
5729
|
-
import { join as
|
|
6034
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync14, unlinkSync as unlinkSync6, writeFileSync as writeFileSync13 } from "node:fs";
|
|
6035
|
+
import { join as join14 } from "node:path";
|
|
5730
6036
|
import { deflateSync } from "node:zlib";
|
|
5731
6037
|
async function importGitHead(gitPath, ws) {
|
|
5732
6038
|
const listing = git(gitPath, "ls-tree", "-r", "-z", "HEAD").toString();
|
|
@@ -5794,9 +6100,9 @@ async function applyGitFile(repo, path, mode, content) {
|
|
|
5794
6100
|
await repo.chmod(path, exec ? 493 : 420);
|
|
5795
6101
|
}
|
|
5796
6102
|
function setHead(fdir, head) {
|
|
5797
|
-
const hf =
|
|
5798
|
-
const cur =
|
|
5799
|
-
|
|
6103
|
+
const hf = join14(fdir, "HEAD");
|
|
6104
|
+
const cur = existsSync14(hf) ? JSON.parse(readFileSync14(hf, "utf8")) : { seq: 0 };
|
|
6105
|
+
writeFileSync13(hf, JSON.stringify({ ...cur, head }));
|
|
5800
6106
|
}
|
|
5801
6107
|
async function importGitRepo(gitPath, fdir) {
|
|
5802
6108
|
const store2 = new FileStore(fdir);
|
|
@@ -5850,7 +6156,7 @@ function exportToGit(store2, head, gitPath, message) {
|
|
|
5850
6156
|
for (const f of tracked) {
|
|
5851
6157
|
if (!want.has(f)) {
|
|
5852
6158
|
try {
|
|
5853
|
-
|
|
6159
|
+
unlinkSync6(join14(gitPath, f));
|
|
5854
6160
|
} catch {}
|
|
5855
6161
|
deleted++;
|
|
5856
6162
|
}
|
|
@@ -5861,20 +6167,20 @@ function exportToGit(store2, head, gitPath, message) {
|
|
|
5861
6167
|
return { written, deleted };
|
|
5862
6168
|
}
|
|
5863
6169
|
function gitObjectsDir(gitPath) {
|
|
5864
|
-
for (const c of [
|
|
5865
|
-
if (
|
|
6170
|
+
for (const c of [join14(gitPath, ".git", "objects"), join14(gitPath, "objects")])
|
|
6171
|
+
if (existsSync14(c))
|
|
5866
6172
|
return c;
|
|
5867
6173
|
return;
|
|
5868
6174
|
}
|
|
5869
6175
|
function writeLooseObject(objectsDir2, o) {
|
|
5870
|
-
const dir =
|
|
5871
|
-
const file =
|
|
5872
|
-
if (
|
|
6176
|
+
const dir = join14(objectsDir2, o.oid.slice(0, 2));
|
|
6177
|
+
const file = join14(dir, o.oid.slice(2));
|
|
6178
|
+
if (existsSync14(file))
|
|
5873
6179
|
return;
|
|
5874
6180
|
const header = Buffer.from(`${o.type} ${o.content.length}\x00`);
|
|
5875
6181
|
const framed = Buffer.concat([header, Buffer.from(o.content)]);
|
|
5876
|
-
|
|
5877
|
-
|
|
6182
|
+
mkdirSync8(dir, { recursive: true });
|
|
6183
|
+
writeFileSync13(file, deflateSync(framed));
|
|
5878
6184
|
}
|
|
5879
6185
|
function exportAncestry(ops) {
|
|
5880
6186
|
const parents = new Map;
|
|
@@ -5986,31 +6292,31 @@ __export(exports_views, {
|
|
|
5986
6292
|
loadViewsRegistry: () => loadViewsRegistry,
|
|
5987
6293
|
createView: () => createView
|
|
5988
6294
|
});
|
|
5989
|
-
import { existsSync as
|
|
5990
|
-
import { join as
|
|
6295
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync9, readdirSync as readdirSync7, readFileSync as readFileSync15, rmSync, writeFileSync as writeFileSync14 } from "node:fs";
|
|
6296
|
+
import { join as join15, relative as relative3, resolve as resolve3 } from "node:path";
|
|
5991
6297
|
function loadViewsRegistry(parentSol) {
|
|
5992
6298
|
const p = viewsRegistryPath(parentSol);
|
|
5993
|
-
if (!
|
|
6299
|
+
if (!existsSync15(p))
|
|
5994
6300
|
return { views: [] };
|
|
5995
6301
|
try {
|
|
5996
|
-
return JSON.parse(
|
|
6302
|
+
return JSON.parse(readFileSync15(p, "utf8"));
|
|
5997
6303
|
} catch {
|
|
5998
6304
|
return { views: [] };
|
|
5999
6305
|
}
|
|
6000
6306
|
}
|
|
6001
6307
|
function saveViewsRegistry(parentSol, reg) {
|
|
6002
|
-
|
|
6308
|
+
writeFileSync14(viewsRegistryPath(parentSol), JSON.stringify(reg, null, 2));
|
|
6003
6309
|
}
|
|
6004
6310
|
function createView(opts) {
|
|
6005
6311
|
const { parentSol, viewDir, name, branch, actor: actor2, startHead } = opts;
|
|
6006
|
-
const viewSol =
|
|
6007
|
-
|
|
6312
|
+
const viewSol = join15(viewDir, ".sol");
|
|
6313
|
+
mkdirSync9(viewSol, { recursive: true });
|
|
6008
6314
|
const meta = { parent: relative3(viewSol, parentSol), name, branch, actor: actor2, startHead, createdAt: Date.now() };
|
|
6009
|
-
|
|
6010
|
-
|
|
6315
|
+
writeFileSync14(join15(viewSol, "view.json"), JSON.stringify(meta, null, 2));
|
|
6316
|
+
writeFileSync14(join15(viewSol, "HEAD"), JSON.stringify({ head: startHead, seq: 0 }));
|
|
6011
6317
|
const refs = { current: branch, branches: { [branch]: { head: startHead, base: startHead } }, tags: {} };
|
|
6012
|
-
|
|
6013
|
-
const store2 = new LazyStore(
|
|
6318
|
+
writeFileSync14(join15(viewSol, "refs.json"), JSON.stringify(refs, null, 2));
|
|
6319
|
+
const store2 = new LazyStore(join15(parentSol, "objects"));
|
|
6014
6320
|
const paths = (startHead ? listAll(store2, startHead) : []).filter((p) => !p.split("/").some(isReservedKey));
|
|
6015
6321
|
for (const f of paths)
|
|
6016
6322
|
materializeInto(store2, startHead, viewDir, f);
|
|
@@ -6025,8 +6331,8 @@ async function viewStatuses(parentSol) {
|
|
|
6025
6331
|
const reg = loadViewsRegistry(parentSol);
|
|
6026
6332
|
const out = [];
|
|
6027
6333
|
for (const v of reg.views) {
|
|
6028
|
-
const viewSol =
|
|
6029
|
-
const exists =
|
|
6334
|
+
const viewSol = join15(v.dir, ".sol");
|
|
6335
|
+
const exists = existsSync15(join15(viewSol, "view.json"));
|
|
6030
6336
|
let head;
|
|
6031
6337
|
if (exists) {
|
|
6032
6338
|
head = await new FileOpLog(viewSol).head();
|
|
@@ -6050,7 +6356,7 @@ function pruneViews(parentSol, opts = {}) {
|
|
|
6050
6356
|
const reg = loadViewsRegistry(parentSol);
|
|
6051
6357
|
const removed = [];
|
|
6052
6358
|
reg.views = reg.views.filter((v) => {
|
|
6053
|
-
const present =
|
|
6359
|
+
const present = existsSync15(join15(v.dir, ".sol", "view.json"));
|
|
6054
6360
|
const target = opts.name ? v.name === opts.name : !present;
|
|
6055
6361
|
if (!target)
|
|
6056
6362
|
return true;
|
|
@@ -6066,12 +6372,12 @@ function pruneViews(parentSol, opts = {}) {
|
|
|
6066
6372
|
return removed;
|
|
6067
6373
|
}
|
|
6068
6374
|
function sharedObjectCount(parentSol) {
|
|
6069
|
-
const dir =
|
|
6070
|
-
if (!
|
|
6375
|
+
const dir = join15(parentSol, "objects");
|
|
6376
|
+
if (!existsSync15(dir))
|
|
6071
6377
|
return 0;
|
|
6072
|
-
return
|
|
6378
|
+
return readdirSync7(dir).filter((n) => !n.endsWith(".tmp")).length;
|
|
6073
6379
|
}
|
|
6074
|
-
var viewsRegistryPath = (parentSol) =>
|
|
6380
|
+
var viewsRegistryPath = (parentSol) => join15(parentSol, "views.json");
|
|
6075
6381
|
var init_views = __esm(() => {
|
|
6076
6382
|
init_file_store();
|
|
6077
6383
|
init_struct();
|
|
@@ -6511,7 +6817,7 @@ __export(exports_secret2, {
|
|
|
6511
6817
|
runEnv: () => runEnv,
|
|
6512
6818
|
resolveReference: () => resolveReference
|
|
6513
6819
|
});
|
|
6514
|
-
import { readFileSync as
|
|
6820
|
+
import { readFileSync as readFileSync16, readSync, writeSync } from "node:fs";
|
|
6515
6821
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
6516
6822
|
function flag(args, name) {
|
|
6517
6823
|
const i = args.indexOf(name);
|
|
@@ -6883,7 +7189,7 @@ async function envValidate(ctx, args, json) {
|
|
|
6883
7189
|
}
|
|
6884
7190
|
function readSchemaText(solDir2) {
|
|
6885
7191
|
try {
|
|
6886
|
-
return
|
|
7192
|
+
return readFileSync16(schemaLockPath(solDir2), "utf8");
|
|
6887
7193
|
} catch {
|
|
6888
7194
|
return;
|
|
6889
7195
|
}
|
|
@@ -7558,14 +7864,14 @@ var exports_sol_secret_mcp = {};
|
|
|
7558
7864
|
__export(exports_sol_secret_mcp, {
|
|
7559
7865
|
startSecretMcp: () => startSecretMcp
|
|
7560
7866
|
});
|
|
7561
|
-
import { existsSync as
|
|
7562
|
-
import { join as
|
|
7867
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
7868
|
+
import { join as join16 } from "node:path";
|
|
7563
7869
|
async function startSecretMcp(opts = {}) {
|
|
7564
7870
|
const { Server } = await import("@modelcontextprotocol/sdk/server/index.js");
|
|
7565
7871
|
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
7566
7872
|
const { CallToolRequestSchema, ListToolsRequestSchema } = await import("@modelcontextprotocol/sdk/types.js");
|
|
7567
|
-
const solDir2 = opts.solDir || process.env.SOL_DIR ||
|
|
7568
|
-
if (!
|
|
7873
|
+
const solDir2 = opts.solDir || process.env.SOL_DIR || join16(process.cwd(), ".sol");
|
|
7874
|
+
if (!existsSync16(solDir2)) {
|
|
7569
7875
|
process.stderr.write(`sol-secret-mcp: no .sol at ${solDir2} — run \`sol init\` first (or set SOL_DIR)
|
|
7570
7876
|
`);
|
|
7571
7877
|
process.exit(1);
|
|
@@ -7719,8 +8025,8 @@ var exports_sol_mcp = {};
|
|
|
7719
8025
|
__export(exports_sol_mcp, {
|
|
7720
8026
|
startWorkspaceMcp: () => startWorkspaceMcp
|
|
7721
8027
|
});
|
|
7722
|
-
import { mkdirSync as
|
|
7723
|
-
import { join as
|
|
8028
|
+
import { mkdirSync as mkdirSync10 } from "node:fs";
|
|
8029
|
+
import { join as join17 } from "node:path";
|
|
7724
8030
|
async function handle(ws, name, a) {
|
|
7725
8031
|
switch (name) {
|
|
7726
8032
|
case "sol_write":
|
|
@@ -7762,8 +8068,8 @@ async function startWorkspaceMcp(opts = {}) {
|
|
|
7762
8068
|
const { Server } = await import("@modelcontextprotocol/sdk/server/index.js");
|
|
7763
8069
|
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
7764
8070
|
const { CallToolRequestSchema, ListToolsRequestSchema } = await import("@modelcontextprotocol/sdk/types.js");
|
|
7765
|
-
const solDir2 = opts.solDir || process.env.SOL_DIR ||
|
|
7766
|
-
|
|
8071
|
+
const solDir2 = opts.solDir || process.env.SOL_DIR || join17(process.cwd(), ".sol");
|
|
8072
|
+
mkdirSync10(solDir2, { recursive: true });
|
|
7767
8073
|
const ws = new SolWorkspace(new FileStore(solDir2), new FileOpLog(solDir2), process.env.SOL_ACTOR || "agent");
|
|
7768
8074
|
const server = new Server({ name: "sol", version: "0.1.0" }, { capabilities: { tools: {} } });
|
|
7769
8075
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));
|
|
@@ -7800,9 +8106,9 @@ __export(exports_dispatch, {
|
|
|
7800
8106
|
dispatch: () => dispatch
|
|
7801
8107
|
});
|
|
7802
8108
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
7803
|
-
import { existsSync as
|
|
8109
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync11, mkdtempSync, readdirSync as readdirSync8, readFileSync as readFileSync17, rmSync as rmSync2, unlinkSync as unlinkSync7, watch, writeFileSync as writeFileSync15 } from "node:fs";
|
|
7804
8110
|
import { homedir as homedir2, hostname, platform as platform2, tmpdir } from "node:os";
|
|
7805
|
-
import { basename, dirname as dirname4, join as
|
|
8111
|
+
import { basename, dirname as dirname4, join as join18, resolve as resolve4, sep as sep2 } from "node:path";
|
|
7806
8112
|
function globCovers(pattern, path) {
|
|
7807
8113
|
let re = "";
|
|
7808
8114
|
for (let i = 0;i < pattern.length; i++) {
|
|
@@ -7830,11 +8136,11 @@ function tokenClaims(token) {
|
|
|
7830
8136
|
}
|
|
7831
8137
|
}
|
|
7832
8138
|
async function loadStoredToken() {
|
|
7833
|
-
if (!
|
|
8139
|
+
if (!existsSync17(CRED_PATH))
|
|
7834
8140
|
return;
|
|
7835
8141
|
let creds;
|
|
7836
8142
|
try {
|
|
7837
|
-
creds = JSON.parse(
|
|
8143
|
+
creds = JSON.parse(readFileSync17(CRED_PATH, "utf8"));
|
|
7838
8144
|
} catch {
|
|
7839
8145
|
return;
|
|
7840
8146
|
}
|
|
@@ -7849,7 +8155,7 @@ async function loadStoredToken() {
|
|
|
7849
8155
|
if (res.ok) {
|
|
7850
8156
|
const r = await res.json();
|
|
7851
8157
|
if (r.accessToken) {
|
|
7852
|
-
|
|
8158
|
+
writeFileSync15(CRED_PATH, JSON.stringify({ ...creds, accessToken: r.accessToken, refreshToken: r.refreshToken ?? creds.refreshToken }, null, 2), { mode: 384 });
|
|
7853
8159
|
return r.accessToken;
|
|
7854
8160
|
}
|
|
7855
8161
|
}
|
|
@@ -7870,7 +8176,7 @@ function authHost() {
|
|
|
7870
8176
|
if (process.env.SOL_AUTH)
|
|
7871
8177
|
return process.env.SOL_AUTH.replace(/\/+$/, "");
|
|
7872
8178
|
try {
|
|
7873
|
-
const w = JSON.parse(
|
|
8179
|
+
const w = JSON.parse(readFileSync17(CRED_PATH, "utf8")).webUrl;
|
|
7874
8180
|
if (w)
|
|
7875
8181
|
return w.replace(/\/+$/, "");
|
|
7876
8182
|
} catch {}
|
|
@@ -7931,7 +8237,7 @@ function cliVersion() {
|
|
|
7931
8237
|
if (typeof __SOL_COMPILED_VERSION__ === "string" && __SOL_COMPILED_VERSION__)
|
|
7932
8238
|
return __SOL_COMPILED_VERSION__;
|
|
7933
8239
|
try {
|
|
7934
|
-
return JSON.parse(
|
|
8240
|
+
return JSON.parse(readFileSync17(new URL("./package.json", import.meta.url), "utf8")).version || "dev";
|
|
7935
8241
|
} catch {
|
|
7936
8242
|
return "dev";
|
|
7937
8243
|
}
|
|
@@ -8461,7 +8767,7 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
8461
8767
|
try {
|
|
8462
8768
|
const { loadSelfIdentity: loadSelfIdentity2 } = await Promise.resolve().then(() => (init_seal_audience(), exports_seal_audience));
|
|
8463
8769
|
const { openContent: openContent2 } = await Promise.resolve().then(() => (init_crypto(), exports_crypto));
|
|
8464
|
-
const ring =
|
|
8770
|
+
const ring = existsSync17(solDir) ? loadKeyRing() : new (await Promise.resolve().then(() => (init_crypto(), exports_crypto))).KeyRing;
|
|
8465
8771
|
const self = loadSelfIdentity2();
|
|
8466
8772
|
setSealedDecryptor((boxStr) => {
|
|
8467
8773
|
const box = JSON.parse(boxStr);
|
|
@@ -8471,19 +8777,19 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
8471
8777
|
} catch {}
|
|
8472
8778
|
}
|
|
8473
8779
|
const servesMcp = cmd === "mcp" || cmd === "secret" && args[0] === "mcp";
|
|
8474
|
-
const release = !servesMcp && new Set(["add", "track", "commit", "checkpoint", "rm", "gc", "branch", "tag", "switch", "merge", "undo", "revert", "pull", "push", "restore", "checkout", "run", "seal", "view", "env", "secret"]).has(cmd) &&
|
|
8780
|
+
const release = !servesMcp && new Set(["add", "track", "commit", "checkpoint", "rm", "gc", "branch", "tag", "switch", "merge", "undo", "revert", "pull", "push", "restore", "checkout", "run", "seal", "view", "env", "secret"]).has(cmd) && existsSync17(solDir) ? acquireLock() : undefined;
|
|
8475
8781
|
try {
|
|
8476
8782
|
switch (cmd) {
|
|
8477
8783
|
case "init": {
|
|
8478
|
-
const here =
|
|
8479
|
-
if (
|
|
8784
|
+
const here = join18(procCwd, ".sol");
|
|
8785
|
+
if (existsSync17(here))
|
|
8480
8786
|
die("already a sol repo: " + procCwd);
|
|
8481
8787
|
if (repoRoot && repoRoot !== procCwd && !args.includes("--force")) {
|
|
8482
8788
|
die(`already inside a Sol repo at ${repoRoot}
|
|
8483
8789
|
-> just commit into it: \`sol commit ...\` works from here (sol walks up to find the repo)
|
|
8484
8790
|
-> to nest a NEW repo here anyway: \`sol init --force\``);
|
|
8485
8791
|
}
|
|
8486
|
-
|
|
8792
|
+
mkdirSync11(here, { recursive: true });
|
|
8487
8793
|
new FileStore(here);
|
|
8488
8794
|
console.log(`initialized empty sol repo in ${here}`);
|
|
8489
8795
|
break;
|
|
@@ -8599,7 +8905,7 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
8599
8905
|
if (sub === "import") {
|
|
8600
8906
|
const passphrase = process.env.SOL_KEYSTORE_PASSPHRASE || die("set SOL_KEYSTORE_PASSPHRASE to decrypt the bundle");
|
|
8601
8907
|
const file = args[1] || die("usage: sol keys import <bundle.json> (set SOL_KEYSTORE_PASSPHRASE)");
|
|
8602
|
-
const bundle = JSON.parse(
|
|
8908
|
+
const bundle = JSON.parse(readFileSync17(file, "utf8"));
|
|
8603
8909
|
let recovered;
|
|
8604
8910
|
try {
|
|
8605
8911
|
recovered = importBundle2(bundle, passphrase);
|
|
@@ -8630,7 +8936,7 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
8630
8936
|
break;
|
|
8631
8937
|
}
|
|
8632
8938
|
case "trust": {
|
|
8633
|
-
if (!
|
|
8939
|
+
if (!existsSync17(solDir))
|
|
8634
8940
|
die("not a sol repo — run `sol init` first");
|
|
8635
8941
|
const map = loadTrust();
|
|
8636
8942
|
if (args[0] === "--remove" || args[0] === "-r") {
|
|
@@ -8677,7 +8983,7 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
8677
8983
|
}
|
|
8678
8984
|
case "track":
|
|
8679
8985
|
case "add": {
|
|
8680
|
-
if (!
|
|
8986
|
+
if (!existsSync17(solDir))
|
|
8681
8987
|
die("not a sol repo — run `sol init` first");
|
|
8682
8988
|
const files = args.filter((a) => a !== "." && !a.startsWith("-"));
|
|
8683
8989
|
if (!files.length) {
|
|
@@ -8688,7 +8994,7 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
8688
8994
|
let n = 0;
|
|
8689
8995
|
for (const f of files) {
|
|
8690
8996
|
const rf = repoRel(f);
|
|
8691
|
-
if (!
|
|
8997
|
+
if (!existsSync17(join18(cwd, rf))) {
|
|
8692
8998
|
console.error("skip (not on disk): " + f);
|
|
8693
8999
|
continue;
|
|
8694
9000
|
}
|
|
@@ -8717,14 +9023,14 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
8717
9023
|
if (!message)
|
|
8718
9024
|
die('commit needs a message: sol commit "what you did" (scoped: sol commit -m "msg" file1 file2)');
|
|
8719
9025
|
const parentHead = await repo.head();
|
|
8720
|
-
const mergeHeadPath =
|
|
8721
|
-
const parent2 =
|
|
9026
|
+
const mergeHeadPath = join18(solDir, "MERGE_HEAD");
|
|
9027
|
+
const parent2 = existsSync17(mergeHeadPath) ? readFileSync17(mergeHeadPath, "utf8").trim() || undefined : undefined;
|
|
8722
9028
|
let changed = 0;
|
|
8723
9029
|
let commitRoot = parentHead;
|
|
8724
9030
|
if (paths.length) {
|
|
8725
9031
|
for (const p of paths) {
|
|
8726
9032
|
const rp = repoRel(p);
|
|
8727
|
-
if (
|
|
9033
|
+
if (existsSync17(join18(cwd, rp))) {
|
|
8728
9034
|
if (await snapshotFile(repo, rp))
|
|
8729
9035
|
changed++;
|
|
8730
9036
|
} else if ((await repo.list()).includes(rp)) {
|
|
@@ -8766,7 +9072,7 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
8766
9072
|
await appendCommit(log, commitRoot, message, parentHead, parent2);
|
|
8767
9073
|
if (parent2) {
|
|
8768
9074
|
try {
|
|
8769
|
-
|
|
9075
|
+
unlinkSync7(mergeHeadPath);
|
|
8770
9076
|
} catch {}
|
|
8771
9077
|
}
|
|
8772
9078
|
const refs = await loadRefs(log);
|
|
@@ -8779,7 +9085,7 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
8779
9085
|
}
|
|
8780
9086
|
case "status": {
|
|
8781
9087
|
const { repo, log } = open();
|
|
8782
|
-
const refs =
|
|
9088
|
+
const refs = existsSync17(refsPath()) ? await loadRefs(log) : undefined;
|
|
8783
9089
|
const head = await repo.head();
|
|
8784
9090
|
const headOp = head ? [...await log.history()].reverse().find((o) => o.rootAfter === head) : undefined;
|
|
8785
9091
|
const headBy = headOp?.by ?? "?";
|
|
@@ -8869,7 +9175,7 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
8869
9175
|
const { listAll: listAll3 } = await Promise.resolve().then(() => (init_tree(), exports_tree));
|
|
8870
9176
|
const { loadSelfIdentity: loadSelfIdentity2 } = await Promise.resolve().then(() => (init_seal_audience(), exports_seal_audience));
|
|
8871
9177
|
const { openContent: openContent2, UNREADABLE: UNREADABLE2 } = await Promise.resolve().then(() => (init_crypto(), exports_crypto));
|
|
8872
|
-
const ring =
|
|
9178
|
+
const ring = existsSync17(solDir) ? loadKeyRing() : new (await Promise.resolve().then(() => (init_crypto(), exports_crypto))).KeyRing;
|
|
8873
9179
|
const self = loadSelfIdentity2();
|
|
8874
9180
|
const decrypt = (boxStr) => {
|
|
8875
9181
|
try {
|
|
@@ -8917,7 +9223,7 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
8917
9223
|
const { readFile: readTree, entryKindAt: kindAt } = await Promise.resolve().then(() => (init_tree(), exports_tree));
|
|
8918
9224
|
const { loadSelfIdentity: loadSelfIdentity2 } = await Promise.resolve().then(() => (init_seal_audience(), exports_seal_audience));
|
|
8919
9225
|
const { openContent: openContent2, UNREADABLE: UNREADABLE2, KeyRing: KeyRing3 } = await Promise.resolve().then(() => (init_crypto(), exports_crypto));
|
|
8920
|
-
const ring =
|
|
9226
|
+
const ring = existsSync17(solDir) ? loadKeyRing() : new KeyRing3;
|
|
8921
9227
|
const self = loadSelfIdentity2();
|
|
8922
9228
|
const decrypt = (boxStr) => {
|
|
8923
9229
|
try {
|
|
@@ -9016,7 +9322,7 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
9016
9322
|
};
|
|
9017
9323
|
const live = await log.head() ?? "";
|
|
9018
9324
|
const refArg = args.find((a) => !a.startsWith("-"));
|
|
9019
|
-
const lrefs =
|
|
9325
|
+
const lrefs = existsSync17(refsPath()) ? JSON.parse(readFileSync17(refsPath(), "utf8")) : null;
|
|
9020
9326
|
let tipRoot = live;
|
|
9021
9327
|
if (refArg) {
|
|
9022
9328
|
tipRoot = lrefs?.branches[refArg]?.head ?? refArg;
|
|
@@ -9069,7 +9375,7 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
9069
9375
|
const path = args[0] || die("rm needs a path");
|
|
9070
9376
|
let onDisk = false;
|
|
9071
9377
|
try {
|
|
9072
|
-
|
|
9378
|
+
unlinkSync7(join18(cwd, path));
|
|
9073
9379
|
onDisk = true;
|
|
9074
9380
|
} catch {}
|
|
9075
9381
|
if (onDisk) {
|
|
@@ -9297,16 +9603,16 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
9297
9603
|
if (op.prov)
|
|
9298
9604
|
walk(op.prov);
|
|
9299
9605
|
}
|
|
9300
|
-
const objDir =
|
|
9606
|
+
const objDir = join18(solDir, "objects");
|
|
9301
9607
|
let removed = 0;
|
|
9302
|
-
for (const name of
|
|
9608
|
+
for (const name of readdirSync8(objDir)) {
|
|
9303
9609
|
if (name.endsWith(".tmp") || !reachable.has(name)) {
|
|
9304
|
-
|
|
9610
|
+
unlinkSync7(join18(objDir, name));
|
|
9305
9611
|
removed++;
|
|
9306
9612
|
}
|
|
9307
9613
|
}
|
|
9308
9614
|
console.log(`gc: kept ${reachable.size} object(s), removed ${removed} unreachable`);
|
|
9309
|
-
if (
|
|
9615
|
+
if (existsSync17(join18(solDir, "env", "seal"))) {
|
|
9310
9616
|
const { gcStaleStanzas: gcStaleStanzas2 } = await Promise.resolve().then(() => (init_secret(), exports_secret));
|
|
9311
9617
|
const st = gcStaleStanzas2(solDir);
|
|
9312
9618
|
if (st.removed)
|
|
@@ -9321,8 +9627,8 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
9321
9627
|
console.log(p);
|
|
9322
9628
|
break;
|
|
9323
9629
|
}
|
|
9324
|
-
const f =
|
|
9325
|
-
const lead =
|
|
9630
|
+
const f = join18(cwd, ".solignore");
|
|
9631
|
+
const lead = existsSync17(f) && !readFileSync17(f, "utf8").endsWith(`
|
|
9326
9632
|
`) ? `
|
|
9327
9633
|
` : "";
|
|
9328
9634
|
appendFileSync2(f, lead + pat + `
|
|
@@ -9423,6 +9729,48 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
9423
9729
|
const wantJson = args.includes("--json");
|
|
9424
9730
|
const reapply = args.includes("--reapply");
|
|
9425
9731
|
const positional = args.filter((a) => !a.startsWith("-"));
|
|
9732
|
+
if (args.includes("--scrub-history")) {
|
|
9733
|
+
const { pendingScrubPaths: pendingScrubPaths2, historyHasCleartext: historyHasCleartext2, scrubHistory: scrubHistory2, clearPendingScrub: clearPendingScrub2, gcAfterScrub: gcAfterScrub2 } = await Promise.resolve().then(() => (init_secret_scrub(), exports_secret_scrub));
|
|
9734
|
+
const ops = await log.history();
|
|
9735
|
+
const only = positional[0];
|
|
9736
|
+
const targets = (only ? [only] : pendingScrubPaths2(solDir)).filter((p) => historyHasCleartext2(solDir, ops, p));
|
|
9737
|
+
if (!targets.length) {
|
|
9738
|
+
if (only)
|
|
9739
|
+
die(`no pre-seal cleartext in history for "${only}" — nothing to scrub (it was never committed in the clear, or is already scrubbed).`);
|
|
9740
|
+
clearPendingScrub2(solDir);
|
|
9741
|
+
console.log(wantJson ? JSON.stringify({ scrubbed: [], rewrittenOps: 0 }) : "no paths with recoverable pre-seal cleartext — nothing to scrub.");
|
|
9742
|
+
break;
|
|
9743
|
+
}
|
|
9744
|
+
let removed = 0;
|
|
9745
|
+
{
|
|
9746
|
+
const res = await scrubHistory2(solDir, ops, targets);
|
|
9747
|
+
writeFileSync15(join18(solDir, "ops.jsonl"), res.ops.map((o) => JSON.stringify(o)).join(`
|
|
9748
|
+
`) + (res.ops.length ? `
|
|
9749
|
+
` : ""));
|
|
9750
|
+
writeFileSync15(join18(solDir, "HEAD"), JSON.stringify({ head: res.newHead, seq: res.newSeq, logTip: res.newLogTip }));
|
|
9751
|
+
if (existsSync17(refsPath())) {
|
|
9752
|
+
const refs = JSON.parse(readFileSync17(refsPath(), "utf8"));
|
|
9753
|
+
for (const b of Object.values(refs.branches)) {
|
|
9754
|
+
if (b.head && res.rootMap.has(b.head))
|
|
9755
|
+
b.head = res.rootMap.get(b.head);
|
|
9756
|
+
if (b.base && res.rootMap.has(b.base))
|
|
9757
|
+
b.base = res.rootMap.get(b.base);
|
|
9758
|
+
if (b.remote && res.rootMap.has(b.remote))
|
|
9759
|
+
b.remote = res.rootMap.get(b.remote);
|
|
9760
|
+
}
|
|
9761
|
+
saveRefs(refs);
|
|
9762
|
+
}
|
|
9763
|
+
removed = gcAfterScrub2(solDir, res.ops);
|
|
9764
|
+
clearPendingScrub2(solDir);
|
|
9765
|
+
}
|
|
9766
|
+
if (wantJson) {
|
|
9767
|
+
console.log(JSON.stringify({ scrubbed: targets, removedObjects: removed }));
|
|
9768
|
+
break;
|
|
9769
|
+
}
|
|
9770
|
+
console.log(`scrubbed pre-seal cleartext from history for: ${targets.join(", ")} — the op-log was rewritten and ${removed} orphaned cleartext object(s) dropped (\`sol restore\` can no longer recover them); push is unblocked.`);
|
|
9771
|
+
console.log(" NOTE: this is a DESTRUCTIVE local history rewrite. collaborators who already pulled the old history must re-clone.");
|
|
9772
|
+
break;
|
|
9773
|
+
}
|
|
9426
9774
|
if (reapply) {
|
|
9427
9775
|
const cfg = resolveRemote(solDir) || die("no remote — the policy lives on the repo; `sol remote <url> <repo>` first");
|
|
9428
9776
|
const token = process.env.SOL_TOKEN || authExpired();
|
|
@@ -9559,10 +9907,10 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
9559
9907
|
if (content === SEALED && !args.includes("--hide-names"))
|
|
9560
9908
|
die("already sealed: " + path);
|
|
9561
9909
|
if (content === undefined) {
|
|
9562
|
-
const abs =
|
|
9563
|
-
if (!
|
|
9910
|
+
const abs = join18(cwd, path);
|
|
9911
|
+
if (!existsSync17(abs))
|
|
9564
9912
|
die("no such file: " + path);
|
|
9565
|
-
content =
|
|
9913
|
+
content = readFileSync17(abs, "utf8");
|
|
9566
9914
|
}
|
|
9567
9915
|
const ring = loadKeyRing();
|
|
9568
9916
|
const { SealedClient: SealedClient2 } = await Promise.resolve().then(() => (init_sealed_client(), exports_sealed_client));
|
|
@@ -9744,6 +10092,18 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
9744
10092
|
recordAudience2(solDir, { path, epoch: 1, at: Date.now(), accounts: [], local: [...localRecipients] });
|
|
9745
10093
|
}
|
|
9746
10094
|
saveKeyRing(ring);
|
|
10095
|
+
if (onTree !== undefined && onTree !== SEALED) {
|
|
10096
|
+
const { historyHasCleartext: historyHasCleartext2, addPendingScrub: addPendingScrub2 } = await Promise.resolve().then(() => (init_secret_scrub(), exports_secret_scrub));
|
|
10097
|
+
if (historyHasCleartext2(solDir, await log.history(), path)) {
|
|
10098
|
+
addPendingScrub2(solDir, path);
|
|
10099
|
+
if (!wantJson) {
|
|
10100
|
+
console.error(`
|
|
10101
|
+
WARNING: "${path}" was committed as PLAINTEXT before this seal — the pre-seal cleartext is STILL recoverable from history (\`sol restore\`) and would ship to every clone on push.`);
|
|
10102
|
+
console.error(` push is now BLOCKED for safety. run \`sol seal ${path} --scrub-history\` to rewrite it out of history, then push.
|
|
10103
|
+
`);
|
|
10104
|
+
}
|
|
10105
|
+
}
|
|
10106
|
+
}
|
|
9747
10107
|
}
|
|
9748
10108
|
if (wantHideName) {
|
|
9749
10109
|
const { slotForPath: slotForPath2, recordNameSlot: recordNameSlot2, recordHiddenPath: recordHiddenPath2 } = await Promise.resolve().then(() => (init_seal_audience(), exports_seal_audience));
|
|
@@ -9843,7 +10203,7 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
9843
10203
|
const { openContent: openContent2, UNREADABLE: UNREADABLE2 } = await Promise.resolve().then(() => (init_crypto(), exports_crypto));
|
|
9844
10204
|
const { parseStruct: parseStruct2 } = await Promise.resolve().then(() => (init_struct(), exports_struct));
|
|
9845
10205
|
const audiences = loadAudiences2(solDir);
|
|
9846
|
-
const ring =
|
|
10206
|
+
const ring = existsSync17(solDir) ? loadKeyRing() : new (await Promise.resolve().then(() => (init_crypto(), exports_crypto))).KeyRing;
|
|
9847
10207
|
const self = loadSelfIdentity2();
|
|
9848
10208
|
const levelOf = (boxStr) => {
|
|
9849
10209
|
try {
|
|
@@ -10038,7 +10398,7 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10038
10398
|
const result = merge2({ store: store2 }, other.base, ours, other.head);
|
|
10039
10399
|
if (result.conflicts.length) {
|
|
10040
10400
|
materializeTree(store2, result.head);
|
|
10041
|
-
|
|
10401
|
+
writeFileSync15(join18(solDir, "MERGE_HEAD"), other.head);
|
|
10042
10402
|
saveMergeConflicts(solDir, result.conflicts);
|
|
10043
10403
|
console.log(`merge ${name} -> ${result.conflicts.length} conflict(s), left in your working tree (uncommitted):`);
|
|
10044
10404
|
for (const c of result.conflicts)
|
|
@@ -10139,7 +10499,7 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10139
10499
|
break;
|
|
10140
10500
|
}
|
|
10141
10501
|
case "remote": {
|
|
10142
|
-
if (!
|
|
10502
|
+
if (!existsSync17(solDir))
|
|
10143
10503
|
die("not a sol repo");
|
|
10144
10504
|
if (args[0]) {
|
|
10145
10505
|
const repoName = args[1] || die("usage: sol remote <url> <repo>");
|
|
@@ -10185,16 +10545,16 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10185
10545
|
}
|
|
10186
10546
|
if (!tokens)
|
|
10187
10547
|
die("timed out waiting for approval");
|
|
10188
|
-
|
|
10189
|
-
|
|
10548
|
+
mkdirSync11(dirname4(CRED_PATH), { recursive: true });
|
|
10549
|
+
writeFileSync15(CRED_PATH, JSON.stringify({ webUrl, ...tokens }, null, 2), { mode: 384 });
|
|
10190
10550
|
const c = tokenClaims(tokens.accessToken);
|
|
10191
10551
|
console.log(`
|
|
10192
10552
|
Logged in as ${c.handle ? `@${c.handle}` : c.email || "user"}.`);
|
|
10193
10553
|
if (!c.handle)
|
|
10194
10554
|
console.log(" (no handle yet — set one in the web app to get your <handle>/<repo> namespace)");
|
|
10195
10555
|
} else if (sub === "logout") {
|
|
10196
|
-
if (
|
|
10197
|
-
|
|
10556
|
+
if (existsSync17(CRED_PATH))
|
|
10557
|
+
unlinkSync7(CRED_PATH);
|
|
10198
10558
|
console.log("logged out");
|
|
10199
10559
|
} else if (sub === "status" || !sub) {
|
|
10200
10560
|
if (process.env.SOL_TOKEN) {
|
|
@@ -10202,11 +10562,11 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10202
10562
|
console.log(`authenticated via SOL_TOKEN (env)${c2.handle ? ` as @${c2.handle}` : ""}`);
|
|
10203
10563
|
break;
|
|
10204
10564
|
}
|
|
10205
|
-
if (!
|
|
10565
|
+
if (!existsSync17(CRED_PATH)) {
|
|
10206
10566
|
console.log("not logged in — run `sol auth login` (or set SOL_TOKEN)");
|
|
10207
10567
|
break;
|
|
10208
10568
|
}
|
|
10209
|
-
const creds = JSON.parse(
|
|
10569
|
+
const creds = JSON.parse(readFileSync17(CRED_PATH, "utf8"));
|
|
10210
10570
|
const c = tokenClaims(creds.accessToken || "");
|
|
10211
10571
|
const stale = typeof c.exp === "number" && c.exp * 1000 < Date.now();
|
|
10212
10572
|
console.log(`logged in as ${c.handle ? `@${c.handle}` : c.email || "user"} via ${creds.webUrl}${stale ? " (token stale — refreshes on next use)" : ""}`);
|
|
@@ -10256,9 +10616,9 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10256
10616
|
console.log("heads-up: changing your handle re-namespaces your repos under the new <handle>/<repo>.");
|
|
10257
10617
|
console.log(`handle set to @${out.handle}`);
|
|
10258
10618
|
} else if (sub === "pat") {
|
|
10259
|
-
if (!
|
|
10619
|
+
if (!existsSync17(CRED_PATH))
|
|
10260
10620
|
die("run `sol auth login` first");
|
|
10261
|
-
const creds = JSON.parse(
|
|
10621
|
+
const creds = JSON.parse(readFileSync17(CRED_PATH, "utf8"));
|
|
10262
10622
|
const token = await loadStoredToken();
|
|
10263
10623
|
if (!token || !creds.webUrl)
|
|
10264
10624
|
die("run `sol auth login` first");
|
|
@@ -10317,10 +10677,10 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10317
10677
|
const peer = openPeer2(localSrc);
|
|
10318
10678
|
const peerHead = await peer.log.head();
|
|
10319
10679
|
const dest = resolve4(procCwd, args[1] || (args[0].replace(/\/+$/, "").split("/").pop() || "clone") + "-clone");
|
|
10320
|
-
const ddir =
|
|
10321
|
-
if (
|
|
10680
|
+
const ddir = join18(dest, ".sol");
|
|
10681
|
+
if (existsSync17(ddir))
|
|
10322
10682
|
die("already a sol repo: " + dest);
|
|
10323
|
-
|
|
10683
|
+
mkdirSync11(ddir, { recursive: true });
|
|
10324
10684
|
const peerOps = await peer.log.history();
|
|
10325
10685
|
const res = await converge2({ store: new FileStore(ddir), log: new FileOpLog(ddir) }, { nodes: await peerNodes2(peer, peerHead, peerOps), ops: peerOps, incomingHead: peerHead, actor });
|
|
10326
10686
|
const dstore = new Store;
|
|
@@ -10330,7 +10690,7 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10330
10690
|
const files = (res.head ? listAll(dstore, res.head) : []).filter((f) => !f.split("/").some(isReservedKey2));
|
|
10331
10691
|
for (const f of files)
|
|
10332
10692
|
materializeInto(dstore, res.head, dest, f);
|
|
10333
|
-
|
|
10693
|
+
writeFileSync15(join18(ddir, "refs.json"), JSON.stringify({ current: "main", branches: { main: { head: res.head, base: res.head, remote: res.head } }, tags: {} }, null, 2));
|
|
10334
10694
|
writeWorkingIndexAt(ddir, dest, files);
|
|
10335
10695
|
console.log(`cloned local peer ${args[0]} -> ${dest} (${(await peer.log.history()).length} ops, ${files.length} files)`);
|
|
10336
10696
|
break;
|
|
@@ -10339,12 +10699,12 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10339
10699
|
const repoName = rest[0] || die("usage: sol clone [<url>] <owner>/<repo> [dir]");
|
|
10340
10700
|
const token = process.env.SOL_TOKEN || die("set SOL_TOKEN to the backend bearer token");
|
|
10341
10701
|
const target = resolve4(cwd, rest[1] || repoName.split("/").pop() || repoName);
|
|
10342
|
-
const fdir =
|
|
10343
|
-
if (
|
|
10702
|
+
const fdir = join18(target, ".sol");
|
|
10703
|
+
if (existsSync17(fdir))
|
|
10344
10704
|
die("already a sol repo: " + target);
|
|
10345
10705
|
const cfg = { url, repo: repoName };
|
|
10346
10706
|
const bundle = await remoteExport(cfg, token);
|
|
10347
|
-
|
|
10707
|
+
mkdirSync11(fdir, { recursive: true });
|
|
10348
10708
|
await writeBundle(fdir, bundle, 0);
|
|
10349
10709
|
saveRemote(fdir, cfg);
|
|
10350
10710
|
await pullEnvState(fdir, cfg, token);
|
|
@@ -10357,8 +10717,8 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10357
10717
|
cloneBranches[name] = { head: h, base: h, remote: h };
|
|
10358
10718
|
if (!cloneBranches[onBranch])
|
|
10359
10719
|
cloneBranches[onBranch] = { head: checkoutHead, base: checkoutHead, remote: checkoutHead };
|
|
10360
|
-
|
|
10361
|
-
|
|
10720
|
+
writeFileSync15(join18(fdir, "refs.json"), JSON.stringify({ current: onBranch, branches: cloneBranches, tags: {} }, null, 2));
|
|
10721
|
+
writeFileSync15(join18(fdir, "HEAD"), JSON.stringify({ head: checkoutHead, seq: bundle.seq, logTip: bundle.tip }));
|
|
10362
10722
|
const store2 = new Store;
|
|
10363
10723
|
for (const node of bundle.nodes)
|
|
10364
10724
|
store2.put(node);
|
|
@@ -10384,12 +10744,20 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10384
10744
|
}
|
|
10385
10745
|
}
|
|
10386
10746
|
const cfg = resolveRemote(solDir) || die("no remote — set one with `sol remote <url> <repo>`, or `sol push <repo>` to use the hosted Sol");
|
|
10747
|
+
{
|
|
10748
|
+
const { pendingScrubPaths: pendingScrubPaths2, historyHasCleartext: historyHasCleartext2 } = await Promise.resolve().then(() => (init_secret_scrub(), exports_secret_scrub));
|
|
10749
|
+
const ops0 = await log.history();
|
|
10750
|
+
const stillLeaking = pendingScrubPaths2(solDir).filter((p) => historyHasCleartext2(solDir, ops0, p));
|
|
10751
|
+
if (stillLeaking.length) {
|
|
10752
|
+
die(`refusing to push — pre-seal CLEARTEXT is still in history for: ${stillLeaking.join(", ")}. the plaintext would ship to every clone (recoverable via \`sol restore\`). run \`sol seal ${stillLeaking[0]} --scrub-history\` (repeat per path, or \`sol seal --scrub-history\` for all) first.`);
|
|
10753
|
+
}
|
|
10754
|
+
}
|
|
10387
10755
|
const token = process.env.SOL_TOKEN || authExpired();
|
|
10388
10756
|
const rh = await remoteHead(cfg, token);
|
|
10389
10757
|
const ops = await log.history();
|
|
10390
10758
|
const localSeq = ops.length ? ops[ops.length - 1].seq : 0;
|
|
10391
10759
|
const localTip = await log.logTip();
|
|
10392
|
-
const localRefs =
|
|
10760
|
+
const localRefs = existsSync17(refsPath()) ? JSON.parse(readFileSync17(refsPath(), "utf8")) : undefined;
|
|
10393
10761
|
const branch = localRefs?.current ?? "main";
|
|
10394
10762
|
const branchHead = await log.head() ?? "";
|
|
10395
10763
|
const remoteWasEmpty = rh.seq === 0 && !rh.tip;
|
|
@@ -10412,8 +10780,8 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10412
10780
|
const prevHead = await log.head() ?? "";
|
|
10413
10781
|
await writeBundle(solDir, canon, 0);
|
|
10414
10782
|
const convergedHead = res.head ?? canon.refs?.branches?.[branch] ?? branchHead;
|
|
10415
|
-
if (
|
|
10416
|
-
const refs = JSON.parse(
|
|
10783
|
+
if (existsSync17(refsPath())) {
|
|
10784
|
+
const refs = JSON.parse(readFileSync17(refsPath(), "utf8"));
|
|
10417
10785
|
if (canon.refs) {
|
|
10418
10786
|
for (const [name, h] of Object.entries(canon.refs.branches)) {
|
|
10419
10787
|
refs.branches[name] = { head: refs.branches[name]?.head ?? h, base: refs.branches[name]?.base ?? h, remote: h };
|
|
@@ -10477,8 +10845,8 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10477
10845
|
const ownMeta = readViewMeta(solDir);
|
|
10478
10846
|
const base2 = peerMeta?.startHead ?? ownMeta?.startHead;
|
|
10479
10847
|
const res = await converge2({ store: new FileStore(solDir, objectsDir()), log }, { nodes: await peerNodes2(peer, peerHead, peerOps), ops: peerOps, incomingHead: peerHead, actor, ...base2 ? { base: base2 } : {} });
|
|
10480
|
-
if (
|
|
10481
|
-
const refs = JSON.parse(
|
|
10848
|
+
if (existsSync17(refsPath())) {
|
|
10849
|
+
const refs = JSON.parse(readFileSync17(refsPath(), "utf8"));
|
|
10482
10850
|
if (refs.branches[refs.current])
|
|
10483
10851
|
refs.branches[refs.current].head = res.head;
|
|
10484
10852
|
saveRefs(refs);
|
|
@@ -10509,11 +10877,11 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10509
10877
|
const ops = await log.history();
|
|
10510
10878
|
const localSeq = ops.length ? ops[ops.length - 1].seq : 0;
|
|
10511
10879
|
const localTip = await log.logTip();
|
|
10512
|
-
const curBranch =
|
|
10880
|
+
const curBranch = existsSync17(refsPath()) ? JSON.parse(readFileSync17(refsPath(), "utf8")).current : bundle.refs?.production || "main";
|
|
10513
10881
|
const remoteCurHead = bundle.refs?.branches?.[curBranch] ?? bundle.head ?? "";
|
|
10514
10882
|
if (bundle.seq === localSeq && bundle.tip === localTip) {
|
|
10515
|
-
if (bundle.refs &&
|
|
10516
|
-
const lr = JSON.parse(
|
|
10883
|
+
if (bundle.refs && existsSync17(refsPath())) {
|
|
10884
|
+
const lr = JSON.parse(readFileSync17(refsPath(), "utf8"));
|
|
10517
10885
|
const before = lr.branches[lr.current]?.head;
|
|
10518
10886
|
for (const [name, h] of Object.entries(bundle.refs.branches))
|
|
10519
10887
|
lr.branches[name] = { head: h, base: lr.branches[name]?.base ?? h, remote: h };
|
|
@@ -10537,9 +10905,9 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10537
10905
|
break;
|
|
10538
10906
|
}
|
|
10539
10907
|
const syncRefHead = (h) => {
|
|
10540
|
-
if (!
|
|
10908
|
+
if (!existsSync17(refsPath()))
|
|
10541
10909
|
return;
|
|
10542
|
-
const refs = JSON.parse(
|
|
10910
|
+
const refs = JSON.parse(readFileSync17(refsPath(), "utf8"));
|
|
10543
10911
|
if (refs.branches[refs.current])
|
|
10544
10912
|
refs.branches[refs.current].head = h;
|
|
10545
10913
|
saveRefs(refs);
|
|
@@ -10557,8 +10925,8 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10557
10925
|
syncRefHead(remoteCurHead);
|
|
10558
10926
|
setOpLogHead(remoteCurHead);
|
|
10559
10927
|
materializeTree(loadStore(), remoteCurHead);
|
|
10560
|
-
if (bundle.refs &&
|
|
10561
|
-
const lr = JSON.parse(
|
|
10928
|
+
if (bundle.refs && existsSync17(refsPath())) {
|
|
10929
|
+
const lr = JSON.parse(readFileSync17(refsPath(), "utf8"));
|
|
10562
10930
|
for (const [name, h] of Object.entries(bundle.refs.branches))
|
|
10563
10931
|
lr.branches[name] = { head: h, base: lr.branches[name]?.base ?? h, remote: h };
|
|
10564
10932
|
saveRefs(lr);
|
|
@@ -10606,9 +10974,9 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10606
10974
|
for (const c of result.conflicts) {
|
|
10607
10975
|
const blob = fileAt(store2, result.head, c.path);
|
|
10608
10976
|
if (blob)
|
|
10609
|
-
|
|
10977
|
+
writeFileSync15(join18(cwd, c.path), blob.encoding === "base64" ? Buffer.from(blob.content, "base64") : blob.content);
|
|
10610
10978
|
}
|
|
10611
|
-
|
|
10979
|
+
writeFileSync15(join18(solDir, "MERGE_HEAD"), remoteHead2);
|
|
10612
10980
|
saveMergeConflicts(solDir, result.conflicts);
|
|
10613
10981
|
console.log(`pulled + merged WITH ${result.conflicts.length} conflict(s), left uncommitted in your working tree:`);
|
|
10614
10982
|
for (const c of result.conflicts)
|
|
@@ -10623,11 +10991,11 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10623
10991
|
break;
|
|
10624
10992
|
}
|
|
10625
10993
|
case "promote": {
|
|
10626
|
-
if (!
|
|
10994
|
+
if (!existsSync17(solDir))
|
|
10627
10995
|
die("not a sol repo");
|
|
10628
10996
|
const cfg = resolveRemote(solDir) || die("no remote — set one with `sol remote <url> <repo>`");
|
|
10629
10997
|
const token = process.env.SOL_TOKEN || authExpired();
|
|
10630
|
-
const cur =
|
|
10998
|
+
const cur = existsSync17(refsPath()) ? JSON.parse(readFileSync17(refsPath(), "utf8")).current : "main";
|
|
10631
10999
|
const branch = args[0] || cur;
|
|
10632
11000
|
const refs = await remotePromote(cfg, token, branch);
|
|
10633
11001
|
console.log(`promoted '${branch}' -> production '${refs.production}' now at ${(refs.branches[refs.production] ?? "").slice(0, 12)}`);
|
|
@@ -10639,8 +11007,8 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10639
11007
|
const newRepo = frest[1] || die("usage: sol fork [<url>] <parent-repo> <new-repo> [dir]");
|
|
10640
11008
|
const token = process.env.SOL_TOKEN || authExpired();
|
|
10641
11009
|
const target = resolve4(cwd, frest[2] || newRepo);
|
|
10642
|
-
const fdir =
|
|
10643
|
-
if (
|
|
11010
|
+
const fdir = join18(target, ".sol");
|
|
11011
|
+
if (existsSync17(fdir))
|
|
10644
11012
|
die("already a sol repo: " + target);
|
|
10645
11013
|
const parentCfg = { url, repo: parent };
|
|
10646
11014
|
const newCfg = { url, repo: newRepo, forkParent: parent };
|
|
@@ -10656,7 +11024,7 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10656
11024
|
}
|
|
10657
11025
|
await forkMeta(newCfg, token, parent);
|
|
10658
11026
|
const canon = await remoteExport(newCfg, token);
|
|
10659
|
-
|
|
11027
|
+
mkdirSync11(fdir, { recursive: true });
|
|
10660
11028
|
await writeBundle(fdir, canon, 0);
|
|
10661
11029
|
const srvRefs = canon.refs ?? { branches: { main: canon.head ?? "" }, production: "main" };
|
|
10662
11030
|
const checkout = canon.checkout ?? { branch: srvRefs.production || "main", head: srvRefs.branches[srvRefs.production] ?? canon.head };
|
|
@@ -10665,8 +11033,8 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10665
11033
|
const cloneBranches = {};
|
|
10666
11034
|
for (const [name, h] of Object.entries(srvRefs.branches))
|
|
10667
11035
|
cloneBranches[name] = { head: h, base: h, remote: h };
|
|
10668
|
-
|
|
10669
|
-
|
|
11036
|
+
writeFileSync15(join18(fdir, "refs.json"), JSON.stringify({ current: onBranch, branches: cloneBranches, tags: {} }, null, 2));
|
|
11037
|
+
writeFileSync15(join18(fdir, "HEAD"), JSON.stringify({ head: checkoutHead, seq: canon.seq, logTip: canon.tip }));
|
|
10670
11038
|
saveRemote(fdir, newCfg);
|
|
10671
11039
|
const store2 = new Store;
|
|
10672
11040
|
for (const node of canon.nodes)
|
|
@@ -10753,7 +11121,7 @@ refused for a non-recipient (host/agent-blind). a missing or malformed reference
|
|
|
10753
11121
|
const token = process.env.SOL_TOKEN || authExpired();
|
|
10754
11122
|
const { mrSummary: mrSummary2 } = await Promise.resolve().then(() => exports_mr);
|
|
10755
11123
|
const sub = args[0];
|
|
10756
|
-
const localRefs = () =>
|
|
11124
|
+
const localRefs = () => existsSync17(refsPath()) ? JSON.parse(readFileSync17(refsPath(), "utf8")) : { current: "main", branches: {}, tags: {} };
|
|
10757
11125
|
const flag2 = (name) => {
|
|
10758
11126
|
const i = args.indexOf(name);
|
|
10759
11127
|
return i >= 0 ? args[i + 1] : undefined;
|
|
@@ -10931,7 +11299,7 @@ ${mrSummary2(pr)}`);
|
|
|
10931
11299
|
die("usage: sol run [--keep <path>] [--isolate] <command...>");
|
|
10932
11300
|
const { capture: capture3, hydrate: hydrate3, isolateCommand: isolateCommand2 } = await Promise.resolve().then(() => (init_runtime(), exports_runtime));
|
|
10933
11301
|
const head = await repo.head();
|
|
10934
|
-
const dir = mkdtempSync(
|
|
11302
|
+
const dir = mkdtempSync(join18(tmpdir(), "sol-run-"));
|
|
10935
11303
|
try {
|
|
10936
11304
|
const hn = hydrate3(loadStore(), head, dir);
|
|
10937
11305
|
console.log(`hydrated ${hn} file(s) -> sandbox${isolate ? " (isolated: no network, writes confined to the sandbox)" : ""}`);
|
|
@@ -10951,8 +11319,8 @@ ${mrSummary2(pr)}`);
|
|
|
10951
11319
|
const { written, deleted } = await capture3(repo, dir, keep);
|
|
10952
11320
|
if (written.length || deleted.length) {
|
|
10953
11321
|
await appendCommit(log, await repo.head(), `run: ${command.join(" ")}`, head);
|
|
10954
|
-
if (
|
|
10955
|
-
const refs = JSON.parse(
|
|
11322
|
+
if (existsSync17(refsPath())) {
|
|
11323
|
+
const refs = JSON.parse(readFileSync17(refsPath(), "utf8"));
|
|
10956
11324
|
if (refs.branches[refs.current]) {
|
|
10957
11325
|
refs.branches[refs.current].head = await repo.head();
|
|
10958
11326
|
saveRefs(refs);
|
|
@@ -10964,7 +11332,7 @@ ${mrSummary2(pr)}`);
|
|
|
10964
11332
|
materialize(synced, nh, f);
|
|
10965
11333
|
for (const f of deleted) {
|
|
10966
11334
|
try {
|
|
10967
|
-
|
|
11335
|
+
unlinkSync7(join18(cwd, f));
|
|
10968
11336
|
} catch {}
|
|
10969
11337
|
}
|
|
10970
11338
|
console.log(`captured ${written.length} written, ${deleted.length} deleted file(s):`);
|
|
@@ -10986,10 +11354,10 @@ ${mrSummary2(pr)}`);
|
|
|
10986
11354
|
if (sub === "import") {
|
|
10987
11355
|
const gitPath = resolve4(cwd, args[1] || die("usage: sol git import <git-repo> [dir]"));
|
|
10988
11356
|
const target = resolve4(cwd, args[2] || basename(gitPath));
|
|
10989
|
-
const fdir =
|
|
10990
|
-
if (
|
|
11357
|
+
const fdir = join18(target, ".sol");
|
|
11358
|
+
if (existsSync17(fdir))
|
|
10991
11359
|
die("already a sol repo: " + target);
|
|
10992
|
-
|
|
11360
|
+
mkdirSync11(fdir, { recursive: true });
|
|
10993
11361
|
const { commits, branches, head, current } = await importGitRepo2(gitPath, fdir);
|
|
10994
11362
|
const refsBranches = {};
|
|
10995
11363
|
for (const b of branches)
|
|
@@ -10997,13 +11365,13 @@ ${mrSummary2(pr)}`);
|
|
|
10997
11365
|
if (!refsBranches[current])
|
|
10998
11366
|
refsBranches[current] = { head, base: head };
|
|
10999
11367
|
refsBranches[current].head = head;
|
|
11000
|
-
|
|
11368
|
+
writeFileSync15(join18(fdir, "refs.json"), JSON.stringify({ current, branches: refsBranches, tags: {} }, null, 2));
|
|
11001
11369
|
const store2 = new Store;
|
|
11002
|
-
for (const name of
|
|
11370
|
+
for (const name of readdirSync8(join18(fdir, "objects"))) {
|
|
11003
11371
|
if (name.endsWith(".tmp"))
|
|
11004
11372
|
continue;
|
|
11005
11373
|
try {
|
|
11006
|
-
store2.put(decodeObject(
|
|
11374
|
+
store2.put(decodeObject(readFileSync17(join18(fdir, "objects", name))));
|
|
11007
11375
|
} catch {}
|
|
11008
11376
|
}
|
|
11009
11377
|
const onDisk = hydrate3(store2, head, target);
|
|
@@ -11035,9 +11403,9 @@ ${mrSummary2(pr)}`);
|
|
|
11035
11403
|
die("already inside a view — create views from the parent repo (its `.sol` owns the shared store + op-log).");
|
|
11036
11404
|
const name = args.find((a) => !a.startsWith("-")) || die("usage: sol view <name> [dir]");
|
|
11037
11405
|
const rest = args.filter((a) => !a.startsWith("-"));
|
|
11038
|
-
const defaultDir =
|
|
11406
|
+
const defaultDir = join18(dirname4(cwd), `${basename(cwd)}-${name}`);
|
|
11039
11407
|
const viewDir = rest[1] ? resolve4(procCwd, rest[1]) : defaultDir;
|
|
11040
|
-
if (
|
|
11408
|
+
if (existsSync17(join18(viewDir, ".sol")))
|
|
11041
11409
|
die("already a sol repo/view: " + viewDir);
|
|
11042
11410
|
const branch = `view/${name}`;
|
|
11043
11411
|
const startHead = await log.head() ?? emptyRoot(loadStore());
|
|
@@ -11051,7 +11419,7 @@ ${mrSummary2(pr)}`);
|
|
|
11051
11419
|
break;
|
|
11052
11420
|
}
|
|
11053
11421
|
case "views": {
|
|
11054
|
-
if (!
|
|
11422
|
+
if (!existsSync17(solDir))
|
|
11055
11423
|
die("not a sol repo");
|
|
11056
11424
|
const parentSol = parentSolDir(solDir) ?? solDir;
|
|
11057
11425
|
const { pruneViews: pruneViews2, viewStatuses: viewStatuses2, sharedObjectCount: sharedObjectCount2 } = await Promise.resolve().then(() => (init_views(), exports_views));
|
|
@@ -11145,7 +11513,7 @@ ${mrSummary2(pr)}`);
|
|
|
11145
11513
|
await startSecretMcp2({ solDir });
|
|
11146
11514
|
break;
|
|
11147
11515
|
}
|
|
11148
|
-
if (!
|
|
11516
|
+
if (!existsSync17(solDir))
|
|
11149
11517
|
die("not a sol repo — run `sol init` first");
|
|
11150
11518
|
const { runEnv: runEnv2, runSecret: runSecret2, resolveReference: resolveReference2 } = await Promise.resolve().then(() => (init_secret2(), exports_secret2));
|
|
11151
11519
|
const { loadSelfIdentity: loadSelfIdentity2, loadManageIdentity: loadManageIdentity2, fetchKey: fetchKey2 } = await Promise.resolve().then(() => (init_seal_audience(), exports_seal_audience));
|
|
@@ -11318,18 +11686,18 @@ var init_dispatch = __esm(() => {
|
|
|
11318
11686
|
init_remote();
|
|
11319
11687
|
init_lib();
|
|
11320
11688
|
init_test_gate();
|
|
11321
|
-
CRED_PATH =
|
|
11689
|
+
CRED_PATH = join18(homedir2(), ".sol", "credentials");
|
|
11322
11690
|
DEFAULT_REMOTE_URL = (process.env.SOL_REMOTE || "https://sol.midsummer.new").replace(/\/+$/, "");
|
|
11323
11691
|
ATTEST_KEY = process.env.SOL_ATTEST_KEY || undefined;
|
|
11324
11692
|
});
|
|
11325
11693
|
|
|
11326
11694
|
// src/bin/sol.ts
|
|
11327
|
-
import { readFileSync as
|
|
11695
|
+
import { readFileSync as readFileSync18 } from "fs";
|
|
11328
11696
|
function cliVersion2() {
|
|
11329
11697
|
if (typeof __SOL_COMPILED_VERSION__ === "string" && __SOL_COMPILED_VERSION__)
|
|
11330
11698
|
return __SOL_COMPILED_VERSION__;
|
|
11331
11699
|
try {
|
|
11332
|
-
return JSON.parse(
|
|
11700
|
+
return JSON.parse(readFileSync18(new URL("./package.json", import.meta.url), "utf8")).version || "dev";
|
|
11333
11701
|
} catch {
|
|
11334
11702
|
return "dev";
|
|
11335
11703
|
}
|