oasis_test_v2 2.2.29 → 2.2.31
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/dist/index.js +474 -46
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -23350,7 +23350,7 @@ function accumulateClaudeUsage(acc, p2) {
|
|
|
23350
23350
|
acc.saw = true;
|
|
23351
23351
|
}
|
|
23352
23352
|
} else if (type === "result") {
|
|
23353
|
-
acc.finalUsage = mergeFinalUsage(
|
|
23353
|
+
acc.finalUsage = mergeFinalUsage(parseModelUsage(p2["modelUsage"]), parseResultUsage(p2["usage"]));
|
|
23354
23354
|
const c = p2["total_cost_usd"];
|
|
23355
23355
|
if (typeof c === "number" && Number.isFinite(c)) {
|
|
23356
23356
|
acc.costUsd = c;
|
|
@@ -25935,11 +25935,19 @@ var init_codex = __esm({
|
|
|
25935
25935
|
active: false,
|
|
25936
25936
|
pendingInputs: /* @__PURE__ */ new Set(),
|
|
25937
25937
|
codex: createCodexNormalizeState(),
|
|
25938
|
-
// 本次 run
|
|
25939
|
-
|
|
25940
|
-
|
|
25941
|
-
//
|
|
25942
|
-
|
|
25938
|
+
// 本次 run 的用量:`thread/tokenUsage/updated` 的 `last`(见该解析函数注释)按轮次记下,
|
|
25939
|
+
// 结算时只加**本次 run 发起的轮次**(runTurnIds)。原因:`thread/resume` 之后 codex 会把线程
|
|
25940
|
+
// **上一轮**的用量通知重放一遍(本机 codex 0.154.0 实测,turnId 是上一轮的),照单全收的话
|
|
25941
|
+
// 每次续接都把上一轮的 token 再记一遍。没带 turnId 的通知(老版本)照旧直接计入。
|
|
25942
|
+
usageByTurn: [],
|
|
25943
|
+
runTurnIds: /* @__PURE__ */ new Set(),
|
|
25944
|
+
// 已经发出本次 run 的 `turn/start`:在这之前出现的 `turn/started` 不是本次的轮次。
|
|
25945
|
+
turnRequested: false,
|
|
25946
|
+
// 会话 rollout 的绝对路径:新开线程时 `thread/started` 通知会给;**续接(thread/resume)不发这条通知**,
|
|
25947
|
+
// 只能从 resume 的响应里取(同上实测)。取不到它就读不到实际模型。
|
|
25948
|
+
rolloutPath: void 0,
|
|
25949
|
+
// thread/start / thread/resume 响应里 codex 报的线程模型:rollout 读不到时的兜底。
|
|
25950
|
+
threadModel: void 0
|
|
25943
25951
|
}),
|
|
25944
25952
|
initialCommand: () => ({
|
|
25945
25953
|
jsonrpc: "2.0",
|
|
@@ -25956,12 +25964,16 @@ var init_codex = __esm({
|
|
|
25956
25964
|
const threadId = thread.thread?.id ?? thread.id;
|
|
25957
25965
|
if (typeof threadId !== "string" || !threadId) throw new Error("codex app-server returned no thread id");
|
|
25958
25966
|
state.threadId = threadId;
|
|
25967
|
+
if (typeof thread.thread?.path === "string" && thread.thread.path) state.rolloutPath ??= thread.thread.path;
|
|
25968
|
+
const responseModel = typeof thread.model === "string" && thread.model ? thread.model : typeof thread.thread?.model === "string" && thread.thread.model ? thread.thread.model : void 0;
|
|
25969
|
+
if (responseModel) state.threadModel = responseModel;
|
|
25959
25970
|
const text5 = currentJob.systemPrompt ? `${currentJob.systemPrompt}
|
|
25960
25971
|
|
|
25961
25972
|
---
|
|
25962
25973
|
|
|
25963
25974
|
${task}` : task;
|
|
25964
25975
|
state.active = true;
|
|
25976
|
+
state.turnRequested = true;
|
|
25965
25977
|
const turn = await send({
|
|
25966
25978
|
jsonrpc: "2.0",
|
|
25967
25979
|
method: "turn/start",
|
|
@@ -25974,7 +25986,10 @@ ${task}` : task;
|
|
|
25974
25986
|
}
|
|
25975
25987
|
});
|
|
25976
25988
|
const turnId = turn.turn?.id ?? turn.id;
|
|
25977
|
-
if (typeof turnId === "string" && turnId)
|
|
25989
|
+
if (typeof turnId === "string" && turnId) {
|
|
25990
|
+
state.turnId = turnId;
|
|
25991
|
+
state.runTurnIds.add(turnId);
|
|
25992
|
+
}
|
|
25978
25993
|
if (!state.turnId) throw new Error("codex app-server returned no turn id");
|
|
25979
25994
|
},
|
|
25980
25995
|
liveEvents(message, state) {
|
|
@@ -26015,16 +26030,14 @@ ${task}` : task;
|
|
|
26015
26030
|
}
|
|
26016
26031
|
if (method === "thread/tokenUsage/updated") {
|
|
26017
26032
|
const turn = parseCodexAppServerTurnUsage(params);
|
|
26018
|
-
if (turn) {
|
|
26019
|
-
addCodexBuckets(state.usage, turn);
|
|
26020
|
-
state.sawUsage = true;
|
|
26021
|
-
}
|
|
26033
|
+
if (turn) state.usageByTurn.push({ turnId: typeof params?.turnId === "string" ? params.turnId : void 0, buckets: turn });
|
|
26022
26034
|
}
|
|
26023
26035
|
if (method === "turn/started") {
|
|
26024
26036
|
const turn = params?.turn;
|
|
26025
26037
|
if (typeof turn?.id === "string") {
|
|
26026
26038
|
state.turnId = turn.id;
|
|
26027
26039
|
state.active = true;
|
|
26040
|
+
if (state.turnRequested) state.runTurnIds.add(turn.id);
|
|
26028
26041
|
}
|
|
26029
26042
|
}
|
|
26030
26043
|
if (method === "item/agentMessage/delta" || method === "item/reasoning/textDelta") {
|
|
@@ -26056,9 +26069,16 @@ ${task}` : task;
|
|
|
26056
26069
|
} catch {
|
|
26057
26070
|
}
|
|
26058
26071
|
}
|
|
26059
|
-
model ??= resolvedModel2;
|
|
26072
|
+
model ??= state.threadModel ?? resolvedModel2;
|
|
26073
|
+
const usage = { input: 0, cacheRead: 0, cacheWrite: 0, output: 0 };
|
|
26074
|
+
let sawUsage = false;
|
|
26075
|
+
for (const entry of state.usageByTurn) {
|
|
26076
|
+
if (entry.turnId !== void 0 && !state.runTurnIds.has(entry.turnId)) continue;
|
|
26077
|
+
addCodexBuckets(usage, entry.buckets);
|
|
26078
|
+
sawUsage = true;
|
|
26079
|
+
}
|
|
26060
26080
|
return {
|
|
26061
|
-
...
|
|
26081
|
+
...sawUsage ? { usage: codexUsageFromBuckets(usage) } : {},
|
|
26062
26082
|
...model ? { model } : {}
|
|
26063
26083
|
};
|
|
26064
26084
|
},
|
|
@@ -26068,7 +26088,10 @@ ${task}` : task;
|
|
|
26068
26088
|
await send({ jsonrpc: "2.0", method: "turn/interrupt", params: { threadId: state.threadId, turnId: state.turnId } });
|
|
26069
26089
|
const next = await send({ jsonrpc: "2.0", method: "turn/start", params: { threadId: state.threadId, input: [{ type: "text", text: input.text }] } });
|
|
26070
26090
|
const nextId = next.turn?.id;
|
|
26071
|
-
if (typeof nextId === "string")
|
|
26091
|
+
if (typeof nextId === "string") {
|
|
26092
|
+
state.turnId = nextId;
|
|
26093
|
+
state.runTurnIds.add(nextId);
|
|
26094
|
+
}
|
|
26072
26095
|
state.active = true;
|
|
26073
26096
|
return { accepted: true, interrupt: "unknown" };
|
|
26074
26097
|
}
|
|
@@ -160494,6 +160517,35 @@ var init_infra_error = __esm({
|
|
|
160494
160517
|
}
|
|
160495
160518
|
});
|
|
160496
160519
|
|
|
160520
|
+
// ../server/src/keyed-mutex.ts
|
|
160521
|
+
function createKeyedMutex() {
|
|
160522
|
+
const tails = /* @__PURE__ */ new Map();
|
|
160523
|
+
return {
|
|
160524
|
+
async acquire(key) {
|
|
160525
|
+
const previous3 = tails.get(key) ?? Promise.resolve();
|
|
160526
|
+
let release;
|
|
160527
|
+
const mine = new Promise((resolve10) => {
|
|
160528
|
+
release = resolve10;
|
|
160529
|
+
});
|
|
160530
|
+
const tail = previous3.then(() => mine);
|
|
160531
|
+
tails.set(key, tail);
|
|
160532
|
+
await previous3;
|
|
160533
|
+
let released = false;
|
|
160534
|
+
return () => {
|
|
160535
|
+
if (released) return;
|
|
160536
|
+
released = true;
|
|
160537
|
+
release();
|
|
160538
|
+
if (tails.get(key) === tail) tails.delete(key);
|
|
160539
|
+
};
|
|
160540
|
+
}
|
|
160541
|
+
};
|
|
160542
|
+
}
|
|
160543
|
+
var init_keyed_mutex = __esm({
|
|
160544
|
+
"../server/src/keyed-mutex.ts"() {
|
|
160545
|
+
"use strict";
|
|
160546
|
+
}
|
|
160547
|
+
});
|
|
160548
|
+
|
|
160497
160549
|
// ../server/src/live-chat.ts
|
|
160498
160550
|
function normalizedKindToItemType(kind) {
|
|
160499
160551
|
if (kind === "text") return "message";
|
|
@@ -203090,6 +203142,15 @@ function toApiError(err) {
|
|
|
203090
203142
|
if (isInfrastructureError(err)) return new ApiError(INFRA_ERROR_STATUS, INFRA_ERROR_CODE, message);
|
|
203091
203143
|
return new ApiError(400, "BAD_REQUEST", message);
|
|
203092
203144
|
}
|
|
203145
|
+
function workorderApplyTarget(rawBody) {
|
|
203146
|
+
try {
|
|
203147
|
+
const body2 = JSON.parse(rawBody);
|
|
203148
|
+
const briefSpawn = body2.plan?.ops?.find((op) => op.action === "spawn" && op.id === body2.briefArtifactId && op.workspace);
|
|
203149
|
+
return briefSpawn?.workspace ?? body2.plan?.workspace ?? "";
|
|
203150
|
+
} catch {
|
|
203151
|
+
return "";
|
|
203152
|
+
}
|
|
203153
|
+
}
|
|
203093
203154
|
async function loadWorkorderSnapshot(kernel, workorderId) {
|
|
203094
203155
|
if (!workorderId) return null;
|
|
203095
203156
|
const store = kernel.getStore?.();
|
|
@@ -204593,6 +204654,7 @@ async function startOasisServer(opts) {
|
|
|
204593
204654
|
const stagingWorkspace = /* @__PURE__ */ new Map();
|
|
204594
204655
|
const discussSessions = opts.discussSessions ?? /* @__PURE__ */ new Map();
|
|
204595
204656
|
const openingDiscussions = /* @__PURE__ */ new Map();
|
|
204657
|
+
const workorderApplyLocks = createKeyedMutex();
|
|
204596
204658
|
const reviewWaiters = /* @__PURE__ */ new Map();
|
|
204597
204659
|
const leftWaiterIds = /* @__PURE__ */ new Map();
|
|
204598
204660
|
const LEFT_WAITER_IDS_MAX_DRAFTS = 512;
|
|
@@ -205885,6 +205947,7 @@ async function startOasisServer(opts) {
|
|
|
205885
205947
|
}
|
|
205886
205948
|
}
|
|
205887
205949
|
if (url.pathname === "/api/workorder/apply" && req.method === "POST") {
|
|
205950
|
+
const releaseApplyLock = await workorderApplyLocks.acquire(`${currentCompanyId ?? ""}\0${workorderApplyTarget(rawBody)}`);
|
|
205888
205951
|
try {
|
|
205889
205952
|
const body2 = JSON.parse(rawBody);
|
|
205890
205953
|
let targetWs = body2.plan.workspace;
|
|
@@ -206043,6 +206106,8 @@ async function startOasisServer(opts) {
|
|
|
206043
206106
|
res.writeHead(status, { "content-type": "application/json" }).end(
|
|
206044
206107
|
JSON.stringify({ error: code2, message: err instanceof Error ? err.message : String(err) })
|
|
206045
206108
|
);
|
|
206109
|
+
} finally {
|
|
206110
|
+
releaseApplyLock();
|
|
206046
206111
|
}
|
|
206047
206112
|
return;
|
|
206048
206113
|
}
|
|
@@ -208764,6 +208829,7 @@ var init_server3 = __esm({
|
|
|
208764
208829
|
init_company_data_store_router();
|
|
208765
208830
|
init_router();
|
|
208766
208831
|
init_infra_error();
|
|
208832
|
+
init_keyed_mutex();
|
|
208767
208833
|
init_live_chat();
|
|
208768
208834
|
init_chat_turn_wait();
|
|
208769
208835
|
init_append_now();
|
|
@@ -212381,6 +212447,66 @@ function foldSingleNodeTasks(items) {
|
|
|
212381
212447
|
}
|
|
212382
212448
|
return folded;
|
|
212383
212449
|
}
|
|
212450
|
+
function basenameOfPath(name) {
|
|
212451
|
+
const i = name.lastIndexOf("/");
|
|
212452
|
+
return i >= 0 ? name.slice(i + 1) : name;
|
|
212453
|
+
}
|
|
212454
|
+
function creatorKindOf(actorId) {
|
|
212455
|
+
if (!actorId) return null;
|
|
212456
|
+
return actorId.startsWith("actor:human:") ? "human" : "agent";
|
|
212457
|
+
}
|
|
212458
|
+
function emitChatFolders(items, chatFiles, resolveName) {
|
|
212459
|
+
const groups = /* @__PURE__ */ new Map();
|
|
212460
|
+
for (const file of chatFiles) {
|
|
212461
|
+
const list2 = groups.get(file.chatSessionId) ?? [];
|
|
212462
|
+
list2.push(file);
|
|
212463
|
+
groups.set(file.chatSessionId, list2);
|
|
212464
|
+
}
|
|
212465
|
+
for (const [sessionId, group] of groups) {
|
|
212466
|
+
const head = group[0];
|
|
212467
|
+
const folderPath = `chat:${sessionId}`;
|
|
212468
|
+
const latest = group.reduce((acc, file) => file.uploadedAt > acc ? file.uploadedAt : acc, group[0].uploadedAt);
|
|
212469
|
+
items.push({
|
|
212470
|
+
kind: "folder",
|
|
212471
|
+
id: `folder:${folderPath}`,
|
|
212472
|
+
name: head.chatTitle,
|
|
212473
|
+
path: folderPath,
|
|
212474
|
+
filePath: null,
|
|
212475
|
+
depth: 0,
|
|
212476
|
+
type: "folder",
|
|
212477
|
+
size: null,
|
|
212478
|
+
taskId: null,
|
|
212479
|
+
taskTitle: CHAT_FOLDER_TASK_LABEL,
|
|
212480
|
+
creatorKind: creatorKindOf(head.chatOwnerId),
|
|
212481
|
+
creatorId: head.chatOwnerId,
|
|
212482
|
+
creatorName: resolveName(head.chatOwnerId),
|
|
212483
|
+
updatedAt: latest,
|
|
212484
|
+
folderKind: "chat",
|
|
212485
|
+
chatSessionId: sessionId
|
|
212486
|
+
});
|
|
212487
|
+
for (const file of group) {
|
|
212488
|
+
items.push({
|
|
212489
|
+
kind: "file",
|
|
212490
|
+
id: file.fileId,
|
|
212491
|
+
name: file.name,
|
|
212492
|
+
path: `${folderPath}/${file.name}`,
|
|
212493
|
+
filePath: null,
|
|
212494
|
+
depth: 1,
|
|
212495
|
+
type: file.contentType ?? inferTypeFromName(basenameOfPath(file.name)),
|
|
212496
|
+
blobRef: file.blobId,
|
|
212497
|
+
contentType: file.contentType ?? null,
|
|
212498
|
+
size: file.size,
|
|
212499
|
+
taskId: null,
|
|
212500
|
+
taskTitle: CHAT_FOLDER_TASK_LABEL,
|
|
212501
|
+
creatorKind: creatorKindOf(file.uploadedBy),
|
|
212502
|
+
creatorId: file.uploadedBy ?? null,
|
|
212503
|
+
creatorName: file.uploadedBy ? resolveName(file.uploadedBy) : null,
|
|
212504
|
+
updatedAt: file.uploadedAt,
|
|
212505
|
+
chatSessionId: sessionId
|
|
212506
|
+
});
|
|
212507
|
+
}
|
|
212508
|
+
}
|
|
212509
|
+
}
|
|
212384
212510
|
function fillFolderSizes(items) {
|
|
212385
212511
|
const folders = items.filter((i) => i.kind === "folder" && i.path);
|
|
212386
212512
|
if (folders.length === 0) return;
|
|
@@ -212600,7 +212726,7 @@ function laterOf(a, b2) {
|
|
|
212600
212726
|
if (!b2) return a;
|
|
212601
212727
|
return b2 > a ? b2 : a;
|
|
212602
212728
|
}
|
|
212603
|
-
var DEFAULT_AGENT_ACTOR, MemoryProjectStateStore, MemoryArtifactStateStore, ProjectsService;
|
|
212729
|
+
var DEFAULT_AGENT_ACTOR, CHAT_FOLDER_TASK_LABEL, MemoryProjectStateStore, MemoryArtifactStateStore, ProjectsService;
|
|
212604
212730
|
var init_service4 = __esm({
|
|
212605
212731
|
"../server/src/domains/projects/service.ts"() {
|
|
212606
212732
|
"use strict";
|
|
@@ -212612,6 +212738,7 @@ var init_service4 = __esm({
|
|
|
212612
212738
|
init_stats();
|
|
212613
212739
|
init_node_state();
|
|
212614
212740
|
DEFAULT_AGENT_ACTOR = "actor:agent:system";
|
|
212741
|
+
CHAT_FOLDER_TASK_LABEL = "\u5BF9\u8BDD";
|
|
212615
212742
|
MemoryProjectStateStore = class {
|
|
212616
212743
|
projects = /* @__PURE__ */ new Map();
|
|
212617
212744
|
members = /* @__PURE__ */ new Map();
|
|
@@ -213387,12 +213514,12 @@ var init_service4 = __esm({
|
|
|
213387
213514
|
...items.filter((item) => item.blobRef).map((item) => `${item.name}\0${item.blobRef}`),
|
|
213388
213515
|
...files.map((file) => `${file.name}\0${file.blobId}`)
|
|
213389
213516
|
]);
|
|
213390
|
-
|
|
213517
|
+
const chatFiles = [];
|
|
213518
|
+
if (this.listChatFiles) {
|
|
213391
213519
|
for (const file of await this.listChatFiles(projectId2)) {
|
|
213392
|
-
const key = `${file.name}\0${file.blobId}`;
|
|
213520
|
+
const key = `${basenameOfPath(file.name)}\0${file.blobId}`;
|
|
213393
213521
|
if (existingFiles.has(key)) continue;
|
|
213394
|
-
|
|
213395
|
-
files.push(file);
|
|
213522
|
+
chatFiles.push(file);
|
|
213396
213523
|
}
|
|
213397
213524
|
}
|
|
213398
213525
|
for (const file of files) {
|
|
@@ -213418,8 +213545,18 @@ var init_service4 = __esm({
|
|
|
213418
213545
|
updatedAt: file.uploadedAt
|
|
213419
213546
|
});
|
|
213420
213547
|
}
|
|
213548
|
+
emitChatFolders(items, chatFiles, (actorId) => this.resolveActorName(actorId));
|
|
213421
213549
|
fillFolderSizes(items);
|
|
213550
|
+
const chatFolderTime = new Map(items.filter((item) => item.folderKind === "chat" && item.chatSessionId).map((item) => [item.chatSessionId, item.updatedAt]));
|
|
213422
213551
|
items.sort((a, b2) => {
|
|
213552
|
+
const chatA = a.chatSessionId ? 1 : 0;
|
|
213553
|
+
const chatB = b2.chatSessionId ? 1 : 0;
|
|
213554
|
+
if (chatA !== chatB) return chatA - chatB;
|
|
213555
|
+
if (a.chatSessionId && b2.chatSessionId && a.chatSessionId !== b2.chatSessionId) {
|
|
213556
|
+
const timeA = chatFolderTime.get(a.chatSessionId) ?? "";
|
|
213557
|
+
const timeB = chatFolderTime.get(b2.chatSessionId) ?? "";
|
|
213558
|
+
return timeB.localeCompare(timeA) || a.chatSessionId.localeCompare(b2.chatSessionId);
|
|
213559
|
+
}
|
|
213423
213560
|
const pathA = a.path ?? "";
|
|
213424
213561
|
const pathB = b2.path ?? "";
|
|
213425
213562
|
if (pathA !== pathB) return pathA.localeCompare(pathB);
|
|
@@ -214744,6 +214881,8 @@ var init_dev_store = __esm({
|
|
|
214744
214881
|
sessionWorkOrderKinds = /* @__PURE__ */ new Map();
|
|
214745
214882
|
/** ADR-0166 D6 待发队列(每会话一条,按 seq 升序 = 入队序)。 */
|
|
214746
214883
|
pending = /* @__PURE__ */ new Map();
|
|
214884
|
+
/** `outputs/` 产出文件的服务端副本表(2026-09-14):sessionId → 路径 → 副本。 */
|
|
214885
|
+
outputCopies = /* @__PURE__ */ new Map();
|
|
214747
214886
|
pendingSeq = 0;
|
|
214748
214887
|
async claimPendingInsert(m2) {
|
|
214749
214888
|
const list2 = this.pending.get(m2.chatSessionId) ?? [];
|
|
@@ -214927,6 +215066,7 @@ var init_dev_store = __esm({
|
|
|
214927
215066
|
this.messages.delete(id);
|
|
214928
215067
|
this.sessionWorkOrders.delete(id);
|
|
214929
215068
|
this.sessionWorkOrderKinds.delete(id);
|
|
215069
|
+
this.outputCopies.delete(id);
|
|
214930
215070
|
}
|
|
214931
215071
|
async appendMessage(m2) {
|
|
214932
215072
|
return (await this.appendMessageOnce(m2)).message;
|
|
@@ -215055,6 +215195,27 @@ var init_dev_store = __esm({
|
|
|
215055
215195
|
}
|
|
215056
215196
|
return rows.sort((left, right) => left.createdAt.localeCompare(right.createdAt) || left.messageId.localeCompare(right.messageId));
|
|
215057
215197
|
}
|
|
215198
|
+
async readOutputCopies(sessionId) {
|
|
215199
|
+
const hit = this.outputCopies.get(sessionId);
|
|
215200
|
+
return hit ? { ...hit } : null;
|
|
215201
|
+
}
|
|
215202
|
+
async mergeOutputCopies(sessionId, copies) {
|
|
215203
|
+
if (copies.length === 0 || !this.sessions.has(sessionId)) return;
|
|
215204
|
+
const next = { ...this.outputCopies.get(sessionId) ?? {} };
|
|
215205
|
+
for (const copy of copies) next[copy.path] = { ...copy };
|
|
215206
|
+
this.outputCopies.set(sessionId, next);
|
|
215207
|
+
}
|
|
215208
|
+
async listOutputCopies(projectId2) {
|
|
215209
|
+
const rows = [];
|
|
215210
|
+
for (const session of this.sessions.values()) {
|
|
215211
|
+
if (session.visibility === "internal") continue;
|
|
215212
|
+
if ((session.projectId ?? null) !== projectId2) continue;
|
|
215213
|
+
const copies = this.outputCopies.get(session.id);
|
|
215214
|
+
if (!copies || Object.keys(copies).length === 0) continue;
|
|
215215
|
+
rows.push({ sessionId: session.id, ...session.projectId ? { projectId: session.projectId } : {}, copies: { ...copies } });
|
|
215216
|
+
}
|
|
215217
|
+
return rows.sort((left, right) => left.sessionId.localeCompare(right.sessionId));
|
|
215218
|
+
}
|
|
215058
215219
|
async listRunningAssistantMessages() {
|
|
215059
215220
|
const out = [];
|
|
215060
215221
|
for (const list2 of this.messages.values()) {
|
|
@@ -216080,6 +216241,148 @@ var init_outputs_scan = __esm({
|
|
|
216080
216241
|
}
|
|
216081
216242
|
});
|
|
216082
216243
|
|
|
216244
|
+
// ../server/src/domains/chat-sessions/outputs-copy.ts
|
|
216245
|
+
function isOutputPath(path41) {
|
|
216246
|
+
return path41.startsWith(`${SESSION_OUTPUTS_DIR}/`);
|
|
216247
|
+
}
|
|
216248
|
+
function basenameOf2(path41) {
|
|
216249
|
+
const i = path41.lastIndexOf("/");
|
|
216250
|
+
return i >= 0 ? path41.slice(i + 1) : path41;
|
|
216251
|
+
}
|
|
216252
|
+
function planOutputCopies(fingerprints, copies, limits = OUTPUT_COPY_LIMITS) {
|
|
216253
|
+
const have = copies ?? {};
|
|
216254
|
+
const plan = { toCopy: [], skipped: [] };
|
|
216255
|
+
let totalBytes = 0;
|
|
216256
|
+
for (const path41 of Object.keys(fingerprints).sort((a, b2) => a.localeCompare(b2))) {
|
|
216257
|
+
if (!isOutputPath(path41)) continue;
|
|
216258
|
+
const fp = fingerprints[path41];
|
|
216259
|
+
if (typeof fp.size !== "number" || !Number.isFinite(fp.size) || typeof fp.mtime !== "string" || fp.mtime === "") continue;
|
|
216260
|
+
const copy = have[path41];
|
|
216261
|
+
if (copy && copy.size === fp.size && copy.mtime === fp.mtime) continue;
|
|
216262
|
+
if (fp.size > limits.maxFileBytes) {
|
|
216263
|
+
plan.skipped.push({ path: path41, code: "TOO_LARGE" });
|
|
216264
|
+
continue;
|
|
216265
|
+
}
|
|
216266
|
+
if (plan.toCopy.length >= limits.maxFiles || totalBytes + fp.size > limits.maxTotalBytes) {
|
|
216267
|
+
plan.skipped.push({ path: path41, code: "BUDGET" });
|
|
216268
|
+
continue;
|
|
216269
|
+
}
|
|
216270
|
+
totalBytes += fp.size;
|
|
216271
|
+
plan.toCopy.push({ path: path41, size: fp.size, mtime: fp.mtime });
|
|
216272
|
+
}
|
|
216273
|
+
return plan;
|
|
216274
|
+
}
|
|
216275
|
+
async function copySessionOutputs(deps) {
|
|
216276
|
+
const now = deps.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
216277
|
+
const limits = deps.limits ?? OUTPUT_COPY_LIMITS;
|
|
216278
|
+
const result = { copied: [], skipped: [] };
|
|
216279
|
+
let existing;
|
|
216280
|
+
try {
|
|
216281
|
+
existing = await deps.readCopies(deps.sessionId);
|
|
216282
|
+
} catch {
|
|
216283
|
+
return result;
|
|
216284
|
+
}
|
|
216285
|
+
const plan = planOutputCopies(deps.fingerprints, existing, limits);
|
|
216286
|
+
result.skipped.push(...plan.skipped);
|
|
216287
|
+
for (const file of plan.toCopy) {
|
|
216288
|
+
let read;
|
|
216289
|
+
try {
|
|
216290
|
+
read = await deps.bridge.read(
|
|
216291
|
+
deps.loc.nodeId,
|
|
216292
|
+
{ workdirKey: deps.loc.workdirKey, runtimeKind: deps.loc.runtimeKind, rtId: deps.loc.rtId, path: file.path },
|
|
216293
|
+
limits.maxFileBytes
|
|
216294
|
+
);
|
|
216295
|
+
} catch {
|
|
216296
|
+
result.skipped.push({ path: file.path, code: "READ_FAILED" });
|
|
216297
|
+
continue;
|
|
216298
|
+
}
|
|
216299
|
+
if (!read.ok) {
|
|
216300
|
+
result.skipped.push({ path: file.path, code: read.code === "TOO_LARGE" ? "TOO_LARGE" : "READ_FAILED" });
|
|
216301
|
+
continue;
|
|
216302
|
+
}
|
|
216303
|
+
const bytes2 = Buffer.from(read.contentBase64, "base64");
|
|
216304
|
+
let blobRef;
|
|
216305
|
+
try {
|
|
216306
|
+
blobRef = await deps.putBlob(new Uint8Array(bytes2));
|
|
216307
|
+
} catch {
|
|
216308
|
+
result.skipped.push({ path: file.path, code: "STORE_FAILED" });
|
|
216309
|
+
continue;
|
|
216310
|
+
}
|
|
216311
|
+
result.copied.push({
|
|
216312
|
+
path: file.path,
|
|
216313
|
+
name: basenameOf2(file.path),
|
|
216314
|
+
blobRef,
|
|
216315
|
+
contentType: read.contentType ? read.contentType : null,
|
|
216316
|
+
size: bytes2.length,
|
|
216317
|
+
// 记**扫描时**的 mtime(不是读的那一刻):下一轮拿同一把节点时钟的指纹来比,相等才算复制过。
|
|
216318
|
+
mtime: file.mtime,
|
|
216319
|
+
copiedAt: now()
|
|
216320
|
+
});
|
|
216321
|
+
}
|
|
216322
|
+
if (result.copied.length > 0) {
|
|
216323
|
+
try {
|
|
216324
|
+
await deps.mergeCopies(deps.sessionId, result.copied);
|
|
216325
|
+
} catch {
|
|
216326
|
+
result.skipped.push(...result.copied.map((copy) => ({ path: copy.path, code: "STORE_FAILED" })));
|
|
216327
|
+
result.copied = [];
|
|
216328
|
+
}
|
|
216329
|
+
}
|
|
216330
|
+
return result;
|
|
216331
|
+
}
|
|
216332
|
+
function createOutputCopyScheduler(deps) {
|
|
216333
|
+
const inFlight = /* @__PURE__ */ new Set();
|
|
216334
|
+
return {
|
|
216335
|
+
schedule(args) {
|
|
216336
|
+
const { store, chatSessionId, companyId } = args;
|
|
216337
|
+
const readCopies = store.readOutputCopies?.bind(store);
|
|
216338
|
+
const mergeCopies = store.mergeOutputCopies?.bind(store);
|
|
216339
|
+
if (!readCopies || !mergeCopies) return Promise.resolve(null);
|
|
216340
|
+
const key = `${companyId ?? ""}|${chatSessionId}`;
|
|
216341
|
+
if (inFlight.has(key)) return Promise.resolve(null);
|
|
216342
|
+
inFlight.add(key);
|
|
216343
|
+
return (async () => {
|
|
216344
|
+
try {
|
|
216345
|
+
const session = await store.getSession(chatSessionId);
|
|
216346
|
+
if (!session || session.visibility === "internal" || session.analyzedRunId) return null;
|
|
216347
|
+
if (deps.isDelegationChild && await deps.isDelegationChild(companyId, chatSessionId).catch(() => false)) return null;
|
|
216348
|
+
const result = await copySessionOutputs({
|
|
216349
|
+
bridge: args.bridge,
|
|
216350
|
+
loc: args.loc,
|
|
216351
|
+
sessionId: chatSessionId,
|
|
216352
|
+
fingerprints: args.fingerprints,
|
|
216353
|
+
readCopies,
|
|
216354
|
+
mergeCopies,
|
|
216355
|
+
putBlob: deps.putBlob,
|
|
216356
|
+
...deps.limits ? { limits: deps.limits } : {}
|
|
216357
|
+
});
|
|
216358
|
+
if (result.skipped.length > 0) {
|
|
216359
|
+
const head = result.skipped.slice(0, 5).map((s2) => `${s2.path}:${s2.code}`).join(", ");
|
|
216360
|
+
deps.log?.(`[outputs-copy] ${chatSessionId}: \u590D\u5236 ${result.copied.length} \u4E2A\uFF0C\u8DF3\u8FC7 ${result.skipped.length} \u4E2A\uFF08${head}${result.skipped.length > 5 ? " \u2026" : ""}\uFF09`);
|
|
216361
|
+
}
|
|
216362
|
+
return result;
|
|
216363
|
+
} catch (err) {
|
|
216364
|
+
deps.log?.(`[outputs-copy] ${chatSessionId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
216365
|
+
return null;
|
|
216366
|
+
} finally {
|
|
216367
|
+
inFlight.delete(key);
|
|
216368
|
+
}
|
|
216369
|
+
})();
|
|
216370
|
+
}
|
|
216371
|
+
};
|
|
216372
|
+
}
|
|
216373
|
+
var OUTPUT_COPY_LIMITS;
|
|
216374
|
+
var init_outputs_copy = __esm({
|
|
216375
|
+
"../server/src/domains/chat-sessions/outputs-copy.ts"() {
|
|
216376
|
+
"use strict";
|
|
216377
|
+
init_src();
|
|
216378
|
+
OUTPUT_COPY_LIMITS = {
|
|
216379
|
+
maxFileBytes: 2 * 1024 * 1024,
|
|
216380
|
+
maxFiles: 50,
|
|
216381
|
+
maxTotalBytes: 50 * 1024 * 1024
|
|
216382
|
+
};
|
|
216383
|
+
}
|
|
216384
|
+
});
|
|
216385
|
+
|
|
216083
216386
|
// ../server/src/org-model-backfill.ts
|
|
216084
216387
|
function resolveDisplayName(existing, humanActor, accountName) {
|
|
216085
216388
|
const pick3 = existing?.trim() || humanActor?.name?.trim() || accountName?.trim();
|
|
@@ -225116,7 +225419,11 @@ function toApiProjectFilesView(view) {
|
|
|
225116
225419
|
creator_kind: item.creatorKind,
|
|
225117
225420
|
creator_id: item.creatorId,
|
|
225118
225421
|
creator_name: item.creatorName,
|
|
225119
|
-
updated_at: item.updatedAt
|
|
225422
|
+
updated_at: item.updatedAt,
|
|
225423
|
+
// 对话文件夹(`"chat"`):前端据此换带对话气泡的文件夹图标。其余文件夹与文件行为 null。
|
|
225424
|
+
folder_kind: item.folderKind ?? null,
|
|
225425
|
+
// 对话文件夹及其子文件所属的对话;前端「所属任务」列的「对话」筛选档靠它。其余行为 null。
|
|
225426
|
+
chat_session_id: item.chatSessionId ?? null
|
|
225120
225427
|
}))
|
|
225121
225428
|
};
|
|
225122
225429
|
}
|
|
@@ -229566,37 +229873,93 @@ var init_files_view = __esm({
|
|
|
229566
229873
|
});
|
|
229567
229874
|
|
|
229568
229875
|
// ../server/src/domains/projects/chat-files.ts
|
|
229569
|
-
|
|
229570
|
-
|
|
229571
|
-
|
|
229572
|
-
|
|
229573
|
-
|
|
229574
|
-
|
|
229575
|
-
|
|
229576
|
-
|
|
229577
|
-
const
|
|
229578
|
-
const
|
|
229579
|
-
|
|
229580
|
-
|
|
229581
|
-
|
|
229582
|
-
|
|
229583
|
-
|
|
229584
|
-
|
|
229585
|
-
|
|
229586
|
-
|
|
229587
|
-
|
|
229588
|
-
|
|
229589
|
-
|
|
229590
|
-
|
|
229591
|
-
|
|
229592
|
-
|
|
229593
|
-
|
|
229876
|
+
function chatFolderTitle(session) {
|
|
229877
|
+
const title = session.title?.trim();
|
|
229878
|
+
return title ? title : "\u672A\u547D\u540D\u5BF9\u8BDD";
|
|
229879
|
+
}
|
|
229880
|
+
function outputDisplayName(path41) {
|
|
229881
|
+
return path41.startsWith("outputs/") ? path41.slice("outputs/".length) : path41;
|
|
229882
|
+
}
|
|
229883
|
+
async function collectProjectChatFiles(chat, projectId2, meta, options = {}) {
|
|
229884
|
+
const scope = isUncategorizedProjectId(projectId2) ? null : projectId2;
|
|
229885
|
+
const [attachmentMessages, outputSessions] = await Promise.all([
|
|
229886
|
+
chat.listAttachmentMessages ? chat.listAttachmentMessages(scope) : Promise.resolve([]),
|
|
229887
|
+
chat.listOutputCopies ? chat.listOutputCopies(scope) : Promise.resolve([])
|
|
229888
|
+
]);
|
|
229889
|
+
const sessionIds = [.../* @__PURE__ */ new Set([
|
|
229890
|
+
...attachmentMessages.map((m2) => m2.sessionId),
|
|
229891
|
+
...outputSessions.map((s2) => s2.sessionId)
|
|
229892
|
+
])];
|
|
229893
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
229894
|
+
await Promise.all(sessionIds.map(async (id) => {
|
|
229895
|
+
const session = await chat.getSession(id);
|
|
229896
|
+
if (!session) return;
|
|
229897
|
+
if ((session.projectId ?? null) !== scope) return;
|
|
229898
|
+
if (session.visibility === "internal" || session.analyzedRunId) return;
|
|
229899
|
+
if (options.isDelegationChild && await options.isDelegationChild(id).catch(() => false)) return;
|
|
229900
|
+
sessions.set(id, session);
|
|
229901
|
+
}));
|
|
229902
|
+
const out = [];
|
|
229903
|
+
const base = (session) => ({
|
|
229904
|
+
projectId: projectId2,
|
|
229905
|
+
chatSessionId: session.id,
|
|
229906
|
+
chatTitle: chatFolderTitle(session),
|
|
229907
|
+
chatOwnerId: session.humanActorId
|
|
229594
229908
|
});
|
|
229909
|
+
const bySession = /* @__PURE__ */ new Map();
|
|
229910
|
+
for (const message of attachmentMessages) {
|
|
229911
|
+
if (!sessions.has(message.sessionId)) continue;
|
|
229912
|
+
const list2 = bySession.get(message.sessionId) ?? [];
|
|
229913
|
+
list2.push(message);
|
|
229914
|
+
bySession.set(message.sessionId, list2);
|
|
229915
|
+
}
|
|
229916
|
+
for (const [sessionId, messages] of bySession) {
|
|
229917
|
+
const session = sessions.get(sessionId);
|
|
229918
|
+
const rows = await collectMessageFiles(messages.map((m2) => ({ ...m2, id: m2.messageId })), { meta });
|
|
229919
|
+
for (const row of mergeChatSessionFiles(rows, [])) {
|
|
229920
|
+
if (row.blob_ref === null) continue;
|
|
229921
|
+
out.push({
|
|
229922
|
+
...base(session),
|
|
229923
|
+
fileId: `chat:${sessionId}:${row.id}`,
|
|
229924
|
+
name: row.name,
|
|
229925
|
+
blobId: row.blob_ref,
|
|
229926
|
+
...row.content_type ? { contentType: row.content_type } : {},
|
|
229927
|
+
size: row.size,
|
|
229928
|
+
uploadedBy: session.humanActorId,
|
|
229929
|
+
uploadedAt: row.updated_at,
|
|
229930
|
+
chatSource: "attachment"
|
|
229931
|
+
});
|
|
229932
|
+
}
|
|
229933
|
+
}
|
|
229934
|
+
for (const record8 of outputSessions) {
|
|
229935
|
+
const session = sessions.get(record8.sessionId);
|
|
229936
|
+
if (!session) continue;
|
|
229937
|
+
const seen = new Set(out.filter((file) => file.chatSessionId === session.id).map((file) => `${file.name}\0${file.blobId}`));
|
|
229938
|
+
const copies = record8.copies ?? {};
|
|
229939
|
+
for (const path41 of Object.keys(copies).sort((a, b2) => a.localeCompare(b2))) {
|
|
229940
|
+
const copy = copies[path41];
|
|
229941
|
+
if (!copy?.blobRef) continue;
|
|
229942
|
+
if (seen.has(`${copy.name}\0${copy.blobRef}`)) continue;
|
|
229943
|
+
out.push({
|
|
229944
|
+
...base(session),
|
|
229945
|
+
fileId: `chat:${session.id}:out:${copy.path}`,
|
|
229946
|
+
name: outputDisplayName(copy.path),
|
|
229947
|
+
blobId: copy.blobRef,
|
|
229948
|
+
...copy.contentType ? { contentType: copy.contentType } : {},
|
|
229949
|
+
size: copy.size,
|
|
229950
|
+
uploadedBy: session.aiActorId,
|
|
229951
|
+
uploadedAt: Number.isNaN(Date.parse(copy.mtime)) ? copy.copiedAt : new Date(copy.mtime).toISOString(),
|
|
229952
|
+
chatSource: "output"
|
|
229953
|
+
});
|
|
229954
|
+
}
|
|
229955
|
+
}
|
|
229956
|
+
return out;
|
|
229595
229957
|
}
|
|
229596
229958
|
var init_chat_files2 = __esm({
|
|
229597
229959
|
"../server/src/domains/projects/chat-files.ts"() {
|
|
229598
229960
|
"use strict";
|
|
229599
229961
|
init_files_view();
|
|
229962
|
+
init_uncategorized_project();
|
|
229600
229963
|
}
|
|
229601
229964
|
});
|
|
229602
229965
|
|
|
@@ -248794,6 +249157,7 @@ var init_postgres_chat_sessions = __esm({
|
|
|
248794
249157
|
await pool.query(`ALTER TABLE ${q2}.chat_sessions ADD COLUMN IF NOT EXISTS model text`);
|
|
248795
249158
|
await pool.query(`ALTER TABLE ${q2}.chat_sessions ADD COLUMN IF NOT EXISTS visibility text`);
|
|
248796
249159
|
await pool.query(`ALTER TABLE ${q2}.chat_sessions ADD COLUMN IF NOT EXISTS outputs_fingerprints jsonb`);
|
|
249160
|
+
await pool.query(`ALTER TABLE ${q2}.chat_sessions ADD COLUMN IF NOT EXISTS outputs_copies jsonb`);
|
|
248797
249161
|
await pool.query(`
|
|
248798
249162
|
WITH ranked AS (
|
|
248799
249163
|
SELECT id, row_number() OVER (PARTITION BY session_id ORDER BY seq, created_at, id) AS rn
|
|
@@ -249041,6 +249405,53 @@ var init_postgres_chat_sessions = __esm({
|
|
|
249041
249405
|
[JSON.stringify(fingerprints), sessionId, this.companyId]
|
|
249042
249406
|
);
|
|
249043
249407
|
}
|
|
249408
|
+
/**
|
|
249409
|
+
* `outputs/` 产出文件的服务端副本表(2026-09-14)。读:没有副本 → null。
|
|
249410
|
+
*/
|
|
249411
|
+
async readOutputCopies(sessionId) {
|
|
249412
|
+
const r = await this.pool.query(
|
|
249413
|
+
`SELECT outputs_copies FROM ${this.s}.chat_sessions WHERE id = $1 AND company_id = $2`,
|
|
249414
|
+
[sessionId, this.companyId]
|
|
249415
|
+
);
|
|
249416
|
+
return r.rows[0]?.outputs_copies ?? null;
|
|
249417
|
+
}
|
|
249418
|
+
/**
|
|
249419
|
+
* 按路径**合并**写入:同一路径新副本覆盖旧副本,其余路径保留。合并在一条 UPDATE 里用 jsonb `||` 完成,
|
|
249420
|
+
* 不是读出来改完再整份写回——两次收尾的复制前后脚落库时,后写的不会把先写的吞掉。
|
|
249421
|
+
*/
|
|
249422
|
+
async mergeOutputCopies(sessionId, copies) {
|
|
249423
|
+
if (copies.length === 0) return;
|
|
249424
|
+
const patch = {};
|
|
249425
|
+
for (const copy of copies) patch[copy.path] = copy;
|
|
249426
|
+
await this.pool.query(
|
|
249427
|
+
`UPDATE ${this.s}.chat_sessions
|
|
249428
|
+
SET outputs_copies = COALESCE(outputs_copies, '{}'::jsonb) || $1::jsonb
|
|
249429
|
+
WHERE id = $2 AND company_id = $3`,
|
|
249430
|
+
[JSON.stringify(patch), sessionId, this.companyId]
|
|
249431
|
+
);
|
|
249432
|
+
}
|
|
249433
|
+
/**
|
|
249434
|
+
* 某个范围内有副本的会话。口径同 {@link listAttachmentMessages}:排除内部会话、按公司收口、
|
|
249435
|
+
* `project_id IS NOT DISTINCT FROM $1`(null = 没绑项目的会话)。只取三列,不碰会话其余字段。
|
|
249436
|
+
*/
|
|
249437
|
+
async listOutputCopies(projectId2) {
|
|
249438
|
+
const r = await this.pool.query(
|
|
249439
|
+
`SELECT id, project_id, outputs_copies
|
|
249440
|
+
FROM ${this.s}.chat_sessions
|
|
249441
|
+
WHERE outputs_copies IS NOT NULL
|
|
249442
|
+
AND outputs_copies <> '{}'::jsonb
|
|
249443
|
+
AND visibility IS DISTINCT FROM 'internal'
|
|
249444
|
+
AND project_id IS NOT DISTINCT FROM $1
|
|
249445
|
+
AND company_id = $2
|
|
249446
|
+
ORDER BY id`,
|
|
249447
|
+
[projectId2, this.companyId]
|
|
249448
|
+
);
|
|
249449
|
+
return r.rows.map((row) => ({
|
|
249450
|
+
sessionId: row.id,
|
|
249451
|
+
...row.project_id ? { projectId: row.project_id } : {},
|
|
249452
|
+
copies: row.outputs_copies ?? {}
|
|
249453
|
+
}));
|
|
249454
|
+
}
|
|
249044
249455
|
/** 删项目时把本公司里绑到它的会话回落成「不指定项目」。会话一条都不删,只清 project_id。 */
|
|
249045
249456
|
async clearProjectBinding(projectId2) {
|
|
249046
249457
|
if (!projectId2) return 0;
|
|
@@ -259219,6 +259630,7 @@ var init_src11 = __esm({
|
|
|
259219
259630
|
init_company_scoped_registry();
|
|
259220
259631
|
init_session_workdir();
|
|
259221
259632
|
init_outputs_scan();
|
|
259633
|
+
init_outputs_copy();
|
|
259222
259634
|
init_org_model_backfill();
|
|
259223
259635
|
init_types_admin();
|
|
259224
259636
|
init_roles_admin();
|
|
@@ -261027,6 +261439,13 @@ async function startServe(opts) {
|
|
|
261027
261439
|
}
|
|
261028
261440
|
}
|
|
261029
261441
|
return null;
|
|
261442
|
+
}, {
|
|
261443
|
+
// 委派子会话不进项目(ADR 0555:它的 outputs/ 是交给协调者的)。闭包在请求时才读
|
|
261444
|
+
// `delegationStoreFor`,避开它在下方声明的 TDZ。
|
|
261445
|
+
isDelegationChild: async (sessionId) => {
|
|
261446
|
+
const ledger = await delegationStoreFor(companyId).catch(() => null);
|
|
261447
|
+
return Boolean(ledger && await ledger.getByChildSession(sessionId).catch(() => null));
|
|
261448
|
+
}
|
|
261030
261449
|
});
|
|
261031
261450
|
},
|
|
261032
261451
|
projects: projectStateStore,
|
|
@@ -262189,6 +262608,14 @@ async function startServe(opts) {
|
|
|
262189
262608
|
delegationStores.set(id, store);
|
|
262190
262609
|
return store;
|
|
262191
262610
|
};
|
|
262611
|
+
const outputCopyScheduler = createOutputCopyScheduler({
|
|
262612
|
+
putBlob: (bytes2) => assets.put(bytes2),
|
|
262613
|
+
isDelegationChild: async (companyId, sessionId) => {
|
|
262614
|
+
const ledger = await delegationStoreFor(companyId).catch(() => null);
|
|
262615
|
+
return Boolean(ledger && await ledger.getByChildSession(sessionId).catch(() => null));
|
|
262616
|
+
},
|
|
262617
|
+
log: (message) => console.warn(message)
|
|
262618
|
+
});
|
|
262192
262619
|
const chatBroadcastMarkers = /* @__PURE__ */ new Map([
|
|
262193
262620
|
[defaultCompanyId, chatBroadcastMarker]
|
|
262194
262621
|
]);
|
|
@@ -262920,6 +263347,7 @@ async function startServe(opts) {
|
|
|
262920
263347
|
readFingerprints: read,
|
|
262921
263348
|
writeFingerprints: write
|
|
262922
263349
|
}).catch(() => null);
|
|
263350
|
+
if (diff && store) void outputCopyScheduler.schedule({ store, bridge, loc: located.loc, chatSessionId, companyId, fingerprints: diff.fingerprints });
|
|
262923
263351
|
return diff?.changed ?? null;
|
|
262924
263352
|
},
|
|
262925
263353
|
delegationWorkdir: createDelegationWorkdirPort({
|
|
@@ -273755,7 +274183,7 @@ function shimScript() {
|
|
|
273755
274183
|
}
|
|
273756
274184
|
|
|
273757
274185
|
// src/index.ts
|
|
273758
|
-
var PKG_VERSION = true ? "2.2.
|
|
274186
|
+
var PKG_VERSION = true ? "2.2.31" : "dev";
|
|
273759
274187
|
var LOCAL_BIN = localBin();
|
|
273760
274188
|
var NPM_PREFIX = npmPrefix();
|
|
273761
274189
|
var INSTANCE = DEFAULT_INSTANCE;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oasis_test_v2",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.31",
|
|
4
4
|
"description": "Oasis node daemon + CLI — background daemon, auto-start, full server CLI",
|
|
5
5
|
"bin": {
|
|
6
6
|
"oasis": "./dist/index.js"
|
|
@@ -26,6 +26,6 @@
|
|
|
26
26
|
"node": ">=20"
|
|
27
27
|
},
|
|
28
28
|
"oasisRelease": {
|
|
29
|
-
"sourceHead": "
|
|
29
|
+
"sourceHead": "bbc56bf65b7e0c10506c3919f42c9c7d8b7c7342"
|
|
30
30
|
}
|
|
31
31
|
}
|