oasis_test_v2 2.2.7 → 2.2.8
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 +517 -116
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -17406,6 +17406,7 @@ ${supplemental.taskAppend.trim()}
|
|
|
17406
17406
|
...Object.keys(jobEnv).length > 0 ? { env: jobEnv } : {},
|
|
17407
17407
|
...provisioned?.wrapperPaths && provisioned.wrapperPaths.length > 0 ? { wrapperPaths: provisioned.wrapperPaths } : {},
|
|
17408
17408
|
...provisioned?.requiredTools && provisioned.requiredTools.length > 0 ? { requiredTools: provisioned.requiredTools } : {},
|
|
17409
|
+
...provisioned?.requiredToolVersions && Object.keys(provisioned.requiredToolVersions).length > 0 ? { requiredToolVersions: provisioned.requiredToolVersions } : {},
|
|
17409
17410
|
// 凭据本体随 job 下发,供**节点侧本机注入**(见上方 provision 注释)。
|
|
17410
17411
|
...provisioned?.connectorCreds && provisioned.connectorCreds.length > 0 ? { connectorCreds: provisioned.connectorCreds } : {},
|
|
17411
17412
|
...executionEnv !== void 0 ? { executionEnv } : {},
|
|
@@ -195837,7 +195838,15 @@ var init_service3 = __esm({
|
|
|
195837
195838
|
...companyId ? { companyId } : {},
|
|
195838
195839
|
...snapshot ? { parentConversationSnapshot: snapshot } : {},
|
|
195839
195840
|
extraSystemPrompt: EXPERT_DELEGATION_SYSTEM_PROMPT,
|
|
195840
|
-
..._DelegationService.inboundBundle(inbound) ? { workspaceBundle: _DelegationService.inboundBundle(inbound) } : {}
|
|
195841
|
+
..._DelegationService.inboundBundle(inbound) ? { workspaceBundle: _DelegationService.inboundBundle(inbound) } : {},
|
|
195842
|
+
/* 派发这一侧要拿它们建 `chat_items` 账本(见本文件 `DelegationDispatchRequest` 的注释)。
|
|
195843
|
+
轮次口径与 `bindChildRunToPlaceholder` / `seedChildRoundRows` **逐字一致**:
|
|
195844
|
+
`record.roundSummaries.length + 1`。三处一旦不同源,item 就会挂到上一轮那条回答行上。 */
|
|
195845
|
+
assistantMessageId: childRoundMessageIds(
|
|
195846
|
+
record8.childSessionId,
|
|
195847
|
+
record8.roundSummaries.length + 1
|
|
195848
|
+
).placeholderId,
|
|
195849
|
+
chatTurnId: turnId
|
|
195841
195850
|
});
|
|
195842
195851
|
outcomeSettled = true;
|
|
195843
195852
|
await opts?.onDispatched?.().catch((err) => console.warn(`[delegation] \u5F85\u8F6C\u8FBE\u6807\u8BB0\u5DF2\u6D88\u8D39\u5931\u8D25\uFF08${record8.id}\uFF09: ${String(err)}`));
|
|
@@ -197101,7 +197110,11 @@ function toChatDispatchRequest(request2) {
|
|
|
197101
197110
|
delegatedChildTurn: true,
|
|
197102
197111
|
// §6.1.3 去程:`--file` 带来的字节就在这一格。**丢了它命令照样回 202**,
|
|
197103
197112
|
// 而专家的工作区里什么都没有——这正是上一版真实发生过的形态。
|
|
197104
|
-
...request2.workspaceBundle ? { workspaceBundle: request2.workspaceBundle } : {}
|
|
197113
|
+
...request2.workspaceBundle ? { workspaceBundle: request2.workspaceBundle } : {},
|
|
197114
|
+
// 这两格漏了同样**不报错**:子会话照跑、正文照回,只是 `chat_items` 的行没有 message_id、
|
|
197115
|
+
// turnId 回落成 `chat-run-turn:<runId>`,右栏面板的增量流对不上轮——正是本文件存在的理由。
|
|
197116
|
+
...request2.assistantMessageId ? { assistantMessageId: request2.assistantMessageId } : {},
|
|
197117
|
+
...request2.chatTurnId ? { chatTurnId: request2.chatTurnId } : {}
|
|
197105
197118
|
};
|
|
197106
197119
|
}
|
|
197107
197120
|
function applyWorkspaceBundle(target, bundle) {
|
|
@@ -197321,27 +197334,77 @@ var init_assembly = __esm({
|
|
|
197321
197334
|
});
|
|
197322
197335
|
|
|
197323
197336
|
// ../server/src/domains/delegations/child-live-turn.ts
|
|
197324
|
-
function registerDelegatedChildTurn(liveChat, childSessionId, session) {
|
|
197337
|
+
function registerDelegatedChildTurn(liveChat, childSessionId, session, deps = {}) {
|
|
197338
|
+
const log3 = deps.log ?? ((m2) => console.warn(m2));
|
|
197325
197339
|
const appendInput = session.appendInput;
|
|
197326
|
-
|
|
197340
|
+
const canAppend = typeof appendInput === "function" && session.canAppendInput !== false;
|
|
197341
|
+
const ledger = new ChatItemLedger({
|
|
197342
|
+
...deps.items ? { items: deps.items } : {},
|
|
197343
|
+
sessionId: childSessionId,
|
|
197344
|
+
turnId: deps.turnId ?? fallbackTurnId(session.runId),
|
|
197345
|
+
...session.runId ? { runId: session.runId } : {},
|
|
197346
|
+
...deps.assistantMessageId ? { messageId: deps.assistantMessageId } : {},
|
|
197347
|
+
...deps.versionSeed !== void 0 ? { versionSeed: deps.versionSeed } : {},
|
|
197348
|
+
log: log3
|
|
197349
|
+
});
|
|
197327
197350
|
const ctrl = liveChat.start(childSessionId, {
|
|
197328
197351
|
runtimeSessionId: session.id,
|
|
197329
197352
|
...session.runId ? { runId: session.runId } : {},
|
|
197330
197353
|
kill: () => {
|
|
197331
197354
|
void session.kill?.();
|
|
197332
197355
|
},
|
|
197333
|
-
|
|
197356
|
+
// 纪律 ①:插不进去的 runtime 也登记,只是这两格照实报。
|
|
197357
|
+
...canAppend && appendInput ? { appendInput: (input) => appendInput.call(session, input) } : {},
|
|
197334
197358
|
// **每次现读**,不快照:一轮跑到收尾时 stdin 会先关,那之后 runtime 自己会回
|
|
197335
197359
|
// `session-closing`,判断权本就该留在它那儿(同 `/api/chat` 那条路的写法)。
|
|
197336
197360
|
get canAppendInput() {
|
|
197337
|
-
return session.canAppendInput !== false;
|
|
197361
|
+
return typeof session.appendInput === "function" && session.canAppendInput !== false;
|
|
197362
|
+
}
|
|
197363
|
+
}, { items: ledger });
|
|
197364
|
+
if (deps.assistantMessageId) ctrl.setAssistantMessageId(deps.assistantMessageId);
|
|
197365
|
+
const hasChannels = typeof session.onOutput === "function" || typeof session.onTelemetry === "function" || typeof session.onLiveEvent === "function";
|
|
197366
|
+
const normalized4 = typeof session.onNormalizedProviderEvent === "function" ? {
|
|
197367
|
+
onNormalizedProviderEvent: session.onNormalizedProviderEvent.bind(session),
|
|
197368
|
+
finishTurn: (signal) => session.finishNormalizedTurn?.(signal)
|
|
197369
|
+
} : hasChannels ? attachStreamNormalizer(
|
|
197370
|
+
{
|
|
197371
|
+
id: session.id,
|
|
197372
|
+
onOutput: (cb) => session.onOutput?.(cb),
|
|
197373
|
+
onTelemetry: (cb) => session.onTelemetry?.(cb),
|
|
197374
|
+
onLiveEvent: (cb) => session.onLiveEvent?.(cb),
|
|
197375
|
+
...session.supportsLiveProtocol !== void 0 ? { supportsLiveProtocol: session.supportsLiveProtocol } : {}
|
|
197376
|
+
},
|
|
197377
|
+
{
|
|
197378
|
+
providerName: deps.runtimeKind ?? "runtime",
|
|
197379
|
+
fallbackTurnId: `oasis-turn:${session.runId ?? session.id}`
|
|
197380
|
+
}
|
|
197381
|
+
) : null;
|
|
197382
|
+
normalized4?.onNormalizedProviderEvent((event) => {
|
|
197383
|
+
try {
|
|
197384
|
+
ctrl.applyNormalizedEvent(event);
|
|
197385
|
+
} catch {
|
|
197338
197386
|
}
|
|
197339
197387
|
});
|
|
197340
|
-
|
|
197388
|
+
const settle = async (signal) => {
|
|
197389
|
+
try {
|
|
197390
|
+
normalized4?.finishTurn(signal);
|
|
197391
|
+
} catch {
|
|
197392
|
+
}
|
|
197393
|
+
try {
|
|
197394
|
+
ledger.finish(signal);
|
|
197395
|
+
await ledger.drain();
|
|
197396
|
+
} catch (err) {
|
|
197397
|
+
log3(`[delegation] \u5B50\u4F1A\u8BDD ${childSessionId} \u8D26\u672C\u6536\u5C3E\u5931\u8D25: ${String(err)}`);
|
|
197398
|
+
}
|
|
197399
|
+
ctrl.finish(signal === "completed" ? "done" : "error");
|
|
197400
|
+
};
|
|
197401
|
+
void session.done.then(() => settle("completed"), () => settle("failed"));
|
|
197341
197402
|
}
|
|
197342
197403
|
var init_child_live_turn = __esm({
|
|
197343
197404
|
"../server/src/domains/delegations/child-live-turn.ts"() {
|
|
197344
197405
|
"use strict";
|
|
197406
|
+
init_src6();
|
|
197407
|
+
init_chat_item_ledger();
|
|
197345
197408
|
}
|
|
197346
197409
|
});
|
|
197347
197410
|
|
|
@@ -197455,10 +197518,12 @@ var init_tool_home = __esm({
|
|
|
197455
197518
|
});
|
|
197456
197519
|
|
|
197457
197520
|
// ../connectors/src/_base/install.ts
|
|
197458
|
-
function installPlan(cmd, platform2, toolsPrefix) {
|
|
197459
|
-
|
|
197521
|
+
function installPlan(cmd, platform2, toolsPrefix, version2) {
|
|
197522
|
+
const npmPkg = NPM_TOOL_PACKAGES[cmd];
|
|
197523
|
+
if (npmPkg) {
|
|
197460
197524
|
const npm = platform2 === "win32" ? "npm.cmd" : "npm";
|
|
197461
|
-
|
|
197525
|
+
const spec = version2 ? `${npmPkg}@${version2}` : npmPkg;
|
|
197526
|
+
return [{ file: npm, args: ["install", "-g", "--prefix", toolsPrefix, spec], ensureDir: toolsPrefix }];
|
|
197462
197527
|
}
|
|
197463
197528
|
const pkg = cmd === "gh" ? { brew: "gh", apt: "gh", dnf: "gh", pacman: "github-cli", apk: "github-cli", winget: "GitHub.cli", choco: "gh", scoop: "gh" } : { brew: "git", apt: "git", dnf: "git", pacman: "git", apk: "git", winget: "Git.Git", choco: "git", scoop: "git" };
|
|
197464
197529
|
if (platform2 === "darwin") {
|
|
@@ -197503,17 +197568,54 @@ function defaultDeps() {
|
|
|
197503
197568
|
mkdirp: (dir) => {
|
|
197504
197569
|
(0, import_node_fs9.mkdirSync)(dir, { recursive: true });
|
|
197505
197570
|
},
|
|
197506
|
-
log: (msg) => console.warn(msg)
|
|
197571
|
+
log: (msg) => console.warn(msg),
|
|
197572
|
+
installedVersion: async (pkg, prefix) => readInstalledVersion(pkg, prefix)
|
|
197507
197573
|
};
|
|
197508
197574
|
}
|
|
197509
|
-
|
|
197575
|
+
function readInstalledVersion(pkg, prefix) {
|
|
197576
|
+
const parts = pkg.split("/");
|
|
197577
|
+
for (const mid of [["lib", "node_modules"], ["node_modules"]]) {
|
|
197578
|
+
const file = (0, import_node_path11.join)(prefix, ...mid, ...parts, "package.json");
|
|
197579
|
+
if (!(0, import_node_fs9.existsSync)(file)) continue;
|
|
197580
|
+
try {
|
|
197581
|
+
const v2 = JSON.parse((0, import_node_fs9.readFileSync)(file, "utf8")).version;
|
|
197582
|
+
if (typeof v2 === "string" && v2) return v2;
|
|
197583
|
+
} catch {
|
|
197584
|
+
}
|
|
197585
|
+
}
|
|
197586
|
+
return null;
|
|
197587
|
+
}
|
|
197588
|
+
async function alignToWantedVersion(cmd, wanted, d) {
|
|
197589
|
+
if (alignedVersion.get(cmd) === wanted) return;
|
|
197590
|
+
const pkg = NPM_TOOL_PACKAGES[cmd];
|
|
197591
|
+
if (!pkg) return;
|
|
197592
|
+
const installed = await d.installedVersion(pkg, d.toolsPrefix);
|
|
197593
|
+
if (!installed) return;
|
|
197594
|
+
if (installed === wanted) {
|
|
197595
|
+
alignedVersion.set(cmd, wanted);
|
|
197596
|
+
return;
|
|
197597
|
+
}
|
|
197598
|
+
const npm = d.platform === "win32" ? "npm.cmd" : "npm";
|
|
197599
|
+
d.log(`[connector-install] ${cmd} ${installed} \u2192 ${wanted}\uFF08\u670D\u52A1\u7AEF\u767B\u8BB0\u7248\u672C\uFF09\uFF0C\u5B89\u88C5\u4E2D\u2026`);
|
|
197600
|
+
try {
|
|
197601
|
+
d.mkdirp(d.toolsPrefix);
|
|
197602
|
+
await d.run(npm, ["install", "-g", "--prefix", d.toolsPrefix, `${pkg}@${wanted}`]);
|
|
197603
|
+
alignedVersion.set(cmd, wanted);
|
|
197604
|
+
d.log(`[connector-install] ${cmd} \u5DF2\u5BF9\u9F50\u5230 ${wanted}`);
|
|
197605
|
+
} catch (err) {
|
|
197606
|
+
d.log(`[connector-install] ${cmd} \u5BF9\u9F50\u5230 ${wanted} \u5931\u8D25\uFF0C\u7EE7\u7EED\u7528 ${installed}\uFF1A${String(err)}`);
|
|
197607
|
+
}
|
|
197608
|
+
}
|
|
197609
|
+
async function ensureToolInstalled(cmd, opts = {}) {
|
|
197610
|
+
const { versions, ...deps } = opts;
|
|
197510
197611
|
const d = { ...defaultDeps(), ...deps };
|
|
197511
|
-
|
|
197512
|
-
if (await d.isPresent(cmd)) {
|
|
197612
|
+
const wanted = versions?.[cmd];
|
|
197613
|
+
if (confirmed.has(cmd) || await d.isPresent(cmd)) {
|
|
197513
197614
|
confirmed.add(cmd);
|
|
197615
|
+
if (wanted) await alignToWantedVersion(cmd, wanted, d);
|
|
197514
197616
|
return true;
|
|
197515
197617
|
}
|
|
197516
|
-
const steps = installPlan(cmd, d.platform, d.toolsPrefix);
|
|
197618
|
+
const steps = installPlan(cmd, d.platform, d.toolsPrefix, wanted);
|
|
197517
197619
|
if (steps.length === 0) {
|
|
197518
197620
|
d.log(`[connector-install] ${cmd} \u7F3A\u5931\uFF0C\u4E14 ${d.platform} \u4E0B\u65E0\u5DF2\u77E5\u81EA\u52A8\u5B89\u88C5\u6CD5\u2014\u2014\u8BF7\u624B\u52A8\u5B89\u88C5`);
|
|
197519
197621
|
return false;
|
|
@@ -197526,6 +197628,7 @@ async function ensureToolInstalled(cmd, deps = {}) {
|
|
|
197526
197628
|
await d.run(step.file, step.args);
|
|
197527
197629
|
if (await d.isPresent(cmd)) {
|
|
197528
197630
|
confirmed.add(cmd);
|
|
197631
|
+
if (wanted) alignedVersion.set(cmd, wanted);
|
|
197529
197632
|
d.log(`[connector-install] ${cmd} \u5B89\u88C5\u6210\u529F\uFF08${step.file} ${step.args.join(" ")}\uFF09`);
|
|
197530
197633
|
return true;
|
|
197531
197634
|
}
|
|
@@ -197536,15 +197639,15 @@ async function ensureToolInstalled(cmd, deps = {}) {
|
|
|
197536
197639
|
d.log(`[connector-install] ${cmd} \u81EA\u52A8\u5B89\u88C5\u672A\u6210\u529F\u2014\u2014\u5C06\u56DE\u9000\u5230 wrapper/\u547D\u4EE4\u81EA\u8EAB\u62A5\u9519`);
|
|
197537
197640
|
return false;
|
|
197538
197641
|
}
|
|
197539
|
-
async function ensureConnectorTools(tools,
|
|
197642
|
+
async function ensureConnectorTools(tools, opts = {}) {
|
|
197540
197643
|
if (!tools || tools.length === 0) return [];
|
|
197541
197644
|
const missing = [];
|
|
197542
197645
|
for (const cmd of tools) {
|
|
197543
|
-
if (!await ensureToolInstalled(cmd,
|
|
197646
|
+
if (!await ensureToolInstalled(cmd, opts)) missing.push(cmd);
|
|
197544
197647
|
}
|
|
197545
197648
|
return missing;
|
|
197546
197649
|
}
|
|
197547
|
-
var import_node_child_process12, import_node_util2, import_node_fs9, import_node_path11, execFileAsync, confirmed;
|
|
197650
|
+
var import_node_child_process12, import_node_util2, import_node_fs9, import_node_path11, execFileAsync, NPM_TOOL_PACKAGES, confirmed, alignedVersion;
|
|
197548
197651
|
var init_install = __esm({
|
|
197549
197652
|
"../connectors/src/_base/install.ts"() {
|
|
197550
197653
|
"use strict";
|
|
@@ -197554,7 +197657,9 @@ var init_install = __esm({
|
|
|
197554
197657
|
import_node_path11 = require("node:path");
|
|
197555
197658
|
init_tool_home();
|
|
197556
197659
|
execFileAsync = (0, import_node_util2.promisify)(import_node_child_process12.execFile);
|
|
197660
|
+
NPM_TOOL_PACKAGES = { "lark-cli": "@larksuite/cli" };
|
|
197557
197661
|
confirmed = /* @__PURE__ */ new Set();
|
|
197662
|
+
alignedVersion = /* @__PURE__ */ new Map();
|
|
197558
197663
|
}
|
|
197559
197664
|
});
|
|
197560
197665
|
|
|
@@ -201625,7 +201730,7 @@ var init_connector_adapter = __esm({
|
|
|
201625
201730
|
async spawn(job) {
|
|
201626
201731
|
const t0 = Date.now();
|
|
201627
201732
|
if (job.requiredTools?.length) {
|
|
201628
|
-
const missing = await ensureConnectorTools(job.requiredTools);
|
|
201733
|
+
const missing = await ensureConnectorTools(job.requiredTools, { versions: job.requiredToolVersions });
|
|
201629
201734
|
if (missing.length) log("[adapter]", ` connector tools still missing (agent may fail): ${missing.join(", ")}`);
|
|
201630
201735
|
}
|
|
201631
201736
|
const prepared = await prepareConnectorsForJob(job);
|
|
@@ -203289,13 +203394,22 @@ async function startOasisServer(opts) {
|
|
|
203289
203394
|
resolveStore: opts.delegationStoreFor,
|
|
203290
203395
|
resolveChatSessions: resolveChatSessionsForDelegation,
|
|
203291
203396
|
resolveActors: async (companyId) => (await actorsDomain2.resolveCtx(companyId)).service,
|
|
203292
|
-
|
|
203293
|
-
|
|
203294
|
-
|
|
203295
|
-
|
|
203397
|
+
/* **派发完顺手把子会话这一轮登记进 live 注册表,并给它接上 `chat_items` 账本。**
|
|
203398
|
+
两件事的成因不同,都在 `child-live-turn.ts` 的文件头:
|
|
203399
|
+
· 不登记 → 下面那行 `appendToChild` 恒回 `no-live-turn`,每一条 `--follow-up` 转达
|
|
203400
|
+
都落队列,专家要等本轮跑完才看见「手上这段作废」(v2 bug 0088);
|
|
203401
|
+
· 不接账本 → 子会话在 `chat_items` 里只有 storage 层镜像来的一问一答两行纯文字,
|
|
203402
|
+
右栏面板只能靠详情接口拿 run_id 去轨迹表**现折**,跑的过程中一片空白。 */
|
|
203296
203403
|
dispatchChat: async (request2) => {
|
|
203297
203404
|
const session = await dispatchChat(request2);
|
|
203298
|
-
|
|
203405
|
+
const itemStore = opts.resolveChatItems ? await opts.resolveChatItems(request2.companyId).catch(() => void 0) : opts.chatItems;
|
|
203406
|
+
const versionSeed = itemStore ? await itemStore.sessionVersionCursor(request2.chatSessionId).catch(() => 0) : 0;
|
|
203407
|
+
registerDelegatedChildTurn(liveChat, request2.chatSessionId, session, {
|
|
203408
|
+
...itemStore ? { items: itemStore } : {},
|
|
203409
|
+
...request2.chatTurnId ? { turnId: request2.chatTurnId } : {},
|
|
203410
|
+
...request2.assistantMessageId ? { assistantMessageId: request2.assistantMessageId } : {},
|
|
203411
|
+
versionSeed
|
|
203412
|
+
});
|
|
203299
203413
|
return session;
|
|
203300
203414
|
},
|
|
203301
203415
|
appendToChild: (childSessionId, text5, extra) => liveChat.append(childSessionId, text5, extra),
|
|
@@ -204070,6 +204184,7 @@ async function startOasisServer(opts) {
|
|
|
204070
204184
|
const rawBody = Buffer.concat(chunks).toString("utf8");
|
|
204071
204185
|
const companyCtx = opts.resolveCompanyContext ? await opts.resolveCompanyContext(actor, req.headers, url.pathname) : void 0;
|
|
204072
204186
|
const currentCompanyId = companyCtx?.kind === "ok" ? companyCtx.companyId : void 0;
|
|
204187
|
+
const connectorActorsService = async (companyId) => opts.actors ? (await opts.actors.resolveCtx(companyId ?? currentCompanyId)).service : void 0;
|
|
204073
204188
|
const wodrafts = opts.resolveWorkorderDrafts ? await opts.resolveWorkorderDrafts(currentCompanyId) : opts.workorderDrafts;
|
|
204074
204189
|
const wodraftPlannerIssues = (opts.resolveWorkorderDraftPlannerIssues && await opts.resolveWorkorderDraftPlannerIssues(currentCompanyId)) ?? opts.workorderDraftPlannerIssues ?? defaultDraftPlannerIssuesStore;
|
|
204075
204190
|
const engine = await resolveEngine(currentCompanyId);
|
|
@@ -206133,12 +206248,12 @@ ${composed}`;
|
|
|
206133
206248
|
const actorCtx = await opts.resolveActorContext(body2.actorId).catch(() => null);
|
|
206134
206249
|
if (actorCtx) {
|
|
206135
206250
|
const { mkdtempSync: mkdtempSync6, mkdirSync: mkdirSync25, writeFileSync: writeFileSync18 } = await import("node:fs");
|
|
206136
|
-
const { join:
|
|
206251
|
+
const { join: join40, dirname: dirname36 } = await import("node:path");
|
|
206137
206252
|
const { tmpdir: tmpdir12 } = await import("node:os");
|
|
206138
|
-
const dir = mkdtempSync6(
|
|
206253
|
+
const dir = mkdtempSync6(join40(tmpdir12(), "oasis-chat-"));
|
|
206139
206254
|
if (actorCtx.config?.prompt) {
|
|
206140
206255
|
for (const [rel, content3] of Object.entries(splitIdentityFiles2(actorCtx.config.prompt))) {
|
|
206141
|
-
const file =
|
|
206256
|
+
const file = join40(dir, rel);
|
|
206142
206257
|
mkdirSync25(dirname36(file), { recursive: true });
|
|
206143
206258
|
writeFileSync18(file, content3);
|
|
206144
206259
|
}
|
|
@@ -206150,12 +206265,12 @@ ${composed}`;
|
|
|
206150
206265
|
const s2 = byId.get(id);
|
|
206151
206266
|
return s2 ? `- **${s2.name}** (\`${s2.id}\`): ${s2.description}` : `- \`${id}\`\uFF08\u672A\u5728\u6280\u80FD\u5E93\u4E2D\uFF0C\u53EF\u80FD\u5DF2\u5378\u8F7D\uFF09`;
|
|
206152
206267
|
});
|
|
206153
|
-
writeFileSync18(
|
|
206268
|
+
writeFileSync18(join40(dir, "SKILLS.md"), ["# \u53EF\u7528\u6280\u80FD", "", "\u4EE5\u4E0B\u6280\u80FD\u5DF2\u4E3A\u4F60\u542F\u7528\uFF0C\u53EF\u5728\u672C\u6B21\u4F1A\u8BDD\u4E2D\u76F4\u63A5\u4F7F\u7528\uFF1A", "", ...lines].join("\n"));
|
|
206154
206269
|
}
|
|
206155
206270
|
if (opts.materializeSkills) {
|
|
206156
206271
|
const skillFiles = await opts.materializeSkills(body2.actorId, "claude").catch(() => ({}));
|
|
206157
206272
|
for (const [rel, content3] of Object.entries(skillFiles)) {
|
|
206158
|
-
const file =
|
|
206273
|
+
const file = join40(dir, rel);
|
|
206159
206274
|
mkdirSync25(dirname36(file), { recursive: true });
|
|
206160
206275
|
writeFileSync18(file, content3);
|
|
206161
206276
|
}
|
|
@@ -206169,7 +206284,7 @@ ${composed}`;
|
|
|
206169
206284
|
const modeNote = c.mode === "oauth" ? "OAuth \xB7 \u51ED\u8BC1\u7531\u5E73\u53F0\u7BA1\u7406\uFF0C\u901A\u8FC7\u5BF9\u5E94 CLI wrapper \u8C03\u7528" : "\u76F4\u63A5\u5199\u5165 \xB7 \u51ED\u8BC1\u5DF2\u6CE8\u5165\u73AF\u5883\u53D8\u91CF";
|
|
206170
206285
|
return `- **${c.name}** (\`${c.id}\`): ${statusNote} \xB7 ${modeNote}`;
|
|
206171
206286
|
});
|
|
206172
|
-
writeFileSync18(
|
|
206287
|
+
writeFileSync18(join40(dir, "CONNECTORS.md"), ["# \u53EF\u7528\u8FDE\u63A5\u5668", "", "\u4EE5\u4E0B\u8FDE\u63A5\u5668\u5DF2\u4E3A\u672C\u6B21\u4F1A\u8BDD\u914D\u7F6E\uFF0C\u51ED\u8BC1\u5DF2\u901A\u8FC7\u73AF\u5883\u53D8\u91CF\u6216 CLI wrapper \u6CE8\u5165\uFF0C\u65E0\u9700\u624B\u52A8\u914D\u7F6E\uFF1A", "", ...lines].join("\n"));
|
|
206173
206288
|
}
|
|
206174
206289
|
spawnCwd = dir;
|
|
206175
206290
|
}
|
|
@@ -206254,7 +206369,7 @@ ${composed}`;
|
|
|
206254
206369
|
}
|
|
206255
206370
|
if (req.method === "POST" && /^\/api\/connectors\/[^/]+\/disconnect$/.test(url.pathname)) {
|
|
206256
206371
|
const connId = decodeURIComponent(url.pathname.split("/")[3] ?? "");
|
|
206257
|
-
const svc =
|
|
206372
|
+
const svc = await connectorActorsService();
|
|
206258
206373
|
if (!svc) {
|
|
206259
206374
|
res.writeHead(501).end(JSON.stringify({ error: "actors service disabled" }));
|
|
206260
206375
|
return;
|
|
@@ -206280,7 +206395,7 @@ ${composed}`;
|
|
|
206280
206395
|
}
|
|
206281
206396
|
if (req.method === "DELETE" && /^\/api\/connectors\/[^/]+$/.test(url.pathname)) {
|
|
206282
206397
|
const connId = decodeURIComponent(url.pathname.slice("/api/connectors/".length));
|
|
206283
|
-
const svc =
|
|
206398
|
+
const svc = await connectorActorsService();
|
|
206284
206399
|
if (!svc) {
|
|
206285
206400
|
res.writeHead(501).end(JSON.stringify({ error: "actors service disabled" }));
|
|
206286
206401
|
return;
|
|
@@ -206299,6 +206414,31 @@ ${composed}`;
|
|
|
206299
206414
|
}
|
|
206300
206415
|
return;
|
|
206301
206416
|
}
|
|
206417
|
+
if (req.method === "DELETE" && /^\/api\/actors\/[^/]+\/connectors\/[^/]+$/.test(url.pathname)) {
|
|
206418
|
+
const parts = url.pathname.split("/");
|
|
206419
|
+
const actorId = decodeURIComponent(parts[3] ?? "");
|
|
206420
|
+
const connId = decodeURIComponent(parts[5] ?? "");
|
|
206421
|
+
const svc = await connectorActorsService();
|
|
206422
|
+
if (!svc) {
|
|
206423
|
+
res.writeHead(501).end(JSON.stringify({ error: "actors service disabled" }));
|
|
206424
|
+
return;
|
|
206425
|
+
}
|
|
206426
|
+
try {
|
|
206427
|
+
const { variablesDeleted } = await svc.deleteActorConnector(actorId, connId);
|
|
206428
|
+
let channelDisabled = false;
|
|
206429
|
+
if (connId === "feishu" && channelService) {
|
|
206430
|
+
const b2 = await channelService.getBindingForActor(actorId);
|
|
206431
|
+
if (b2 && b2.status !== "revoked") {
|
|
206432
|
+
await channelService.disable(actorId);
|
|
206433
|
+
channelDisabled = true;
|
|
206434
|
+
}
|
|
206435
|
+
}
|
|
206436
|
+
res.writeHead(200, { "content-type": "application/json" }).end(JSON.stringify({ ok: true, variablesDeleted, channelDisabled }));
|
|
206437
|
+
} catch (e) {
|
|
206438
|
+
res.writeHead(500).end(JSON.stringify({ error: String(e) }));
|
|
206439
|
+
}
|
|
206440
|
+
return;
|
|
206441
|
+
}
|
|
206302
206442
|
if (url.pathname === "/api/connectors/feishu/setup" && req.method === "GET") {
|
|
206303
206443
|
res.writeHead(200, { "content-type": "text/event-stream", "cache-control": "no-cache", connection: "keep-alive" });
|
|
206304
206444
|
const send = (obj2) => res.write(`data: ${JSON.stringify(obj2)}
|
|
@@ -206348,8 +206488,8 @@ ${composed}`;
|
|
|
206348
206488
|
if (!errStr && pollData["client_id"]) {
|
|
206349
206489
|
const clientId = String(pollData["client_id"]);
|
|
206350
206490
|
const clientSecret = pollData["client_secret"] ? String(pollData["client_secret"]) : void 0;
|
|
206351
|
-
|
|
206352
|
-
|
|
206491
|
+
const svc = clientSecret ? await connectorActorsService() : void 0;
|
|
206492
|
+
if (svc && clientSecret) {
|
|
206353
206493
|
const credScope = actorIdParam ? { scope: "personal", actorId: actorIdParam } : { scope: "global" };
|
|
206354
206494
|
await svc.putVariable({ key: "FEISHU_APP_ID", value: clientId, ...credScope, connectorId: "feishu", encrypted: true });
|
|
206355
206495
|
await svc.putVariable({ key: "FEISHU_APP_SECRET", value: clientSecret, ...credScope, connectorId: "feishu", encrypted: true });
|
|
@@ -206412,6 +206552,8 @@ ${composed}`;
|
|
|
206412
206552
|
});
|
|
206413
206553
|
githubAppPending.put(state, {
|
|
206414
206554
|
...actorId ? { actorId } : {},
|
|
206555
|
+
// 回调那一步没有鉴权头,解析不出公司——只能在这里记下来带过去。
|
|
206556
|
+
...currentCompanyId ? { companyId: currentCompanyId } : {},
|
|
206415
206557
|
employeeSlug: nameSlug,
|
|
206416
206558
|
createdAtMs: Date.now(),
|
|
206417
206559
|
// 存下这次选的归属——回调时要拿它跟 GitHub 返回的 owner 比对。
|
|
@@ -206432,7 +206574,7 @@ ${composed}`;
|
|
|
206432
206574
|
if (url.pathname === "/api/connectors/github/app/orgs" && req.method === "POST") {
|
|
206433
206575
|
try {
|
|
206434
206576
|
const { actorId } = JSON.parse(rawBody || "{}");
|
|
206435
|
-
const svc =
|
|
206577
|
+
const svc = await connectorActorsService();
|
|
206436
206578
|
if (!svc) throw new Error("actors service unavailable");
|
|
206437
206579
|
const token = await svc.revealResolvedVariable("GITHUB_TOKEN", actorId);
|
|
206438
206580
|
if (!token) {
|
|
@@ -206465,7 +206607,7 @@ ${composed}`;
|
|
|
206465
206607
|
}
|
|
206466
206608
|
if (url.pathname === "/api/connectors/github/app/available" && req.method === "POST") {
|
|
206467
206609
|
try {
|
|
206468
|
-
const svc =
|
|
206610
|
+
const svc = await connectorActorsService();
|
|
206469
206611
|
if (!svc) throw new Error("actors service unavailable");
|
|
206470
206612
|
const rows = await svc.listVariables();
|
|
206471
206613
|
const plain = (key, actorId) => rows.find((r) => r.key === key && r.actorId === actorId && !r.encrypted)?.maskedValue ?? "";
|
|
@@ -206528,7 +206670,7 @@ ${composed}`;
|
|
|
206528
206670
|
res.writeHead(400, { "content-type": "application/json" }).end(JSON.stringify({ error: "\u7F3A\u5C11 appId" }));
|
|
206529
206671
|
return;
|
|
206530
206672
|
}
|
|
206531
|
-
const svc =
|
|
206673
|
+
const svc = await connectorActorsService();
|
|
206532
206674
|
if (!svc) throw new Error("actors service unavailable");
|
|
206533
206675
|
const rows = await svc.listVariables();
|
|
206534
206676
|
const owners = rows.filter((r) => r.key === "GITHUB_APP_ID" && !r.encrypted && r.maskedValue === appId);
|
|
@@ -206575,7 +206717,7 @@ ${composed}`;
|
|
|
206575
206717
|
bad(400, "\u8FD9\u4E0D\u50CF\u4E00\u4E2A\u79C1\u94A5\u6587\u4EF6\u2014\u2014\u8BF7\u4E0A\u4F20 GitHub \u4E0B\u8F7D\u7684 .pem\uFF08\u5185\u5BB9\u4EE5 -----BEGIN ... PRIVATE KEY----- \u5F00\u5934\uFF09");
|
|
206576
206718
|
return;
|
|
206577
206719
|
}
|
|
206578
|
-
const svc =
|
|
206720
|
+
const svc = await connectorActorsService();
|
|
206579
206721
|
if (!svc) throw new Error("actors service unavailable");
|
|
206580
206722
|
let meta;
|
|
206581
206723
|
try {
|
|
@@ -206633,7 +206775,7 @@ ${composed}`;
|
|
|
206633
206775
|
if (url.pathname === "/api/connectors/github/app/permissions" && req.method === "POST") {
|
|
206634
206776
|
try {
|
|
206635
206777
|
const { actorId } = JSON.parse(rawBody || "{}");
|
|
206636
|
-
const svc =
|
|
206778
|
+
const svc = await connectorActorsService();
|
|
206637
206779
|
if (!svc) throw new Error("actors service unavailable");
|
|
206638
206780
|
const appId = await svc.revealResolvedVariable("GITHUB_APP_ID", actorId);
|
|
206639
206781
|
const privateKeyPem = await svc.revealResolvedVariable("GITHUB_APP_PRIVATE_KEY", actorId);
|
|
@@ -206687,7 +206829,7 @@ ${composed}`;
|
|
|
206687
206829
|
fail(problem.message);
|
|
206688
206830
|
return;
|
|
206689
206831
|
}
|
|
206690
|
-
const svc =
|
|
206832
|
+
const svc = await connectorActorsService(pending.companyId);
|
|
206691
206833
|
if (!svc) throw new Error("actors service unavailable");
|
|
206692
206834
|
const scope = pending.actorId ? { scope: "personal", actorId: pending.actorId } : { scope: "global" };
|
|
206693
206835
|
const put3 = (key, value2, encrypted) => svc.putVariable({ key, value: value2, ...scope, connectorId: "github", encrypted });
|
|
@@ -206756,7 +206898,7 @@ ${composed}`;
|
|
|
206756
206898
|
reply({ ok: false, error: "pending" });
|
|
206757
206899
|
return;
|
|
206758
206900
|
}
|
|
206759
|
-
const svc =
|
|
206901
|
+
const svc = await connectorActorsService();
|
|
206760
206902
|
if (!svc) throw new Error("actors service unavailable");
|
|
206761
206903
|
const scope = pending.actorId ? { scope: "personal", actorId: pending.actorId } : { scope: "global" };
|
|
206762
206904
|
const put3 = (key, value2, encrypted) => svc.putVariable({ key, value: value2, ...scope, connectorId: "github", encrypted });
|
|
@@ -206845,8 +206987,8 @@ ${composed}`;
|
|
|
206845
206987
|
throw new Error(String(data["error_description"] ?? errStr ?? "login failed"));
|
|
206846
206988
|
}
|
|
206847
206989
|
if (!data["access_token"]) throw new Error("no access_token in response");
|
|
206848
|
-
|
|
206849
|
-
|
|
206990
|
+
const svc = await connectorActorsService();
|
|
206991
|
+
if (svc) {
|
|
206850
206992
|
if (actorId) {
|
|
206851
206993
|
await svc.putVariable({ key: "FEISHU_APP_ID", value: appId, scope: "personal", actorId, connectorId: "feishu", encrypted: true });
|
|
206852
206994
|
} else {
|
|
@@ -206947,8 +207089,8 @@ ${composed}`;
|
|
|
206947
207089
|
});
|
|
206948
207090
|
const p2 = await pr.json();
|
|
206949
207091
|
if (p2.access_token) {
|
|
206950
|
-
|
|
206951
|
-
|
|
207092
|
+
const svc = await connectorActorsService();
|
|
207093
|
+
if (svc) {
|
|
206952
207094
|
const connId = "github";
|
|
206953
207095
|
await svc.upsertConnector({ id: connId, name: "GitHub", mode: "oauth", status: "connected", account: "github" });
|
|
206954
207096
|
for (const [k2, v2] of [["GIT_AUTHOR_NAME", actorNameParam], ["GIT_AUTHOR_EMAIL", ""], ["GIT_COMMITTER_NAME", actorNameParam], ["GIT_COMMITTER_EMAIL", ""], ["EMAIL", ""]])
|
|
@@ -218233,9 +218375,32 @@ var init_service5 = __esm({
|
|
|
218233
218375
|
const a = await this.opts.store.getActor(id);
|
|
218234
218376
|
if (!a) throw new Error(`actor not found: ${id}`);
|
|
218235
218377
|
await this.upsertActor({ ...a, status: "disabled" }, by);
|
|
218378
|
+
await this.dropRuntimeBindingOfDeletedAgent(a.id, a.kind, by);
|
|
218236
218379
|
if (a.status === "active") await this.opts.onActorDisabled?.(id, by);
|
|
218237
218380
|
return a;
|
|
218238
218381
|
}
|
|
218382
|
+
/**
|
|
218383
|
+
* 删掉 Agent 时把它跟 runtime 的绑定一起撤掉。
|
|
218384
|
+
*
|
|
218385
|
+
* 为什么必须做(2026-09-09 线上实测):删除只写 `status='disabled'`,`actor_bindings` 那行
|
|
218386
|
+
* 原样留着且仍是 `active`。而 `GET /api/actors` 会把已删 Agent 过滤掉、`GET /api/bindings` 不会——
|
|
218387
|
+
* 运行时管理页拿两份数据对着算「运行 Agent」,于是已删的 Agent 继续占着一格,
|
|
218388
|
+
* 名字还查不回来,页面上直接露出 `asst-xxx-cbf34f` 这种裸 id。didi 组织实测:yx_claude 上
|
|
218389
|
+
* 12 条 active 绑定里 7 条的 Agent 早被删了(其中 5 条是助理)。
|
|
218390
|
+
*
|
|
218391
|
+
* 顺带修好另一处:`pickAssistantRuntime` 用「(nodeId,kind) 上的 active 绑定数」当负载做均衡,
|
|
218392
|
+
* 已删 Agent 的残留绑定会把负载算高,把新助理往别的机器上赶。
|
|
218393
|
+
*
|
|
218394
|
+
* 只对 agent 生效:真人被移出组织是「离岗」不是删除,PRD 明确其助理照常在岗、账号回来还能接上。
|
|
218395
|
+
* 幂等:removeBinding 对没有绑定的 actor 是 no-op,所以重复删也安全(存量脏数据也能靠再删一次修好)。
|
|
218396
|
+
*/
|
|
218397
|
+
async dropRuntimeBindingOfDeletedAgent(id, kind, by) {
|
|
218398
|
+
if (kind !== "agent") return;
|
|
218399
|
+
const existing = await this.opts.store.getBinding(id);
|
|
218400
|
+
if (!existing) return;
|
|
218401
|
+
await this.opts.store.removeBinding(id);
|
|
218402
|
+
await this.audit({ kind: "binding_change", actorId: id, by, at: this.now(), detail: { removed: true, reason: "agent_deleted" } });
|
|
218403
|
+
}
|
|
218239
218404
|
/**
|
|
218240
218405
|
* 原子「若当前 active 则停用」(QA R10):与 disableActor 的区别在于——
|
|
218241
218406
|
* 只在 actor 当前**确为 active** 时才写,返回 `ok:true + before + seq`;已被并发者/别的路径先 disable
|
|
@@ -218259,6 +218424,7 @@ var init_service5 = __esm({
|
|
|
218259
218424
|
if (!res.ok) return res;
|
|
218260
218425
|
this.opts.onRolesChanged?.(id, []);
|
|
218261
218426
|
await this.audit({ kind: "actor_upsert", actorId: id, by, at: this.now(), detail: { status: "disabled", roles: res.before.roles } });
|
|
218427
|
+
await this.dropRuntimeBindingOfDeletedAgent(id, res.before.kind, by);
|
|
218262
218428
|
await this.opts.onActorDisabled?.(id, by);
|
|
218263
218429
|
return { ok: true, before: res.before, seq };
|
|
218264
218430
|
}
|
|
@@ -218859,39 +219025,42 @@ ${input.description}
|
|
|
218859
219025
|
const c = cfg ?? await this.opts.store.latestConfig(actorId);
|
|
218860
219026
|
return new Set(c?.connectorIds ?? []);
|
|
218861
219027
|
}
|
|
218862
|
-
/**
|
|
218863
|
-
|
|
218864
|
-
|
|
219028
|
+
/**
|
|
219029
|
+
* 设置某员工×连接器的连接记录(启用/停用)。无则创建,有则翻转 enabled。
|
|
219030
|
+
*
|
|
219031
|
+
* `configuredBy` 只在**授权流程走完**时传(「谁为这名员工把它接上的」)。普通开关不传,
|
|
219032
|
+
* 此时把已有值原样带回——**只增不抹**:翻一次开关不该把授权时记下的人擦掉。
|
|
219033
|
+
* pg 侧另有 `COALESCE` 兜同一条,两层都做是因为内存 store 是整行替换。
|
|
219034
|
+
*/
|
|
219035
|
+
async setActorConnectorEnabled(actorId, connectorId, enabled, configuredBy) {
|
|
219036
|
+
const keep = configuredBy ?? (await this.opts.store.listActorConnectorConnections(actorId)).find((c) => c.connectorId === connectorId)?.configuredBy;
|
|
219037
|
+
const conn = {
|
|
219038
|
+
actorId,
|
|
219039
|
+
connectorId,
|
|
219040
|
+
enabled,
|
|
219041
|
+
updatedAt: this.now(),
|
|
219042
|
+
...keep ? { configuredBy: keep } : {}
|
|
219043
|
+
};
|
|
218865
219044
|
await this.opts.store.upsertActorConnectorConnection(conn);
|
|
218866
219045
|
return conn;
|
|
218867
219046
|
}
|
|
218868
|
-
listActorConnectorConnections(actorId) {
|
|
218869
|
-
return this.opts.store.listActorConnectorConnections(actorId);
|
|
218870
|
-
}
|
|
218871
219047
|
/**
|
|
218872
|
-
*
|
|
219048
|
+
* 删除**一条**「员工 × 连接器」连接:连接记录 + 该员工这个连接器的**个人凭据变量**。
|
|
218873
219049
|
*
|
|
218874
|
-
*
|
|
218875
|
-
*
|
|
218876
|
-
* 不删的话,「移除」之后 `actorConnected` 里还有它,卡片照样在,读作「删不掉」;
|
|
218877
|
-
* ② 「员工×连接器」的连接记录——不删的话 `effective` 里还有它(enabled=false),
|
|
218878
|
-
* 卡片变成一张「已停用」的僵尸卡,而人要的是它消失。
|
|
219050
|
+
* 与开关的区别(发起人 2026-09-09 定的,两颗按钮并存):开关是「暂时不用」,凭据留着、
|
|
219051
|
+
* 打开就能接着用;删除是「不要了」,凭据清掉、再要用得重走一遍授权。
|
|
218879
219052
|
*
|
|
218880
|
-
*
|
|
218881
|
-
*
|
|
218882
|
-
* 于是:组织已连接时,移除个人连接后这名员工会**回落到组织默认**——卡片仍在,但身份那一行
|
|
218883
|
-
* 变回组织账号。这是对的,不是没删干净。
|
|
218884
|
-
*
|
|
218885
|
-
* 幂等:没有个人凭据、没有记录时照样返回成功(`variablesDeleted: 0`)——重复点、并发点都不该报错。
|
|
219053
|
+
* **只动这名员工自己的东西**:组织级变量(scope=global)一个不碰——那是别人也在用的。
|
|
219054
|
+
* 飞书对话通道的下线不在这里做(本服务够不到 channelService),由路由层在删完凭据后补一刀。
|
|
218886
219055
|
*/
|
|
218887
|
-
async
|
|
218888
|
-
const
|
|
218889
|
-
const
|
|
218890
|
-
(v2) => v2.scope === "personal" && v2.actorId === actorId && v2.connectorId === connectorId
|
|
218891
|
-
);
|
|
218892
|
-
for (const v2 of mine) await this.opts.store.deleteVariable(v2.key, actorId);
|
|
219056
|
+
async deleteActorConnector(actorId, connectorId) {
|
|
219057
|
+
const personal = (await this.opts.store.listVariables(actorId)).filter((v2) => v2.scope === "personal" && v2.actorId === actorId && v2.connectorId === connectorId);
|
|
219058
|
+
for (const v2 of personal) await this.deleteVariable(v2.key, actorId);
|
|
218893
219059
|
await this.opts.store.deleteActorConnectorConnection(actorId, connectorId);
|
|
218894
|
-
return {
|
|
219060
|
+
return { variablesDeleted: personal.length };
|
|
219061
|
+
}
|
|
219062
|
+
listActorConnectorConnections(actorId) {
|
|
219063
|
+
return this.opts.store.listActorConnectorConnections(actorId);
|
|
218895
219064
|
}
|
|
218896
219065
|
/**
|
|
218897
219066
|
* 员工连接器面板所需状态:连接记录 + 组织级已连接集合 + 该员工已授权(有个人 connector 变量)集合。
|
|
@@ -220860,14 +221029,9 @@ function actorsDomain(opts) {
|
|
|
220860
221029
|
const { service } = await resolveCtx(req.auth.companyId);
|
|
220861
221030
|
const b2 = req.body;
|
|
220862
221031
|
if (typeof b2?.enabled !== "boolean") throw new ApiError(400, "BAD_REQUEST", "\u7F3A\u5C11 enabled (boolean)");
|
|
220863
|
-
const conn = await service.setActorConnectorEnabled(req.params.id, req.params.connectorId,
|
|
221032
|
+
const conn = b2.enabled ? await service.setActorConnectorEnabled(req.params.id, req.params.connectorId, true, req.auth.actor) : await service.setActorConnectorEnabled(req.params.id, req.params.connectorId, false);
|
|
220864
221033
|
return { status: 200, body: conn };
|
|
220865
221034
|
});
|
|
220866
|
-
router.delete("/api/actors/:id/connectors/:connectorId", async (req) => {
|
|
220867
|
-
const { service } = await resolveCtx(req.auth.companyId);
|
|
220868
|
-
const r = await service.removeActorConnector(req.params.id, req.params.connectorId);
|
|
220869
|
-
return { status: 200, body: r };
|
|
220870
|
-
});
|
|
220871
221035
|
const requireVariableManager = (req) => {
|
|
220872
221036
|
if (!isHumanActor(req.auth.actor)) {
|
|
220873
221037
|
throw new ApiError(
|
|
@@ -226090,7 +226254,13 @@ function reviewSummary(snap, reviews, events) {
|
|
|
226090
226254
|
const name = node2?.title ?? first.nodeId;
|
|
226091
226255
|
const latest = latestActivityReviews(reviews, events);
|
|
226092
226256
|
const requirements = snap.requirements.filter((r) => r.nodeId === first.nodeId && r.reviewerActorId === first.reviewerActorId);
|
|
226093
|
-
|
|
226257
|
+
for (const requirement of requirements) {
|
|
226258
|
+
const current = reviews.find((r) => r.id === requirement.latestReviewId);
|
|
226259
|
+
if (!current) continue;
|
|
226260
|
+
const index2 = latest.findIndex((r) => r.reviewGroup === requirement.reviewGroup);
|
|
226261
|
+
if (index2 >= 0) latest[index2] = current;
|
|
226262
|
+
}
|
|
226263
|
+
const judgement = judgeWork({ requirements: requirements.length ? requirements : latest, reviews: latest });
|
|
226094
226264
|
const pending = latest.filter((r) => !r.cancelledAt && !r.verdict && reviewState(r) === "running");
|
|
226095
226265
|
if (work?.acceptanceState === "accepted" || work?.acceptedAt || work?.acceptanceState !== "rejected" && judgement === "passed") {
|
|
226096
226266
|
return { phase: "done", status: `\u300A${name}\u300B\u5BA1\u6838\u901A\u8FC7\u3002`, latest, pending: [] };
|
|
@@ -226126,6 +226296,66 @@ var init_review_activity = __esm({
|
|
|
226126
226296
|
}
|
|
226127
226297
|
});
|
|
226128
226298
|
|
|
226299
|
+
// ../server/src/domains/collab/review-requirement-activity.ts
|
|
226300
|
+
function reviewRequirementActivity(snap, events, ref2) {
|
|
226301
|
+
const previous3 = /* @__PURE__ */ new Map();
|
|
226302
|
+
const titles = new Map(snap.nodes.map((n) => [n.id, n.title]));
|
|
226303
|
+
const cards = [];
|
|
226304
|
+
const label = (r) => `${ref2(r.reviewerActorId).name || "\u672A\u547D\u540D\u5BA1\u6838\u4EBA"}${r.source === "closure" ? "\uFF08\u7ED3\u6848\u5BA1\u6838\uFF09" : ""}`;
|
|
226305
|
+
const names = (rows) => [...new Set(rows.map(label))].join("\u3001") || "\u65E0";
|
|
226306
|
+
for (const rec of [...events].sort((a, b2) => a.seq - b2.seq)) {
|
|
226307
|
+
if (rec.status === "pending" || rec.status === "failed") continue;
|
|
226308
|
+
const e = rec.event;
|
|
226309
|
+
if (e.kind === "plan.changed") {
|
|
226310
|
+
for (const node2 of e.addNodes ?? []) previous3.set(node2.id, node2.reviewers ?? []);
|
|
226311
|
+
for (const id of e.removeNodes ?? []) previous3.delete(id);
|
|
226312
|
+
continue;
|
|
226313
|
+
}
|
|
226314
|
+
if (e.kind === "plan.add_node") {
|
|
226315
|
+
previous3.set(e.nodeId, e.reviewers ?? []);
|
|
226316
|
+
continue;
|
|
226317
|
+
}
|
|
226318
|
+
if (e.kind !== "plan.update_review_requirements") continue;
|
|
226319
|
+
const before = previous3.get(e.nodeId);
|
|
226320
|
+
const after = e.reviewers;
|
|
226321
|
+
const beforeKeys = new Set(before?.map(requirementKey));
|
|
226322
|
+
const afterKeys = new Set(after.map(requirementKey));
|
|
226323
|
+
const added = before ? after.filter((r) => !beforeKeys.has(requirementKey(r))) : [];
|
|
226324
|
+
const removed = before?.filter((r) => !afterKeys.has(requirementKey(r))) ?? [];
|
|
226325
|
+
const nodeTitle = titles.get(e.nodeId) || "\u5DF2\u79FB\u9664\u7684\u8282\u70B9";
|
|
226326
|
+
const system = rec.actorId.startsWith("actor:system:");
|
|
226327
|
+
const closureAdded = system && added.length > 0 && !removed.length && added.every((r) => r.source === "closure");
|
|
226328
|
+
cards.push({
|
|
226329
|
+
id: `wo:${rec.seq}`,
|
|
226330
|
+
seq: rec.seq,
|
|
226331
|
+
at: rec.createdAt,
|
|
226332
|
+
updatedAt: rec.createdAt,
|
|
226333
|
+
nodeId: e.nodeId,
|
|
226334
|
+
nodeTitle,
|
|
226335
|
+
executor: system ? { ...ref2(rec.actorId), name: "\u7CFB\u7EDF" } : ref2(rec.actorId),
|
|
226336
|
+
...rec.handActorId ? { handActor: ref2(rec.handActorId) } : {},
|
|
226337
|
+
phase: "done",
|
|
226338
|
+
status: closureAdded ? `\u4E3A\u300A${nodeTitle}\u300B\u8865\u5145\u4E86\u7ED3\u6848\u5BA1\u6838\u8981\u6C42\u3002` : `\u66F4\u65B0\u4E86\u300A${nodeTitle}\u300B\u7684\u5BA1\u6838\u5217\u8868\u3002`,
|
|
226339
|
+
detail: [
|
|
226340
|
+
...added.length ? [`\u65B0\u589E\uFF1A${names(added)}`] : [],
|
|
226341
|
+
...removed.length ? [`\u79FB\u9664\uFF1A${names(removed)}`] : [],
|
|
226342
|
+
`\u66F4\u65B0\u540E\uFF1A${names(after)}`
|
|
226343
|
+
].join("\n"),
|
|
226344
|
+
artifacts: [],
|
|
226345
|
+
actions: []
|
|
226346
|
+
});
|
|
226347
|
+
previous3.set(e.nodeId, after);
|
|
226348
|
+
}
|
|
226349
|
+
return cards;
|
|
226350
|
+
}
|
|
226351
|
+
var requirementKey;
|
|
226352
|
+
var init_review_requirement_activity = __esm({
|
|
226353
|
+
"../server/src/domains/collab/review-requirement-activity.ts"() {
|
|
226354
|
+
"use strict";
|
|
226355
|
+
requirementKey = (r) => JSON.stringify([r.reviewerActorId, r.reviewGroup, r.source]);
|
|
226356
|
+
}
|
|
226357
|
+
});
|
|
226358
|
+
|
|
226129
226359
|
// ../server/src/domains/collab/workorder-manager.ts
|
|
226130
226360
|
function resolveWorkorderManager(snap) {
|
|
226131
226361
|
const nodes = snap.nodes;
|
|
@@ -226806,6 +227036,8 @@ function buildWorkorderActivity(input) {
|
|
|
226806
227036
|
.../* @__PURE__ */ ((r) => r ? { runId: r, traceAvailable: true } : {})(traced ? runIdOfCard(d) : void 0)
|
|
226807
227037
|
};
|
|
226808
227038
|
});
|
|
227039
|
+
cards.push(...reviewRequirementActivity(snap, events, ref2));
|
|
227040
|
+
cards.sort((a, b2) => a.updatedAt.localeCompare(b2.updatedAt) || a.seq - b2.seq || a.id.localeCompare(b2.id));
|
|
226809
227041
|
return { workorderId, cards, truncated };
|
|
226810
227042
|
}
|
|
226811
227043
|
var ACTIVITY_EVENT_KINDS, ACTIVITY_EVENT_LIMIT, ACTIVITY_COPY, REWORK_ANNOTATION_PREFIX, ENGINE_RETRY_EXHAUSTED, BUTTON;
|
|
@@ -226815,9 +227047,12 @@ var init_activity2 = __esm({
|
|
|
226815
227047
|
init_src();
|
|
226816
227048
|
init_src4();
|
|
226817
227049
|
init_review_activity();
|
|
227050
|
+
init_review_requirement_activity();
|
|
226818
227051
|
init_workorder_manager();
|
|
226819
227052
|
ACTIVITY_EVENT_KINDS = [
|
|
226820
227053
|
"plan.changed",
|
|
227054
|
+
"plan.add_node",
|
|
227055
|
+
"plan.update_review_requirements",
|
|
226821
227056
|
"plan.update_spec",
|
|
226822
227057
|
"plan.node_retry",
|
|
226823
227058
|
"work.create",
|
|
@@ -228045,9 +228280,18 @@ function toAuditEntry(op) {
|
|
|
228045
228280
|
summary: `${KIND_LABEL2[op.kind] ?? op.kind} \xB7 ${op.artifactId}`
|
|
228046
228281
|
};
|
|
228047
228282
|
}
|
|
228283
|
+
function nodeIdOfWorkId(workId) {
|
|
228284
|
+
if (!workId || !workId.startsWith("wk:")) return null;
|
|
228285
|
+
const body2 = workId.slice(3);
|
|
228286
|
+
const cut = body2.lastIndexOf(":");
|
|
228287
|
+
if (cut <= 0) return null;
|
|
228288
|
+
if (!/^\d+$/.test(body2.slice(cut + 1))) return null;
|
|
228289
|
+
const nodeId = body2.slice(0, cut);
|
|
228290
|
+
return nodeId.startsWith("artifact:") ? nodeId : null;
|
|
228291
|
+
}
|
|
228048
228292
|
function eventToAuditEntry(rec) {
|
|
228049
228293
|
const ev = rec.event;
|
|
228050
|
-
const artifactId = rec.nodeId ?? rec.workId ?? "";
|
|
228294
|
+
const artifactId = rec.nodeId ?? nodeIdOfWorkId(rec.workId) ?? "";
|
|
228051
228295
|
return {
|
|
228052
228296
|
seq: rec.seq,
|
|
228053
228297
|
at: rec.createdAt,
|
|
@@ -228057,7 +228301,11 @@ function eventToAuditEntry(rec) {
|
|
|
228057
228301
|
summary: `${KIND_LABEL2[ev.kind] ?? ev.kind}${artifactId ? ` \xB7 ${artifactId}` : ""}`
|
|
228058
228302
|
};
|
|
228059
228303
|
}
|
|
228060
|
-
function enrichAudit(entry, model, titleOf) {
|
|
228304
|
+
function enrichAudit(entry, model, titleOf, workorderId) {
|
|
228305
|
+
if (!entry.artifactId) {
|
|
228306
|
+
const workspaceTitle2 = workorderId ? titleOf.get(workorderId) : void 0;
|
|
228307
|
+
return { ...entry, ...workspaceTitle2 ? { workspaceTitle: workspaceTitle2 } : {}, visibility: "ok" };
|
|
228308
|
+
}
|
|
228061
228309
|
const a = model.artifacts.get(entry.artifactId);
|
|
228062
228310
|
if (!a) return { ...entry, visibility: "deleted" };
|
|
228063
228311
|
const workspaceTitle = titleOf.get(a.workspace);
|
|
@@ -228075,8 +228323,8 @@ async function buildAudit(source, q2 = {}, model) {
|
|
|
228075
228323
|
const items = [];
|
|
228076
228324
|
let lastCursor = null;
|
|
228077
228325
|
let truncated = false;
|
|
228078
|
-
const push2 = (entry, cursor) => {
|
|
228079
|
-
items.push(model && titleOf ? enrichAudit(entry, model, titleOf) : entry);
|
|
228326
|
+
const push2 = (entry, cursor, workorderId) => {
|
|
228327
|
+
items.push(model && titleOf ? enrichAudit(entry, model, titleOf, workorderId) : entry);
|
|
228080
228328
|
lastCursor = cursor;
|
|
228081
228329
|
};
|
|
228082
228330
|
const match = (actor, kind, at) => {
|
|
@@ -228087,30 +228335,33 @@ async function buildAudit(source, q2 = {}, model) {
|
|
|
228087
228335
|
return true;
|
|
228088
228336
|
};
|
|
228089
228337
|
if (q2.latest) {
|
|
228090
|
-
|
|
228338
|
+
const collected = [];
|
|
228091
228339
|
if (source.engineStore) {
|
|
228092
228340
|
const records = await source.engineStore.transaction((tx) => tx.listEvents(void 0, 0));
|
|
228093
228341
|
for (const rec of records) {
|
|
228094
228342
|
const ev = rec.event;
|
|
228095
228343
|
if (!match(rec.actorId, ev.kind, rec.createdAt)) continue;
|
|
228096
|
-
collected.push(eventToAuditEntry(rec));
|
|
228344
|
+
collected.push({ entry: eventToAuditEntry(rec), workorderId: rec.workorderId });
|
|
228097
228345
|
}
|
|
228098
228346
|
} else if (source.oplog) {
|
|
228099
228347
|
const src = source.oplog.readFilteredOps ? source.oplog.readFilteredOps({ ...q2.actor ? { actor: q2.actor } : {}, ...q2.kind ? { kind: q2.kind } : {} }, void 0, { latest: true }) : source.oplog.readAll();
|
|
228100
228348
|
for await (const { op } of src) {
|
|
228101
228349
|
if (!match(op.actor, op.kind, op.timestamp)) continue;
|
|
228102
|
-
collected.push(toAuditEntry(op));
|
|
228350
|
+
collected.push({ entry: toAuditEntry(op) });
|
|
228103
228351
|
}
|
|
228104
228352
|
}
|
|
228105
228353
|
const tail = collected.slice(-limit).reverse();
|
|
228106
|
-
return {
|
|
228354
|
+
return {
|
|
228355
|
+
items: model && titleOf ? tail.map(({ entry, workorderId }) => enrichAudit(entry, model, titleOf, workorderId)) : tail.map(({ entry }) => entry),
|
|
228356
|
+
cursor: null
|
|
228357
|
+
};
|
|
228107
228358
|
}
|
|
228108
228359
|
if (source.engineStore) {
|
|
228109
228360
|
const records = await source.engineStore.transaction((tx) => tx.listEvents(void 0, fromSeq));
|
|
228110
228361
|
for (const rec of records) {
|
|
228111
228362
|
const ev = rec.event;
|
|
228112
228363
|
if (!match(rec.actorId, ev.kind, rec.createdAt)) continue;
|
|
228113
|
-
push2(eventToAuditEntry(rec), String(rec.seq));
|
|
228364
|
+
push2(eventToAuditEntry(rec), String(rec.seq), rec.workorderId);
|
|
228114
228365
|
if (items.length >= limit) {
|
|
228115
228366
|
truncated = true;
|
|
228116
228367
|
break;
|
|
@@ -228156,6 +228407,30 @@ var init_audit = __esm({
|
|
|
228156
228407
|
"workorder.paused": "\u6682\u505C\u6D3E\u53D1",
|
|
228157
228408
|
"workorder.resumed": "\u6062\u590D\u6D3E\u53D1",
|
|
228158
228409
|
"workorder.sealed": "\u5C01\u5B58",
|
|
228410
|
+
// 其余新引擎事件 kind——缺标签时 summary 直接露英文 kind(生产实测:`plan.changed` 是量最大的
|
|
228411
|
+
// 一类审计条目,界面上就写着「plan.changed」)。这张表按 EngineEvent 的 kind 全集补齐。
|
|
228412
|
+
"plan.changed": "\u6539\u4EFB\u52A1\u56FE",
|
|
228413
|
+
"plan.add_edge": "\u63A5\u4F9D\u8D56",
|
|
228414
|
+
"plan.delete_edge": "\u65AD\u4F9D\u8D56",
|
|
228415
|
+
"plan.update_review_requirements": "\u6539\u8BC4\u5BA1\u8981\u6C42",
|
|
228416
|
+
"plan.update_fields": "\u6539\u5B57\u6BB5",
|
|
228417
|
+
"work.started": "\u5F00\u5DE5",
|
|
228418
|
+
"work.redispatch": "\u91CD\u6D3E",
|
|
228419
|
+
"work.snapshot_recorded": "\u5B58\u5FEB\u7167",
|
|
228420
|
+
"work.handoff_recorded": "\u8BB0\u4EA4\u63A5",
|
|
228421
|
+
"work.reject": "\u6253\u56DE",
|
|
228422
|
+
"work.content_edited": "\u6539\u5185\u5BB9",
|
|
228423
|
+
"work.conclude": "\u5B9A\u7A3F",
|
|
228424
|
+
"node.latest_proposed.rebased": "\u6362\u57FA\u7EBF",
|
|
228425
|
+
"review.started": "\u5F00\u59CB\u8BC4\u5BA1",
|
|
228426
|
+
"review.kill": "\u64A4\u8BC4\u5BA1",
|
|
228427
|
+
"review.timeout": "\u8BC4\u5BA1\u8D85\u65F6",
|
|
228428
|
+
"issue.resolution_proposed": "\u63D0\u89E3\u51B3\u65B9\u6848",
|
|
228429
|
+
"issue.resolution_rejected": "\u9A73\u56DE\u89E3\u51B3\u65B9\u6848",
|
|
228430
|
+
"workorder.created": "\u5EFA\u5DE5\u5355",
|
|
228431
|
+
"workorder.root_set": "\u5B9A\u6839\u8282\u70B9",
|
|
228432
|
+
"workorder.meta_changed": "\u6539\u5DE5\u5355\u4FE1\u606F",
|
|
228433
|
+
"workorder.ping": "\u5524\u9192",
|
|
228159
228434
|
// 旧 op kind(oplog 回退路径)
|
|
228160
228435
|
spawn_artifact: "\u5EFA\u4EA7\u7269",
|
|
228161
228436
|
propose_revision: "\u63D0\u4FEE\u8BA2",
|
|
@@ -237750,6 +238025,11 @@ var init_daemon_adapter = __esm({
|
|
|
237750
238025
|
clearTimeout(entry.ackTimer);
|
|
237751
238026
|
entry.ackTimer = void 0;
|
|
237752
238027
|
}
|
|
238028
|
+
const reapTimer = this.sessionReapTimers.get(dispatchId);
|
|
238029
|
+
if (reapTimer) {
|
|
238030
|
+
clearTimeout(reapTimer);
|
|
238031
|
+
this.sessionReapTimers.delete(dispatchId);
|
|
238032
|
+
}
|
|
237753
238033
|
entry.exited = info;
|
|
237754
238034
|
for (const w2 of entry.appendWaiters.splice(0)) {
|
|
237755
238035
|
clearTimeout(w2.timer);
|
|
@@ -237845,6 +238125,10 @@ var init_daemon_adapter = __esm({
|
|
|
237845
238125
|
for (const [dispatchId, entry] of this.pending) {
|
|
237846
238126
|
if (entry.nodeId !== daemonId || entry.exited || present.has(dispatchId)) continue;
|
|
237847
238127
|
if (this.hub.hasSession?.(dispatchId)) continue;
|
|
238128
|
+
if (this.sessionReapTimers.has(dispatchId)) {
|
|
238129
|
+
this.log(`[dispatch-delivery] ${dispatchId}\uFF1A\u8282\u70B9 ${daemonId} \u7A7A\u5E93\u5B58\u4E0D\u8986\u76D6\u72EC\u7ACB\u4F1A\u8BDD\u65AD\u7EBF\u5BBD\u9650\uFF0C\u7ED3\u8BBA=unknown\uFF08\u4F9D\u636E\uFF1A\u6570\u636E\u9762\u66FE\u8FDE\u63A5\uFF0C\u7B49\u5F85\u91CD\u8FDE\u6216\u539F ${this.sessionReapGraceMs}ms \u671F\u9650\uFF09`);
|
|
238130
|
+
continue;
|
|
238131
|
+
}
|
|
237848
238132
|
absent.push(dispatchId);
|
|
237849
238133
|
}
|
|
237850
238134
|
for (const dispatchId of absent) {
|
|
@@ -237877,8 +238161,7 @@ var init_daemon_adapter = __esm({
|
|
|
237877
238161
|
*/
|
|
237878
238162
|
onSessionDown(dispatchId) {
|
|
237879
238163
|
if (this.sessionReapTimers.has(dispatchId)) return;
|
|
237880
|
-
|
|
237881
|
-
if (!entry || entry.exited) return;
|
|
238164
|
+
if (this.settledDispatchIds.has(dispatchId)) return;
|
|
237882
238165
|
const timer = setTimeout(() => {
|
|
237883
238166
|
this.sessionReapTimers.delete(dispatchId);
|
|
237884
238167
|
const e = this.pending.get(dispatchId);
|
|
@@ -239214,6 +239497,7 @@ ${ctx.nodeFault}
|
|
|
239214
239497
|
env: { ...prov?.env ?? {}, OASIS_STAGE: "1", ...workspace ? { OASIS_WORKSPACE: workspace } : {} },
|
|
239215
239498
|
...prov?.wrapperPaths && prov.wrapperPaths.length > 0 ? { wrapperPaths: prov.wrapperPaths } : {},
|
|
239216
239499
|
...prov?.requiredTools && prov.requiredTools.length > 0 ? { requiredTools: prov.requiredTools } : {},
|
|
239500
|
+
...prov?.requiredToolVersions && Object.keys(prov.requiredToolVersions).length > 0 ? { requiredToolVersions: prov.requiredToolVersions } : {},
|
|
239217
239501
|
...prov?.connectorCreds && prov.connectorCreds.length > 0 ? { connectorCreds: prov.connectorCreds } : {}
|
|
239218
239502
|
};
|
|
239219
239503
|
this.deps.log?.(`[coordinator] ${logMsg}`);
|
|
@@ -239774,6 +240058,7 @@ var init_postgres_registry = __esm({
|
|
|
239774
240058
|
updated_at timestamptz NOT NULL,
|
|
239775
240059
|
PRIMARY KEY (actor_id, connector_id)
|
|
239776
240060
|
)`);
|
|
240061
|
+
await pool.query(`ALTER TABLE "${s2}".actor_connector_connections ADD COLUMN IF NOT EXISTS configured_by text`);
|
|
239777
240062
|
await pool.query(`
|
|
239778
240063
|
CREATE TABLE IF NOT EXISTS "${s2}".skill_catalog (
|
|
239779
240064
|
id text PRIMARY KEY, -- slug
|
|
@@ -240161,10 +240446,11 @@ var init_postgres_registry = __esm({
|
|
|
240161
240446
|
}
|
|
240162
240447
|
async upsertActorConnectorConnection(c) {
|
|
240163
240448
|
await this.pool.query(
|
|
240164
|
-
`INSERT INTO ${this.s}.actor_connector_connections (actor_id, connector_id, enabled, updated_at)
|
|
240165
|
-
VALUES ($1, $2, $3, $4)
|
|
240166
|
-
ON CONFLICT (actor_id, connector_id) DO UPDATE SET enabled = $3, updated_at = $4
|
|
240167
|
-
|
|
240449
|
+
`INSERT INTO ${this.s}.actor_connector_connections (actor_id, connector_id, enabled, updated_at, configured_by)
|
|
240450
|
+
VALUES ($1, $2, $3, $4, $5)
|
|
240451
|
+
ON CONFLICT (actor_id, connector_id) DO UPDATE SET enabled = $3, updated_at = $4,
|
|
240452
|
+
configured_by = COALESCE($5, ${this.s}.actor_connector_connections.configured_by)`,
|
|
240453
|
+
[c.actorId, c.connectorId, c.enabled, c.updatedAt, c.configuredBy ?? null]
|
|
240168
240454
|
);
|
|
240169
240455
|
}
|
|
240170
240456
|
async listActorConnectorConnections(actorId) {
|
|
@@ -240176,7 +240462,8 @@ var init_postgres_registry = __esm({
|
|
|
240176
240462
|
actorId: row.actor_id,
|
|
240177
240463
|
connectorId: row.connector_id,
|
|
240178
240464
|
enabled: row.enabled,
|
|
240179
|
-
updatedAt: new Date(row.updated_at).toISOString()
|
|
240465
|
+
updatedAt: new Date(row.updated_at).toISOString(),
|
|
240466
|
+
...row.configured_by ? { configuredBy: row.configured_by } : {}
|
|
240180
240467
|
}));
|
|
240181
240468
|
}
|
|
240182
240469
|
async listAllActorConnectorConnections() {
|
|
@@ -240187,7 +240474,8 @@ var init_postgres_registry = __esm({
|
|
|
240187
240474
|
actorId: row.actor_id,
|
|
240188
240475
|
connectorId: row.connector_id,
|
|
240189
240476
|
enabled: row.enabled,
|
|
240190
|
-
updatedAt: new Date(row.updated_at).toISOString()
|
|
240477
|
+
updatedAt: new Date(row.updated_at).toISOString(),
|
|
240478
|
+
...row.configured_by ? { configuredBy: row.configured_by } : {}
|
|
240191
240479
|
}));
|
|
240192
240480
|
}
|
|
240193
240481
|
async deleteActorConnectorConnection(actorId, connectorId) {
|
|
@@ -255201,6 +255489,98 @@ var init_chat_builtin_skills = __esm({
|
|
|
255201
255489
|
}
|
|
255202
255490
|
});
|
|
255203
255491
|
|
|
255492
|
+
// ../server/src/governance/connector-tool-versions.ts
|
|
255493
|
+
function connectorToolVersionsFile(dataDir) {
|
|
255494
|
+
return (0, import_node_path25.join)(dataDir, "connector-tools", "versions.json");
|
|
255495
|
+
}
|
|
255496
|
+
function registryBase() {
|
|
255497
|
+
const raw = process.env["npm_config_registry"] || process.env["NPM_CONFIG_REGISTRY"] || "https://registry.npmjs.org";
|
|
255498
|
+
return raw.replace(/\/+$/, "");
|
|
255499
|
+
}
|
|
255500
|
+
async function fetchLatestNpmVersion(pkg) {
|
|
255501
|
+
try {
|
|
255502
|
+
const url = `${registryBase()}/${pkg.split("/").map(encodeURIComponent).join("%2F")}/latest`;
|
|
255503
|
+
const res = await fetch(url, { headers: { accept: "application/json" }, signal: AbortSignal.timeout(NPM_PROBE_TIMEOUT_MS) });
|
|
255504
|
+
if (!res.ok) return null;
|
|
255505
|
+
const v2 = (await res.json()).version;
|
|
255506
|
+
return typeof v2 === "string" && v2 ? v2 : null;
|
|
255507
|
+
} catch {
|
|
255508
|
+
return null;
|
|
255509
|
+
}
|
|
255510
|
+
}
|
|
255511
|
+
async function readRegisteredToolVersions(dataDir) {
|
|
255512
|
+
try {
|
|
255513
|
+
const raw = JSON.parse(await (0, import_promises14.readFile)(connectorToolVersionsFile(dataDir), "utf8"));
|
|
255514
|
+
if (!raw || typeof raw !== "object") return {};
|
|
255515
|
+
const out = {};
|
|
255516
|
+
for (const [k2, v2] of Object.entries(raw)) {
|
|
255517
|
+
if (typeof v2 === "string" && v2) out[k2] = v2;
|
|
255518
|
+
}
|
|
255519
|
+
return out;
|
|
255520
|
+
} catch {
|
|
255521
|
+
return {};
|
|
255522
|
+
}
|
|
255523
|
+
}
|
|
255524
|
+
async function writeRegisteredToolVersions(dataDir, versions) {
|
|
255525
|
+
const file = connectorToolVersionsFile(dataDir);
|
|
255526
|
+
await (0, import_promises14.mkdir)((0, import_node_path25.join)(dataDir, "connector-tools"), { recursive: true });
|
|
255527
|
+
const tmp = `${file}.${process.pid}.tmp`;
|
|
255528
|
+
await (0, import_promises14.writeFile)(tmp, `${JSON.stringify(versions, null, 2)}
|
|
255529
|
+
`, "utf8");
|
|
255530
|
+
await (0, import_promises14.rename)(tmp, file);
|
|
255531
|
+
}
|
|
255532
|
+
async function refreshConnectorToolVersions(opts) {
|
|
255533
|
+
const fetchLatest = opts.fetchLatest ?? fetchLatestNpmVersion;
|
|
255534
|
+
const log3 = opts.log ?? (() => {
|
|
255535
|
+
});
|
|
255536
|
+
const versions = await readRegisteredToolVersions(opts.dataDir);
|
|
255537
|
+
const results = [];
|
|
255538
|
+
let changed = false;
|
|
255539
|
+
for (const [tool, pkg] of Object.entries(NPM_TOOL_PACKAGES)) {
|
|
255540
|
+
const before = versions[tool];
|
|
255541
|
+
const latest = await fetchLatest(pkg);
|
|
255542
|
+
if (!latest) {
|
|
255543
|
+
results.push({ tool, pkg, ...before ? { from: before, to: before } : {}, outcome: "unreachable" });
|
|
255544
|
+
log3(`[connector-tools] ${pkg} \u95EE\u4E0D\u5230\u6700\u65B0\u7248\uFF0C\u6CBF\u7528\u767B\u8BB0\u7248\u672C ${before ?? "\uFF08\u65E0\uFF09"}`);
|
|
255545
|
+
continue;
|
|
255546
|
+
}
|
|
255547
|
+
if (before === latest) {
|
|
255548
|
+
results.push({ tool, pkg, from: before, to: latest, outcome: "unchanged" });
|
|
255549
|
+
continue;
|
|
255550
|
+
}
|
|
255551
|
+
versions[tool] = latest;
|
|
255552
|
+
changed = true;
|
|
255553
|
+
results.push({ tool, pkg, ...before ? { from: before } : {}, to: latest, outcome: "updated" });
|
|
255554
|
+
log3(`[connector-tools] ${pkg} \u767B\u8BB0\u7248\u672C ${before ?? "\uFF08\u65E0\uFF09"} \u2192 ${latest}`);
|
|
255555
|
+
}
|
|
255556
|
+
if (changed) {
|
|
255557
|
+
try {
|
|
255558
|
+
await writeRegisteredToolVersions(opts.dataDir, versions);
|
|
255559
|
+
} catch (err) {
|
|
255560
|
+
log3(`[connector-tools] \u767B\u8BB0\u7248\u672C\u843D\u76D8\u5931\u8D25\uFF08\u672C\u8FDB\u7A0B\u5185\u4ECD\u751F\u6548\uFF09\uFF1A${String(err)}`);
|
|
255561
|
+
}
|
|
255562
|
+
}
|
|
255563
|
+
return { versions, results };
|
|
255564
|
+
}
|
|
255565
|
+
function pickToolVersions(registered, tools) {
|
|
255566
|
+
const out = {};
|
|
255567
|
+
for (const t of tools) {
|
|
255568
|
+
const v2 = registered[t];
|
|
255569
|
+
if (v2) out[t] = v2;
|
|
255570
|
+
}
|
|
255571
|
+
return out;
|
|
255572
|
+
}
|
|
255573
|
+
var import_promises14, import_node_path25, NPM_PROBE_TIMEOUT_MS;
|
|
255574
|
+
var init_connector_tool_versions = __esm({
|
|
255575
|
+
"../server/src/governance/connector-tool-versions.ts"() {
|
|
255576
|
+
"use strict";
|
|
255577
|
+
import_promises14 = require("node:fs/promises");
|
|
255578
|
+
import_node_path25 = require("node:path");
|
|
255579
|
+
init_src8();
|
|
255580
|
+
NPM_PROBE_TIMEOUT_MS = 3e3;
|
|
255581
|
+
}
|
|
255582
|
+
});
|
|
255583
|
+
|
|
255204
255584
|
// ../server/src/design/board-watch.ts
|
|
255205
255585
|
function decideBoardLetter(c, nowMs, quietMs) {
|
|
255206
255586
|
if (c.hasOpenWatchLetter) return false;
|
|
@@ -255996,6 +256376,7 @@ var init_src11 = __esm({
|
|
|
255996
256376
|
init_builtin_skills();
|
|
255997
256377
|
init_chat_builtin_skills();
|
|
255998
256378
|
init_connector_skills();
|
|
256379
|
+
init_connector_tool_versions();
|
|
255999
256380
|
init_board_watch();
|
|
256000
256381
|
init_ephemeral_project();
|
|
256001
256382
|
init_run_settlement();
|
|
@@ -256858,6 +257239,7 @@ function materializeBuiltins(builtins, runtimeKind, opts) {
|
|
|
256858
257239
|
var CONNECTOR_SKILL_SOURCES = [
|
|
256859
257240
|
{ connectorId: "feishu", baseUrl: FEISHU_WELL_KNOWN_SKILLS_BASE }
|
|
256860
257241
|
];
|
|
257242
|
+
var registeredToolVersions = {};
|
|
256861
257243
|
async function readAllConnectorSkills(dataDir) {
|
|
256862
257244
|
const out = [];
|
|
256863
257245
|
for (const src of CONNECTOR_SKILL_SOURCES) {
|
|
@@ -256889,11 +257271,18 @@ async function refreshConnectorSkillsNow(dataDir, apply) {
|
|
|
256889
257271
|
}
|
|
256890
257272
|
}
|
|
256891
257273
|
if (out.length > 0) apply(out);
|
|
257274
|
+
try {
|
|
257275
|
+
const { versions } = await refreshConnectorToolVersions({ dataDir, log: (m2) => console.log(m2) });
|
|
257276
|
+
registeredToolVersions = versions;
|
|
257277
|
+
} catch (err) {
|
|
257278
|
+
console.warn(`[serve] connector CLI \u767B\u8BB0\u7248\u672C\u5237\u65B0\u5931\u8D25\uFF0C\u6CBF\u7528\u4E0A\u4E00\u4EFD\uFF1A${String(err)}`);
|
|
257279
|
+
}
|
|
256892
257280
|
return results;
|
|
256893
257281
|
}
|
|
256894
257282
|
function refreshConnectorSkillsInBackground(dataDir, apply) {
|
|
256895
257283
|
void refreshConnectorSkillsNow(dataDir, apply);
|
|
256896
257284
|
}
|
|
257285
|
+
var CONNECTOR_SKILL_REFRESH_MS = 24 * 60 * 6e4;
|
|
256897
257286
|
var SESSION_TOKEN_GRACE_MS = 15 * 6e4;
|
|
256898
257287
|
function makeResumeRetryProxy(first, spawnFallback) {
|
|
256899
257288
|
const relay = () => {
|
|
@@ -257087,6 +257476,8 @@ async function buildActorProvision(service, actorId, scope, onBrokerRefused) {
|
|
|
257087
257476
|
env,
|
|
257088
257477
|
wrapperPaths: [oasisWrapperScript(), ...provision.wrapperPaths],
|
|
257089
257478
|
requiredTools: provision.requiredTools,
|
|
257479
|
+
// 只挑本次真要用的那几个:job 里不塞无关工具的版本号。
|
|
257480
|
+
requiredToolVersions: pickToolVersions(registeredToolVersions, provision.requiredTools),
|
|
257090
257481
|
connectorCreds: provision.connectorCreds,
|
|
257091
257482
|
cleanup: provision.cleanup
|
|
257092
257483
|
};
|
|
@@ -258275,10 +258666,17 @@ async function startServe(opts) {
|
|
|
258275
258666
|
});
|
|
258276
258667
|
console.log(`[serve] loaded ${builtinSkills.length} builtin skill(s): ${builtinSkills.map((s2) => s2.id).join(", ") || "(none)"}`);
|
|
258277
258668
|
connectorSkills = await readAllConnectorSkills(opts.dir);
|
|
258669
|
+
registeredToolVersions = await readRegisteredToolVersions(opts.dir);
|
|
258278
258670
|
console.log(`[serve] connector skills\uFF08\u843D\u76D8\u526F\u672C\uFF09\uFF1A${connectorSkills.length} \u4E2A`);
|
|
258279
258671
|
refreshConnectorSkillsInBackground(opts.dir, (s2) => {
|
|
258280
258672
|
connectorSkills = s2;
|
|
258281
258673
|
});
|
|
258674
|
+
const connectorSkillTimer = setInterval(() => {
|
|
258675
|
+
refreshConnectorSkillsInBackground(opts.dir, (s2) => {
|
|
258676
|
+
connectorSkills = s2;
|
|
258677
|
+
});
|
|
258678
|
+
}, CONNECTOR_SKILL_REFRESH_MS);
|
|
258679
|
+
connectorSkillTimer.unref?.();
|
|
258282
258680
|
if (defaultCompanyMigration.createdCompany) {
|
|
258283
258681
|
const seededAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
258284
258682
|
for (const devActor of ["actor:human:yx"]) {
|
|
@@ -259148,6 +259546,7 @@ async function startServe(opts) {
|
|
|
259148
259546
|
env: provision.env,
|
|
259149
259547
|
wrapperPaths: provision.wrapperPaths,
|
|
259150
259548
|
...provision.requiredTools.length > 0 ? { requiredTools: provision.requiredTools } : {},
|
|
259549
|
+
...Object.keys(provision.requiredToolVersions).length > 0 ? { requiredToolVersions: provision.requiredToolVersions } : {},
|
|
259151
259550
|
...provision.connectorCreds.length > 0 ? { connectorCreds: provision.connectorCreds } : {}
|
|
259152
259551
|
});
|
|
259153
259552
|
const chunks = [];
|
|
@@ -260133,7 +260532,7 @@ async function startServe(opts) {
|
|
|
260133
260532
|
console.warn(`[trace] chat run ${traceRunId} \u7EED\u8D26\u5F02\u5E38: ${String(err)}`);
|
|
260134
260533
|
});
|
|
260135
260534
|
};
|
|
260136
|
-
const provision = isolatedKnowledgeTurn ? { env: {}, wrapperPaths: [], requiredTools: [], connectorCreds: [], cleanup: async () => void 0 } : await buildActorProvision(actorService, actorId);
|
|
260535
|
+
const provision = isolatedKnowledgeTurn ? { env: {}, wrapperPaths: [], requiredTools: [], requiredToolVersions: {}, connectorCreds: [], cleanup: async () => void 0 } : await buildActorProvision(actorService, actorId);
|
|
260137
260536
|
const actorCtx = await buildActorContext(actorService, actorId).catch(() => null);
|
|
260138
260537
|
const chatResolvedModel = sessionModelOverride ?? actorCtx?.config?.model ?? void 0;
|
|
260139
260538
|
const chatModel = chatResolvedModel ?? await registryStore.getRuntimeConfig(`runtime:${binding.nodeId}:${binding.runtimeKind}`).then((c) => c?.model).catch(() => void 0) ?? void 0;
|
|
@@ -260273,6 +260672,7 @@ async function startServe(opts) {
|
|
|
260273
260672
|
},
|
|
260274
260673
|
wrapperPaths: provision.wrapperPaths,
|
|
260275
260674
|
...provision.requiredTools.length > 0 ? { requiredTools: provision.requiredTools } : {},
|
|
260675
|
+
...Object.keys(provision.requiredToolVersions).length > 0 ? { requiredToolVersions: provision.requiredToolVersions } : {},
|
|
260276
260676
|
...provision.connectorCreds.length > 0 ? { connectorCreds: provision.connectorCreds } : {},
|
|
260277
260677
|
...requiredConnectors.length > 0 ? { requiredConnectorSlugs: requiredConnectors } : {}
|
|
260278
260678
|
});
|
|
@@ -262894,6 +263294,7 @@ ${nodeFault}` : "");
|
|
|
262894
263294
|
if (gitTimer) clearInterval(gitTimer);
|
|
262895
263295
|
if (coordTimer) clearInterval(coordTimer);
|
|
262896
263296
|
if (livenessTimer) clearInterval(livenessTimer);
|
|
263297
|
+
clearInterval(connectorSkillTimer);
|
|
262897
263298
|
if (orphanSweepTimer) clearInterval(orphanSweepTimer);
|
|
262898
263299
|
for (const t of dropSweepTimers) clearInterval(t);
|
|
262899
263300
|
if (deadlineClockTimer) clearInterval(deadlineClockTimer);
|
|
@@ -263092,7 +263493,7 @@ async function runSession(dispatchId, job, deps) {
|
|
|
263092
263493
|
}
|
|
263093
263494
|
}
|
|
263094
263495
|
if (job.requiredTools?.length) {
|
|
263095
|
-
const missing = await ensureConnectorTools(job.requiredTools);
|
|
263496
|
+
const missing = await ensureConnectorTools(job.requiredTools, { versions: job.requiredToolVersions });
|
|
263096
263497
|
if (missing.length) log2("[node-cli]", ` connector tools still missing (agent may fail): ${missing.join(", ")}`);
|
|
263097
263498
|
}
|
|
263098
263499
|
const prepared = await prepareConnectorsForJob(job);
|
|
@@ -263495,7 +263896,7 @@ function detectRuntimes() {
|
|
|
263495
263896
|
|
|
263496
263897
|
// ../cli/src/daemon/workdir-handler.ts
|
|
263497
263898
|
var import_node_fs19 = __toESM(require("node:fs"), 1);
|
|
263498
|
-
var
|
|
263899
|
+
var import_node_path26 = __toESM(require("node:path"), 1);
|
|
263499
263900
|
init_src6();
|
|
263500
263901
|
init_src();
|
|
263501
263902
|
var WORKDIR_READ_MAX_BYTES2 = 2 * 1024 * 1024;
|
|
@@ -263514,10 +263915,10 @@ function isSensitiveSegment(segment) {
|
|
|
263514
263915
|
}
|
|
263515
263916
|
function relPathIsSensitive(rel) {
|
|
263516
263917
|
if (!rel) return false;
|
|
263517
|
-
return rel.split(
|
|
263918
|
+
return rel.split(import_node_path26.default.sep).some((seg) => seg.length > 0 && isSensitiveSegment(seg));
|
|
263518
263919
|
}
|
|
263519
263920
|
function withinBase(p2, base) {
|
|
263520
|
-
return p2 === base || p2.startsWith(base +
|
|
263921
|
+
return p2 === base || p2.startsWith(base + import_node_path26.default.sep);
|
|
263521
263922
|
}
|
|
263522
263923
|
function normalizeRel(raw) {
|
|
263523
263924
|
const trimmed = (raw ?? "").trim();
|
|
@@ -263534,7 +263935,7 @@ async function trustedCanonicalContainer(req, logicalBase, dirKind) {
|
|
|
263534
263935
|
} catch {
|
|
263535
263936
|
return null;
|
|
263536
263937
|
}
|
|
263537
|
-
return isLegacy ?
|
|
263938
|
+
return isLegacy ? import_node_path26.default.join(trustedRootReal, "oasis-chat-sessions") : import_node_path26.default.join(trustedRootReal, "sessions", dirKind);
|
|
263538
263939
|
}
|
|
263539
263940
|
async function resolveWithinWorkdir(req) {
|
|
263540
263941
|
const dirKind = sessionDirKind(req.runtimeKind);
|
|
@@ -263552,11 +263953,11 @@ async function resolveWithinWorkdir(req) {
|
|
|
263552
263953
|
} catch {
|
|
263553
263954
|
return { ok: false, code: "NOT_FOUND" };
|
|
263554
263955
|
}
|
|
263555
|
-
if (
|
|
263956
|
+
if (import_node_path26.default.dirname(base) !== canonicalContainer) return { ok: false, code: "PATH_ESCAPE" };
|
|
263556
263957
|
const rel = normalizeRel(req.path);
|
|
263557
|
-
const requested =
|
|
263958
|
+
const requested = import_node_path26.default.resolve(base, rel);
|
|
263558
263959
|
if (!withinBase(requested, base)) return { ok: false, code: "PATH_ESCAPE" };
|
|
263559
|
-
const cleanRel = base === requested ? "" :
|
|
263960
|
+
const cleanRel = base === requested ? "" : import_node_path26.default.relative(base, requested);
|
|
263560
263961
|
if (relPathIsSensitive(cleanRel)) return { ok: false, code: "SENSITIVE" };
|
|
263561
263962
|
let real;
|
|
263562
263963
|
try {
|
|
@@ -263566,7 +263967,7 @@ async function resolveWithinWorkdir(req) {
|
|
|
263566
263967
|
return { ok: false, code: "PATH_ESCAPE" };
|
|
263567
263968
|
}
|
|
263568
263969
|
if (!withinBase(real, base)) return { ok: false, code: "PATH_ESCAPE" };
|
|
263569
|
-
const realRel = base === real ? "" :
|
|
263970
|
+
const realRel = base === real ? "" : import_node_path26.default.relative(base, real);
|
|
263570
263971
|
if (relPathIsSensitive(realRel)) return { ok: false, code: "SENSITIVE" };
|
|
263571
263972
|
return { ok: true, base, real };
|
|
263572
263973
|
}
|
|
@@ -263602,7 +264003,7 @@ async function handleWorkdirList(req) {
|
|
|
263602
264003
|
const slice = truncated ? visible.slice(0, WORKDIR_LIST_MAX_ENTRIES) : visible;
|
|
263603
264004
|
const entries = [];
|
|
263604
264005
|
for (const d of slice) {
|
|
263605
|
-
const abs =
|
|
264006
|
+
const abs = import_node_path26.default.join(anchor, d.name);
|
|
263606
264007
|
try {
|
|
263607
264008
|
const st = await import_node_fs19.default.promises.lstat(abs);
|
|
263608
264009
|
if (st.isSymbolicLink()) continue;
|
|
@@ -263634,7 +264035,7 @@ async function verifyOpenedFd(fh, base, fallback) {
|
|
|
263634
264035
|
const fdReal = await fdCanonicalPath(fh);
|
|
263635
264036
|
if (fdReal === null) return { anchor: fallback };
|
|
263636
264037
|
if (!withinBase(fdReal, base)) return { error: { ok: false, code: "PATH_ESCAPE" } };
|
|
263637
|
-
const fdRel = base === fdReal ? "" :
|
|
264038
|
+
const fdRel = base === fdReal ? "" : import_node_path26.default.relative(base, fdReal);
|
|
263638
264039
|
if (relPathIsSensitive(fdRel)) return { error: { ok: false, code: "SENSITIVE" } };
|
|
263639
264040
|
return { anchor: `/proc/self/fd/${fh.fd}` };
|
|
263640
264041
|
}
|
|
@@ -263723,7 +264124,7 @@ function looksBinary(bytes2) {
|
|
|
263723
264124
|
function contentTypeFor(absPath, bytes2) {
|
|
263724
264125
|
const sniffed = sniffContentType(bytes2);
|
|
263725
264126
|
if (sniffed) return sniffed;
|
|
263726
|
-
const ext =
|
|
264127
|
+
const ext = import_node_path26.default.extname(absPath).toLowerCase();
|
|
263727
264128
|
if (EXT_CONTENT_TYPE[ext]) return EXT_CONTENT_TYPE[ext];
|
|
263728
264129
|
return looksBinary(bytes2) ? "application/octet-stream" : "text/plain; charset=utf-8";
|
|
263729
264130
|
}
|
|
@@ -264319,17 +264720,17 @@ var RuntimeRouterAdapter = class {
|
|
|
264319
264720
|
// ../cli/src/daemon/reap-claude-projects.ts
|
|
264320
264721
|
var import_node_fs20 = __toESM(require("node:fs"), 1);
|
|
264321
264722
|
var import_node_os10 = __toESM(require("node:os"), 1);
|
|
264322
|
-
var
|
|
264723
|
+
var import_node_path27 = __toESM(require("node:path"), 1);
|
|
264323
264724
|
function claudeProjectSlug(cwd) {
|
|
264324
264725
|
return cwd.replace(/[^a-zA-Z0-9]/g, "-");
|
|
264325
264726
|
}
|
|
264326
264727
|
function claudeProjectsRoot() {
|
|
264327
|
-
const configDir = process.env["CLAUDE_CONFIG_DIR"] ||
|
|
264328
|
-
return
|
|
264728
|
+
const configDir = process.env["CLAUDE_CONFIG_DIR"] || import_node_path27.default.join(import_node_os10.default.homedir(), ".claude");
|
|
264729
|
+
return import_node_path27.default.join(configDir, "projects");
|
|
264329
264730
|
}
|
|
264330
264731
|
function reapClaudeProjects(workdir, runtimeKind) {
|
|
264331
264732
|
if (runtimeKind !== "claude" && runtimeKind !== "claude-code") return;
|
|
264332
|
-
const dir =
|
|
264733
|
+
const dir = import_node_path27.default.join(claudeProjectsRoot(), claudeProjectSlug(workdir));
|
|
264333
264734
|
if (!import_node_fs20.default.existsSync(dir)) return;
|
|
264334
264735
|
try {
|
|
264335
264736
|
import_node_fs20.default.rmSync(dir, { recursive: true, force: true });
|
|
@@ -264338,7 +264739,7 @@ function reapClaudeProjects(workdir, runtimeKind) {
|
|
|
264338
264739
|
}
|
|
264339
264740
|
function measureClaudeProjects(workdir, runtimeKind) {
|
|
264340
264741
|
if (runtimeKind !== "claude" && runtimeKind !== "claude-code") return 0;
|
|
264341
|
-
const dir =
|
|
264742
|
+
const dir = import_node_path27.default.join(claudeProjectsRoot(), claudeProjectSlug(workdir));
|
|
264342
264743
|
return dirSizeBytes2(dir);
|
|
264343
264744
|
}
|
|
264344
264745
|
function dirSizeBytes2(dir) {
|
|
@@ -264350,7 +264751,7 @@ function dirSizeBytes2(dir) {
|
|
|
264350
264751
|
return 0;
|
|
264351
264752
|
}
|
|
264352
264753
|
for (const e of entries) {
|
|
264353
|
-
const p2 =
|
|
264754
|
+
const p2 = import_node_path27.default.join(dir, e.name);
|
|
264354
264755
|
if (e.isSymbolicLink()) continue;
|
|
264355
264756
|
if (e.isDirectory()) {
|
|
264356
264757
|
total += dirSizeBytes2(p2);
|
|
@@ -266761,7 +267162,7 @@ function fieldsFromFlags(flags, ownFlags) {
|
|
|
266761
267162
|
}
|
|
266762
267163
|
return Object.keys(fields).length > 0 ? fields : void 0;
|
|
266763
267164
|
}
|
|
266764
|
-
function buildStageOp(cmd, flags, positional,
|
|
267165
|
+
function buildStageOp(cmd, flags, positional, readFile9 = (file) => fs39.readFileSync(file, "utf8")) {
|
|
266765
267166
|
switch (cmd) {
|
|
266766
267167
|
case "link":
|
|
266767
267168
|
return {
|
|
@@ -266783,7 +267184,7 @@ function buildStageOp(cmd, flags, positional, readFile8 = (file) => fs39.readFil
|
|
|
266783
267184
|
...flags.get("title") !== void 0 ? { title: flags.get("title") } : {},
|
|
266784
267185
|
...(flags.get("brief") ?? flags.get("description")) !== void 0 ? { description: flags.get("brief") ?? flags.get("description") } : {},
|
|
266785
267186
|
...flags.get("input") !== void 0 ? { inputs: flags.get("input").split(",").map((to) => ({ to: to.trim() })) } : {},
|
|
266786
|
-
...partsFile !== void 0 ? { parts: JSON.parse(
|
|
267187
|
+
...partsFile !== void 0 ? { parts: JSON.parse(readFile9(partsFile)) } : {},
|
|
266787
267188
|
...fields !== void 0 ? { fields } : {}
|
|
266788
267189
|
};
|
|
266789
267190
|
}
|
|
@@ -270150,7 +270551,7 @@ function shimScript() {
|
|
|
270150
270551
|
}
|
|
270151
270552
|
|
|
270152
270553
|
// src/index.ts
|
|
270153
|
-
var PKG_VERSION = true ? "2.2.
|
|
270554
|
+
var PKG_VERSION = true ? "2.2.8" : "dev";
|
|
270154
270555
|
var LOCAL_BIN = localBin();
|
|
270155
270556
|
var NPM_PREFIX = npmPrefix();
|
|
270156
270557
|
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.8",
|
|
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": "6677c1551a7015b5a37a4fc4c3d7f7e7aaf395e6"
|
|
30
30
|
}
|
|
31
31
|
}
|