oasis_test_v2 2.2.81 → 2.2.82
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 +325 -73
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2950,6 +2950,25 @@ async function fetchResultPackage(base, fetchImpl, runId) {
|
|
|
2950
2950
|
}));
|
|
2951
2951
|
return { artifacts, fileCount: body2.project?.fileCount ?? artifacts.length };
|
|
2952
2952
|
}
|
|
2953
|
+
function toEpochMs(v2) {
|
|
2954
|
+
if (typeof v2 === "number" && Number.isFinite(v2)) return v2;
|
|
2955
|
+
if (typeof v2 === "string" && v2.length > 0) {
|
|
2956
|
+
const ms = Date.parse(v2);
|
|
2957
|
+
return Number.isNaN(ms) ? void 0 : ms;
|
|
2958
|
+
}
|
|
2959
|
+
return void 0;
|
|
2960
|
+
}
|
|
2961
|
+
function runTime(r) {
|
|
2962
|
+
return r.createdAt ?? r.updatedAt ?? Number.NEGATIVE_INFINITY;
|
|
2963
|
+
}
|
|
2964
|
+
function latestSucceededRun(runs) {
|
|
2965
|
+
let best;
|
|
2966
|
+
for (const r of runs) {
|
|
2967
|
+
if (r.status !== "succeeded") continue;
|
|
2968
|
+
if (best === void 0 || runTime(r) > runTime(best)) best = r;
|
|
2969
|
+
}
|
|
2970
|
+
return best;
|
|
2971
|
+
}
|
|
2953
2972
|
async function fetchBoardStatus(base, fetchImpl, artifactId) {
|
|
2954
2973
|
const boardKey = deriveBoardKey(artifactId);
|
|
2955
2974
|
let boardExists = true;
|
|
@@ -2975,10 +2994,20 @@ async function fetchBoardStatus(base, fetchImpl, artifactId) {
|
|
|
2975
2994
|
"GET",
|
|
2976
2995
|
`/api/runs?projectId=${encodeURIComponent(boardKey)}`
|
|
2977
2996
|
);
|
|
2978
|
-
runs = (body2.runs ?? []).map((r) =>
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2997
|
+
runs = (body2.runs ?? []).map((r) => {
|
|
2998
|
+
const run = {
|
|
2999
|
+
runId: String(r["runId"] ?? r["id"] ?? ""),
|
|
3000
|
+
status: String(r["status"] ?? "unknown")
|
|
3001
|
+
};
|
|
3002
|
+
if (typeof r["agentId"] === "string" && r["agentId"].length > 0) run.agentId = r["agentId"];
|
|
3003
|
+
if (typeof r["error"] === "string" && r["error"].trim().length > 0) run.error = r["error"];
|
|
3004
|
+
const createdAt = toEpochMs(r["createdAt"]);
|
|
3005
|
+
if (createdAt !== void 0) run.createdAt = createdAt;
|
|
3006
|
+
const updatedAt = toEpochMs(r["updatedAt"]);
|
|
3007
|
+
if (updatedAt !== void 0) run.updatedAt = updatedAt;
|
|
3008
|
+
return run;
|
|
3009
|
+
});
|
|
3010
|
+
runs.sort((a, b2) => runTime(b2) - runTime(a) || 0);
|
|
2982
3011
|
} catch {
|
|
2983
3012
|
}
|
|
2984
3013
|
}
|
|
@@ -218354,13 +218383,22 @@ function cloneOffboarding(op) {
|
|
|
218354
218383
|
assignmentDecisions: op.assignmentDecisions.map((d) => ({ ...d, toPrincipal: { ...d.toPrincipal } }))
|
|
218355
218384
|
};
|
|
218356
218385
|
}
|
|
218357
|
-
var memberKey, scopedKey, bridgeKey, MemoryControlPlaneStore;
|
|
218386
|
+
var memberKey, scopedKey, bridgeKey, migrationRow, MemoryControlPlaneStore;
|
|
218358
218387
|
var init_memory_control_plane_store = __esm({
|
|
218359
218388
|
"../testkit/src/memory-control-plane-store.ts"() {
|
|
218360
218389
|
"use strict";
|
|
218361
218390
|
memberKey = (companyId, accountId) => `${companyId} ${accountId}`;
|
|
218362
218391
|
scopedKey = (companyId, id) => `${companyId}\0${id}`;
|
|
218363
218392
|
bridgeKey = (companyId, type, id) => `${companyId}\0${type}\0${id}`;
|
|
218393
|
+
migrationRow = (companyId, accountId, roleBefore, roleAfter, audit2) => ({
|
|
218394
|
+
companyId,
|
|
218395
|
+
accountId,
|
|
218396
|
+
roleBefore,
|
|
218397
|
+
roleAfter,
|
|
218398
|
+
evidence: audit2.evidence,
|
|
218399
|
+
...audit2.evidence === "manifest" && audit2.manifestVersion !== void 0 ? { manifestVersion: audit2.manifestVersion } : {},
|
|
218400
|
+
appliedAt: audit2.appliedAt
|
|
218401
|
+
});
|
|
218364
218402
|
MemoryControlPlaneStore = class {
|
|
218365
218403
|
companies = /* @__PURE__ */ new Map();
|
|
218366
218404
|
members = /* @__PURE__ */ new Map();
|
|
@@ -218480,6 +218518,21 @@ var init_memory_control_plane_store = __esm({
|
|
|
218480
218518
|
this.members.delete(key2);
|
|
218481
218519
|
return { ok: true, member: { ...target } };
|
|
218482
218520
|
}
|
|
218521
|
+
async removeMemberAndReleaseOwnedAgents(companyId, accountId, at2) {
|
|
218522
|
+
const target = this.members.get(memberKey(companyId, accountId));
|
|
218523
|
+
if (!target) return { ok: false, reason: "not_found" };
|
|
218524
|
+
if (target.role === "owner") return { ok: false, reason: "owner_protected" };
|
|
218525
|
+
const releasedAgents = [];
|
|
218526
|
+
for (const [key2, e] of this.digitalEmployees) {
|
|
218527
|
+
if (e.companyId !== companyId || e.ownerAccountId !== accountId) continue;
|
|
218528
|
+
const { ownerAccountId: _cleared, ...rest } = e;
|
|
218529
|
+
this.digitalEmployees.set(key2, { ...rest, updatedAt: at2 });
|
|
218530
|
+
releasedAgents.push(e.id);
|
|
218531
|
+
}
|
|
218532
|
+
this.principalBridges.delete(bridgeKey(companyId, "human", accountId));
|
|
218533
|
+
this.members.delete(memberKey(companyId, accountId));
|
|
218534
|
+
return { ok: true, member: { ...target }, releasedAgents };
|
|
218535
|
+
}
|
|
218483
218536
|
async updateMemberRoleIfNotLastOwner(companyId, accountId, role) {
|
|
218484
218537
|
const key2 = memberKey(companyId, accountId);
|
|
218485
218538
|
const target = this.members.get(key2);
|
|
@@ -218506,7 +218559,7 @@ var init_memory_control_plane_store = __esm({
|
|
|
218506
218559
|
return { ok: false, reason: "target_not_listed" };
|
|
218507
218560
|
}
|
|
218508
218561
|
const acc = this.accounts.get(toAccountId);
|
|
218509
|
-
if (acc
|
|
218562
|
+
if (!acc || acc.status !== "active") return { ok: false, reason: "target_inactive" };
|
|
218510
218563
|
const others = [];
|
|
218511
218564
|
for (const m2 of this.members.values()) {
|
|
218512
218565
|
if (m2.companyId === companyId && m2.role === "owner" && m2.accountId !== toAccountId) others.push(m2);
|
|
@@ -218523,6 +218576,37 @@ var init_memory_control_plane_store = __esm({
|
|
|
218523
218576
|
this.members.set(memberKey(companyId, toAccountId), owner);
|
|
218524
218577
|
return { ok: true, owner: { ...owner }, demoted };
|
|
218525
218578
|
}
|
|
218579
|
+
// —— 存量身份映射(ADR D3)——
|
|
218580
|
+
async migrateSoleCompanyOwner(companyId, toAccountId, audit2) {
|
|
218581
|
+
const target = this.members.get(memberKey(companyId, toAccountId));
|
|
218582
|
+
if (!target) return { ok: false, reason: "not_found" };
|
|
218583
|
+
const others = [];
|
|
218584
|
+
for (const m2 of this.members.values()) {
|
|
218585
|
+
if (m2.companyId === companyId && m2.role === "owner" && m2.accountId !== toAccountId) others.push(m2);
|
|
218586
|
+
}
|
|
218587
|
+
if (others.length === 0 && target.role === "owner") {
|
|
218588
|
+
return { ok: true, owner: { ...target }, demoted: [], auditRows: [] };
|
|
218589
|
+
}
|
|
218590
|
+
const auditRows = [];
|
|
218591
|
+
const demoted = others.map((m2) => {
|
|
218592
|
+
const next = { ...m2, role: "admin" };
|
|
218593
|
+
this.members.set(memberKey(companyId, m2.accountId), next);
|
|
218594
|
+
auditRows.push(migrationRow(companyId, m2.accountId, "owner", "admin", audit2));
|
|
218595
|
+
return { ...next };
|
|
218596
|
+
});
|
|
218597
|
+
if (target.role !== "owner") auditRows.push(migrationRow(companyId, toAccountId, target.role, "owner", audit2));
|
|
218598
|
+
const owner = { ...target, role: "owner" };
|
|
218599
|
+
this.members.set(memberKey(companyId, toAccountId), owner);
|
|
218600
|
+
for (const r of auditRows) this.roleMigrations.push({ ...r });
|
|
218601
|
+
return { ok: true, owner: { ...owner }, demoted, auditRows };
|
|
218602
|
+
}
|
|
218603
|
+
async setMemberRoleOnly(companyId, accountId, role) {
|
|
218604
|
+
const key2 = memberKey(companyId, accountId);
|
|
218605
|
+
const cur = this.members.get(key2);
|
|
218606
|
+
if (!cur) return false;
|
|
218607
|
+
this.members.set(key2, { ...cur, role });
|
|
218608
|
+
return true;
|
|
218609
|
+
}
|
|
218526
218610
|
// —— 存量身份映射审计(ADR D3.4):只追加 ——
|
|
218527
218611
|
async appendMemberRoleMigrations(rows) {
|
|
218528
218612
|
for (const r of rows) this.roleMigrations.push({ ...r });
|
|
@@ -223813,6 +223897,9 @@ var init_control_plane_file_store = __esm({
|
|
|
223813
223897
|
"removeMemberIfNotLastOwner",
|
|
223814
223898
|
"updateMemberRoleIfNotLastOwner",
|
|
223815
223899
|
"setSoleCompanyOwner",
|
|
223900
|
+
"removeMemberAndReleaseOwnedAgents",
|
|
223901
|
+
"migrateSoleCompanyOwner",
|
|
223902
|
+
"setMemberRoleOnly",
|
|
223816
223903
|
"appendMemberRoleMigrations",
|
|
223817
223904
|
"createInvitation",
|
|
223818
223905
|
"updateInvitationStatus",
|
|
@@ -225260,38 +225347,17 @@ async function backfillOrgIdentity(deps, opts = {}) {
|
|
|
225260
225347
|
const desc = row.changes.map((c) => `${c.accountId} ${c.roleBefore}\u2192${c.roleAfter}`).join("\uFF0C");
|
|
225261
225348
|
log3(` ${row.companyId}\uFF1A${desc}${opts.apply ? "" : "\uFF08dry-run\uFF09"}`);
|
|
225262
225349
|
if (!opts.apply) continue;
|
|
225263
|
-
const res = await deps.store.setSoleCompanyOwner(row.companyId, target);
|
|
225264
|
-
if (!res.ok) {
|
|
225265
|
-
throw new Error(
|
|
225266
|
-
`${row.companyId} \u6536\u655B\u5230 ${target} \u5931\u8D25\uFF1A${res.reason}\uFF08target_not_listed = \u90A3\u4E2A\u4EBA\u8FD8\u6CA1\u8D70\u5B8C\u65B0\u624B\u6307\u5F15\uFF1Btarget_inactive = \u8D26\u53F7\u5DF2\u505C\u7528\uFF09`
|
|
225267
|
-
);
|
|
225268
|
-
}
|
|
225269
|
-
applied += 1;
|
|
225270
|
-
const at2 = now();
|
|
225271
225350
|
const evidence = row.decision === "manifest" ? "manifest" : "E1";
|
|
225272
|
-
const
|
|
225273
|
-
companyId: row.companyId,
|
|
225274
|
-
accountId: m2.accountId,
|
|
225275
|
-
roleBefore: "owner",
|
|
225276
|
-
roleAfter: "admin",
|
|
225351
|
+
const res = await deps.store.migrateSoleCompanyOwner(row.companyId, target, {
|
|
225277
225352
|
evidence,
|
|
225278
|
-
...opts.manifest?.manifestVersion !== void 0
|
|
225279
|
-
appliedAt:
|
|
225280
|
-
})
|
|
225281
|
-
|
|
225282
|
-
|
|
225283
|
-
rows.push({
|
|
225284
|
-
companyId: row.companyId,
|
|
225285
|
-
accountId: target,
|
|
225286
|
-
roleBefore: promoted.roleBefore,
|
|
225287
|
-
roleAfter: "owner",
|
|
225288
|
-
evidence,
|
|
225289
|
-
...opts.manifest?.manifestVersion !== void 0 && evidence === "manifest" ? { manifestVersion: opts.manifest.manifestVersion } : {},
|
|
225290
|
-
appliedAt: at2
|
|
225291
|
-
});
|
|
225353
|
+
...opts.manifest?.manifestVersion !== void 0 ? { manifestVersion: opts.manifest.manifestVersion } : {},
|
|
225354
|
+
appliedAt: now()
|
|
225355
|
+
});
|
|
225356
|
+
if (!res.ok) {
|
|
225357
|
+
throw new Error(`${row.companyId} \u6536\u655B\u5230 ${target} \u5931\u8D25\uFF1A${res.reason}\uFF08\u90A3\u4E00\u884C\u4E0D\u5728\u8BE5\u7EC4\u7EC7\u7684\u6210\u5458\u8868\u91CC\uFF09`);
|
|
225292
225358
|
}
|
|
225293
|
-
|
|
225294
|
-
auditRows +=
|
|
225359
|
+
applied += 1;
|
|
225360
|
+
auditRows += res.auditRows.length;
|
|
225295
225361
|
}
|
|
225296
225362
|
return { ...inv, applied, auditRows };
|
|
225297
225363
|
}
|
|
@@ -225311,7 +225377,7 @@ async function rollbackOrgIdentity(deps, opts) {
|
|
|
225311
225377
|
plan.push({ companyId: r.companyId, accountId: r.accountId, from: member.role, to: r.roleBefore });
|
|
225312
225378
|
log3(` ${r.companyId} ${r.accountId} ${member.role}\u2192${r.roleBefore}${opts.apply ? "" : "\uFF08dry-run\uFF09"}`);
|
|
225313
225379
|
if (!opts.apply) continue;
|
|
225314
|
-
await deps.store.
|
|
225380
|
+
await deps.store.setMemberRoleOnly(r.companyId, r.accountId, r.roleBefore);
|
|
225315
225381
|
reverted += 1;
|
|
225316
225382
|
}
|
|
225317
225383
|
return { plan, reverted };
|
|
@@ -232799,6 +232865,12 @@ function actorsDomain(opts) {
|
|
|
232799
232865
|
}
|
|
232800
232866
|
await asForbidden(() => assertMayManageAgent(opts.agentManageGuard, ctx, { id: actor.id, positions: actor.roles }));
|
|
232801
232867
|
};
|
|
232868
|
+
const guardPositionsChange = async (req, existing, nextPositions) => {
|
|
232869
|
+
if (existing.kind !== "agent" || nextPositions === void 0) return;
|
|
232870
|
+
if (isAssistantAgent({ positions: existing.roles }) === isAssistantAgent({ positions: nextPositions })) return;
|
|
232871
|
+
const ctx = { companyId: req.auth.companyId, callerActorId: req.auth.actor };
|
|
232872
|
+
await asForbidden(() => assertMayManageAgent(opts.agentManageGuard, ctx, { id: existing.id, positions: nextPositions }));
|
|
232873
|
+
};
|
|
232802
232874
|
const guardExistingActorWrite = async (req, service, actorId) => {
|
|
232803
232875
|
const existing = await service.getActor(actorId);
|
|
232804
232876
|
if (!existing) throw new ApiError(404, "NOT_FOUND", `\u6CA1\u6709\u8FD9\u4E2A\u5458\u5DE5\uFF1A${actorId}`);
|
|
@@ -232891,6 +232963,7 @@ function actorsDomain(opts) {
|
|
|
232891
232963
|
const positions = positionsFromPayload(b2);
|
|
232892
232964
|
const avatar = avatarRefFromPayload(b2);
|
|
232893
232965
|
const tags = tagsFromPayload(b2);
|
|
232966
|
+
await guardPositionsChange(req, existing, positions);
|
|
232894
232967
|
const {
|
|
232895
232968
|
positions: _positions,
|
|
232896
232969
|
id: _id,
|
|
@@ -242321,8 +242394,8 @@ var init_service6 = __esm({
|
|
|
242321
242394
|
const target = await this.store.getMember(companyId, accountId);
|
|
242322
242395
|
if (!target) throw new CompanyError(404, "NOT_FOUND", `\u4E0D\u662F\u8BE5\u516C\u53F8\u6210\u5458\uFF1A${accountId}`);
|
|
242323
242396
|
if (target.role === "owner") throw this.ownerProtected();
|
|
242324
|
-
const res = await this.store.
|
|
242325
|
-
if (res.ok) return res.member;
|
|
242397
|
+
const res = await this.store.removeMemberAndReleaseOwnedAgents(companyId, accountId, this.now());
|
|
242398
|
+
if (res.ok) return { member: res.member, releasedAgents: res.releasedAgents };
|
|
242326
242399
|
if (res.reason === "not_found") throw new CompanyError(404, "NOT_FOUND", `\u4E0D\u662F\u8BE5\u516C\u53F8\u6210\u5458\uFF1A${accountId}`);
|
|
242327
242400
|
throw this.ownerProtected();
|
|
242328
242401
|
}
|
|
@@ -242846,12 +242919,14 @@ var init_offboarding = __esm({
|
|
|
242846
242919
|
listInFlight;
|
|
242847
242920
|
transferAssignment;
|
|
242848
242921
|
disableActor;
|
|
242922
|
+
restoreActor;
|
|
242849
242923
|
constructor(opts) {
|
|
242850
242924
|
this.store = opts.store;
|
|
242851
242925
|
this.now = opts.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
242852
242926
|
this.listInFlight = opts.listInFlightAssignments;
|
|
242853
242927
|
this.transferAssignment = opts.transferAssignment;
|
|
242854
242928
|
this.disableActor = opts.disableActor;
|
|
242929
|
+
this.restoreActor = opts.restoreActor;
|
|
242855
242930
|
}
|
|
242856
242931
|
/** 该成员是不是公司最后一个 owner(最后一个 owner 立即阻断,先于任何交接讨论)。 */
|
|
242857
242932
|
async isLastOwner(companyId, accountId) {
|
|
@@ -242877,14 +242952,13 @@ var init_offboarding = __esm({
|
|
|
242877
242952
|
*/
|
|
242878
242953
|
async blockersForRemoval(companyId, accountId) {
|
|
242879
242954
|
const blockers = [];
|
|
242880
|
-
const
|
|
242955
|
+
const members = await this.store.listMembers(companyId);
|
|
242956
|
+
const member = members.find((m2) => m2.accountId === accountId);
|
|
242881
242957
|
if (!member) {
|
|
242882
242958
|
return [{ code: "NOT_FOUND", message: `\u4E0D\u662F\u8BE5\u516C\u53F8\u6210\u5458\uFF1A${accountId}` }];
|
|
242883
242959
|
}
|
|
242884
242960
|
if (member.role === "owner") {
|
|
242885
242961
|
blockers.push({ code: "OWNER_PROTECTED", message: OWNER_PROTECTED_MESSAGE });
|
|
242886
|
-
} else if (await this.isLastOwner(companyId, accountId)) {
|
|
242887
|
-
blockers.push({ code: "LAST_OWNER", message: "\u516C\u53F8\u81F3\u5C11\u8981\u7559 1 \u4E2A owner\uFF0C\u4E0D\u80FD\u79FB\u9664\u6700\u540E\u4E00\u4E2A owner" });
|
|
242888
242962
|
}
|
|
242889
242963
|
return blockers;
|
|
242890
242964
|
}
|
|
@@ -242953,12 +243027,9 @@ var init_offboarding = __esm({
|
|
|
242953
243027
|
if (op.version !== expectedVersion) {
|
|
242954
243028
|
throw new CompanyError(409, "STALE_PLAN", `\u8BA1\u5212\u7248\u672C\u5DF2\u53D8\uFF08\u5F53\u524D ${op.version}\uFF0C\u4F60\u7ED9\u7684\u662F ${expectedVersion}\uFF09\uFF0C\u8BF7\u91CD\u65B0\u53D6\u8BA1\u5212`);
|
|
242955
243029
|
}
|
|
242956
|
-
const
|
|
243030
|
+
const members = await this.store.listMembers(companyId);
|
|
243031
|
+
const target = members.find((m2) => m2.accountId === accountId);
|
|
242957
243032
|
if (target?.role === "owner") throw new CompanyError(403, "OWNER_PROTECTED", OWNER_PROTECTED_MESSAGE);
|
|
242958
|
-
if (await this.isLastOwner(companyId, accountId)) {
|
|
242959
|
-
throw new CompanyError(409, "LAST_OWNER", "\u516C\u53F8\u81F3\u5C11\u8981\u7559 1 \u4E2A owner\uFF0C\u4E0D\u80FD\u79FB\u9664\u6700\u540E\u4E00\u4E2A owner");
|
|
242960
|
-
}
|
|
242961
|
-
const released = await this.releaseOwnedAgents(companyId, accountId);
|
|
242962
243033
|
const remaining = await this.blockersForRemoval(companyId, accountId);
|
|
242963
243034
|
if (remaining.length > 0) {
|
|
242964
243035
|
await this.store.updateMemberOffboardingIfVersion(
|
|
@@ -242970,7 +243041,7 @@ var init_offboarding = __esm({
|
|
|
242970
243041
|
);
|
|
242971
243042
|
throw new CompanyError(409, remaining[0].code, `\u4ECD\u6709\u672A\u4EA4\u63A5\u9879\uFF1A${remaining.map((b2) => b2.message).join("; ")}`);
|
|
242972
243043
|
}
|
|
242973
|
-
await this.applyMemberRemoval(companyId, accountId);
|
|
243044
|
+
const released = await this.applyMemberRemoval(companyId, accountId);
|
|
242974
243045
|
await this.store.updateMemberOffboardingIfVersion(
|
|
242975
243046
|
companyId,
|
|
242976
243047
|
operationId,
|
|
@@ -242981,35 +243052,63 @@ var init_offboarding = __esm({
|
|
|
242981
243052
|
return { status: "removed", transferred: [], left: released };
|
|
242982
243053
|
}
|
|
242983
243054
|
/**
|
|
242984
|
-
*
|
|
242985
|
-
*
|
|
242986
|
-
* 不清就是一个裸 FK 违例);**只清 owner**——不改状态、不撤凭证、不解绑助理(PRD v1.5);
|
|
242987
|
-
* ② 停用花名册里这个人(**还在别家公司在职就不停用**——停用打的是全局那一行);
|
|
242988
|
-
* ③ 删 human principal bridge(对 company_member 是 CASCADE,但文件/内存实现没有级联,
|
|
242989
|
-
* 显式删一次让「桥随主体走」在应用层也成立);
|
|
242990
|
-
* ④ 删成员行(走 `removeMemberIfNotLastOwner`,组织管理员那一位在这里被纵深防御挡住)。
|
|
243055
|
+
* 移除一条成员关系的**全套副作用**,三条移除路径共用(管理员移除他人 `commit`、
|
|
243056
|
+
* 本人退出组织 `DELETE …/members/me`、注销账号 `DELETE /api/accounts/me`)。
|
|
242991
243057
|
*
|
|
242992
|
-
*
|
|
242993
|
-
*
|
|
243058
|
+
* 顺序与原子性(2026-09-23 代码评审打回后重排):
|
|
243059
|
+
* ① 读一遍成员行:不存在 → 404;**已经是组织管理员 → 当场 403,一个副作用都不做**(D5.2)。
|
|
243060
|
+
* ② 停用花名册里这个人(**还在别家公司在职就不停用**——停用打的是全局那一行)。
|
|
243061
|
+
* 这一步必须在③之前:成员行一删,本公司的 scoped registry 就不再认这个 actor,
|
|
243062
|
+
* 停用会静默 no-op,人被移除了却还挂在花名册上(QA D3 修过一次的病)。
|
|
243063
|
+
* ③ **一个事务**做完控制面三件事:锁内复核目标不是组织管理员 → 清名下 agent 的负责人字段
|
|
243064
|
+
* (`digital_employee.owner` 的复合 FK 是 ON DELETE RESTRICT,不清就是裸 FK 违例;
|
|
243065
|
+
* **只清 owner**,不改状态、不撤凭证、不解绑助理,PRD v1.5)→ 删 human principal bridge
|
|
243066
|
+
* → 删成员行(`store.removeMemberAndReleaseOwnedAgents`)。
|
|
243067
|
+
* ④ ③失败(并发转交把这个人升成了组织管理员,A09)→ 把②CAS 还原回去。
|
|
242994
243068
|
*
|
|
242995
|
-
*
|
|
242996
|
-
*
|
|
243069
|
+
* **为什么③非要是一个事务**:以前①②③是「先清负责人、再停用、再删桥,最后才去拿锁删成员行」
|
|
243070
|
+
* 四段独立的写。A09 那条并发(`O` 转交给 `A1` 的同时另一位管理员删 `A1`)走到最后一步才被
|
|
243071
|
+
* `OWNER_PROTECTED` 拒——而此刻 `A1` 名下 Agent 的负责人已经被清空、桥已经被删、人已经被停用。
|
|
243072
|
+
* 请求失败了,破坏却留下了:新上任的组织管理员丢了名下全部 Agent 的归属、还从花名册上消失。
|
|
243073
|
+
* 现在控制面那三件事共一把锁(与转交锁同一组行),失败时一行都没写;跨不进这把锁的只有员工侧
|
|
243074
|
+
* 停用,用 CAS 补偿还原——「停用之后有别人写过这个 actor」就跳过,不撤销他人的合法写(QA R9)。
|
|
242997
243075
|
*/
|
|
242998
243076
|
async applyMemberRemoval(companyId, accountId) {
|
|
242999
|
-
const released = await this.releaseOwnedAgents(companyId, accountId);
|
|
243000
243077
|
const member = await this.store.getMember(companyId, accountId);
|
|
243001
|
-
if (member
|
|
243002
|
-
|
|
243078
|
+
if (!member) throw new CompanyError(404, "NOT_FOUND", `\u4E0D\u662F\u8BE5\u516C\u53F8\u6210\u5458\uFF1A${accountId}`);
|
|
243079
|
+
if (member.role === "owner") throw new CompanyError(403, "OWNER_PROTECTED", OWNER_PROTECTED_MESSAGE);
|
|
243080
|
+
let ticket = null;
|
|
243081
|
+
if (!await isEmployedElsewhere(this.store, companyId, accountId)) {
|
|
243082
|
+
ticket = await this.disableActor?.(companyId, member.actorId) ?? null;
|
|
243003
243083
|
}
|
|
243004
|
-
await this.store.
|
|
243005
|
-
|
|
243084
|
+
const removed = await this.store.removeMemberAndReleaseOwnedAgents(companyId, accountId, this.now()).catch(async (e) => {
|
|
243085
|
+
await this.compensateDisable(companyId, ticket);
|
|
243086
|
+
throw e;
|
|
243087
|
+
});
|
|
243006
243088
|
if (!removed.ok) {
|
|
243089
|
+
await this.compensateDisable(companyId, ticket);
|
|
243007
243090
|
if (removed.reason === "not_found") {
|
|
243008
243091
|
throw new CompanyError(404, "NOT_FOUND", `\u4E0D\u662F\u8BE5\u516C\u53F8\u6210\u5458\uFF1A${accountId}`);
|
|
243009
243092
|
}
|
|
243010
243093
|
throw new CompanyError(403, "OWNER_PROTECTED", OWNER_PROTECTED_MESSAGE);
|
|
243011
243094
|
}
|
|
243012
|
-
return
|
|
243095
|
+
return removed.releasedAgents;
|
|
243096
|
+
}
|
|
243097
|
+
/**
|
|
243098
|
+
* 把②那次停用还原回去。**只还原本次自己造成的那一次**:`restoreActor` 走 CAS,
|
|
243099
|
+
* 停用之后但凡有别人写过这个 actor 就跳过——留下「成员还在 + actor 已停用」这个合法终态
|
|
243100
|
+
* (与员工页 `DELETE /api/actors/:id` 的终态同构),比静默撤销他人的合法停用安全。
|
|
243101
|
+
* 补偿本身失败不改写主错误:调用方要看到的是「为什么没删成」,不是补偿的二级故障。
|
|
243102
|
+
*/
|
|
243103
|
+
async compensateDisable(companyId, ticket) {
|
|
243104
|
+
if (!ticket || !this.restoreActor) return;
|
|
243105
|
+
try {
|
|
243106
|
+
await this.restoreActor(companyId, ticket);
|
|
243107
|
+
} catch (e) {
|
|
243108
|
+
console.error(
|
|
243109
|
+
`[offboarding] restore actor ${ticket.actorId} failed after removal was rejected: ${e instanceof Error ? e.message : String(e)}`
|
|
243110
|
+
);
|
|
243111
|
+
}
|
|
243013
243112
|
}
|
|
243014
243113
|
/**
|
|
243015
243114
|
* 把该成员名下所有 agent 的负责人字段清空,返回被清的 agent id。
|
|
@@ -243098,10 +243197,18 @@ function companiesDomain(opts) {
|
|
|
243098
243197
|
}
|
|
243099
243198
|
return n;
|
|
243100
243199
|
};
|
|
243200
|
+
const requireActiveCompany = async (companyId) => {
|
|
243201
|
+
const company = await service.get(companyId);
|
|
243202
|
+
if (!company || company.status !== "active") {
|
|
243203
|
+
throw new ApiError(404, "COMPANY_NOT_FOUND", `\u7EC4\u7EC7\u4E0D\u5B58\u5728\u6216\u5DF2\u4E0D\u53EF\u7528\uFF1A${companyId}`);
|
|
243204
|
+
}
|
|
243205
|
+
};
|
|
243101
243206
|
const requireOwnerOrAdmin = async (req, companyId) => {
|
|
243102
243207
|
const me = await whoami(req);
|
|
243103
243208
|
const member = await service.getMember(companyId, me.accountId);
|
|
243104
|
-
if (!member
|
|
243209
|
+
if (!member) throw new ApiError(403, "FORBIDDEN", "\u9700\u8981\u8BE5\u516C\u53F8\u7684 owner/admin \u6743\u9650");
|
|
243210
|
+
await requireActiveCompany(companyId);
|
|
243211
|
+
if (member.role !== "owner" && member.role !== "admin") {
|
|
243105
243212
|
throw new ApiError(403, "FORBIDDEN", "\u9700\u8981\u8BE5\u516C\u53F8\u7684 owner/admin \u6743\u9650");
|
|
243106
243213
|
}
|
|
243107
243214
|
};
|
|
@@ -243109,6 +243216,7 @@ function companiesDomain(opts) {
|
|
|
243109
243216
|
const me = await whoami(req);
|
|
243110
243217
|
const member = await service.getMember(companyId, me.accountId);
|
|
243111
243218
|
if (!member) throw new ApiError(403, "NOT_A_MEMBER", "\u4E0D\u662F\u8BE5\u516C\u53F8\u6210\u5458\uFF0C\u8BBF\u95EE\u88AB\u62D2");
|
|
243219
|
+
await requireActiveCompany(companyId);
|
|
243112
243220
|
return me;
|
|
243113
243221
|
};
|
|
243114
243222
|
return (router) => {
|
|
@@ -243232,7 +243340,6 @@ function companiesDomain(opts) {
|
|
|
243232
243340
|
const aid = req.params.accountId;
|
|
243233
243341
|
await requireOwnerOrAdmin(req, cid);
|
|
243234
243342
|
const member = await service.peekRemovableMember(cid, aid).catch(mapErr);
|
|
243235
|
-
if (offboarding) await offboarding.releaseOwnedAgents(cid, aid).catch(mapErr);
|
|
243236
243343
|
let actorsSvc;
|
|
243237
243344
|
let ownedDisableBefore = null;
|
|
243238
243345
|
let disableSeq = 0;
|
|
@@ -243628,9 +243735,30 @@ function createCompaniesDomain(opts) {
|
|
|
243628
243735
|
...opts.resolveActorsCtx !== void 0 ? {
|
|
243629
243736
|
// 未认领转 left 的 agent、以及 commit 移除掉的那位成员,都要把员工侧 ActorRecord
|
|
243630
243737
|
// 一并软停用——否则控制面说「已离开/已移除」、花名册还显示在岗,两个事实源当场分叉。
|
|
243738
|
+
//
|
|
243739
|
+
// 用 `disableActorIfCurrentlyActive` 而不是 `disableActor`,并把 `{before, seq}` 回给
|
|
243740
|
+
// offboarding:只有**真的把这个 actor 从 active 拉到 disabled** 的那一次调用才拿得到
|
|
243741
|
+
// 返回值,也才「拥有」这次状态变更;已被并发请求或员工页先停用的一律 ok:false,
|
|
243742
|
+
// 本次就不 own、移除失败也不补偿(QA R10 的判据,两条移除路径同一套)。
|
|
243631
243743
|
disableActor: async (companyId, actorId) => {
|
|
243632
243744
|
const ctx = await opts.resolveActorsCtx(companyId);
|
|
243633
|
-
await ctx.service.disableActorIfCurrentlyActive(actorId, "system:offboarding");
|
|
243745
|
+
const res = await ctx.service.disableActorIfCurrentlyActive(actorId, "system:offboarding");
|
|
243746
|
+
return res.ok ? { actorId, before: res.before, seq: res.seq } : null;
|
|
243747
|
+
},
|
|
243748
|
+
// 移除最终失败时的补偿:**CAS** 写回停用前那一行。`expectedSeq` 对不上(停用之后
|
|
243749
|
+
// 有任何第三方写过这个 actor)就跳过——不静默撤销他人的合法停用 / 改名(QA R9)。
|
|
243750
|
+
restoreActor: async (companyId, ticket) => {
|
|
243751
|
+
const ctx = await opts.resolveActorsCtx(companyId);
|
|
243752
|
+
const res = await ctx.service.casUpsertActor(
|
|
243753
|
+
{ ...ticket.before, status: "active" },
|
|
243754
|
+
ticket.seq,
|
|
243755
|
+
"system:offboarding"
|
|
243756
|
+
);
|
|
243757
|
+
if (!res.ok) {
|
|
243758
|
+
console.info(
|
|
243759
|
+
`[companies] restore skipped for ${ticket.actorId}: another write intervened after the disable`
|
|
243760
|
+
);
|
|
243761
|
+
}
|
|
243634
243762
|
}
|
|
243635
243763
|
} : {}
|
|
243636
243764
|
});
|
|
@@ -260652,7 +260780,7 @@ async function ensureOneOwnerInvariant(pool, s2) {
|
|
|
260652
260780
|
);
|
|
260653
260781
|
}
|
|
260654
260782
|
}
|
|
260655
|
-
var ident8, PostgresControlPlaneStore, rowToDigitalEmployee, rowToAgentCredential, rowToBridge, rowToOffboarding, toIso, rowToCompany, rowToRoleMigration, rowToMember, rowToInvitation, rowToInviteLink, rowToAccount, rowToVerificationCode;
|
|
260783
|
+
var ident8, PostgresControlPlaneStore, rowToDigitalEmployee, rowToAgentCredential, rowToBridge, rowToOffboarding, toIso, rowToCompany, rowToRoleMigration, migrationRow2, rowToMember, rowToInvitation, rowToInviteLink, rowToAccount, rowToVerificationCode;
|
|
260656
260784
|
var init_postgres_control_plane = __esm({
|
|
260657
260785
|
"../storage/src/postgres-control-plane.ts"() {
|
|
260658
260786
|
"use strict";
|
|
@@ -261043,6 +261171,48 @@ var init_postgres_control_plane = __esm({
|
|
|
261043
261171
|
client.release();
|
|
261044
261172
|
}
|
|
261045
261173
|
}
|
|
261174
|
+
async removeMemberAndReleaseOwnedAgents(companyId, accountId, at2) {
|
|
261175
|
+
const client = await this.pool.connect();
|
|
261176
|
+
try {
|
|
261177
|
+
await client.query("BEGIN");
|
|
261178
|
+
const all2 = await client.query(
|
|
261179
|
+
`SELECT company_id, account_id, actor_id, role, display_name, onboarding_completed_at, onboarding_step
|
|
261180
|
+
FROM ${this.s}.company_members WHERE company_id = $1 FOR UPDATE`,
|
|
261181
|
+
[companyId]
|
|
261182
|
+
);
|
|
261183
|
+
const target = all2.rows.map(rowToMember).find((m2) => m2.accountId === accountId);
|
|
261184
|
+
if (!target) {
|
|
261185
|
+
await client.query("ROLLBACK");
|
|
261186
|
+
return { ok: false, reason: "not_found" };
|
|
261187
|
+
}
|
|
261188
|
+
if (target.role === "owner") {
|
|
261189
|
+
await client.query("ROLLBACK");
|
|
261190
|
+
return { ok: false, reason: "owner_protected" };
|
|
261191
|
+
}
|
|
261192
|
+
const released = await client.query(
|
|
261193
|
+
`UPDATE ${this.s}.digital_employees SET owner_account_id = NULL, updated_at = $3
|
|
261194
|
+
WHERE company_id = $1 AND owner_account_id = $2
|
|
261195
|
+
RETURNING id`,
|
|
261196
|
+
[companyId, accountId, at2]
|
|
261197
|
+
);
|
|
261198
|
+
await client.query(
|
|
261199
|
+
`DELETE FROM ${this.s}.principal_bridge WHERE company_id = $1 AND principal_type = 'human' AND principal_id = $2`,
|
|
261200
|
+
[companyId, accountId]
|
|
261201
|
+
);
|
|
261202
|
+
await client.query(
|
|
261203
|
+
`DELETE FROM ${this.s}.company_members WHERE company_id = $1 AND account_id = $2`,
|
|
261204
|
+
[companyId, accountId]
|
|
261205
|
+
);
|
|
261206
|
+
await client.query("COMMIT");
|
|
261207
|
+
return { ok: true, member: target, releasedAgents: released.rows.map((r) => r.id) };
|
|
261208
|
+
} catch (e) {
|
|
261209
|
+
await client.query("ROLLBACK").catch(() => {
|
|
261210
|
+
});
|
|
261211
|
+
throw e;
|
|
261212
|
+
} finally {
|
|
261213
|
+
client.release();
|
|
261214
|
+
}
|
|
261215
|
+
}
|
|
261046
261216
|
async updateMemberRoleIfNotLastOwner(companyId, accountId, role) {
|
|
261047
261217
|
const client = await this.pool.connect();
|
|
261048
261218
|
try {
|
|
@@ -261111,7 +261281,7 @@ var init_postgres_control_plane = __esm({
|
|
|
261111
261281
|
`SELECT status FROM ${this.s}.accounts WHERE id = $1`,
|
|
261112
261282
|
[toAccountId]
|
|
261113
261283
|
);
|
|
261114
|
-
if (acc.rows[0]
|
|
261284
|
+
if (!acc.rows[0] || acc.rows[0].status !== "active") {
|
|
261115
261285
|
await client.query("ROLLBACK");
|
|
261116
261286
|
return { ok: false, reason: "target_inactive" };
|
|
261117
261287
|
}
|
|
@@ -261148,6 +261318,73 @@ var init_postgres_control_plane = __esm({
|
|
|
261148
261318
|
client.release();
|
|
261149
261319
|
}
|
|
261150
261320
|
}
|
|
261321
|
+
// —— 存量身份映射(ADR D3)——
|
|
261322
|
+
async migrateSoleCompanyOwner(companyId, toAccountId, audit2) {
|
|
261323
|
+
const client = await this.pool.connect();
|
|
261324
|
+
try {
|
|
261325
|
+
await client.query("BEGIN");
|
|
261326
|
+
const all2 = await client.query(
|
|
261327
|
+
`SELECT company_id, account_id, actor_id, role, display_name, onboarding_completed_at, onboarding_step
|
|
261328
|
+
FROM ${this.s}.company_members WHERE company_id = $1 FOR UPDATE`,
|
|
261329
|
+
[companyId]
|
|
261330
|
+
);
|
|
261331
|
+
const rows = all2.rows.map(rowToMember);
|
|
261332
|
+
const target = rows.find((m2) => m2.accountId === toAccountId);
|
|
261333
|
+
if (!target) {
|
|
261334
|
+
await client.query("ROLLBACK");
|
|
261335
|
+
return { ok: false, reason: "not_found" };
|
|
261336
|
+
}
|
|
261337
|
+
const others = rows.filter((m2) => m2.role === "owner" && m2.accountId !== toAccountId);
|
|
261338
|
+
if (others.length === 0 && target.role === "owner") {
|
|
261339
|
+
await client.query("COMMIT");
|
|
261340
|
+
return { ok: true, owner: target, demoted: [], auditRows: [] };
|
|
261341
|
+
}
|
|
261342
|
+
if (others.length > 0) {
|
|
261343
|
+
await client.query(
|
|
261344
|
+
`UPDATE ${this.s}.company_members SET role = 'admin' WHERE company_id = $1 AND role = 'owner' AND account_id <> $2`,
|
|
261345
|
+
[companyId, toAccountId]
|
|
261346
|
+
);
|
|
261347
|
+
}
|
|
261348
|
+
if (target.role !== "owner") {
|
|
261349
|
+
await client.query(
|
|
261350
|
+
`UPDATE ${this.s}.company_members SET role = 'owner' WHERE company_id = $1 AND account_id = $2`,
|
|
261351
|
+
[companyId, toAccountId]
|
|
261352
|
+
);
|
|
261353
|
+
}
|
|
261354
|
+
const auditRows = [
|
|
261355
|
+
...others.map((m2) => migrationRow2(companyId, m2.accountId, "owner", "admin", audit2)),
|
|
261356
|
+
...target.role !== "owner" ? [migrationRow2(companyId, toAccountId, target.role, "owner", audit2)] : []
|
|
261357
|
+
];
|
|
261358
|
+
for (const r of auditRows) {
|
|
261359
|
+
await client.query(
|
|
261360
|
+
`INSERT INTO ${this.s}.company_member_role_migrations
|
|
261361
|
+
(company_id, account_id, role_before, role_after, evidence, manifest_version, applied_at)
|
|
261362
|
+
VALUES ($1,$2,$3,$4,$5,$6,$7)`,
|
|
261363
|
+
[r.companyId, r.accountId, r.roleBefore, r.roleAfter, r.evidence, r.manifestVersion ?? null, r.appliedAt]
|
|
261364
|
+
);
|
|
261365
|
+
}
|
|
261366
|
+
await client.query("COMMIT");
|
|
261367
|
+
return {
|
|
261368
|
+
ok: true,
|
|
261369
|
+
owner: { ...target, role: "owner" },
|
|
261370
|
+
demoted: others.map((m2) => ({ ...m2, role: "admin" })),
|
|
261371
|
+
auditRows
|
|
261372
|
+
};
|
|
261373
|
+
} catch (e) {
|
|
261374
|
+
await client.query("ROLLBACK").catch(() => {
|
|
261375
|
+
});
|
|
261376
|
+
throw e;
|
|
261377
|
+
} finally {
|
|
261378
|
+
client.release();
|
|
261379
|
+
}
|
|
261380
|
+
}
|
|
261381
|
+
async setMemberRoleOnly(companyId, accountId, role) {
|
|
261382
|
+
const r = await this.pool.query(
|
|
261383
|
+
`UPDATE ${this.s}.company_members SET role = $3 WHERE company_id = $1 AND account_id = $2`,
|
|
261384
|
+
[companyId, accountId, role]
|
|
261385
|
+
);
|
|
261386
|
+
return (r.rowCount ?? 0) > 0;
|
|
261387
|
+
}
|
|
261151
261388
|
// —— 存量身份映射审计(ADR D3.4)——
|
|
261152
261389
|
async appendMemberRoleMigrations(rows) {
|
|
261153
261390
|
if (rows.length === 0) return;
|
|
@@ -261661,6 +261898,15 @@ var init_postgres_control_plane = __esm({
|
|
|
261661
261898
|
...row.manifest_version != null ? { manifestVersion: row.manifest_version } : {},
|
|
261662
261899
|
appliedAt: toIso(row.applied_at)
|
|
261663
261900
|
});
|
|
261901
|
+
migrationRow2 = (companyId, accountId, roleBefore, roleAfter, audit2) => ({
|
|
261902
|
+
companyId,
|
|
261903
|
+
accountId,
|
|
261904
|
+
roleBefore,
|
|
261905
|
+
roleAfter,
|
|
261906
|
+
evidence: audit2.evidence,
|
|
261907
|
+
...audit2.evidence === "manifest" && audit2.manifestVersion !== void 0 ? { manifestVersion: audit2.manifestVersion } : {},
|
|
261908
|
+
appliedAt: audit2.appliedAt
|
|
261909
|
+
});
|
|
261664
261910
|
rowToMember = (row) => ({
|
|
261665
261911
|
companyId: row.company_id,
|
|
261666
261912
|
accountId: row.account_id,
|
|
@@ -293490,7 +293736,7 @@ async function waitForCommandAuthorization(base, headers, draftId, fallback) {
|
|
|
293490
293736
|
}
|
|
293491
293737
|
}
|
|
293492
293738
|
}
|
|
293493
|
-
var CLI_VERSION = "2.2.
|
|
293739
|
+
var CLI_VERSION = "2.2.82" ? "2.2.82" : "dev";
|
|
293494
293740
|
function apiHeaders(token, company) {
|
|
293495
293741
|
const headers = {
|
|
293496
293742
|
authorization: `Bearer ${token}`,
|
|
@@ -295287,7 +295533,13 @@ ${res.warning}`);
|
|
|
295287
295533
|
if (live.length > 0) {
|
|
295288
295534
|
for (const r of live) println(`[design] \u5F15\u64CE\u5728\u8DD1\uFF1Arun ${r.runId.slice(0, 8)} \u72B6\u6001=${r.status}\u2014\u2014\u522B\u518D\u8D77\u65B0\u8F6E\uFF1B\u8FC7\u51E0\u5206\u949F\u518D status\uFF0C\u6216\u672C\u8F6E\u6536\u5DE5\u7B49\u91CD\u6D3E\u3002`);
|
|
295289
295535
|
} else if (st.runs.length > 0) {
|
|
295290
|
-
for (const r of st.runs.slice(0, 3))
|
|
295536
|
+
for (const r of st.runs.slice(0, 3)) {
|
|
295537
|
+
println(`[design] \u8FD1\u671F run\uFF1A${r.runId.slice(0, 8)} \u7EC8\u6001=${r.status}${r.agentId ? ` \u5F15\u64CE=${r.agentId}` : ""}`);
|
|
295538
|
+
if (r.status === "failed" && r.error) {
|
|
295539
|
+
const reason = r.error.length > 300 ? `${r.error.slice(0, 300)}\u2026` : r.error;
|
|
295540
|
+
println(`[design] \u5931\u8D25\u539F\u56E0\uFF08od \u539F\u6587\uFF09\uFF1A${reason}`);
|
|
295541
|
+
}
|
|
295542
|
+
}
|
|
295291
295543
|
} else {
|
|
295292
295544
|
println(`[design] \u65E0\u5728\u4E16 run \u8BB0\u5F55\uFF08od \u91CD\u542F\u540E\u4E3A\u7A7A\uFF0C\u5C5E\u6B63\u5E38\uFF09\u2014\u2014\u770B\u4E0B\u9762\u677F\u4E0A\u4EA7\u7269\u5373\u6301\u4E45\u771F\u76F8\u3002`);
|
|
295293
295545
|
}
|
|
@@ -295299,7 +295551,7 @@ ${res.warning}`);
|
|
|
295299
295551
|
for (const a of st.artifacts) println(` - ${a.path}\uFF08${a.kind ?? "?"}\uFF09status=${a.status ?? "?"}${a.mtime ? ` \xB7 ${new Date(a.mtime).toISOString()}` : ""}`);
|
|
295300
295552
|
if (flags.get("pull") === "true") {
|
|
295301
295553
|
const odPublic = (flags.get("od-public-url") ?? process.env["OASIS_OPEN_DESIGN_PUBLIC_URL"] ?? "https://design.open-friday.com").replace(/\/$/, "");
|
|
295302
|
-
const { dir: dir2, entry } = await harvestBoard(odBase, odFetch, odPublic, os13.tmpdir(), st.boardKey, st.runs
|
|
295554
|
+
const { dir: dir2, entry } = await harvestBoard(odBase, odFetch, odPublic, os13.tmpdir(), st.boardKey, latestSucceededRun(st.runs)?.runId ?? "status-pull");
|
|
295303
295555
|
println(`[design] \u5DF2\u62C9\u5230\u672C\u5730\uFF1A${dir2}\uFF08\u5165\u53E3 ${entry}\uFF09`);
|
|
295304
295556
|
println(`[design] \u8BFB\u5B8C\u6EE1\u610F\u5373\u4EA4\u7A3F\uFF1Aoasis propose ${artifactId} --from-dir ${dir2} --reason "<\u8FD9\u7248\u505A\u4E86\u4EC0\u4E48>"`);
|
|
295305
295557
|
} else {
|
|
@@ -297400,7 +297652,7 @@ function shimScript() {
|
|
|
297400
297652
|
}
|
|
297401
297653
|
|
|
297402
297654
|
// src/index.ts
|
|
297403
|
-
var PKG_VERSION = true ? "2.2.
|
|
297655
|
+
var PKG_VERSION = true ? "2.2.82" : "dev";
|
|
297404
297656
|
var LOCAL_BIN = localBin();
|
|
297405
297657
|
var NPM_PREFIX = npmPrefix();
|
|
297406
297658
|
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.82",
|
|
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": "6a195fdb899ac4fe62d0cb8a164be7840880a6a7"
|
|
30
30
|
}
|
|
31
31
|
}
|