oasis_test 0.1.78 → 0.1.80

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 +45 -18
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1087,9 +1087,10 @@ function owesReplyOn(model, a, recipient, owner) {
1087
1087
  if (model.disabledActors.has(recipient)) return false;
1088
1088
  const rootSeq = model.annotationSeq.get(a.id) ?? 0;
1089
1089
  const lastSelf = lastPostSeqOf(model, a, recipient);
1090
+ const cutoff = Math.max(lastSelf, a.resolvedAtSeq ?? Number.NEGATIVE_INFINITY);
1090
1091
  const isDefault = defaultRecipientOf(model, a, owner) === recipient;
1091
1092
  const owed = (author, mentions, seq) => {
1092
- if (author === recipient || seq <= lastSelf) return false;
1093
+ if (author === recipient || seq <= cutoff) return false;
1093
1094
  if (mentions.length === 0) return isDefault;
1094
1095
  return mentions.includes(recipient) || recipient === owner && mentions.some((m2) => model.disabledActors.has(m2));
1095
1096
  };
@@ -1103,11 +1104,11 @@ function openMailOf(model, id) {
1103
1104
  const cu = model.convergenceUnified;
1104
1105
  return annotationsOf(model, id).filter((a) => {
1105
1106
  if (!(a.mail || cu)) return false;
1106
- if (!(a.state === "open" || isReactivatedLetter(a, cu))) return false;
1107
1107
  if (isRoundLimitParked(a)) return false;
1108
1108
  if (a.raisedFrom == null && !isHumanChangeRequest(a)) {
1109
1109
  return owesReplyOn(model, a, owner, owner);
1110
1110
  }
1111
+ if (!(a.state === "open" || isReactivatedLetter(a, cu))) return false;
1111
1112
  return a.author !== owner && !pending.has(a.id) && (a.mentions.length === 0 || owner !== void 0 && a.mentions.includes(owner));
1112
1113
  });
1113
1114
  }
@@ -1122,7 +1123,10 @@ function openLetterBlockersOf(model, id, anns) {
1122
1123
  a.author !== owner && // 非 owner 自留言
1123
1124
  !isHumanChangeRequest(a) && // 人工 change-request 整条移出 letter 轴(R12 方向 b,委给 open-human-change-request)
1124
1125
  !isRoundLimitParked(a) && // 停牌信全轴统一豁免(park=完整人工接管,R4/§4.5.6/§7 A9)
1125
- (a.state === "open" || isReactivatedLetter(a, cu)) && // 复活信(关后作者又追问、未答)算未答,与 openMailOf
1126
+ owesReplyOn(model, a, owner, owner) && // 外层 state 门换成 owesReplyOn(含 L5 cutoff),与 openMailOf 纯来信支同源:
1127
+ // 闭信只认关闭后的新帖(红线 5)、追评/未回帖照挡收口。其余四条(raisedFrom==null / author!==owner /
1128
+ // !isHumanChangeRequest / mentions 路由)作防御性冗余保留——owesReplyOn 内部已含前三者等价语义,
1129
+ // 但按内部自洽飞检(mem:39e05e78)不去重,防将来 owesReplyOn 语义漂移再分叉。
1126
1130
  (a.mentions.length === 0 || owner !== void 0 && a.mentions.includes(owner))
1127
1131
  // @ 路由收敛到 owner
1128
1132
  );
@@ -4988,11 +4992,11 @@ async function assembleContext(args) {
4988
4992
  const declaredPending = declaredByQueuedRevision(model, artifactId);
4989
4993
  const ownerId = artifact.owner;
4990
4994
  const openAnnosHere = annotationsOf(model, artifactId).filter((a) => {
4991
- if (!(a.state === "open" || isReactivatedLetter(a, model.convergenceUnified))) return false;
4992
- if (a.raisedFrom !== null || a.author.startsWith("actor:human:") && a.kind === "change-request") {
4993
- return !declaredPending.has(a.id);
4995
+ if (a.raisedFrom == null && !(a.author.startsWith("actor:human:") && a.kind === "change-request")) {
4996
+ return owesReplyOn(model, a, ownerId, ownerId);
4994
4997
  }
4995
- return owesReplyOn(model, a, ownerId, ownerId);
4998
+ if (!(a.state === "open" || isReactivatedLetter(a, model.convergenceUnified))) return false;
4999
+ return !declaredPending.has(a.id);
4996
5000
  });
4997
5001
  const pendingRaisedIds = new Set(pendingBackpressureResponsesOf(model, artifactId).map((a) => a.id));
4998
5002
  const raisedAnnos = [...model.annotations.values()].filter(
@@ -139667,9 +139671,9 @@ function requiresMeReasonOf(model, artifact, viewer, facts) {
139667
139671
  const pending = f2.queuedResolvesFor(artifact.id);
139668
139672
  for (const a of f2.annotationsFor(artifact.id)) {
139669
139673
  if (!a.mail && !model.convergenceUnified) continue;
139670
- if (!(a.state === "open" || isReactivatedLetter(a, model.convergenceUnified))) continue;
139671
139674
  if (isRoundLimitParked(a)) continue;
139672
139675
  const plainComment = a.raisedFrom == null && !isHumanChangeRequest(a);
139676
+ if (!plainComment && !(a.state === "open" || isReactivatedLetter(a, model.convergenceUnified))) continue;
139673
139677
  if (pending.has(a.id) && !(plainComment && (owesReplyOn(model, a, viewer, artifact.owner) || hasUnansweredMention(model, a, viewer)))) continue;
139674
139678
  if (hasUnansweredMention(model, a, viewer)) consider("mention");
139675
139679
  if (artifact.owner === viewer) {
@@ -153991,6 +153995,13 @@ function retryBackoffMs(attempt, baseMs) {
153991
153995
  const jitter = Math.floor(Math.random() * baseMs);
153992
153996
  return Math.min(exp + jitter, 15e3);
153993
153997
  }
153998
+ function errText(err) {
153999
+ if (err instanceof Error) {
154000
+ const code = err.code;
154001
+ return `${code ? `[${code}] ` : ""}${err.message}`.slice(0, 8e3);
154002
+ }
154003
+ return String(err).slice(0, 8e3);
154004
+ }
153994
154005
  function withResilience(inner, cfg = {}) {
153995
154006
  const idleTimeoutMs = cfg.idleTimeoutMs ?? numEnv("OASIS_RUNTIME_IDLE_TIMEOUT_MS", 0);
153996
154007
  const maxRetries = cfg.maxRetries ?? numEnv("OASIS_RUNTIME_MAX_RETRIES", 2);
@@ -154080,8 +154091,8 @@ function withResilience(inner, cfg = {}) {
154080
154091
  let handle;
154081
154092
  try {
154082
154093
  handle = await inner.spawn(job);
154083
- } catch {
154084
- finish({ code: null, reason: "error" });
154094
+ } catch (err) {
154095
+ finish({ code: null, reason: "error", errorMessage: errText(err) });
154085
154096
  return;
154086
154097
  }
154087
154098
  const { info, produced } = await runOnce(handle);
@@ -154096,7 +154107,7 @@ function withResilience(inner, cfg = {}) {
154096
154107
  await sleep(retryBackoffMs(attempt, retryBaseMs));
154097
154108
  }
154098
154109
  finish(lastInfo);
154099
- })().catch(() => finish({ code: null, reason: "error" }));
154110
+ })().catch((err) => finish({ code: null, reason: "error", errorMessage: errText(err) }));
154100
154111
  await ready;
154101
154112
  return {
154102
154113
  id: outerId ?? `resilient-${job.artifactId.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 32)}`,
@@ -155008,7 +155019,7 @@ function normalizeCodexConsoleLine(line, state = createCodexNormalizeState()) {
155008
155019
  tool.output.push(line);
155009
155020
  return [];
155010
155021
  }
155011
- var import_node_child_process11, import_node_crypto19, fs15, os4, path14, readline2, CodexAdapter;
155022
+ var import_node_child_process11, import_node_crypto19, fs15, os4, path14, readline2, CODEX_ARGV_PROMPT_MAX_BYTES, CodexAdapter;
155012
155023
  var init_codex = __esm({
155013
155024
  "../adapters/src/codex/index.ts"() {
155014
155025
  "use strict";
@@ -155024,6 +155035,7 @@ var init_codex = __esm({
155024
155035
  init_session_paths();
155025
155036
  init_claude_code();
155026
155037
  init_transcript();
155038
+ CODEX_ARGV_PROMPT_MAX_BYTES = 1e5;
155027
155039
  CodexAdapter = class {
155028
155040
  constructor(opts = {}) {
155029
155041
  this.opts = opts;
@@ -155074,6 +155086,7 @@ var init_codex = __esm({
155074
155086
  const task2 = materializeBundle(dir, job.bundle);
155075
155087
  const prompt = job.systemPrompt ? ["# System Prompt", job.systemPrompt, "", "# Task", task2].join("\n") : task2;
155076
155088
  const isResume = Boolean(job.resumeRuntimeSession && job.runtimeSessionId);
155089
+ const promptViaStdin = Buffer.byteLength(prompt, "utf8") > CODEX_ARGV_PROMPT_MAX_BYTES;
155077
155090
  const args = [
155078
155091
  "exec",
155079
155092
  "-C",
@@ -155087,7 +155100,7 @@ var init_codex = __esm({
155087
155100
  ...this.opts.reasoningSummary !== "none" ? ["-c", `model_reasoning_summary=${this.opts.reasoningSummary ?? "auto"}`] : [],
155088
155101
  ...this.opts.reasoningEffort ? ["-c", `model_reasoning_effort=${this.opts.reasoningEffort}`] : [],
155089
155102
  ...this.opts.extraArgs ?? [],
155090
- prompt
155103
+ promptViaStdin ? "-" : prompt
155091
155104
  ];
155092
155105
  const child = (0, import_node_child_process11.spawn)(this.opts.codexBin ?? "codex", args, {
155093
155106
  cwd: dir,
@@ -155099,8 +155112,18 @@ var init_codex = __esm({
155099
155112
  OASIS_SERVER: job.server.url,
155100
155113
  OASIS_TOKEN: job.actorToken
155101
155114
  },
155102
- stdio: ["ignore", "pipe", "pipe"]
155103
- });
155115
+ // stdin 只在走 stdin 时开管道。**不能图省事恒开 pipe**(claude 那边可以):codex 的
155116
+ // `--help` 明载「stdin is piped and a prompt is also provided → stdin 作为 `<stdin>` 块
155117
+ // 追加」,恒开会给每一次普通派发都塞一个空 `<stdin>` 块,白白改了小 prompt 的行为。
155118
+ // 代价是 stdio 不再是全 pipe 字面量,spawn 的返回类型退化成流可空的 ChildProcess——
155119
+ // stdout/stderr 这里恒为 "pipe",读取处按此断言(stdin 才是真可空的那个,见下方判空)。
155120
+ stdio: [promptViaStdin ? "pipe" : "ignore", "pipe", "pipe"]
155121
+ });
155122
+ if (promptViaStdin && child.stdin) {
155123
+ child.stdin.on("error", () => {
155124
+ });
155125
+ child.stdin.end(prompt);
155126
+ }
155104
155127
  if (child.pid !== void 0 && job.workdirKey) lockWorkdir(dir, child.pid, "session", job.workdirKey);
155105
155128
  let transcriptRef = path14.join(dir, "transcript.txt");
155106
155129
  const out = openTranscript(transcriptRef);
@@ -155207,7 +155230,7 @@ var init_codex = __esm({
155207
155230
  const model = telemetry.model ?? job.model ?? this.opts.model;
155208
155231
  const runtimeSessionId = telemetry.sessionId ?? resumeSessionId;
155209
155232
  const sawStreamError = streamErrorMessages.length > 0;
155210
- const isError = !killReason && (typeof code === "number" && code !== 0 || sawStreamError);
155233
+ const isError = !killReason && (code !== 0 || sawStreamError);
155211
155234
  const errorMessage = isError ? [...streamErrorMessages, ...stdoutErrorLines, ...stderrTail].join("\n").trim().slice(-4e3) || void 0 : void 0;
155212
155235
  const sessionNotFound = !killReason && isResume && isSessionNotFoundError([...streamErrorMessages, ...stdoutErrorLines, ...stderrTail].join("\n"));
155213
155236
  const reason = killReason ? killReason : sessionNotFound ? "session-not-found" : sawStreamError ? "error" : code === 0 ? "clean" : "error";
@@ -192600,7 +192623,7 @@ ${res.warning}`);
192600
192623
  init_src6();
192601
192624
 
192602
192625
  // src/index.ts
192603
- var PKG_VERSION = true ? "0.1.78" : "dev";
192626
+ var PKG_VERSION = true ? "0.1.80" : "dev";
192604
192627
  var OASIS_DIR = path28.join(os9.homedir(), ".oasis");
192605
192628
  var CONFIG_FILE = path28.join(OASIS_DIR, "node-config.json");
192606
192629
  var PID_FILE = path28.join(OASIS_DIR, "node.pid");
@@ -192743,7 +192766,11 @@ function selfUpdate() {
192743
192766
  const nameArg = cfg.name ? ` --name '${cfg.name.replace(/'/g, "'\\''")}'` : "";
192744
192767
  const oasisBin = path28.join(NPM_PREFIX, "bin", "oasis");
192745
192768
  const startCmd = `"${oasisBin}" daemon start --server-ws '${cfg.serverUrl}'${nameArg}`;
192746
- const inner = `{ echo "[oasis] self-update \u2192 npm install --prefix ${NPM_PREFIX} ${PKG_NAME}@latest"; sleep 2; npm install -g --prefer-online --prefix '${NPM_PREFIX}' '${PKG_NAME}@latest' && ${startCmd}; } >> '${LOG_FILE}' 2>&1`;
192769
+ const OFFICIAL = "https://registry.npmjs.org/";
192770
+ const installOfficial = `npm install -g --prefer-online --registry '${OFFICIAL}' --prefix '${NPM_PREFIX}' '${PKG_NAME}@latest'`;
192771
+ const installFallback = `npm install -g --prefer-online --prefix '${NPM_PREFIX}' '${PKG_NAME}@latest'`;
192772
+ const printVersion = `node -p "'[oasis] self-update installed ' + require('${NPM_PREFIX}/lib/node_modules/${PKG_NAME}/package.json').version" || true`;
192773
+ const inner = `{ echo "[oasis] self-update \u2192 ${PKG_NAME}@latest (registry ${OFFICIAL}, \u5931\u8D25\u56DE\u843D\u9ED8\u8BA4\u6E90)"; sleep 2; { ${installOfficial} || ${installFallback}; } && ${printVersion} && ${startCmd}; } >> '${LOG_FILE}' 2>&1`;
192747
192774
  const hasSystemd = process.platform === "linux" && (() => {
192748
192775
  try {
192749
192776
  (0, import_node_child_process17.execSync)("command -v systemd-run", { stdio: "ignore" });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oasis_test",
3
- "version": "0.1.78",
3
+ "version": "0.1.80",
4
4
  "description": "Oasis node daemon + CLI — background daemon, auto-start, full server CLI",
5
5
  "bin": {
6
6
  "oasis": "./dist/index.js"