ship 1.4.35:Arcrun@d1c44a5
This commit is contained in:
@@ -12,7 +12,7 @@ Served via jsDelivr; fetched automatically during install — you never need to
|
||||
- `arcrun-mcp/` — **arcrun-mcp**
|
||||
- `daemon/` — 桌面 App(Mac/Windows)安裝檔
|
||||
|
||||
Built from `Arcrun@eebb691` by `installer/scripts/ship.mjs`(arcrun-rag repo,release 1.4.33,built 2026-08-10)。
|
||||
Built from `Arcrun@d1c44a5` by `installer/scripts/ship.mjs`(arcrun-rag repo,release 1.4.35,built 2026-08-11)。
|
||||
|
||||
⚠️ 這份檔案由出貨管線每次自動重寫(`installer/scripts/render-bundles-readme.mjs`)——
|
||||
不要手動改這裡列的零件清單,要改就改 `installer/scripts/bundle-components.mjs`(唯一真相源,改一個地方兩條出貨路徑同時生效)。
|
||||
|
||||
@@ -12685,6 +12685,10 @@ function randomHex2(bytes) {
|
||||
crypto.getRandomValues(arr);
|
||||
return Array.from(arr).map((b) => b.toString(16).padStart(2, "0")).join("");
|
||||
}
|
||||
async function sha256Hex2(input) {
|
||||
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(input));
|
||||
return Array.from(new Uint8Array(digest)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
||||
}
|
||||
function generatePassword(length = 16) {
|
||||
const charset = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789";
|
||||
const arr = new Uint8Array(length);
|
||||
@@ -13219,26 +13223,166 @@ portalRouter.get(
|
||||
});
|
||||
})
|
||||
);
|
||||
portalRouter.post(
|
||||
"/portal/me/password",
|
||||
(c) => run(c, async () => {
|
||||
const auth = await requirePortalUser(c);
|
||||
if (!auth.ok) return auth.res;
|
||||
const body = await c.req.json().catch(() => null);
|
||||
const current = String(body?.current ?? "");
|
||||
const next = String(body?.new ?? "");
|
||||
if (!current || !next) return c.json({ error: "current \u8207 new \u5FC5\u586B" }, 400);
|
||||
if (next.length < 8) return c.json({ error: "\u65B0\u5BC6\u78BC\u81F3\u5C11 8 \u78BC" }, 400);
|
||||
const ok = await verifyPassword(current, auth.user.values.password_hash ?? "");
|
||||
if (!ok) return c.json({ error: "\u820A\u5BC6\u78BC\u4E0D\u6B63\u78BA" }, 401);
|
||||
const newHash = await hashPassword2(next);
|
||||
await patchRecordValues(c.env, auth.user.recordId, {
|
||||
password_hash: newHash,
|
||||
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
||||
var PWRESET_PREFIX = "portal_pwreset:";
|
||||
var PWRESET_TTL_SECONDS = 30 * 60;
|
||||
var PWRESET_THROTTLE_PREFIX = "portal_pwreset_req:";
|
||||
var PWRESET_THROTTLE_SECONDS = 120;
|
||||
var RELAY_TICKET_PREFIX = "portal_relay_ticket:";
|
||||
var RELAY_TICKET_TTL_SECONDS = 120;
|
||||
function portalUiOrigin(env) {
|
||||
const declared = String(env.UI_ORIGINS ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
||||
if (declared.length > 0) return declared[0];
|
||||
const sub = String(env.WORKER_SUBDOMAIN ?? "").trim();
|
||||
return sub ? `https://arcrun-rag-ui.${sub}.workers.dev` : null;
|
||||
}
|
||||
async function issueResetToken(env, recordId, email) {
|
||||
const token = randomHex2(32);
|
||||
const payload = { record_id: recordId, email, created_at: (/* @__PURE__ */ new Date()).toISOString() };
|
||||
await env.SESSIONS_KV.put(`${PWRESET_PREFIX}${await sha256Hex2(token)}`, JSON.stringify(payload), {
|
||||
expirationTtl: PWRESET_TTL_SECONDS
|
||||
});
|
||||
return token;
|
||||
}
|
||||
async function peekResetToken(env, token) {
|
||||
if (!token || !/^[0-9a-f]{16,128}$/i.test(token)) return null;
|
||||
const raw2 = await env.SESSIONS_KV.get(`${PWRESET_PREFIX}${await sha256Hex2(token)}`);
|
||||
if (!raw2) return null;
|
||||
try {
|
||||
return JSON.parse(raw2);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async function consumeResetToken(env, token) {
|
||||
const payload = await peekResetToken(env, token);
|
||||
if (!payload) return null;
|
||||
await env.SESSIONS_KV.delete(`${PWRESET_PREFIX}${await sha256Hex2(token)}`);
|
||||
return payload;
|
||||
}
|
||||
async function writeNewPassword(env, recordId, newPassword) {
|
||||
const newHash = await hashPassword2(newPassword);
|
||||
await patchRecordValues(env, recordId, {
|
||||
password_hash: newHash,
|
||||
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
||||
});
|
||||
}
|
||||
async function relayResetLink(env, apiOrigin, email, ticket) {
|
||||
const base = String(env.PORTAL_MAIL_RELAY_BASE ?? "").trim().replace(/\/$/, "");
|
||||
if (!base) return "not_configured";
|
||||
const headers = { "Content-Type": "application/json" };
|
||||
if (env.PORTAL_MAIL_RELAY_KEY) headers["X-Arcrun-Relay-Key"] = env.PORTAL_MAIL_RELAY_KEY;
|
||||
try {
|
||||
const res = await fetch(`${base}/api/send-password-reset`, {
|
||||
method: "POST",
|
||||
headers,
|
||||
body: JSON.stringify({ email, api_origin: apiOrigin, ticket })
|
||||
});
|
||||
return c.json({ success: true });
|
||||
return res.ok ? "sent" : "failed";
|
||||
} catch {
|
||||
return "failed";
|
||||
}
|
||||
}
|
||||
portalRouter.post(
|
||||
"/portal/password/relay-verify",
|
||||
(c) => run(c, async () => {
|
||||
const body = await c.req.json().catch(() => null);
|
||||
const ticket = String(body?.ticket ?? "").trim();
|
||||
if (!ticket || !/^[0-9a-f]{8,64}$/i.test(ticket)) return c.json({ ok: false }, 400);
|
||||
const key = `${RELAY_TICKET_PREFIX}${ticket}`;
|
||||
const raw2 = await c.env.SESSIONS_KV.get(key);
|
||||
if (!raw2) return c.json({ ok: false }, 404);
|
||||
await c.env.SESSIONS_KV.delete(key);
|
||||
let parsed;
|
||||
try {
|
||||
parsed = JSON.parse(raw2);
|
||||
} catch {
|
||||
return c.json({ ok: false }, 404);
|
||||
}
|
||||
return c.json({ ok: true, email_sha256: await sha256Hex2(parsed.email), link: parsed.link });
|
||||
})
|
||||
);
|
||||
portalRouter.get("/portal/password/reset-link", (c) => {
|
||||
const token = c.req.query("token") ?? "";
|
||||
const ui = portalUiOrigin(c.env);
|
||||
if (!ui) return c.text("\u9019\u53F0\u5BE6\u4F8B\u6C92\u6709\u8A2D\u5B9A portal \u524D\u7AEF\u7DB2\u5740\uFF0C\u7121\u6CD5\u5C0E\u5411\u4FEE\u6539\u5BC6\u78BC\u756B\u9762\u3002", 500);
|
||||
return c.redirect(`${ui}/portal/#/reset?token=${encodeURIComponent(token)}`, 302);
|
||||
});
|
||||
portalRouter.post(
|
||||
"/portal/password/forgot",
|
||||
(c) => run(c, async () => {
|
||||
const body = await c.req.json().catch(() => null);
|
||||
const email = String(body?.email ?? "").trim().toLowerCase();
|
||||
if (!email || !isValidEmail(email)) return c.json({ error: "email \u683C\u5F0F\u4E0D\u6B63\u78BA" }, 400);
|
||||
if (!String(c.env.PORTAL_MAIL_RELAY_BASE ?? "").trim()) {
|
||||
return c.json(
|
||||
{
|
||||
error: "\u9019\u53F0\u5BE6\u4F8B\u9084\u6C92\u6709\u8A2D\u5B9A\u5BC4\u4FE1\u670D\u52D9\uFF0C\u300C\u5FD8\u8A18\u5BC6\u78BC\u300D\u7684\u9023\u7D50\u5BC4\u4E0D\u51FA\u53BB\u3002\u8ACB\u91CD\u65B0\u57F7\u884C\u5B89\u88DD\uFF0F\u66F4\u65B0\u8B93\u5B83\u5C31\u7DD2\uFF0C\u6216\u8ACB\u7BA1\u7406\u54E1\u76F4\u63A5\u5E6B\u4F60\u6539\u5BC6\u78BC\u3002",
|
||||
code: "mail_relay_not_configured"
|
||||
},
|
||||
503
|
||||
);
|
||||
}
|
||||
const generic = {
|
||||
success: true,
|
||||
message: "\u5982\u679C\u9019\u500B email \u5728\u9019\u53F0\u5BE6\u4F8B\u4E0A\u6709\u5E33\u865F\uFF0C\u6211\u5011\u5DF2\u7D93\u628A\u300C\u4FEE\u6539\u5BC6\u78BC\u300D\u7684\u9023\u7D50\u5BC4\u904E\u53BB\u4E86\uFF08\u9023\u7D50 30 \u5206\u9418\u5167\u6709\u6548\u3001\u53EA\u80FD\u7528\u4E00\u6B21\uFF09\u3002"
|
||||
};
|
||||
const throttleKey = `${PWRESET_THROTTLE_PREFIX}${email}`;
|
||||
if (await c.env.SESSIONS_KV.get(throttleKey)) return c.json(generic);
|
||||
await c.env.SESSIONS_KV.put(throttleKey, "1", { expirationTtl: PWRESET_THROTTLE_SECONDS });
|
||||
const recordId = await findUserRecordId(c.env, email).catch(() => null);
|
||||
if (!recordId) return c.json(generic);
|
||||
const token = await issueResetToken(c.env, recordId, email);
|
||||
const apiOrigin = new URL(c.req.url).origin;
|
||||
const link = `${apiOrigin}/portal/password/reset-link?token=${encodeURIComponent(token)}`;
|
||||
const ticket = randomHex2(16);
|
||||
await c.env.SESSIONS_KV.put(`${RELAY_TICKET_PREFIX}${ticket}`, JSON.stringify({ email, link }), {
|
||||
expirationTtl: RELAY_TICKET_TTL_SECONDS
|
||||
});
|
||||
await relayResetLink(c.env, apiOrigin, email, ticket);
|
||||
return c.json(generic);
|
||||
})
|
||||
);
|
||||
portalRouter.get(
|
||||
"/portal/password/reset",
|
||||
(c) => run(c, async () => {
|
||||
const payload = await peekResetToken(c.env, c.req.query("token") ?? "");
|
||||
if (!payload) {
|
||||
return c.json(
|
||||
{ valid: false, error: "\u9019\u689D\u9023\u7D50\u5DF2\u7D93\u5931\u6548\u4E86\uFF08\u53EA\u80FD\u7528\u4E00\u6B21\u300130 \u5206\u9418\u5167\u6709\u6548\uFF09\u3002\u8ACB\u56DE\u767B\u5165\u9801\u91CD\u65B0\u6309\u4E00\u6B21\u300C\u5FD8\u8A18\u5BC6\u78BC\u300D\u3002" },
|
||||
400
|
||||
);
|
||||
}
|
||||
return c.json({ valid: true, email: payload.email });
|
||||
})
|
||||
);
|
||||
async function handlePasswordChange(c) {
|
||||
const body = await c.req.json().catch(() => null);
|
||||
const next = String(body?.new ?? "");
|
||||
const resetToken = String(body?.reset_token ?? "").trim();
|
||||
if (!next) return c.json({ error: "new\uFF08\u65B0\u5BC6\u78BC\uFF09\u5FC5\u586B" }, 400);
|
||||
if (next.length < 8) return c.json({ error: "\u65B0\u5BC6\u78BC\u81F3\u5C11 8 \u78BC" }, 400);
|
||||
if (resetToken) {
|
||||
const payload = await consumeResetToken(c.env, resetToken);
|
||||
if (!payload) {
|
||||
return c.json(
|
||||
{ error: "\u9019\u689D\u9023\u7D50\u5DF2\u7D93\u5931\u6548\u4E86\uFF08\u53EA\u80FD\u7528\u4E00\u6B21\u300130 \u5206\u9418\u5167\u6709\u6548\uFF09\u3002\u8ACB\u56DE\u767B\u5165\u9801\u91CD\u65B0\u6309\u4E00\u6B21\u300C\u5FD8\u8A18\u5BC6\u78BC\u300D\u3002", code: "reset_token_invalid" },
|
||||
400
|
||||
);
|
||||
}
|
||||
await writeNewPassword(c.env, payload.record_id, next);
|
||||
return c.json({ success: true, email: payload.email, via: "reset_link" });
|
||||
}
|
||||
const auth = await requirePortalUser(c);
|
||||
if (!auth.ok) return auth.res;
|
||||
const current = String(body?.current ?? "");
|
||||
if (!current) return c.json({ error: "current\uFF08\u73FE\u6709\u5BC6\u78BC\uFF09\u5FC5\u586B" }, 400);
|
||||
const ok = await verifyPassword(current, auth.user.values.password_hash ?? "");
|
||||
if (!ok) return c.json({ error: "\u820A\u5BC6\u78BC\u4E0D\u6B63\u78BA" }, 401);
|
||||
await writeNewPassword(c.env, auth.user.recordId, next);
|
||||
return c.json({ success: true, via: "current_password" });
|
||||
}
|
||||
portalRouter.post("/portal/password/change", (c) => run(c, () => handlePasswordChange(c)));
|
||||
portalRouter.post("/portal/me/password", (c) => run(c, () => handlePasswordChange(c)));
|
||||
portalRouter.post(
|
||||
"/portal/admin/bootstrap",
|
||||
(c) => run(c, async () => {
|
||||
|
||||
+150
-5
@@ -2222,6 +2222,144 @@ function buildContentLike(q) {
|
||||
split: true
|
||||
};
|
||||
}
|
||||
var MAX_SEARCH_TERMS = 6;
|
||||
var MAX_TERM_WEIGHT = 8;
|
||||
var KEYWORD_RELATIVE_CUT = 0.6;
|
||||
var CJK_STOP_CHARS = new Set(
|
||||
"\u7684\u4E86\u662F\u5728\u6211\u4F60\u4ED6\u5979\u5B83\u5011\u9019\u90A3\u54EA\u8AB0\u55CE\u5462\u5427\u554A\u5440\u561B\u5594\u54E6\u4EC0\u9EBC\u600E\u4E4B\u4E4E\u800C\u4F46\u4E26\u537B\u5C31\u90FD\u4E5F\u5F88\u592A\u53EA\u9084\u53C8\u518D\u6BCF\u4E9B\u628A\u88AB\u8DDF\u8B93\u82E5".split("")
|
||||
);
|
||||
var ASCII_STOP_WORDS = /* @__PURE__ */ new Set([
|
||||
"the",
|
||||
"a",
|
||||
"an",
|
||||
"and",
|
||||
"or",
|
||||
"of",
|
||||
"to",
|
||||
"in",
|
||||
"on",
|
||||
"at",
|
||||
"is",
|
||||
"are",
|
||||
"was",
|
||||
"were",
|
||||
"be",
|
||||
"do",
|
||||
"does",
|
||||
"did",
|
||||
"for",
|
||||
"it",
|
||||
"its",
|
||||
"this",
|
||||
"that",
|
||||
"these",
|
||||
"those",
|
||||
"with",
|
||||
"what",
|
||||
"how",
|
||||
"why",
|
||||
"when",
|
||||
"where",
|
||||
"who",
|
||||
"which",
|
||||
"can",
|
||||
"could",
|
||||
"should",
|
||||
"would",
|
||||
"my",
|
||||
"our",
|
||||
"your",
|
||||
"their",
|
||||
"me",
|
||||
"we",
|
||||
"you",
|
||||
"they"
|
||||
]);
|
||||
var isCjkChar = (ch) => /[-ヿ㐀-䶿一-鿿豈-]/.test(ch);
|
||||
var isWordChar = (ch) => /[A-Za-z0-9_.-]/.test(ch);
|
||||
function splitRuns(q) {
|
||||
const runs = [];
|
||||
let cur = "";
|
||||
let curCjk = false;
|
||||
const flush = () => {
|
||||
if (cur) runs.push({ text: cur, cjk: curCjk });
|
||||
cur = "";
|
||||
};
|
||||
for (const ch of q) {
|
||||
const cjk = isCjkChar(ch);
|
||||
if (!cjk && !isWordChar(ch)) {
|
||||
flush();
|
||||
continue;
|
||||
}
|
||||
if (cur && cjk !== curCjk) flush();
|
||||
cur += ch;
|
||||
curCjk = cjk;
|
||||
}
|
||||
flush();
|
||||
return runs;
|
||||
}
|
||||
function contentBigrams(run) {
|
||||
const chars = [...run];
|
||||
const out = [];
|
||||
for (let i = 0; i + 1 < chars.length; i++) {
|
||||
if (CJK_STOP_CHARS.has(chars[i]) || CJK_STOP_CHARS.has(chars[i + 1])) continue;
|
||||
out.push(chars[i] + chars[i + 1]);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
function tokenizeQuery(q) {
|
||||
const found = /* @__PURE__ */ new Map();
|
||||
const add = (t, w) => {
|
||||
for (const piece of chunkByBytes(t, MAX_LIKE_Q_BYTES)) {
|
||||
if (!piece) continue;
|
||||
found.set(piece, Math.max(found.get(piece) ?? 0, Math.min(w, MAX_TERM_WEIGHT)));
|
||||
}
|
||||
};
|
||||
const runs = splitRuns(q);
|
||||
const isQuestion = runs.length > 1;
|
||||
for (const run of runs) {
|
||||
if (!run.cjk) {
|
||||
const w = run.text.toLowerCase();
|
||||
if (w.length >= 2 && !ASCII_STOP_WORDS.has(w)) add(run.text, run.text.length);
|
||||
continue;
|
||||
}
|
||||
const chars = [...run.text];
|
||||
if (chars.length >= 2 && chars.length <= 4) add(run.text, chars.length);
|
||||
if (isQuestion || chars.length > 4) for (const bg of contentBigrams(run.text)) add(bg, 2);
|
||||
}
|
||||
return [...found.entries()].map(([term, weight]) => ({ term, weight })).sort((a, b) => b.weight - a.weight || a.term.localeCompare(b.term)).slice(0, MAX_SEARCH_TERMS);
|
||||
}
|
||||
function buildSearchScore(q) {
|
||||
const trimmed = q.trim();
|
||||
const terms = tokenizeQuery(trimmed);
|
||||
if (terms.length === 0) {
|
||||
const m = buildContentLike(trimmed);
|
||||
return {
|
||||
scoreExpr: m.conds.map(() => "CASE WHEN content LIKE ? THEN 1 ELSE 0 END").join(" + "),
|
||||
scoreParams: m.params,
|
||||
terms: [],
|
||||
legacyShape: true
|
||||
};
|
||||
}
|
||||
const parts = [];
|
||||
const params = [];
|
||||
for (const { term, weight } of terms) {
|
||||
parts.push(`CASE WHEN content LIKE ? THEN ${weight} ELSE 0 END`);
|
||||
params.push(`%${term}%`);
|
||||
}
|
||||
const single = terms.length === 1 && terms[0].term === trimmed;
|
||||
if (!single && utf8Len(trimmed) <= MAX_LIKE_Q_BYTES) {
|
||||
const bonus = terms.reduce((s, t) => s + t.weight, 0);
|
||||
parts.push(`CASE WHEN content LIKE ? THEN ${bonus} ELSE 0 END`);
|
||||
params.push(`%${trimmed}%`);
|
||||
}
|
||||
return { scoreExpr: parts.join(" + "), scoreParams: params, terms, legacyShape: single };
|
||||
}
|
||||
function applyRelativeCut(rows) {
|
||||
if (rows.length <= 1) return rows;
|
||||
const cut = rows[0].match_score * KEYWORD_RELATIVE_CUT;
|
||||
return rows.filter((r) => r.match_score >= cut);
|
||||
}
|
||||
function libraryPredicate(libraries) {
|
||||
const placeholders = libraries.map(() => "?").join(",");
|
||||
return `COALESCE(json_extract(metadata_json, '$.library'), 'general') IN (${placeholders})`;
|
||||
@@ -2237,9 +2375,9 @@ function isDeprecatedEntry(entry) {
|
||||
}
|
||||
}
|
||||
async function searchEntries(db, q, owner_id, entry_type, limit = 50, library, source, includeDeprecated = false) {
|
||||
const m = buildContentLike(q);
|
||||
const conds = [...m.conds];
|
||||
const params = [...m.params];
|
||||
const plan = buildSearchScore(q);
|
||||
const conds = [];
|
||||
const params = [...plan.scoreParams];
|
||||
if (owner_id) {
|
||||
conds.push("owner_id = ?");
|
||||
params.push(owner_id);
|
||||
@@ -2259,8 +2397,15 @@ async function searchEntries(db, q, owner_id, entry_type, limit = 50, library, s
|
||||
if (!includeDeprecated) {
|
||||
conds.push(NOT_DEPRECATED_PREDICATE);
|
||||
}
|
||||
const res = await db.prepare(`SELECT * FROM entries WHERE ${conds.join(" AND ")} ORDER BY updated_at DESC LIMIT ?`).bind(...params, Math.min(limit, 200)).all();
|
||||
return res.results ?? [];
|
||||
const inner = conds.length > 0 ? `WHERE ${conds.join(" AND ")}` : "";
|
||||
const res = await db.prepare(
|
||||
`SELECT * FROM (
|
||||
SELECT *, (${plan.scoreExpr}) AS match_score FROM entries ${inner}
|
||||
) WHERE match_score > 0
|
||||
ORDER BY match_score DESC, updated_at DESC
|
||||
LIMIT ?`
|
||||
).bind(...params, Math.min(limit, 200)).all();
|
||||
return applyRelativeCut(res.results ?? []);
|
||||
}
|
||||
|
||||
// ../../matrix/arcrun/kbdb/src/embed.ts
|
||||
|
||||
+12
-12
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"built": "2026-08-10",
|
||||
"source": "Arcrun@eebb691",
|
||||
"built": "2026-08-11",
|
||||
"source": "Arcrun@d1c44a5",
|
||||
"core": [
|
||||
{
|
||||
"name": "arcrun-cypher-executor",
|
||||
"canonical": null,
|
||||
"main_module": "worker.mjs",
|
||||
"main_file": "arcrun-cypher-executor/worker.mjs",
|
||||
"js_bytes": 564132,
|
||||
"js_bytes": 571136,
|
||||
"modules": [],
|
||||
"compat_date": "2025-02-19",
|
||||
"compat_flags": [
|
||||
@@ -50,15 +50,15 @@
|
||||
"services": 13
|
||||
},
|
||||
"warnings": [],
|
||||
"sha256": "b9ff5f63430accd2d345389481dcd72fc3a57a6c3b3f856e67c6c750028501b2",
|
||||
"bytes": 564132
|
||||
"sha256": "fa29f7df569c442f00081f9ee4f127339363a36c6467f0efa13476054146fedf",
|
||||
"bytes": 571136
|
||||
},
|
||||
{
|
||||
"name": "arcrun-kbdb",
|
||||
"canonical": null,
|
||||
"main_module": "worker.mjs",
|
||||
"main_file": "arcrun-kbdb/worker.mjs",
|
||||
"js_bytes": 132667,
|
||||
"js_bytes": 136576,
|
||||
"modules": [],
|
||||
"compat_date": "2025-02-19",
|
||||
"compat_flags": [
|
||||
@@ -79,8 +79,8 @@
|
||||
}
|
||||
},
|
||||
"warnings": [],
|
||||
"sha256": "b9b95766282ef409c882174c59445cdffd2f6c238f669cefe37f128c7c7b2762",
|
||||
"bytes": 132667
|
||||
"sha256": "138956bf7c3df55dd797b6d0a174908764a53f3ba685c659ec5f0e2a06e181ed",
|
||||
"bytes": 136576
|
||||
},
|
||||
{
|
||||
"name": "arcrun-http-request",
|
||||
@@ -172,7 +172,7 @@
|
||||
"tier": 2,
|
||||
"main_file": "tier2/ui/index.js",
|
||||
"main_module": "index.js",
|
||||
"sha256": "276883752c8e93c0be65cb2f0e7ce596125f6be7d2b05a34d6e3e8c7303e7d0d",
|
||||
"sha256": "dd88fb04de28d999eb76f756f818d24ef9f75d19f0846b2b1c8830f9c5eb775b",
|
||||
"compat_date": "2026-07-01",
|
||||
"compat_flags": [],
|
||||
"modules": [],
|
||||
@@ -182,7 +182,7 @@
|
||||
"ai": false,
|
||||
"vars": {}
|
||||
},
|
||||
"bytes": 509551
|
||||
"bytes": 519945
|
||||
}
|
||||
],
|
||||
"daemon": {
|
||||
@@ -202,8 +202,8 @@
|
||||
"sha256": "782a3b2212884f789e1725f82046cf34ef6bb02e1a8b585cab8e4ae6c6e441ca"
|
||||
}
|
||||
},
|
||||
"release": "1.4.33",
|
||||
"release": "1.4.35",
|
||||
"built_for": "oauth-installer-lazy-load",
|
||||
"notes": [],
|
||||
"fingerprint": "4fb344a0466fb8ca13480d1f71e012f2858d08683e580e35e612097864fbdacc"
|
||||
"fingerprint": "d241afc9489600203d7f1179ffe563dae84f2b0a1a8f4b613cc89c447e8ad1a5"
|
||||
}
|
||||
|
||||
+2
-2
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user