oasis_test_v2 2.2.58 → 2.2.59

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.
Files changed (2) hide show
  1. package/dist/index.js +77 -7
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -226703,6 +226703,37 @@ var init_service5 = __esm({
226703
226703
  await this.opts.store.removeBinding(actorId);
226704
226704
  await this.audit({ kind: "binding_change", actorId, by, at: this.now(), detail: { removed: true } });
226705
226705
  }
226706
+ /**
226707
+ * 运行时被删除时,把指向它的绑定一并撤掉(与 {@link dropRuntimeBindingOfDeletedAgent} 对称的另一头)。
226708
+ *
226709
+ * 为什么撤绑而不是把绑定留着标成失效(缺陷 0124,2026-09-21 R05 第 4 步实测):
226710
+ * 管理员删掉 `node-abe354908271` 上的 codex 后,绑在它上面的两个 Agent 的绑定行仍是
226711
+ * `codex / active`,指着一条已经不存在的运行时——运行时页要靠「这行还在不在」去过滤它,
226712
+ * 派单要靠 resolveBinding 去挡它,组织页要自己推「绑的那个还在不在」,**每个读者各挡一遍,
226713
+ * 漏一处就复发**。绑定表是「此刻该派到哪」的唯一事实源,不是历史账本:历史在 agent_runs /
226714
+ * traces / 审计里,撤绑一条都不动,所以 R05 要的「已有运行记录仍查得到」不受影响。
226715
+ * `BindingStatus` 只有 `active | paused` 两个值,拿 `paused`(人工暂停、可恢复)表示
226716
+ * 「目标没了」会让后来的读者误判,而加新值是 `packages/contract` 变更(红线 4)。
226717
+ *
226718
+ * 幂等:没有绑定就是空数组;`removeBinding` 对不存在的 actor 是 no-op。
226719
+ * @returns 被撤绑的 actorId 列表(调用方用来回给界面:删完影响了谁)。
226720
+ */
226721
+ async releaseBindingsOnRuntime(target, by) {
226722
+ const affected = (await this.opts.store.listBindings()).filter(
226723
+ (b2) => b2.nodeId === target.nodeId && b2.runtimeKind === target.runtimeKind
226724
+ );
226725
+ for (const b2 of affected) {
226726
+ await this.opts.store.removeBinding(b2.actorId);
226727
+ await this.audit({
226728
+ kind: "binding_change",
226729
+ actorId: b2.actorId,
226730
+ by,
226731
+ at: this.now(),
226732
+ detail: { removed: true, reason: "runtime_deleted", nodeId: b2.nodeId, runtimeKind: b2.runtimeKind }
226733
+ });
226734
+ }
226735
+ return affected.map((b2) => b2.actorId);
226736
+ }
226706
226737
  listBindings() {
226707
226738
  return this.opts.store.listBindings();
226708
226739
  }
@@ -241008,8 +241039,9 @@ function nodesDomain(deps) {
241008
241039
  const runtime = (await deps.nodeStore.listRuntimes()).find((r) => r.id === runtimeId);
241009
241040
  const { nodeDeleted } = await deps.nodeStore.deleteRuntime(runtimeId);
241010
241041
  if (nodeDeleted && runtime) revokeNodeAccess(runtime.nodeId);
241042
+ const releasedActorIds = runtime ? await deps.releaseBindingsOnRuntime?.(req.auth.companyId, { nodeId: runtime.nodeId, runtimeKind: runtime.kind }, req.auth.actor) ?? [] : [];
241011
241043
  deps.onStatusChange?.();
241012
- return { status: 200, body: { ok: true } };
241044
+ return { status: 200, body: { ok: true, releasedActorIds } };
241013
241045
  });
