oasis_test 0.1.70 → 0.1.72

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 +172 -71
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -137173,7 +137173,6 @@ var init_live_chat = __esm({
137173
137173
  if (!turn || turn.status !== "running") return { accepted: false, reason: "no-live-turn" };
137174
137174
  const fn = turn.handle.appendInput;
137175
137175
  if (typeof fn !== "function") return { accepted: false, reason: "unsupported" };
137176
- if (turn.handle.canAppendInput === false) return { accepted: false, reason: "session-closing" };
137177
137176
  let res;
137178
137177
  try {
137179
137178
  res = await fn.call(turn.handle, { text: text2 });
@@ -138897,7 +138896,7 @@ function requiresMeReasonOf(model, artifact, viewer, facts) {
138897
138896
  function computeRequiresMe(model, artifact, viewer, facts) {
138898
138897
  return requiresMeReasonOf(model, artifact, viewer, facts) !== null;
138899
138898
  }
138900
- function buildWorkorderDetail(model, workspaceId, resolveActor, resolveProject, dispatchJournal = [], dispatchPausedOf, ops = [], reviewerPreview, dispatcherSignalsOf, viewer, roleDefaultOwnerOf) {
138899
+ function buildWorkorderDetail(model, workspaceId, resolveActor, resolveProject, dispatchJournal = [], dispatchPausedOf, ops = [], reviewerPreview, dispatcherSignalsOf, viewer, roleDefaultOwnerOf, roleLabelOf) {
138901
138900
  const arts = [...model.artifacts.values()].filter((a) => a.workspace === workspaceId);
138902
138901
  if (arts.length === 0) return null;
138903
138902
  const ref2 = (id) => {
@@ -138961,11 +138960,15 @@ function buildWorkorderDetail(model, workspaceId, resolveActor, resolveProject,
138961
138960
  quorum: pv.quorum,
138962
138961
  // 0089:每桶门槛后端给,前端别拿聚合 quorum 做减法。
138963
138962
  // 诊断 f1641dd3-abdaa869(改 B):给角色桶补**纯展示**的 defaultOwner(该角色 RoleDef.defaultOwner
138964
- // 解析成 ActorRef)。core 无岗位目录、算不出,故在此注入。未配 / 无解析器 → 不带该字段。
138963
+ // 解析成 ActorRef)与 roleLabel(RoleDef.label 中文名,annotation 6e3608ee)。core 无岗位目录、
138964
+ // 算不出,故在此注入。未配 / 无解析器 → 不带对应字段(前端各自兜底)。
138965
138965
  reviewerRequirements: pv.requirements.map((r) => {
138966
138966
  if (r.source !== "type") return r;
138967
- const owner = r.roles?.[0] ? roleDefaultOwnerOf?.(r.roles[0]) : void 0;
138968
- return owner ? { ...r, defaultOwner: ref2(owner) } : r;
138967
+ const role = r.roles?.[0];
138968
+ const owner = role ? roleDefaultOwnerOf?.(role) : void 0;
138969
+ const label = role ? roleLabelOf?.(role) : void 0;
138970
+ const withOwner = owner ? { ...r, defaultOwner: ref2(owner) } : r;
138971
+ return label ? { ...withOwner, roleLabel: label } : withOwner;
138969
138972
  }),
138970
138973
  // 0101:审核角色是否被覆盖过(替换了类型默认)——供详情页角色位徽标/复原判断。
138971
138974
  ...a.reviewRoles !== void 0 ? { reviewRolesOverridden: true } : {},
@@ -142560,13 +142563,13 @@ async function startOasisServer(opts) {
142560
142563
  const actorCtx = await opts.resolveActorContext(body.actorId).catch(() => null);
142561
142564
  if (actorCtx) {
142562
142565
  const { mkdtempSync: mkdtempSync5, mkdirSync: mkdirSync20, writeFileSync: writeFileSync13 } = await import("node:fs");
142563
- const { join: join28, dirname: dirname24 } = await import("node:path");
142566
+ const { join: join28, dirname: dirname25 } = await import("node:path");
142564
142567
  const { tmpdir: tmpdir9 } = await import("node:os");
142565
142568
  const dir = mkdtempSync5(join28(tmpdir9(), "oasis-chat-"));
142566
142569
  if (actorCtx.config?.prompt) {
142567
142570
  for (const [rel, content] of Object.entries(splitIdentityFiles2(actorCtx.config.prompt))) {
142568
142571
  const file = join28(dir, rel);
142569
- mkdirSync20(dirname24(file), { recursive: true });
142572
+ mkdirSync20(dirname25(file), { recursive: true });
142570
142573
  writeFileSync13(file, content);
142571
142574
  }
142572
142575
  }
@@ -142583,7 +142586,7 @@ async function startOasisServer(opts) {
142583
142586
  const skillFiles = await opts.materializeSkills(body.actorId, "claude").catch(() => ({}));
142584
142587
  for (const [rel, content] of Object.entries(skillFiles)) {
142585
142588
  const file = join28(dir, rel);
142586
- mkdirSync20(dirname24(file), { recursive: true });
142589
+ mkdirSync20(dirname25(file), { recursive: true });
142587
142590
  writeFileSync13(file, content);
142588
142591
  }
142589
142592
  }
@@ -151656,6 +151659,25 @@ export GITHUB_TOKEN=${shSingleQuote2(token)}
151656
151659
  }
151657
151660
  });
151658
151661
 
151662
+ // ../connectors/src/registry.ts
151663
+ function createConnectorBySlug(slug5) {
151664
+ switch (slug5) {
151665
+ case "feishu":
151666
+ return new FeishuConnector();
151667
+ case "github":
151668
+ return new GithubConnector();
151669
+ default:
151670
+ return null;
151671
+ }
151672
+ }
151673
+ var init_registry2 = __esm({
151674
+ "../connectors/src/registry.ts"() {
151675
+ "use strict";
151676
+ init_feishu();
151677
+ init_github();
151678
+ }
151679
+ });
151680
+
151659
151681
  // ../adapters/src/open-design/driver.ts
151660
151682
  function deriveBoardKey(artifactId) {
151661
151683
  const tail = artifactId.split(":").pop() ?? artifactId;
@@ -152324,6 +152346,11 @@ function buildClaudeUsage(acc) {
152324
152346
  costUsdMicros: acc.costUsd != null ? Math.round(acc.costUsd * 1e6) : null
152325
152347
  };
152326
152348
  }
152349
+ function claudeAppendGraceMs(opts) {
152350
+ const raw = opts.appendGraceMs ?? Number(process.env["OASIS_CLAUDE_APPEND_GRACE_MS"] ?? NaN);
152351
+ const n = Number.isFinite(raw) ? Number(raw) : 8e3;
152352
+ return n > 0 ? n : 0;
152353
+ }
152327
152354
  function claudeAppendEnabled(opts) {
152328
152355
  if (opts.streamJson !== true) return false;
152329
152356
  if (opts.enableAppendInput === false) return false;
@@ -152426,6 +152453,7 @@ var init_claude_code = __esm({
152426
152453
  const prompt = materializeBundle(dir, job.bundle);
152427
152454
  const promptViaStdin = Buffer.byteLength(prompt, "utf8") > 1e5;
152428
152455
  const appendMode = claudeAppendEnabled(this.opts);
152456
+ const appendGraceMs = claudeAppendGraceMs(this.opts);
152429
152457
  const promptOnStdin = appendMode || promptViaStdin;
152430
152458
  const runtimeSessionArgs = job.runtimeSessionId ? job.resumeRuntimeSession ? ["--resume", job.runtimeSessionId] : ["--session-id", job.runtimeSessionId] : [];
152431
152459
  const oneShotSafety = this.opts.oneShotSafety !== false;
@@ -152471,18 +152499,27 @@ var init_claude_code = __esm({
152471
152499
  let writes = 0;
152472
152500
  let results = 0;
152473
152501
  let inputClosing = false;
152502
+ let pendingClose = null;
152503
+ const cancelPendingClose = () => {
152504
+ if (pendingClose) {
152505
+ clearTimeout(pendingClose);
152506
+ pendingClose = null;
152507
+ }
152508
+ };
152474
152509
  const writeUserMessage = (text2) => {
152475
152510
  try {
152476
152511
  child.stdin.write(
152477
152512
  JSON.stringify({ type: "user", message: { role: "user", content: [{ type: "text", text: text2 }] } }) + "\n"
152478
152513
  );
152479
152514
  writes++;
152515
+ cancelPendingClose();
152480
152516
  return true;
152481
152517
  } catch {
152482
152518
  return false;
152483
152519
  }
152484
152520
  };
152485
152521
  const closeInput = () => {
152522
+ cancelPendingClose();
152486
152523
  if (inputClosing) return;
152487
152524
  inputClosing = true;
152488
152525
  try {
@@ -152491,7 +152528,17 @@ var init_claude_code = __esm({
152491
152528
  }
152492
152529
  };
152493
152530
  const maybeCloseInputOnResult = () => {
152494
- if (appendMode && !inputClosing && results >= writes) closeInput();
152531
+ if (!appendMode || inputClosing || results < writes) return;
152532
+ if (appendGraceMs <= 0) {
152533
+ closeInput();
152534
+ return;
152535
+ }
152536
+ cancelPendingClose();
152537
+ pendingClose = setTimeout(() => {
152538
+ pendingClose = null;
152539
+ closeInput();
152540
+ }, appendGraceMs);
152541
+ pendingClose.unref?.();
152495
152542
  };
152496
152543
  let interruptSeq = 0;
152497
152544
  const writeInterrupt = () => {
@@ -152641,11 +152688,13 @@ var init_claude_code = __esm({
152641
152688
  ...sessionModel ? { model: sessionModel } : {},
152642
152689
  ...errorMessage ? { errorMessage } : {}
152643
152690
  };
152691
+ cancelPendingClose();
152644
152692
  for (const cb of callbacks.splice(0)) cb(exited);
152645
152693
  });
152646
152694
  return {
152647
152695
  id,
152648
152696
  async kill() {
152697
+ cancelPendingClose();
152649
152698
  inputClosing = true;
152650
152699
  killReason ??= "cancelled";
152651
152700
  child.kill("SIGKILL");
@@ -156137,15 +156186,17 @@ var init_logger = __esm({
156137
156186
  });
156138
156187
 
156139
156188
  // ../connectors/src/connector-adapter.ts
156140
- var import_promises3, import_node_os7, import_node_path10, ConnectorAwareAdapter;
156189
+ var import_promises3, import_node_fs8, import_node_os7, import_node_path10, ConnectorAwareAdapter;
156141
156190
  var init_connector_adapter = __esm({
156142
156191
  "../connectors/src/connector-adapter.ts"() {
156143
156192
  "use strict";
156144
156193
  import_promises3 = require("node:fs/promises");
156194
+ import_node_fs8 = require("node:fs");
156145
156195
  import_node_os7 = require("node:os");
156146
156196
  import_node_path10 = require("node:path");
156147
156197
  init_src5();
156148
156198
  init_base();
156199
+ init_registry2();
156149
156200
  init_logger();
156150
156201
  ConnectorAwareAdapter = class {
156151
156202
  constructor(baseOpts = {}) {
@@ -156158,13 +156209,39 @@ var init_connector_adapter = __esm({
156158
156209
  if (missing.length) log("[adapter]", ` connector tools still missing (agent may fail): ${missing.join(", ")}`);
156159
156210
  }
156160
156211
  const sentinelWrappers = Object.entries(job.env ?? {}).filter(([k2]) => k2.endsWith("_WRAPPER")).map(([, v2]) => v2);
156161
- const wrapperPaths = [...job.wrapperPaths ?? [], ...sentinelWrappers];
156212
+ const remoteWrappers = [...job.wrapperPaths ?? [], ...sentinelWrappers];
156213
+ const wrapperPaths = remoteWrappers.filter((p2) => (0, import_node_fs8.existsSync)(p2));
156214
+ const droppedWrappers = remoteWrappers.length - wrapperPaths.length;
156162
156215
  const strippedEnv = Object.fromEntries(
156163
156216
  Object.entries(job.env ?? {}).filter(([k2]) => !k2.endsWith("_WRAPPER"))
156164
156217
  );
156165
156218
  let extraEnv = { ...strippedEnv };
156166
156219
  const toolsBin = connectorToolsBinDir();
156167
156220
  const inheritedPath = process.env["PATH"] ?? "";
156221
+ const localBinDirs = [];
156222
+ const localCleanups = [];
156223
+ for (const { slug: slug5, credentials } of job.connectorCreds ?? []) {
156224
+ const connector = createConnectorBySlug(slug5);
156225
+ if (!connector) {
156226
+ log("[adapter]", ` unknown connector slug from server: ${slug5}\uFF08\u8DF3\u8FC7\uFF09`);
156227
+ continue;
156228
+ }
156229
+ try {
156230
+ const sessionEnv = /* @__PURE__ */ new Map();
156231
+ await connector.inject(credentials, sessionEnv);
156232
+ for (const [k2, v2] of sessionEnv) extraEnv[k2] = v2;
156233
+ const staged = stageConnectorWrapper(connector);
156234
+ if (staged) localBinDirs.push((0, import_node_path10.dirname)(staged));
156235
+ localCleanups.push(() => connector.cleanup(sessionEnv));
156236
+ log("[adapter]", ` ${slug5} injected locally creds+wrapper on this node`);
156237
+ } catch (err) {
156238
+ log("[adapter]", ` ${slug5} local inject failed\uFF08\u8BE5 connector \u672C\u8F6E\u4E0D\u53EF\u7528\uFF09: ${String(err)}`);
156239
+ }
156240
+ }
156241
+ if (droppedWrappers > 0) {
156242
+ log("[adapter]", ` dropped ${droppedWrappers} wrapper path(s) not present on this node\uFF08server \u4FA7\u8DEF\u5F84\uFF0C\u5DF2\u7531\u672C\u5730\u6CE8\u5165\u63A5\u7BA1\uFF09`);
156243
+ }
156244
+ const pathParts = [...localBinDirs];
156168
156245
  if (wrapperPaths.length > 0) {
156169
156246
  const wrapperBinDir = await (0, import_promises3.mkdtemp)((0, import_node_path10.join)((0, import_node_os7.tmpdir)(), "oasis-wrappers-"));
156170
156247
  await (0, import_promises3.mkdir)(wrapperBinDir, { recursive: true });
@@ -156172,14 +156249,24 @@ var init_connector_adapter = __esm({
156172
156249
  const linkName = (0, import_node_path10.basename)(wp).replace(/\.sh$/, "");
156173
156250
  await (0, import_promises3.symlink)(wp, (0, import_node_path10.join)(wrapperBinDir, linkName));
156174
156251
  }
156175
- extraEnv = { ...extraEnv, PATH: [wrapperBinDir, toolsBin, inheritedPath].filter(Boolean).join(":") };
156176
- log("[adapter]", ` connectors injected +${Date.now() - t0}ms wrappers=${wrapperPaths.length} env_keys=${Object.keys(job.env ?? {}).join(",")}`);
156252
+ pathParts.push(wrapperBinDir);
156253
+ }
156254
+ pathParts.push(toolsBin, inheritedPath);
156255
+ extraEnv = { ...extraEnv, PATH: pathParts.filter(Boolean).join(":") };
156256
+ if (localBinDirs.length > 0 || wrapperPaths.length > 0) {
156257
+ log("[adapter]", ` connectors injected +${Date.now() - t0}ms local=${localBinDirs.length} remote_wrappers=${wrapperPaths.length} env_keys=${Object.keys(job.env ?? {}).join(",")}`);
156177
156258
  } else {
156178
- extraEnv = { ...extraEnv, PATH: [toolsBin, inheritedPath].filter(Boolean).join(":") };
156179
156259
  log("[adapter]", ` no connectors +${Date.now() - t0}ms`);
156180
156260
  }
156181
156261
  const jobAdapter = new ClaudeCodeAdapter({ ...this.baseOpts, env: extraEnv });
156182
- return jobAdapter.spawn(job);
156262
+ const handle = await jobAdapter.spawn(job);
156263
+ if (localCleanups.length > 0) {
156264
+ handle.onExit(() => {
156265
+ for (const fn of localCleanups) void fn().catch(() => {
156266
+ });
156267
+ });
156268
+ }
156269
+ return handle;
156183
156270
  }
156184
156271
  };
156185
156272
  }
@@ -156195,6 +156282,7 @@ var init_src6 = __esm({
156195
156282
  init_feishu();
156196
156283
  init_well_known_skills();
156197
156284
  init_github();
156285
+ init_registry2();
156198
156286
  init_connector_adapter();
156199
156287
  }
156200
156288
  });
@@ -157990,11 +158078,11 @@ var init_routes2 = __esm({
157990
158078
  });
157991
158079
 
157992
158080
  // ../server/src/domains/projects/postgres-documents.ts
157993
- var import_node_fs8, ident2, PostgresProjectDocumentStore;
158081
+ var import_node_fs9, ident2, PostgresProjectDocumentStore;
157994
158082
  var init_postgres_documents = __esm({
157995
158083
  "../server/src/domains/projects/postgres-documents.ts"() {
157996
158084
  "use strict";
157997
- import_node_fs8 = __toESM(require("node:fs"), 1);
158085
+ import_node_fs9 = __toESM(require("node:fs"), 1);
157998
158086
  init_service2();
157999
158087
  ident2 = (s2) => {
158000
158088
  if (!/^[a-z_][a-z0-9_]*$/.test(s2)) throw new Error(`invalid schema name: ${s2}`);
@@ -158032,10 +158120,10 @@ var init_postgres_documents = __esm({
158032
158120
  async backfillFromFile(file) {
158033
158121
  const counted = await this.sql.query(`SELECT count(*) AS n FROM ${this.s}.project_document_spaces`);
158034
158122
  if (Number(counted.rows[0]?.["n"] ?? 0) > 0) return;
158035
- if (!import_node_fs8.default.existsSync(file)) return;
158123
+ if (!import_node_fs9.default.existsSync(file)) return;
158036
158124
  let snap;
158037
158125
  try {
158038
- snap = JSON.parse(import_node_fs8.default.readFileSync(file, "utf8"));
158126
+ snap = JSON.parse(import_node_fs9.default.readFileSync(file, "utf8"));
158039
158127
  } catch {
158040
158128
  console.warn(`[projectdoc-backfill] ${file} \u89E3\u6790\u5931\u8D25\uFF0C\u8DF3\u8FC7\u56DE\u586B\uFF08\u7A7A\u95F4\u5C06\u6309\u9700\u91CD\u65B0\u521D\u59CB\u5316\uFF09`);
158041
158129
  return;
@@ -159399,7 +159487,7 @@ function nodesDomain(deps) {
159399
159487
  const here = (0, import_node_path12.dirname)((0, import_node_url4.fileURLToPath)(__esm_import_meta_url));
159400
159488
  for (const rel of ["../../../../node-daemon/package.json", "../../../../../node-daemon/package.json"]) {
159401
159489
  try {
159402
- const raw = (0, import_node_fs9.readFileSync)((0, import_node_path12.resolve)(here, rel), "utf8");
159490
+ const raw = (0, import_node_fs10.readFileSync)((0, import_node_path12.resolve)(here, rel), "utf8");
159403
159491
  const pkg = JSON.parse(raw);
159404
159492
  if (pkg.version) return { version: pkg.version, source: "monorepo" };
159405
159493
  } catch {
@@ -159753,12 +159841,12 @@ function nodesDomain(deps) {
159753
159841
  });
159754
159842
  };
159755
159843
  }
159756
- var import_node_crypto24, import_node_fs9, import_node_url4, import_node_path12;
159844
+ var import_node_crypto24, import_node_fs10, import_node_url4, import_node_path12;
159757
159845
  var init_routes4 = __esm({
159758
159846
  "../server/src/domains/nodes/routes.ts"() {
159759
159847
  "use strict";
159760
159848
  import_node_crypto24 = require("node:crypto");
159761
- import_node_fs9 = require("node:fs");
159849
+ import_node_fs10 = require("node:fs");
159762
159850
  import_node_url4 = require("node:url");
159763
159851
  import_node_path12 = require("node:path");
159764
159852
  init_src5();
@@ -160807,11 +160895,11 @@ function nameKey(name) {
160807
160895
  function cleanName(name) {
160808
160896
  return name.trim().replace(/\s+/g, " ");
160809
160897
  }
160810
- var import_node_fs10, import_node_path13, import_node_crypto25, SEP, keyOf, prefixOf, MemoryWorkorderTagStore, FileWorkorderTagStore;
160898
+ var import_node_fs11, import_node_path13, import_node_crypto25, SEP, keyOf, prefixOf, MemoryWorkorderTagStore, FileWorkorderTagStore;
160811
160899
  var init_tags = __esm({
160812
160900
  "../server/src/domains/collab/tags.ts"() {
160813
160901
  "use strict";
160814
- import_node_fs10 = __toESM(require("node:fs"), 1);
160902
+ import_node_fs11 = __toESM(require("node:fs"), 1);
160815
160903
  import_node_path13 = __toESM(require("node:path"), 1);
160816
160904
  import_node_crypto25 = __toESM(require("node:crypto"), 1);
160817
160905
  SEP = "::";
@@ -160889,7 +160977,7 @@ var init_tags = __esm({
160889
160977
  super();
160890
160978
  this.file = file;
160891
160979
  try {
160892
- const raw = JSON.parse(import_node_fs10.default.readFileSync(file, "utf8"));
160980
+ const raw = JSON.parse(import_node_fs11.default.readFileSync(file, "utf8"));
160893
160981
  for (const [k2, v2] of Object.entries(raw)) {
160894
160982
  if (v2 && typeof v2 === "object" && typeof v2.id === "string" && typeof v2.name === "string") this.map.set(k2, v2);
160895
160983
  }
@@ -160898,10 +160986,10 @@ var init_tags = __esm({
160898
160986
  }
160899
160987
  persist() {
160900
160988
  try {
160901
- import_node_fs10.default.mkdirSync(import_node_path13.default.dirname(this.file), { recursive: true });
160989
+ import_node_fs11.default.mkdirSync(import_node_path13.default.dirname(this.file), { recursive: true });
160902
160990
  const tmp = `${this.file}.tmp`;
160903
- import_node_fs10.default.writeFileSync(tmp, JSON.stringify(Object.fromEntries(this.map), null, 2));
160904
- import_node_fs10.default.renameSync(tmp, this.file);
160991
+ import_node_fs11.default.writeFileSync(tmp, JSON.stringify(Object.fromEntries(this.map), null, 2));
160992
+ import_node_fs11.default.renameSync(tmp, this.file);
160905
160993
  } catch {
160906
160994
  }
160907
160995
  }
@@ -161080,11 +161168,12 @@ function collabDomain(opts) {
161080
161168
  const wsArts = [...kernel.model.artifacts.values()].filter((a) => a.workspace === req.params.id);
161081
161169
  const ops = (await Promise.all(wsArts.map((a) => oplog.read(a.id)))).flat();
161082
161170
  const signalsForThisCompany = opts.dispatcherSignalsOf ? (id) => opts.dispatcherSignalsOf(req.auth.companyId, id) : void 0;
161083
- const roleDefaultOwners = opts.roles ? new Map((await opts.roles.list()).map((r) => [r.name, r.defaultOwner])) : void 0;
161084
- const roleDefaultOwnerOf = roleDefaultOwners ? (role) => {
161085
- const o = roleDefaultOwners.get(role);
161171
+ const roleDefsByName = opts.roles ? new Map((await opts.roles.list()).map((r) => [r.name, { label: r.label, defaultOwner: r.defaultOwner }])) : void 0;
161172
+ const roleDefaultOwnerOf = roleDefsByName ? (role) => {
161173
+ const o = roleDefsByName.get(role)?.defaultOwner;
161086
161174
  return o ? o : void 0;
161087
161175
  } : void 0;
161176
+ const roleLabelOf = roleDefsByName ? (role) => roleDefsByName.get(role)?.label : void 0;
161088
161177
  const detail = buildWorkorderDetail(
161089
161178
  kernel.model,
161090
161179
  req.params.id,
@@ -161096,7 +161185,8 @@ function collabDomain(opts) {
161096
161185
  (id) => kernel.reviewerPreview(id),
161097
161186
  signalsForThisCompany,
161098
161187
  req.auth.actor,
161099
- roleDefaultOwnerOf
161188
+ roleDefaultOwnerOf,
161189
+ roleLabelOf
161100
161190
  );
161101
161191
  if (detail) return { status: 200, body: detail };
161102
161192
  const draft = await opts.workorderDrafts?.forWorkspace(req.params.id);
@@ -171187,7 +171277,7 @@ async function caseManifests(root) {
171187
171277
  return output.sort();
171188
171278
  }
171189
171279
  async function optionalResolvedFile(allowedRoot, referenceBase, value) {
171190
- if (typeof value !== "string" || ![".md", ".yaml", ".yml", ".json"].includes((0, import_node_path14.extname)(value))) return void 0;
171280
+ if (typeof value !== "string" || (0, import_node_path14.isAbsolute)(value) || ![".md", ".yaml", ".yml", ".json"].includes((0, import_node_path14.extname)(value))) return void 0;
171191
171281
  const referenced = (0, import_node_path14.resolve)(referenceBase, value);
171192
171282
  const path28 = inside(allowedRoot, referenced, "Referenced file");
171193
171283
  try {
@@ -171198,7 +171288,7 @@ async function optionalResolvedFile(allowedRoot, referenceBase, value) {
171198
171288
  return void 0;
171199
171289
  }
171200
171290
  }
171201
- async function resolvedEvaluator(caseDirectory, caseSpecialPath, input) {
171291
+ async function resolvedEvaluator(repositoryRoot, caseDirectory, caseSpecialPath, input) {
171202
171292
  const evaluator = structuredClone(object2(input, "caseSpecial.items[].evaluator"));
171203
171293
  const configPath = text(evaluator["config"], "caseSpecial.items[].evaluator.config");
171204
171294
  const absoluteConfig = inside((0, import_node_path14.dirname)(caseSpecialPath), configPath, "Evaluator config");
@@ -171208,14 +171298,14 @@ async function resolvedEvaluator(caseDirectory, caseSpecialPath, input) {
171208
171298
  if (!value || typeof value !== "object") return;
171209
171299
  for (const [key, child] of Object.entries(value)) {
171210
171300
  const childPath = keyPath ? `${keyPath}.${key}` : key;
171211
- const resolved = await optionalResolvedFile(caseDirectory, (0, import_node_path14.dirname)(absoluteConfig), child);
171301
+ const resolved = await optionalResolvedFile(repositoryRoot, (0, import_node_path14.dirname)(absoluteConfig), child);
171212
171302
  if (resolved !== void 0) resolvedFiles[childPath] = resolved;
171213
171303
  await walk(child, childPath);
171214
171304
  }
171215
171305
  };
171216
171306
  await walk(config2, "");
171217
171307
  const promptRef = config2["prompt"] ?? object2(config2["protocol"] ?? {}, "evaluator.protocol")["judge_prompt"];
171218
- const resolvedPrompt = await optionalResolvedFile(caseDirectory, (0, import_node_path14.dirname)(absoluteConfig), promptRef);
171308
+ const resolvedPrompt = await optionalResolvedFile(repositoryRoot, (0, import_node_path14.dirname)(absoluteConfig), promptRef);
171219
171309
  return {
171220
171310
  ...evaluator,
171221
171311
  resolved_config: {
@@ -171226,7 +171316,7 @@ async function resolvedEvaluator(caseDirectory, caseSpecialPath, input) {
171226
171316
  resolved_config_path: (0, import_node_path14.relative)(caseDirectory, absoluteConfig)
171227
171317
  };
171228
171318
  }
171229
- async function resolveCaseSpecial(caseDirectory, manifest) {
171319
+ async function resolveCaseSpecial(repositoryRoot, caseDirectory, manifest) {
171230
171320
  const evaluation = object2(manifest["evaluation"], "case.evaluation");
171231
171321
  const caseSpecialPath = inside(
171232
171322
  caseDirectory,
@@ -171242,7 +171332,7 @@ async function resolveCaseSpecial(caseDirectory, manifest) {
171242
171332
  const oraclePath = item["oracle"];
171243
171333
  return {
171244
171334
  ...item,
171245
- evaluator: await resolvedEvaluator(caseDirectory, caseSpecialPath, item["evaluator"]),
171335
+ evaluator: await resolvedEvaluator(repositoryRoot, caseDirectory, caseSpecialPath, item["evaluator"]),
171246
171336
  ...typeof oraclePath === "string" ? { resolved_oracle: await yaml(inside(caseDirectory, oraclePath, "Case oracle")) } : {}
171247
171337
  };
171248
171338
  }))
@@ -171278,7 +171368,7 @@ async function loadCase(root, manifestPath, commonRubric, registry2) {
171278
171368
  stages: Array.isArray(classification["stages"]) ? classification["stages"].map((stage) => text(stage, "case.classification.stages[]")) : [],
171279
171369
  commonRubric,
171280
171370
  specialtyRubric: await (0, import_promises5.readFile)(inside(root, text(rubricEntry["path"], `S rubric ${scopeType}.path`), "S rubric path"), "utf8"),
171281
- caseSpecial: await resolveCaseSpecial(caseDirectory, manifest),
171371
+ caseSpecial: await resolveCaseSpecial(root, caseDirectory, manifest),
171282
171372
  task: await task(caseDirectory, manifest),
171283
171373
  evaluatorVersion: `oasis-bench/${version2}`,
171284
171374
  rubricVersion: `oasis-bench/${version2}`
@@ -171647,7 +171737,7 @@ function resolvePlaybook2(ref2, ctx) {
171647
171737
  return def ? def.resolve(ctx) : null;
171648
171738
  }
171649
171739
  var BUG_FIX_INPUTS, BUG_FIX_STRUCTURE, ADOPT_EXTERNAL_INPUTS, ADOPT_EXTERNAL_STRUCTURE, BUILTIN2, PLAYBOOK_REFS;
171650
- var init_registry2 = __esm({
171740
+ var init_registry3 = __esm({
171651
171741
  "../server/src/domains/playbooks/registry.ts"() {
171652
171742
  "use strict";
171653
171743
  init_src();
@@ -172031,7 +172121,7 @@ var init_routes8 = __esm({
172031
172121
  "use strict";
172032
172122
  import_node_crypto29 = require("node:crypto");
172033
172123
  init_router();
172034
- init_registry2();
172124
+ init_registry3();
172035
172125
  init_planner();
172036
172126
  init_config_audit();
172037
172127
  init_migrate();
@@ -172050,11 +172140,11 @@ function normalize(patch) {
172050
172140
  ...reviewRoles !== void 0 ? { reviewRoles: [...new Set(reviewRoles.map((r) => r.trim()).filter(Boolean))] } : {}
172051
172141
  };
172052
172142
  }
172053
- var import_node_fs11, import_node_path15, SEP2, keyOf2, prefixOf2, MemoryPlaybookOverrideStore, FilePlaybookOverrideStore;
172143
+ var import_node_fs12, import_node_path15, SEP2, keyOf2, prefixOf2, MemoryPlaybookOverrideStore, FilePlaybookOverrideStore;
172054
172144
  var init_overrides = __esm({
172055
172145
  "../server/src/domains/playbooks/overrides.ts"() {
172056
172146
  "use strict";
172057
- import_node_fs11 = __toESM(require("node:fs"), 1);
172147
+ import_node_fs12 = __toESM(require("node:fs"), 1);
172058
172148
  import_node_path15 = __toESM(require("node:path"), 1);
172059
172149
  SEP2 = "::";
172060
172150
  keyOf2 = (companyId, ref2, nodeKey) => `${companyId}${SEP2}${ref2}${SEP2}${nodeKey}`;
@@ -172085,7 +172175,7 @@ var init_overrides = __esm({
172085
172175
  super();
172086
172176
  this.file = file;
172087
172177
  try {
172088
- const raw = JSON.parse(import_node_fs11.default.readFileSync(file, "utf8"));
172178
+ const raw = JSON.parse(import_node_fs12.default.readFileSync(file, "utf8"));
172089
172179
  for (const [k2, v2] of Object.entries(raw)) {
172090
172180
  if (v2 && typeof v2 === "object") this.map.set(k2, v2);
172091
172181
  }
@@ -172094,10 +172184,10 @@ var init_overrides = __esm({
172094
172184
  }
172095
172185
  persist() {
172096
172186
  try {
172097
- import_node_fs11.default.mkdirSync(import_node_path15.default.dirname(this.file), { recursive: true });
172187
+ import_node_fs12.default.mkdirSync(import_node_path15.default.dirname(this.file), { recursive: true });
172098
172188
  const tmp = `${this.file}.tmp`;
172099
- import_node_fs11.default.writeFileSync(tmp, JSON.stringify(Object.fromEntries(this.map), null, 2));
172100
- import_node_fs11.default.renameSync(tmp, this.file);
172189
+ import_node_fs12.default.writeFileSync(tmp, JSON.stringify(Object.fromEntries(this.map), null, 2));
172190
+ import_node_fs12.default.renameSync(tmp, this.file);
172101
172191
  } catch {
172102
172192
  }
172103
172193
  }
@@ -172125,7 +172215,7 @@ var init_playbooks2 = __esm({
172125
172215
  "../server/src/domains/playbooks/index.ts"() {
172126
172216
  "use strict";
172127
172217
  init_routes8();
172128
- init_registry2();
172218
+ init_registry3();
172129
172219
  init_routes8();
172130
172220
  init_overrides();
172131
172221
  }
@@ -172451,17 +172541,17 @@ var init_daemon_adapter = __esm({
172451
172541
  });
172452
172542
 
172453
172543
  // ../server/src/side-map.ts
172454
- var import_node_fs12, import_node_path16, FileSideMap;
172544
+ var import_node_fs13, import_node_path16, FileSideMap;
172455
172545
  var init_side_map = __esm({
172456
172546
  "../server/src/side-map.ts"() {
172457
172547
  "use strict";
172458
- import_node_fs12 = __toESM(require("node:fs"), 1);
172548
+ import_node_fs13 = __toESM(require("node:fs"), 1);
172459
172549
  import_node_path16 = __toESM(require("node:path"), 1);
172460
172550
  FileSideMap = class {
172461
172551
  constructor(file) {
172462
172552
  this.file = file;
172463
172553
  try {
172464
- const raw = JSON.parse(import_node_fs12.default.readFileSync(file, "utf8"));
172554
+ const raw = JSON.parse(import_node_fs13.default.readFileSync(file, "utf8"));
172465
172555
  for (const [k2, v2] of Object.entries(raw)) if (typeof v2 === "string") this.map.set(k2, v2);
172466
172556
  } catch {
172467
172557
  }
@@ -172483,10 +172573,10 @@ var init_side_map = __esm({
172483
172573
  }
172484
172574
  persist() {
172485
172575
  try {
172486
- import_node_fs12.default.mkdirSync(import_node_path16.default.dirname(this.file), { recursive: true });
172576
+ import_node_fs13.default.mkdirSync(import_node_path16.default.dirname(this.file), { recursive: true });
172487
172577
  const tmp = `${this.file}.tmp`;
172488
- import_node_fs12.default.writeFileSync(tmp, JSON.stringify(Object.fromEntries(this.map), null, 2));
172489
- import_node_fs12.default.renameSync(tmp, this.file);
172578
+ import_node_fs13.default.writeFileSync(tmp, JSON.stringify(Object.fromEntries(this.map), null, 2));
172579
+ import_node_fs13.default.renameSync(tmp, this.file);
172490
172580
  } catch {
172491
172581
  }
172492
172582
  }
@@ -173880,7 +173970,8 @@ ${ctx.nodeFault}
173880
173970
  // OASIS_STAGE=1:本会话里 link/spawn/unlink/seal/cancel-part 进编辑缓冲、apply 才提交(react 攒事务)。
173881
173971
  env: { ...prov?.env ?? {}, OASIS_STAGE: "1", ...workspace ? { OASIS_WORKSPACE: workspace } : {} },
173882
173972
  ...prov?.wrapperPaths && prov.wrapperPaths.length > 0 ? { wrapperPaths: prov.wrapperPaths } : {},
173883
- ...prov?.requiredTools && prov.requiredTools.length > 0 ? { requiredTools: prov.requiredTools } : {}
173973
+ ...prov?.requiredTools && prov.requiredTools.length > 0 ? { requiredTools: prov.requiredTools } : {},
173974
+ ...prov?.connectorCreds && prov.connectorCreds.length > 0 ? { connectorCreds: prov.connectorCreds } : {}
173884
173975
  };
173885
173976
  this.deps.log?.(`[coordinator] ${logMsg}`);
173886
173977
  const handle = await this.deps.adapter.spawn(job);
@@ -183371,10 +183462,10 @@ var init_postgres_model_prices = __esm({
183371
183462
  // ../storage/src/postgres-type-registry.ts
183372
183463
  async function backfillTypeRegistryFromFile(store, file) {
183373
183464
  if ((await store.list()).length > 0) return { filled: 0 };
183374
- if (!import_node_fs13.default.existsSync(file)) return { filled: 0 };
183465
+ if (!import_node_fs14.default.existsSync(file)) return { filled: 0 };
183375
183466
  let defs;
183376
183467
  try {
183377
- defs = JSON.parse(import_node_fs13.default.readFileSync(file, "utf8"));
183468
+ defs = JSON.parse(import_node_fs14.default.readFileSync(file, "utf8"));
183378
183469
  } catch {
183379
183470
  console.warn(`[type-registry-backfill] ${file} \u89E3\u6790\u5931\u8D25\uFF0C\u8DF3\u8FC7\u56DE\u586B\uFF08serve \u5C06\u7528\u4EE3\u7801\u5E38\u91CF\u64AD\u79CD\uFF09`);
183380
183471
  return { filled: 0 };
@@ -183384,11 +183475,11 @@ async function backfillTypeRegistryFromFile(store, file) {
183384
183475
  console.log(`[type-registry-backfill] \u51B3\u7B56 0062 \u56DE\u586B\uFF1A${defs.length} \u4E2A\u4EA7\u7269\u7C7B\u578B\u5DF2\u8FC1\u5165 Postgres`);
183385
183476
  return { filled: defs.length };
183386
183477
  }
183387
- var import_node_fs13, ident13, PostgresTypeRegistryStore;
183478
+ var import_node_fs14, ident13, PostgresTypeRegistryStore;
183388
183479
  var init_postgres_type_registry = __esm({
183389
183480
  "../storage/src/postgres-type-registry.ts"() {
183390
183481
  "use strict";
183391
- import_node_fs13 = __toESM(require("node:fs"), 1);
183482
+ import_node_fs14 = __toESM(require("node:fs"), 1);
183392
183483
  init_esm2();
183393
183484
  ident13 = (s2) => {
183394
183485
  if (!/^[a-z_][a-z0-9_]*$/.test(s2)) throw new Error(`invalid schema name: ${s2}`);
@@ -184502,6 +184593,7 @@ async function buildActorProvision(service, actorId) {
184502
184593
  const raw = await service.resolveActorEnv(actorId);
184503
184594
  const env = { ...raw };
184504
184595
  const wrapperPaths = [oasisWrapperScript()];
184596
+ const connectorCreds = [];
184505
184597
  const requiredTools = /* @__PURE__ */ new Set();
184506
184598
  const cleanupFns = [];
184507
184599
  const SENSITIVE_KEYS = [
@@ -184519,11 +184611,13 @@ async function buildActorProvision(service, actorId) {
184519
184611
  try {
184520
184612
  const feishu = new FeishuConnector();
184521
184613
  const sessionEnv = /* @__PURE__ */ new Map();
184522
- await feishu.inject({
184614
+ const feishuCreds = {
184523
184615
  app_id: raw["FEISHU_APP_ID"],
184524
184616
  app_secret: raw["FEISHU_APP_SECRET"],
184525
184617
  ...raw["FEISHU_USER_ACCESS_TOKEN"] ? { user_access_token: raw["FEISHU_USER_ACCESS_TOKEN"] } : {}
184526
- }, sessionEnv);
184618
+ };
184619
+ connectorCreds.push({ slug: feishu.config.slug, credentials: feishuCreds });
184620
+ await feishu.inject(feishuCreds, sessionEnv);
184527
184621
  for (const [k2, v2] of sessionEnv) env[k2] = v2;
184528
184622
  const staged = stageConnectorWrapper(feishu);
184529
184623
  if (staged) wrapperPaths.push(staged);
@@ -184537,7 +184631,12 @@ async function buildActorProvision(service, actorId) {
184537
184631
  try {
184538
184632
  const github = new GithubConnector();
184539
184633
  const sessionEnv = /* @__PURE__ */ new Map();
184540
- await github.inject({ access_token: raw["GITHUB_TOKEN"], actor_name: raw["GIT_AUTHOR_NAME"] ?? actorId.split(":").pop() ?? "oasis-agent" }, sessionEnv);
184634
+ const githubCreds = {
184635
+ access_token: raw["GITHUB_TOKEN"],
184636
+ actor_name: raw["GIT_AUTHOR_NAME"] ?? actorId.split(":").pop() ?? "oasis-agent"
184637
+ };
184638
+ connectorCreds.push({ slug: github.config.slug, credentials: githubCreds });
184639
+ await github.inject(githubCreds, sessionEnv);
184541
184640
  for (const [k2, v2] of sessionEnv) env[k2] = v2;
184542
184641
  const staged = stageConnectorWrapper(github);
184543
184642
  if (staged) wrapperPaths.push(staged);
@@ -184551,7 +184650,7 @@ async function buildActorProvision(service, actorId) {
184551
184650
  for (const fn of cleanupFns) await fn().catch(() => {
184552
184651
  });
184553
184652
  };
184554
- return { env, wrapperPaths, requiredTools: [...requiredTools], cleanup };
184653
+ return { env, wrapperPaths, requiredTools: [...requiredTools], connectorCreds, cleanup };
184555
184654
  }
184556
184655
  async function buildActorContext(service, actorId) {
184557
184656
  const [config2, connectors, installedSkills, record6] = await Promise.all([
@@ -185318,7 +185417,8 @@ async function startServe(opts) {
185318
185417
  limits,
185319
185418
  env: provision.env,
185320
185419
  wrapperPaths: provision.wrapperPaths,
185321
- ...provision.requiredTools.length > 0 ? { requiredTools: provision.requiredTools } : {}
185420
+ ...provision.requiredTools.length > 0 ? { requiredTools: provision.requiredTools } : {},
185421
+ ...provision.connectorCreds.length > 0 ? { connectorCreds: provision.connectorCreds } : {}
185322
185422
  });
185323
185423
  const chunks = [];
185324
185424
  handle.onOutput?.((chunk) => chunks.push(chunk));
@@ -185669,7 +185769,8 @@ async function startServe(opts) {
185669
185769
  ...workspace ? { OASIS_WORKSPACE: workspace } : {}
185670
185770
  },
185671
185771
  wrapperPaths: provision.wrapperPaths,
185672
- ...provision.requiredTools.length > 0 ? { requiredTools: provision.requiredTools } : {}
185772
+ ...provision.requiredTools.length > 0 ? { requiredTools: provision.requiredTools } : {},
185773
+ ...provision.connectorCreds.length > 0 ? { connectorCreds: provision.connectorCreds } : {}
185673
185774
  });
185674
185775
  const chatJobKey = `chat::${artifactId}`;
185675
185776
  chatLiveSessions.set(chatJobKey, { artifactId, sessionId: traceRunId, dispatchId: handle.id, kill: () => handle.kill() });
@@ -187230,7 +187331,7 @@ var RuntimeRouterAdapter = class {
187230
187331
  };
187231
187332
 
187232
187333
  // ../cli/src/daemon/reap-claude-projects.ts
187233
- var import_node_fs14 = __toESM(require("node:fs"), 1);
187334
+ var import_node_fs15 = __toESM(require("node:fs"), 1);
187234
187335
  var import_node_os9 = __toESM(require("node:os"), 1);
187235
187336
  var import_node_path18 = __toESM(require("node:path"), 1);
187236
187337
  function claudeProjectSlug(cwd) {
@@ -187243,9 +187344,9 @@ function claudeProjectsRoot() {
187243
187344
  function reapClaudeProjects(workdir, runtimeKind) {
187244
187345
  if (runtimeKind !== "claude" && runtimeKind !== "claude-code") return;
187245
187346
  const dir = import_node_path18.default.join(claudeProjectsRoot(), claudeProjectSlug(workdir));
187246
- if (!import_node_fs14.default.existsSync(dir)) return;
187347
+ if (!import_node_fs15.default.existsSync(dir)) return;
187247
187348
  try {
187248
- import_node_fs14.default.rmSync(dir, { recursive: true, force: true });
187349
+ import_node_fs15.default.rmSync(dir, { recursive: true, force: true });
187249
187350
  } catch {
187250
187351
  }
187251
187352
  }
@@ -187346,13 +187447,13 @@ async function startNode(opts) {
187346
187447
 
187347
187448
  // ../cli/src/daemon/machine-id.ts
187348
187449
  var import_node_child_process16 = require("node:child_process");
187349
- var import_node_fs15 = require("node:fs");
187450
+ var import_node_fs16 = require("node:fs");
187350
187451
  var import_node_crypto38 = require("node:crypto");
187351
187452
  var import_node_os11 = require("node:os");
187352
187453
  function linuxMachineId() {
187353
187454
  for (const p2 of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) {
187354
187455
  try {
187355
- const v2 = (0, import_node_fs15.readFileSync)(p2, "utf8").trim();
187456
+ const v2 = (0, import_node_fs16.readFileSync)(p2, "utf8").trim();
187356
187457
  if (v2) return v2;
187357
187458
  } catch {
187358
187459
  }
@@ -189577,7 +189678,7 @@ ${res.warning}`);
189577
189678
  init_src6();
189578
189679
 
189579
189680
  // src/index.ts
189580
- var PKG_VERSION = true ? "0.1.70" : "dev";
189681
+ var PKG_VERSION = true ? "0.1.72" : "dev";
189581
189682
  var OASIS_DIR = path27.join(os9.homedir(), ".oasis");
189582
189683
  var CONFIG_FILE = path27.join(OASIS_DIR, "node-config.json");
189583
189684
  var PID_FILE = path27.join(OASIS_DIR, "node.pid");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oasis_test",
3
- "version": "0.1.70",
3
+ "version": "0.1.72",
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": "20ad053a32c3636f94509e06767e7bbb49b1bb8f"
29
+ "sourceHead": "d0ee4c4d3e4ff3fb73c414c8a84c9eab1b20916d"
30
30
  }
31
31
  }