ship 1.4.40:Arcrun@1791ffa4972b
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@3eb8b31f2bfa` by `installer/scripts/ship.mjs`(arcrun-rag repo,release 1.4.38,built 2026-08-12)。
|
||||
Built from `Arcrun@1791ffa4972b` by `installer/scripts/ship.mjs`(arcrun-rag repo,release 1.4.40,built 2026-08-12)。
|
||||
|
||||
⚠️ 這份檔案由出貨管線每次自動重寫(`installer/scripts/render-bundles-readme.mjs`)——
|
||||
不要手動改這裡列的零件清單,要改就改 `installer/scripts/bundle-components.mjs`(唯一真相源,改一個地方兩條出貨路徑同時生效)。
|
||||
|
||||
@@ -2650,7 +2650,7 @@ var init_recipes = __esm({
|
||||
});
|
||||
|
||||
// cypher-executor/src/lib/constants.ts
|
||||
var VALID_EDGE_TYPES, SEMANTIC_EDGE_MAP, BUILTIN_COMPONENTS;
|
||||
var VALID_EDGE_TYPES, SEMANTIC_EDGE_MAP, WAIT_MAX_MS, BUILTIN_COMPONENTS;
|
||||
var init_constants3 = __esm({
|
||||
"cypher-executor/src/lib/constants.ts"() {
|
||||
"use strict";
|
||||
@@ -2698,6 +2698,7 @@ var init_constants3 = __esm({
|
||||
"CLICK": "ON_CLICK",
|
||||
"SUBFLOW": "CALLS_SUBFLOW"
|
||||
};
|
||||
WAIT_MAX_MS = 3e4;
|
||||
BUILTIN_COMPONENTS = /* @__PURE__ */ new Map([
|
||||
["comp_passthrough", (ctx) => ctx],
|
||||
["comp_uppercase", (ctx) => {
|
||||
@@ -2707,6 +2708,54 @@ var init_constants3 = __esm({
|
||||
["comp_counter", (ctx) => {
|
||||
const c = ctx;
|
||||
return { ...c, count: (Number(c.count) || 0) + 1 };
|
||||
}],
|
||||
// ── wait:等待 N 毫秒後繼續(Arcrun#101,2026-08-12)────────────────────────
|
||||
//
|
||||
// 為什麼「等待」搬進引擎,而不是修那顆 WASM:
|
||||
//
|
||||
// 舊實作是 registry/components/wait/main.go(TinyGo → WASM),用 time.Sleep。
|
||||
// TinyGo 的 sleep 走 WASI `poll_oneoff`;而每顆 component worker 的 WASI shim 把
|
||||
// poll_oneoff 實作成 ENOSYS(`.component-builds/*/src/index.ts`:`poll_oneoff: () => 76`)
|
||||
// ⇒ TinyGo 排程器拿不到「睡到某個時間」的手段,退化成迴圈重讀 `clock_time_get`
|
||||
// 自旋等時間到(wasm 內可見 runtime.sleepTicks / sleepQueue / runtime.ticks 符號)。
|
||||
//
|
||||
// 🔴 到這裡為止是**查得到原始碼的事實**。再往下「所以那個自旋迴圈的結束條件永遠
|
||||
// 不成立」曾被當成結論寫在這裡,但**寫了測試去證,反而被打臉**:在
|
||||
// vitest-pool-workers 的 workerd 裡,同步自旋 2553 圈之後 Date.now() 就前進了
|
||||
// ⇒ 時鐘並沒有全程凍結。
|
||||
// ⇒ 「為什麼三秒的等待會拖到 35 秒才死」的完整機制**目前仍是推測**,
|
||||
// 證據只有下面 leo 的四次實測。別把它當定論往外傳。
|
||||
//
|
||||
// 所以症狀不是「等 N 秒花 N 秒 CPU」,而是「不管 ms 填多少都跑到 CPU 上限被砍」。
|
||||
// leo 2026-08-12 在 youlin stage 實測(只有 input >> wait 兩個節點):
|
||||
// ms=3000 → 38.9s 後 503 / ms=20000 → 34.0s / ms=30000 → 34.9s / 寫死 3000 → 34.8s
|
||||
// 四個值同一個死法、與 ms 無關 —— 3 秒的等待撐到 35 秒才死,就是「迴圈根本沒結束」
|
||||
// 的證據(若成本與時長成正比,ms=3000 只會花 3 秒 CPU,根本不該死)。
|
||||
// 也就是說 wait 零件在 Workers 上從來沒有真的等待成功過,不只是貴。
|
||||
//
|
||||
// 純 WASI 沙箱(stdin→stdout、無 socket、同步呼叫)本來就沒有「不花 CPU 地等」這種
|
||||
// 東西 —— 會等的只有宿主。故 wait 與 trigger_workflow 同類:**是 orchestrator 的
|
||||
// 執行排程職責,不是業務邏輯**(rule 02 §2.3 明列「workflow 執行排程」屬 cypher-executor
|
||||
// 合法職責;§2.2 禁的是解密/簽章/template 展開/具體 API 呼叫,等待都不是)。
|
||||
// 搬進引擎不違反「業務邏輯走 WASM」鐵律。引擎這側 await 一個 timer 只花 wall-clock、
|
||||
// 不記 CPU ⇒ 等 30 秒與等 3 秒同價(皆 ≈0)。
|
||||
//
|
||||
// I/O 契約沿用 component.contract.yaml,既有 workflow 的 wait 節點定義不必改:
|
||||
// 吃 ms(必填 > 0)+可選 context;ms > WAIT_MAX_MS 截斷;
|
||||
// 回 { success: true, data: { ...context, waited_ms } };ms <= 0 回 success:false。
|
||||
// 唯一刻意的放寬:ms 允許數字字串("3000")。WASM 版 json.Unmarshal 進 int 會直接
|
||||
// 失敗,但 node.data 走 interpolateData 後 `ms: "{{input.delay}}"` 必然是字串
|
||||
// ⇒ 收字串只會把「本來就跑不動的」變成跑得動,不會改變任何既有成功案例的行為。
|
||||
["wait", async (ctx) => {
|
||||
const c = ctx && typeof ctx === "object" ? ctx : {};
|
||||
const requested = typeof c.ms === "number" ? c.ms : Number(c.ms);
|
||||
if (!Number.isFinite(requested) || requested <= 0) {
|
||||
return { success: false, error: "ms \u5FC5\u9808\u5927\u65BC 0" };
|
||||
}
|
||||
const ms = Math.min(Math.floor(requested), WAIT_MAX_MS);
|
||||
await new Promise((resolve) => setTimeout(resolve, ms));
|
||||
const passthrough = c.context && typeof c.context === "object" && !Array.isArray(c.context) ? c.context : {};
|
||||
return { success: true, data: { ...passthrough, waited_ms: ms } };
|
||||
}]
|
||||
]);
|
||||
}
|
||||
@@ -3060,7 +3109,12 @@ var init_component_loader = __esm({
|
||||
filter: "SVC_FILTER",
|
||||
merge: "SVC_MERGE",
|
||||
try_catch: "SVC_TRY_CATCH",
|
||||
wait: "SVC_WAIT",
|
||||
// wait 已於 Arcrun#101(2026-08-12)移進 BUILTIN_COMPONENTS(step 1)——
|
||||
// 等待是 orchestrator 的排程職責,WASI 沙箱裡做不到「不花 CPU 地等」。理由全文見
|
||||
// constants.ts 的 wait 註解。這裡刻意**移除**而非留著:step 1 本來就先於 step 5 命中,
|
||||
// 留下這行只會讓讀者以為 wait 還走 SVC_WAIT(實際永遠走不到)=誤導人的死路由。
|
||||
// wrangler.toml 的 SVC_WAIT binding 不動(rule 3.1:13 個既有 binding 保留不新增),
|
||||
// 拆綁定要重新部署、與本票無關。
|
||||
set: "SVC_SET",
|
||||
array_ops: "SVC_ARRAY_OPS",
|
||||
string_ops: "SVC_STRING_OPS",
|
||||
@@ -3145,6 +3199,11 @@ function graphBase(env) {
|
||||
if (env.KBDB_GRAPH_URL) return env.KBDB_GRAPH_URL.replace(/\/$/, "");
|
||||
return `https://kbdb-graph-plugin.${env.WORKER_SUBDOMAIN}.workers.dev`;
|
||||
}
|
||||
function graphHeaders(env) {
|
||||
const headers = {};
|
||||
if (env.KBDB_INTERNAL_TOKEN) headers["Authorization"] = `Bearer ${env.KBDB_INTERNAL_TOKEN}`;
|
||||
return headers;
|
||||
}
|
||||
var kbdbProxyRouter, NEED_KEY;
|
||||
var init_kbdb_proxy = __esm({
|
||||
"cypher-executor/src/routes/kbdb-proxy.ts"() {
|
||||
@@ -3278,8 +3337,7 @@ var init_kbdb_proxy = __esm({
|
||||
kbdbProxyRouter.get("/kbdb/graph/neighbors/:name", async (c) => {
|
||||
if (!tenant(c)) return c.json(NEED_KEY, 401);
|
||||
const base = graphBase(c.env);
|
||||
const headers = {};
|
||||
if (c.env.KBDB_INTERNAL_TOKEN) headers["Authorization"] = `Bearer ${c.env.KBDB_INTERNAL_TOKEN}`;
|
||||
const headers = graphHeaders(c.env);
|
||||
try {
|
||||
const res = await fetch(`${base}/graph/neighbors/${encodeURIComponent(c.req.param("name"))}`, { headers });
|
||||
return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } });
|
||||
@@ -14537,6 +14595,20 @@ async function fetchJson(url, headers) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async function fetchTripletTotal(env, tenant2) {
|
||||
const { base, headers } = kbdbBase(env);
|
||||
const data = await fetchJson(
|
||||
`${base}/records/triplet-stats?owner_id=${encodeURIComponent(tenant2)}`,
|
||||
headers
|
||||
);
|
||||
if (!data || !Array.isArray(data.stats)) return null;
|
||||
let total = 0;
|
||||
for (const row of data.stats) {
|
||||
if (typeof row?.triplet_count !== "number") return null;
|
||||
total += row.triplet_count;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
async function fetchEntryTotal(env, filters) {
|
||||
const { base, headers } = kbdbBase(env);
|
||||
const params = new URLSearchParams({ ...filters, limit: "1" });
|
||||
@@ -14644,6 +14716,7 @@ consoleDashboardRouter.get("/console/dashboard-data", async (c) => {
|
||||
kbdbHealth,
|
||||
embedStatus,
|
||||
graphStats,
|
||||
tripletTotal,
|
||||
entriesTotal,
|
||||
wikiCardTotal,
|
||||
workflowTotal
|
||||
@@ -14655,7 +14728,13 @@ consoleDashboardRouter.get("/console/dashboard-data", async (c) => {
|
||||
cachedGiteaSprint(c.env, now2, (p) => c.executionCtx.waitUntil(p)),
|
||||
fetchJson(`${kbdbUrl}/health`, kbdbHeaders),
|
||||
fetchJson(`${kbdbUrl}/embed/backfill/status`, kbdbHeaders),
|
||||
fetchJson(`${graphUrl}/triplets/stats`),
|
||||
// graph-plugin 只拿來判「圖服務活著沒」(燈號)——數字不從這裡拿,見 fetchTripletTotal。
|
||||
// headers 一定要帶:plugin 的 /triplets 前綴掛 Bearer 閘,漏帶=永遠 401=永遠假紅燈(#100)。
|
||||
fetchJson(
|
||||
`${graphUrl}/triplets/stats`,
|
||||
graphHeaders(c.env)
|
||||
),
|
||||
fetchTripletTotal(c.env, tenant2),
|
||||
// owner_id 一律鎖本租戶:原本不帶 owner 會混到別租戶(實測 459,137 vs leo 的 458,732)
|
||||
fetchEntryTotal(c.env, { owner_id: tenant2 }),
|
||||
fetchEntryTotal(c.env, { entry_type: "wiki_card", owner_id: tenant2 }),
|
||||
@@ -14763,13 +14842,14 @@ consoleDashboardRouter.get("/console/dashboard-data", async (c) => {
|
||||
system: {
|
||||
kbdb_ok: kbdbHealth ? kbdbHealth.ok === true : false,
|
||||
embed: embedStatus ? { enabled: embedStatus.enabled === true, embedded: embedStatus.embedded ?? null, pending: embedStatus.pending ?? null } : null,
|
||||
graph: graphStats ? { ok: true, triplets: graphStats.total ?? null } : { ok: false, triplets: null },
|
||||
// ok = plugin 通不通(graphStats 讀得到就是通);triplets = KBDB 真 COUNT(與 plugin 分頁長度無關)
|
||||
graph: { ok: graphStats !== null, triplets: tripletTotal },
|
||||
workflow_total: workflowTotal
|
||||
},
|
||||
kb: {
|
||||
entries_total: entriesTotal,
|
||||
wiki_card_total: wikiCardTotal,
|
||||
triplets_total: graphStats?.total ?? null
|
||||
triplets_total: tripletTotal
|
||||
},
|
||||
generated_at: new Date(now2).toISOString()
|
||||
});
|
||||
@@ -14777,22 +14857,22 @@ consoleDashboardRouter.get("/console/dashboard-data", async (c) => {
|
||||
consoleDashboardRouter.get("/console/kb-scale-data", async (c) => {
|
||||
const tenant2 = c.env.CONSOLE_TENANT || "leo";
|
||||
const { base, headers } = kbdbBase(c.env);
|
||||
const graphUrl = graphBase(c.env);
|
||||
const now2 = Date.now();
|
||||
const [wikiCards, graphStats, embedStatus] = await Promise.all([
|
||||
const [wikiCards, tripletTotal, embedStatus] = await Promise.all([
|
||||
// limit=1 順手拿最新一筆 created_at(list 為 created_at DESC)=「最近寫入時間」
|
||||
fetchJson(
|
||||
`${base}/entries?${new URLSearchParams({ owner_id: tenant2, entry_type: "wiki_card", limit: "1" }).toString()}`,
|
||||
headers
|
||||
),
|
||||
fetchJson(`${graphUrl}/triplets/stats`),
|
||||
// #100:三元組數改讀 KBDB 真 COUNT,不再讀 graph-plugin 的分頁長度(見 fetchTripletTotal 註)
|
||||
fetchTripletTotal(c.env, tenant2),
|
||||
fetchJson(`${base}/embed/backfill/status`, headers)
|
||||
]);
|
||||
const latestMs = parseCreatedAtMs(wikiCards?.entries?.[0]?.created_at ?? null);
|
||||
return c.json({
|
||||
wiki_card_total: typeof wikiCards?.total === "number" ? wikiCards.total : null,
|
||||
wiki_card_latest_ago_minutes: latestMs === null ? -1 : agoMinutes(now2, latestMs),
|
||||
triplets_total: typeof graphStats?.total === "number" ? graphStats.total : null,
|
||||
triplets_total: tripletTotal,
|
||||
embedded: embedStatus?.embedded ?? null,
|
||||
embed_enabled: embedStatus ? embedStatus.enabled === true : null,
|
||||
generated_at: new Date(now2).toISOString()
|
||||
@@ -14944,6 +15024,27 @@ function findBestNodeMatch(searchTerm, nodeNames) {
|
||||
if (hits.length === 0) return null;
|
||||
return hits.reduce((a, b) => a.length <= b.length ? a : b);
|
||||
}
|
||||
async function tripletCount(env, owner) {
|
||||
try {
|
||||
const res = await kbdbFetch(env, `/records/triplet-stats?owner_id=${encodeURIComponent(owner)}`);
|
||||
if (!res.ok) return null;
|
||||
const body = await res.json().catch(() => null);
|
||||
if (!body || !Array.isArray(body.stats)) return null;
|
||||
let total = 0;
|
||||
for (const row of body.stats) {
|
||||
if (typeof row?.triplet_count !== "number") return null;
|
||||
total += row.triplet_count;
|
||||
}
|
||||
return total;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async function tripletCensus(env, tenant2) {
|
||||
const owned = await tripletCount(env, tenant2);
|
||||
if (owned !== 0) return { owned, any: null };
|
||||
return { owned, any: await tripletCount(env, "") };
|
||||
}
|
||||
async function fuzzyFindNode(env, tenant2, searchTerm) {
|
||||
try {
|
||||
const res = await kbdbFetch(env, `/records/by-template/triplet?owner_id=${encodeURIComponent(tenant2)}`);
|
||||
@@ -15045,8 +15146,7 @@ portalDataRouter.get(
|
||||
return c.json(mapGraphWorkflowOutput(result.data));
|
||||
}
|
||||
const base = graphBase(c.env);
|
||||
const headers = {};
|
||||
if (c.env.KBDB_INTERNAL_TOKEN) headers["Authorization"] = `Bearer ${c.env.KBDB_INTERNAL_TOKEN}`;
|
||||
const headers = graphHeaders(c.env);
|
||||
try {
|
||||
const res = await fetch(`${base}/graph/neighbors/${encodeURIComponent(nodeName)}`, { headers });
|
||||
if (!res.ok) {
|
||||
@@ -15081,12 +15181,19 @@ portalDataRouter.get(
|
||||
return c.json({ error: "\u7121\u77E5\u8B58\u5716\u8B5C\u6AA2\u8996\u6B0A\u9650" }, 403);
|
||||
}
|
||||
const tenant2 = portalTenant(c.env);
|
||||
const res = await kbdbFetch(c.env, `/records/by-template/triplet?owner_id=${encodeURIComponent(tenant2)}`);
|
||||
const [res, census] = await Promise.all([
|
||||
kbdbFetch(c.env, `/records/by-template/triplet?owner_id=${encodeURIComponent(tenant2)}&limit=500`),
|
||||
tripletCensus(c.env, tenant2)
|
||||
]);
|
||||
const tripletsTotal = census.owned;
|
||||
if (!res.ok) {
|
||||
return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } });
|
||||
}
|
||||
const body = await res.json().catch(() => null);
|
||||
const records = body && Array.isArray(body.records) ? body.records : [];
|
||||
if (!body || !Array.isArray(body.records)) {
|
||||
return c.json({ error: "\u4E09\u5143\u7D44\u8B80\u53D6\u5931\u6557\uFF1AKBDB \u56DE\u61C9\u4E0D\u662F\u9810\u671F\u7684 records \u6E05\u55AE" }, 502);
|
||||
}
|
||||
const records = body.records;
|
||||
const EDGE_CAP = 500;
|
||||
const seen = /* @__PURE__ */ new Set();
|
||||
const edges = [];
|
||||
@@ -15112,7 +15219,24 @@ portalDataRouter.get(
|
||||
degree.set(o, (degree.get(o) ?? 0) + 1);
|
||||
}
|
||||
const nodes = [...degree.entries()].map(([name, d]) => ({ name, degree: d }));
|
||||
return c.json({ nodes, edges, node_count: nodes.length, edge_count: edges.length, truncated });
|
||||
let emptyReason = null;
|
||||
if (nodes.length === 0) {
|
||||
if (census.owned === null) emptyReason = "unreadable";
|
||||
else if (census.owned > 0) emptyReason = "scope_mismatch";
|
||||
else if (census.any === null) emptyReason = "unreadable";
|
||||
else emptyReason = census.any > 0 ? "scope_mismatch" : "confirmed_empty";
|
||||
}
|
||||
return c.json({
|
||||
nodes,
|
||||
edges,
|
||||
node_count: nodes.length,
|
||||
edge_count: edges.length,
|
||||
// 取到的 record 已達 KBDB 單頁上限 → 這張圖只是全庫的一部分,別讓 meta 看起來像全部
|
||||
truncated: truncated || records.length >= 500,
|
||||
triplets_total: tripletsTotal,
|
||||
empty_confirmed: nodes.length > 0 || emptyReason === "confirmed_empty",
|
||||
empty_reason: emptyReason
|
||||
});
|
||||
})
|
||||
);
|
||||
portalDataRouter.get(
|
||||
|
||||
+18
-11
@@ -2189,11 +2189,18 @@ async function deprecateEntriesByLibrary(db, ownerId, library) {
|
||||
var MAX_LIKE_Q_BYTES = 48;
|
||||
var MAX_LIKE_TERMS = 6;
|
||||
var utf8Len = (s) => new TextEncoder().encode(s).length;
|
||||
var LIKE_ESCAPE = "\\";
|
||||
var CONTENT_LIKE = `content LIKE ? ESCAPE '${LIKE_ESCAPE}'`;
|
||||
function escapeLikeLiteral(s) {
|
||||
return s.replace(/[\\%_]/g, (ch) => LIKE_ESCAPE + ch);
|
||||
}
|
||||
var likeBytes = (s) => utf8Len(escapeLikeLiteral(s));
|
||||
var likePattern = (s) => `%${escapeLikeLiteral(s)}%`;
|
||||
function chunkByBytes(s, maxBytes) {
|
||||
const out = [];
|
||||
let cur = "";
|
||||
for (const ch of s) {
|
||||
if (utf8Len(cur + ch) > maxBytes) {
|
||||
if (likeBytes(cur + ch) > maxBytes) {
|
||||
if (cur) out.push(cur);
|
||||
cur = ch;
|
||||
} else {
|
||||
@@ -2204,8 +2211,8 @@ function chunkByBytes(s, maxBytes) {
|
||||
return out;
|
||||
}
|
||||
function buildContentLike(q) {
|
||||
if (utf8Len(q) <= MAX_LIKE_Q_BYTES) {
|
||||
return { conds: ["content LIKE ?"], params: [`%${q}%`], split: false };
|
||||
if (likeBytes(q) <= MAX_LIKE_Q_BYTES) {
|
||||
return { conds: [CONTENT_LIKE], params: [likePattern(q)], split: false };
|
||||
}
|
||||
const terms = [];
|
||||
for (const word of q.split(/\s+/).filter(Boolean)) {
|
||||
@@ -2217,8 +2224,8 @@ function buildContentLike(q) {
|
||||
}
|
||||
if (terms.length === 0) terms.push(chunkByBytes(q, MAX_LIKE_Q_BYTES)[0] ?? "");
|
||||
return {
|
||||
conds: terms.map(() => "content LIKE ?"),
|
||||
params: terms.map((t) => `%${t}%`),
|
||||
conds: terms.map(() => CONTENT_LIKE),
|
||||
params: terms.map(likePattern),
|
||||
split: true
|
||||
};
|
||||
}
|
||||
@@ -2335,7 +2342,7 @@ function buildSearchScore(q) {
|
||||
if (terms.length === 0) {
|
||||
const m = buildContentLike(trimmed);
|
||||
return {
|
||||
scoreExpr: m.conds.map(() => "CASE WHEN content LIKE ? THEN 1 ELSE 0 END").join(" + "),
|
||||
scoreExpr: m.conds.map(() => `CASE WHEN ${CONTENT_LIKE} THEN 1 ELSE 0 END`).join(" + "),
|
||||
scoreParams: m.params,
|
||||
terms: [],
|
||||
legacyShape: true
|
||||
@@ -2344,14 +2351,14 @@ function buildSearchScore(q) {
|
||||
const parts = [];
|
||||
const params = [];
|
||||
for (const { term, weight } of terms) {
|
||||
parts.push(`CASE WHEN content LIKE ? THEN ${weight} ELSE 0 END`);
|
||||
params.push(`%${term}%`);
|
||||
parts.push(`CASE WHEN ${CONTENT_LIKE} THEN ${weight} ELSE 0 END`);
|
||||
params.push(likePattern(term));
|
||||
}
|
||||
const single = terms.length === 1 && terms[0].term === trimmed;
|
||||
if (!single && utf8Len(trimmed) <= MAX_LIKE_Q_BYTES) {
|
||||
if (!single && likeBytes(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}%`);
|
||||
parts.push(`CASE WHEN ${CONTENT_LIKE} THEN ${bonus} ELSE 0 END`);
|
||||
params.push(likePattern(trimmed));
|
||||
}
|
||||
return { scoreExpr: parts.join(" + "), scoreParams: params, terms, legacyShape: single };
|
||||
}
|
||||
|
||||
+15
-15
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"built": "2026-08-12",
|
||||
"source": "Arcrun@3eb8b31f2bfa",
|
||||
"source": "Arcrun@1791ffa4972b",
|
||||
"core": [
|
||||
{
|
||||
"name": "arcrun-cypher-executor",
|
||||
"canonical": null,
|
||||
"main_module": "worker.mjs",
|
||||
"main_file": "arcrun-cypher-executor/worker.mjs",
|
||||
"js_bytes": 570290,
|
||||
"js_bytes": 577374,
|
||||
"modules": [],
|
||||
"compat_date": "2025-02-19",
|
||||
"compat_flags": [
|
||||
@@ -49,17 +49,17 @@
|
||||
"stripped": {
|
||||
"services": 13
|
||||
},
|
||||
"source_commit": "525faaf5d01e156a9b8f90808607bead92f40165",
|
||||
"source_content_sha256": "49d59597c01b5264875e0295c86c7bb2212bf54d3c5858cd4a167752370fa716",
|
||||
"sha256": "49d59597c01b5264875e0295c86c7bb2212bf54d3c5858cd4a167752370fa716",
|
||||
"bytes": 570290
|
||||
"source_commit": "f1370e2275eea62b64a88821a096f2c2cfe76fb0",
|
||||
"source_content_sha256": "8411ed59b7ad9e1a74ac0d8e3b620d7166e7d0178ac5939e6cc736f2e8d1d2be",
|
||||
"sha256": "8411ed59b7ad9e1a74ac0d8e3b620d7166e7d0178ac5939e6cc736f2e8d1d2be",
|
||||
"bytes": 577374
|
||||
},
|
||||
{
|
||||
"name": "arcrun-kbdb",
|
||||
"canonical": null,
|
||||
"main_module": "worker.mjs",
|
||||
"main_file": "arcrun-kbdb/worker.mjs",
|
||||
"js_bytes": 149234,
|
||||
"js_bytes": 149533,
|
||||
"modules": [],
|
||||
"compat_date": "2025-02-19",
|
||||
"compat_flags": [
|
||||
@@ -79,10 +79,10 @@
|
||||
"ENVIRONMENT": "production"
|
||||
}
|
||||
},
|
||||
"source_commit": "3eb8b31f2bfa029e15a8119e229082fbafb8d2b1",
|
||||
"source_content_sha256": "7bc666568f453a2fc5fc9339fc997c12d3927fb8a293439f2c80695be8da9767",
|
||||
"sha256": "7bc666568f453a2fc5fc9339fc997c12d3927fb8a293439f2c80695be8da9767",
|
||||
"bytes": 149234
|
||||
"source_commit": "c497ec418eba6cd94b1d5872671c51fd5812c11c",
|
||||
"source_content_sha256": "ffb8d43467d0cefbd7545fdc0d347f2b965e3c3de20b3315eed7613f20266891",
|
||||
"sha256": "ffb8d43467d0cefbd7545fdc0d347f2b965e3c3de20b3315eed7613f20266891",
|
||||
"bytes": 149533
|
||||
},
|
||||
{
|
||||
"name": "arcrun-http-request",
|
||||
@@ -177,7 +177,7 @@
|
||||
"tier": 2,
|
||||
"main_file": "tier2/ui/index.js",
|
||||
"main_module": "index.js",
|
||||
"sha256": "dd88fb04de28d999eb76f756f818d24ef9f75d19f0846b2b1c8830f9c5eb775b",
|
||||
"sha256": "2cbf796ee5eeed99b71cda2d551934f6c48e77e7ae244985bf43b2274cc9dcac",
|
||||
"compat_date": "2026-07-01",
|
||||
"compat_flags": [],
|
||||
"modules": [],
|
||||
@@ -187,7 +187,7 @@
|
||||
"ai": false,
|
||||
"vars": {}
|
||||
},
|
||||
"bytes": 519945
|
||||
"bytes": 522727
|
||||
}
|
||||
],
|
||||
"daemon": {
|
||||
@@ -207,8 +207,8 @@
|
||||
"sha256": "782a3b2212884f789e1725f82046cf34ef6bb02e1a8b585cab8e4ae6c6e441ca"
|
||||
}
|
||||
},
|
||||
"release": "1.4.38",
|
||||
"release": "1.4.40",
|
||||
"built_for": "oauth-installer-lazy-load",
|
||||
"notes": [],
|
||||
"fingerprint": "d25fe26913762693183d45506295c88a86110a4f4682fd43375e0668ae93c215"
|
||||
"fingerprint": "3f35ae8255861b36a0d41c3c7a004e6b85c9de0c9826124acbf5b86d03968782"
|
||||
}
|
||||
|
||||
+2
-2
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user