241014
241046
  router.get("/api/runtimes/:runtimeId/models", async (req) => {
241015
241047
  const runtimeId = req.params["runtimeId"];
@@ -276843,6 +276875,12 @@ async function startServe(opts) {
276843
276875
  const [roster, bindings] = await Promise.all([service.listActors({ kind: "agent" }), service.listBindings()]);
276844
276876
  return { actors: roster, bindings };
276845
276877
  },
276878
+ // 缺陷 0124:删掉运行时后,绑在它上面的 Agent 不该继续挂在一条已经不存在的运行时上。
276879
+ // 与 actorBindings 同一条解析路径(按请求公司拿这家的员工域),写侧落审计。
276880
+ releaseBindingsOnRuntime: async (companyId, target, by) => {
276881
+ const { service } = await actors.resolveCtx(companyId ?? defaultCompanyId);
276882
+ return service.releaseBindingsOnRuntime(target, by);
276883
+ },
276846
276884
  nodeTokens,
276847
276885
  enrollTokens,
276848
276886
  nodeStore,
@@ -285224,8 +285262,9 @@ function safeFileName(raw, fallback) {
285224
285262
  const cleaned = displayName2(raw).replace(/[\\/:*?"<>|-]+/g, "_").replace(/\s+/g, "_").replace(/^\.+/, "").replace(/_+/g, "_").replace(/^_|_$/g, "");
285225
285263
  return cleaned || fallback;
285226
285264
  }
285227
- function resolveProjectFileOutPath(rawOut, fileName) {
285228
- const fallback = `${PROJECT_FILES_DIR}/${safeFileName(fileName, "file")}`;
285265
+ function resolveProjectFileOutPath(rawOut, fileName, contentType) {
285266
+ const ext = sourceExtension(fileName, contentType);
285267
+ const fallback = keepExtension(`${PROJECT_FILES_DIR}/${safeFileName(fileName, "file")}`, ext);
285229
285268
  if (rawOut === void 0 || rawOut.trim() === "") return fallback;
285230
285269
  const raw = rawOut.trim();
285231
285270
  if (path35.isAbsolute(raw) || /^[a-zA-Z]:[\\/]/.test(raw)) {
@@ -285244,7 +285283,38 @@ function resolveProjectFileOutPath(rawOut, fileName) {
285244
285283
  if (segments.length < 2 || segments[0] !== PROJECT_FILES_DIR) {
285245
285284
  throw new Error(`--out \u5FC5\u987B\u843D\u5728 ${PROJECT_FILES_DIR}/ \u4E0B\uFF08\u4F8B\uFF1A--out ${PROJECT_FILES_DIR}/${safeFileName(fileName, "file")}\uFF09`);
285246
285285
  }
285247
- return segments.join("/");
285286
+ return keepExtension(segments.join("/"), ext);
285287
+ }
285288
+ var EXT_BY_MIME = {
285289
+ "text/markdown": ".md",
285290
+ "text/x-markdown": ".md",
285291
+ "text/plain": ".txt",
285292
+ "text/html": ".html",
285293
+ "text/csv": ".csv",
285294
+ "application/json": ".json",
285295
+ "application/pdf": ".pdf",
285296
+ "image/png": ".png",
285297
+ "image/jpeg": ".jpg",
285298
+ "image/gif": ".gif",
285299
+ "image/webp": ".webp",
285300
+ "image/svg+xml": ".svg",
285301
+ "application/zip": ".zip"
285302
+ };
285303
+ function realExtension(name) {
285304
+ const ext = path35.posix.extname(name);
285305
+ return /^\.[A-Za-z0-9]{1,8}$/.test(ext) ? ext : "";
285306
+ }
285307
+ function sourceExtension(fileName, contentType) {
285308
+ const own3 = realExtension(displayName2(fileName));
285309
+ if (own3) return own3;
285310
+ const mime = (contentType ?? "").split(";")[0].trim().toLowerCase();
285311
+ return EXT_BY_MIME[mime] ?? "";
285312
+ }
285313
+ function keepExtension(rel, ext) {
285314
+ if (!ext) return rel;
285315
+ const current = realExtension(rel);
285316
+ if (current.toLowerCase() === ext.toLowerCase()) return rel;
285317
+ return `${current ? rel.slice(0, rel.length - current.length) : rel}${ext}`;
285248
285318
  }
285249
285319
  function isTextLike(name, contentType) {
285250
285320
  if (contentType) {
@@ -285532,7 +285602,7 @@ async function waitForCommandAuthorization(base, headers, draftId, fallback) {
285532
285602
  }
285533
285603
  }
285534
285604
  }
285535
- var CLI_VERSION = "2.2.58" ? "2.2.58" : "dev";
285605
+ var CLI_VERSION = "2.2.59" ? "2.2.59" : "dev";
285536
285606
  function apiHeaders(token, company) {
285537
285607
  const headers = {
285538
285608
  authorization: `Bearer ${token}`,
@@ -286953,7 +287023,7 @@ ${t.ref} ${t.name} [\u5267\u672C=${t.playbookRef}]`);
286953
287023
  );
286954
287024
  const row = findByBlobRef(view.items ?? [], ref2);
286955
287025
  const name = displayName2(row.name);
286956
- const rel = resolveProjectFileOutPath(flags.get("out"), name);
287026
+ const rel = resolveProjectFileOutPath(flags.get("out"), name, row.content_type);
286957
287027
  const bytes2 = await api.bytes(`/api/blobs/${encodeURIComponent((row.blob_ref ?? "").replace(/^blob:/, ""))}`);
286958
287028
  const abs = path36.resolve(process.cwd(), rel);
286959
287029
  fs41.mkdirSync(path36.dirname(abs), { recursive: true });
@@ -289223,7 +289293,7 @@ function shimScript() {
289223
289293
  }
289224
289294
 
289225
289295
  // src/index.ts
289226
- var PKG_VERSION = true ? "2.2.58" : "dev";
289296
+ var PKG_VERSION = true ? "2.2.59" : "dev";
289227
289297
  var LOCAL_BIN = localBin();
289228
289298
  var NPM_PREFIX = npmPrefix();
289229
289299
  var INSTANCE = DEFAULT_INSTANCE;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oasis_test_v2",
3
- "version": "2.2.58",
3
+ "version": "2.2.59",
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": "cdfbae7cb82edf949c9985a7cddd3aee06ca1017"
29
+ "sourceHead": "4292e61fee71d87d1776f8fa63d4015adc9c544c"
30
30
  }
31
31
  }