@cfio/cohort-sync 0.34.1 → 0.34.3

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 CHANGED
@@ -207,11 +207,11 @@ var TypeBoxError = class extends Error {
207
207
  };
208
208
 
209
209
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.48/node_modules/@sinclair/typebox/build/esm/type/symbols/symbols.mjs
210
- var TransformKind = Symbol.for("TypeBox.Transform");
211
- var ReadonlyKind = Symbol.for("TypeBox.Readonly");
212
- var OptionalKind = Symbol.for("TypeBox.Optional");
213
- var Hint = Symbol.for("TypeBox.Hint");
214
- var Kind = Symbol.for("TypeBox.Kind");
210
+ var TransformKind = /* @__PURE__ */ Symbol.for("TypeBox.Transform");
211
+ var ReadonlyKind = /* @__PURE__ */ Symbol.for("TypeBox.Readonly");
212
+ var OptionalKind = /* @__PURE__ */ Symbol.for("TypeBox.Optional");
213
+ var Hint = /* @__PURE__ */ Symbol.for("TypeBox.Hint");
214
+ var Kind = /* @__PURE__ */ Symbol.for("TypeBox.Kind");
215
215
 
216
216
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.48/node_modules/@sinclair/typebox/build/esm/type/guard/kind.mjs
217
217
  function IsReadonly(value) {
@@ -449,8 +449,8 @@ function IsPattern(value) {
449
449
  function IsControlCharacterFree(value) {
450
450
  if (!IsString(value))
451
451
  return false;
452
- for (let i = 0; i < value.length; i++) {
453
- const code2 = value.charCodeAt(i);
452
+ for (let i2 = 0; i2 < value.length; i2++) {
453
+ const code2 = value.charCodeAt(i2);
454
454
  if (code2 >= 7 && code2 <= 13 || code2 === 27 || code2 === 127) {
455
455
  return false;
456
456
  }
@@ -977,20 +977,20 @@ function* FromTerminal(syntax) {
977
977
  const R = FromSyntax(syntax.slice(1));
978
978
  return yield* [L, ...R];
979
979
  }
980
- for (let i = 2; i < syntax.length; i++) {
981
- if (syntax[i] === "}") {
982
- const L = FromUnion(syntax.slice(2, i));
983
- const R = FromSyntax(syntax.slice(i + 1));
980
+ for (let i2 = 2; i2 < syntax.length; i2++) {
981
+ if (syntax[i2] === "}") {
982
+ const L = FromUnion(syntax.slice(2, i2));
983
+ const R = FromSyntax(syntax.slice(i2 + 1));
984
984
  return yield* [...L, ...R];
985
985
  }
986
986
  }
987
987
  yield Literal(syntax);
988
988
  }
989
989
  function* FromSyntax(syntax) {
990
- for (let i = 0; i < syntax.length; i++) {
991
- if (syntax[i] === "$") {
992
- const L = Literal(syntax.slice(0, i));
993
- const R = FromTerminal(syntax.slice(i));
990
+ for (let i2 = 0; i2 < syntax.length; i2++) {
991
+ if (syntax[i2] === "$") {
992
+ const L = Literal(syntax.slice(0, i2));
993
+ const R = FromTerminal(syntax.slice(i2));
994
994
  return yield* [L, ...R];
995
995
  }
996
996
  }
@@ -2662,9 +2662,9 @@ function isNewerVersion(a, b) {
2662
2662
  const strip = (v2) => v2.replace(/-.*$/, "");
2663
2663
  const pa = strip(a).split(".").map(Number);
2664
2664
  const pb = strip(b).split(".").map(Number);
2665
- for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
2666
- const na = pa[i] ?? 0;
2667
- const nb = pb[i] ?? 0;
2665
+ for (let i2 = 0; i2 < Math.max(pa.length, pb.length); i2++) {
2666
+ const na = pa[i2] ?? 0;
2667
+ const nb = pb[i2] ?? 0;
2668
2668
  if (isNaN(na) || isNaN(nb)) return false;
2669
2669
  if (na > nb) return true;
2670
2670
  if (na < nb) return false;
@@ -2861,13 +2861,13 @@ var len;
2861
2861
  revLookup["-".charCodeAt(0)] = 62;
2862
2862
  revLookup["_".charCodeAt(0)] = 63;
2863
2863
  function getLens(b64) {
2864
- var len = b64.length;
2865
- if (len % 4 > 0) {
2864
+ var len2 = b64.length;
2865
+ if (len2 % 4 > 0) {
2866
2866
  throw new Error("Invalid string. Length must be a multiple of 4");
2867
2867
  }
2868
2868
  var validLen = b64.indexOf("=");
2869
- if (validLen === -1) validLen = len;
2870
- var placeHoldersLen = validLen === len ? 0 : 4 - validLen % 4;
2869
+ if (validLen === -1) validLen = len2;
2870
+ var placeHoldersLen = validLen === len2 ? 0 : 4 - validLen % 4;
2871
2871
  return [validLen, placeHoldersLen];
2872
2872
  }
2873
2873
  function byteLength(b64) {
@@ -2886,20 +2886,20 @@ function toByteArray(b64) {
2886
2886
  var placeHoldersLen = lens[1];
2887
2887
  var arr2 = new Arr(_byteLength(b64, validLen, placeHoldersLen));
2888
2888
  var curByte = 0;
2889
- var len = placeHoldersLen > 0 ? validLen - 4 : validLen;
2890
- var i;
2891
- for (i = 0; i < len; i += 4) {
2892
- tmp = revLookup[b64.charCodeAt(i)] << 18 | revLookup[b64.charCodeAt(i + 1)] << 12 | revLookup[b64.charCodeAt(i + 2)] << 6 | revLookup[b64.charCodeAt(i + 3)];
2889
+ var len2 = placeHoldersLen > 0 ? validLen - 4 : validLen;
2890
+ var i2;
2891
+ for (i2 = 0; i2 < len2; i2 += 4) {
2892
+ tmp = revLookup[b64.charCodeAt(i2)] << 18 | revLookup[b64.charCodeAt(i2 + 1)] << 12 | revLookup[b64.charCodeAt(i2 + 2)] << 6 | revLookup[b64.charCodeAt(i2 + 3)];
2893
2893
  arr2[curByte++] = tmp >> 16 & 255;
2894
2894
  arr2[curByte++] = tmp >> 8 & 255;
2895
2895
  arr2[curByte++] = tmp & 255;
2896
2896
  }
2897
2897
  if (placeHoldersLen === 2) {
2898
- tmp = revLookup[b64.charCodeAt(i)] << 2 | revLookup[b64.charCodeAt(i + 1)] >> 4;
2898
+ tmp = revLookup[b64.charCodeAt(i2)] << 2 | revLookup[b64.charCodeAt(i2 + 1)] >> 4;
2899
2899
  arr2[curByte++] = tmp & 255;
2900
2900
  }
2901
2901
  if (placeHoldersLen === 1) {
2902
- tmp = revLookup[b64.charCodeAt(i)] << 10 | revLookup[b64.charCodeAt(i + 1)] << 4 | revLookup[b64.charCodeAt(i + 2)] >> 2;
2902
+ tmp = revLookup[b64.charCodeAt(i2)] << 10 | revLookup[b64.charCodeAt(i2 + 1)] << 4 | revLookup[b64.charCodeAt(i2 + 2)] >> 2;
2903
2903
  arr2[curByte++] = tmp >> 8 & 255;
2904
2904
  arr2[curByte++] = tmp & 255;
2905
2905
  }
@@ -2911,32 +2911,32 @@ function tripletToBase64(num) {
2911
2911
  function encodeChunk(uint8, start, end) {
2912
2912
  var tmp;
2913
2913
  var output = [];
2914
- for (var i = start; i < end; i += 3) {
2915
- tmp = (uint8[i] << 16 & 16711680) + (uint8[i + 1] << 8 & 65280) + (uint8[i + 2] & 255);
2914
+ for (var i2 = start; i2 < end; i2 += 3) {
2915
+ tmp = (uint8[i2] << 16 & 16711680) + (uint8[i2 + 1] << 8 & 65280) + (uint8[i2 + 2] & 255);
2916
2916
  output.push(tripletToBase64(tmp));
2917
2917
  }
2918
2918
  return output.join("");
2919
2919
  }
2920
2920
  function fromByteArray(uint8) {
2921
2921
  var tmp;
2922
- var len = uint8.length;
2923
- var extraBytes = len % 3;
2922
+ var len2 = uint8.length;
2923
+ var extraBytes = len2 % 3;
2924
2924
  var parts = [];
2925
2925
  var maxChunkLength = 16383;
2926
- for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
2926
+ for (var i2 = 0, len22 = len2 - extraBytes; i2 < len22; i2 += maxChunkLength) {
2927
2927
  parts.push(
2928
2928
  encodeChunk(
2929
2929
  uint8,
2930
- i,
2931
- i + maxChunkLength > len2 ? len2 : i + maxChunkLength
2930
+ i2,
2931
+ i2 + maxChunkLength > len22 ? len22 : i2 + maxChunkLength
2932
2932
  )
2933
2933
  );
2934
2934
  }
2935
2935
  if (extraBytes === 1) {
2936
- tmp = uint8[len - 1];
2936
+ tmp = uint8[len2 - 1];
2937
2937
  parts.push(lookup[tmp >> 2] + lookup[tmp << 4 & 63] + "==");
2938
2938
  } else if (extraBytes === 2) {
2939
- tmp = (uint8[len - 2] << 8) + uint8[len - 1];
2939
+ tmp = (uint8[len2 - 2] << 8) + uint8[len2 - 1];
2940
2940
  parts.push(
2941
2941
  lookup[tmp >> 10] + lookup[tmp >> 4 & 63] + lookup[tmp << 2 & 63] + "="
2942
2942
  );
@@ -3014,9 +3014,9 @@ function slowBigIntToBase64(value) {
3014
3014
  let hex = value.toString(16);
3015
3015
  if (hex.length % 2 === 1) hex = "0" + hex;
3016
3016
  const bytes = new Uint8Array(new ArrayBuffer(8));
3017
- let i = 0;
3017
+ let i2 = 0;
3018
3018
  for (const hexByte of hex.match(/.{2}/g).reverse()) {
3019
- bytes.set([parseInt(hexByte, 16)], i++);
3019
+ bytes.set([parseInt(hexByte, 16)], i2++);
3020
3020
  value >>= EIGHT;
3021
3021
  }
3022
3022
  return fromByteArray(bytes);
@@ -3071,11 +3071,11 @@ function validateObjectField(k) {
3071
3071
  if (k.startsWith("$")) {
3072
3072
  throw new Error(`Field name ${k} starts with a '$', which is reserved.`);
3073
3073
  }
3074
- for (let i = 0; i < k.length; i += 1) {
3075
- const charCode = k.charCodeAt(i);
3074
+ for (let i2 = 0; i2 < k.length; i2 += 1) {
3075
+ const charCode = k.charCodeAt(i2);
3076
3076
  if (charCode < 32 || charCode >= 127) {
3077
3077
  throw new Error(
3078
- `Field name ${k} has invalid character '${k[i]}': Field names can only contain non-control ASCII characters`
3078
+ `Field name ${k} has invalid character '${k[i2]}': Field names can only contain non-control ASCII characters`
3079
3079
  );
3080
3080
  }
3081
3081
  }
@@ -3211,7 +3211,7 @@ function convexToJsonInternal(value, originalValue, context, includeTopLevelUnde
3211
3211
  }
3212
3212
  if (Array.isArray(value)) {
3213
3213
  return value.map(
3214
- (value2, i) => convexToJsonInternal(value2, originalValue, context + `[${i}]`, false)
3214
+ (value2, i2) => convexToJsonInternal(value2, originalValue, context + `[${i2}]`, false)
3215
3215
  );
3216
3216
  }
3217
3217
  if (value instanceof Set) {
@@ -3947,7 +3947,7 @@ var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp3(obj, key, {
3947
3947
  var __publicField2 = (obj, key, value) => __defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value);
3948
3948
  var _a;
3949
3949
  var _b;
3950
- var IDENTIFYING_FIELD = Symbol.for("ConvexError");
3950
+ var IDENTIFYING_FIELD = /* @__PURE__ */ Symbol.for("ConvexError");
3951
3951
  var ConvexError = class extends (_b = Error, _a = IDENTIFYING_FIELD, _b) {
3952
3952
  constructor(data) {
3953
3953
  super(typeof data === "string" ? data : stringifyValueForError(data));
@@ -3989,7 +3989,7 @@ var DefaultLogger = class {
3989
3989
  }
3990
3990
  addLogLineListener(func) {
3991
3991
  let id = Math.random().toString(36).substring(2, 15);
3992
- for (let i = 0; i < 10; i++) {
3992
+ for (let i2 = 0; i2 < 10; i2++) {
3993
3993
  if (this._onLogLineFuncs[id] === void 0) {
3994
3994
  break;
3995
3995
  }
@@ -4621,10 +4621,10 @@ var RequestManager = class {
4621
4621
  };
4622
4622
 
4623
4623
  // ../../node_modules/.pnpm/convex@1.33.0_patch_hash=l43bztwr6e2lbmpd6ao6hmcg24_react@19.2.1/node_modules/convex/dist/esm/server/functionName.js
4624
- var functionName = Symbol.for("functionName");
4624
+ var functionName = /* @__PURE__ */ Symbol.for("functionName");
4625
4625
 
4626
4626
  // ../../node_modules/.pnpm/convex@1.33.0_patch_hash=l43bztwr6e2lbmpd6ao6hmcg24_react@19.2.1/node_modules/convex/dist/esm/server/components/paths.js
4627
- var toReferencePath = Symbol.for("toReferencePath");
4627
+ var toReferencePath = /* @__PURE__ */ Symbol.for("toReferencePath");
4628
4628
  function extractReferencePath(reference) {
4629
4629
  return reference[toReferencePath] ?? null;
4630
4630
  }
@@ -6213,12 +6213,12 @@ var BaseConvexClient = class {
6213
6213
  this.debug = options.reportDebugInfoToConvex ?? false;
6214
6214
  this.address = address;
6215
6215
  this.logger = options.logger === false ? instantiateNoopLogger({ verbose: options.verbose ?? false }) : options.logger !== true && options.logger ? options.logger : instantiateDefaultLogger({ verbose: options.verbose ?? false });
6216
- const i = address.search("://");
6217
- if (i === -1) {
6216
+ const i2 = address.search("://");
6217
+ if (i2 === -1) {
6218
6218
  throw new Error("Provided address was not an absolute URL.");
6219
6219
  }
6220
- const origin = address.substring(i + 3);
6221
- const protocol = address.substring(0, i);
6220
+ const origin = address.substring(i2 + 3);
6221
+ const protocol = address.substring(0, i2);
6222
6222
  let wsProtocol;
6223
6223
  if (protocol === "http") {
6224
6224
  wsProtocol = "ws";
@@ -7754,10 +7754,10 @@ var require_constants = __commonJS({
7754
7754
  EMPTY_BUFFER: Buffer.alloc(0),
7755
7755
  GUID: "258EAFA5-E914-47DA-95CA-C5AB0DC85B11",
7756
7756
  hasBlob,
7757
- kForOnEventAttribute: Symbol("kIsForOnEventAttribute"),
7758
- kListener: Symbol("kListener"),
7759
- kStatusCode: Symbol("status-code"),
7760
- kWebSocket: Symbol("websocket"),
7757
+ kForOnEventAttribute: /* @__PURE__ */ Symbol("kIsForOnEventAttribute"),
7758
+ kListener: /* @__PURE__ */ Symbol("kListener"),
7759
+ kStatusCode: /* @__PURE__ */ Symbol("status-code"),
7760
+ kWebSocket: /* @__PURE__ */ Symbol("websocket"),
7761
7761
  NOOP: () => {
7762
7762
  }
7763
7763
  };
@@ -7863,8 +7863,8 @@ var require_node_gyp_build = __commonJS({
7863
7863
  var extension = arr2.pop();
7864
7864
  var tags = { file, specificity: 0 };
7865
7865
  if (extension !== "node") return;
7866
- for (var i = 0; i < arr2.length; i++) {
7867
- var tag = arr2[i];
7866
+ for (var i2 = 0; i2 < arr2.length; i2++) {
7867
+ var tag = arr2[i2];
7868
7868
  if (tag === "node" || tag === "electron" || tag === "node-webkit") {
7869
7869
  tags.runtime = tag;
7870
7870
  } else if (tag === "napi") {
@@ -7944,14 +7944,14 @@ var require_fallback = __commonJS({
7944
7944
  "../common/temp/node_modules/.pnpm/bufferutil@4.0.9/node_modules/bufferutil/fallback.js"(exports, module) {
7945
7945
  "use strict";
7946
7946
  var mask = (source, mask2, output, offset, length) => {
7947
- for (var i = 0; i < length; i++) {
7948
- output[offset + i] = source[i] ^ mask2[i & 3];
7947
+ for (var i2 = 0; i2 < length; i2++) {
7948
+ output[offset + i2] = source[i2] ^ mask2[i2 & 3];
7949
7949
  }
7950
7950
  };
7951
7951
  var unmask = (buffer, mask2) => {
7952
7952
  const length = buffer.length;
7953
- for (var i = 0; i < length; i++) {
7954
- buffer[i] ^= mask2[i & 3];
7953
+ for (var i2 = 0; i2 < length; i2++) {
7954
+ buffer[i2] ^= mask2[i2 & 3];
7955
7955
  }
7956
7956
  };
7957
7957
  module.exports = { mask, unmask };
@@ -7977,8 +7977,8 @@ var require_buffer_util = __commonJS({
7977
7977
  if (list.length === 1) return list[0];
7978
7978
  const target = Buffer.allocUnsafe(totalLength);
7979
7979
  let offset = 0;
7980
- for (let i = 0; i < list.length; i++) {
7981
- const buf = list[i];
7980
+ for (let i2 = 0; i2 < list.length; i2++) {
7981
+ const buf = list[i2];
7982
7982
  target.set(buf, offset);
7983
7983
  offset += buf.length;
7984
7984
  }
@@ -7988,13 +7988,13 @@ var require_buffer_util = __commonJS({
7988
7988
  return target;
7989
7989
  }
7990
7990
  function _mask(source, mask, output, offset, length) {
7991
- for (let i = 0; i < length; i++) {
7992
- output[offset + i] = source[i] ^ mask[i & 3];
7991
+ for (let i2 = 0; i2 < length; i2++) {
7992
+ output[offset + i2] = source[i2] ^ mask[i2 & 3];
7993
7993
  }
7994
7994
  }
7995
7995
  function _unmask(buffer, mask) {
7996
- for (let i = 0; i < buffer.length; i++) {
7997
- buffer[i] ^= mask[i & 3];
7996
+ for (let i2 = 0; i2 < buffer.length; i2++) {
7997
+ buffer[i2] ^= mask[i2 & 3];
7998
7998
  }
7999
7999
  }
8000
8000
  function toArrayBuffer(buf) {
@@ -8043,8 +8043,8 @@ var require_buffer_util = __commonJS({
8043
8043
  var require_limiter = __commonJS({
8044
8044
  "../common/temp/node_modules/.pnpm/ws@8.18.0_bufferutil@4.0.9/node_modules/ws/lib/limiter.js"(exports, module) {
8045
8045
  "use strict";
8046
- var kDone = Symbol("kDone");
8047
- var kRun = Symbol("kRun");
8046
+ var kDone = /* @__PURE__ */ Symbol("kDone");
8047
+ var kRun = /* @__PURE__ */ Symbol("kRun");
8048
8048
  var Limiter = class {
8049
8049
  /**
8050
8050
  * Creates a new `Limiter`.
@@ -8097,11 +8097,11 @@ var require_permessage_deflate = __commonJS({
8097
8097
  var { kStatusCode } = require_constants();
8098
8098
  var FastBuffer = Buffer[Symbol.species];
8099
8099
  var TRAILER = Buffer.from([0, 0, 255, 255]);
8100
- var kPerMessageDeflate = Symbol("permessage-deflate");
8101
- var kTotalLength = Symbol("total-length");
8102
- var kCallback = Symbol("callback");
8103
- var kBuffers = Symbol("buffers");
8104
- var kError = Symbol("error");
8100
+ var kPerMessageDeflate = /* @__PURE__ */ Symbol("permessage-deflate");
8101
+ var kTotalLength = /* @__PURE__ */ Symbol("total-length");
8102
+ var kCallback = /* @__PURE__ */ Symbol("callback");
8103
+ var kBuffers = /* @__PURE__ */ Symbol("buffers");
8104
+ var kError = /* @__PURE__ */ Symbol("error");
8105
8105
  var zlibLimiter;
8106
8106
  var PerMessageDeflate = class {
8107
8107
  /**
@@ -8612,28 +8612,28 @@ var require_validation = __commonJS({
8612
8612
  return code2 >= 1e3 && code2 <= 1014 && code2 !== 1004 && code2 !== 1005 && code2 !== 1006 || code2 >= 3e3 && code2 <= 4999;
8613
8613
  }
8614
8614
  function _isValidUTF8(buf) {
8615
- const len = buf.length;
8616
- let i = 0;
8617
- while (i < len) {
8618
- if ((buf[i] & 128) === 0) {
8619
- i++;
8620
- } else if ((buf[i] & 224) === 192) {
8621
- if (i + 1 === len || (buf[i + 1] & 192) !== 128 || (buf[i] & 254) === 192) {
8615
+ const len2 = buf.length;
8616
+ let i2 = 0;
8617
+ while (i2 < len2) {
8618
+ if ((buf[i2] & 128) === 0) {
8619
+ i2++;
8620
+ } else if ((buf[i2] & 224) === 192) {
8621
+ if (i2 + 1 === len2 || (buf[i2 + 1] & 192) !== 128 || (buf[i2] & 254) === 192) {
8622
8622
  return false;
8623
8623
  }
8624
- i += 2;
8625
- } else if ((buf[i] & 240) === 224) {
8626
- if (i + 2 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || buf[i] === 224 && (buf[i + 1] & 224) === 128 || // Overlong
8627
- buf[i] === 237 && (buf[i + 1] & 224) === 160) {
8624
+ i2 += 2;
8625
+ } else if ((buf[i2] & 240) === 224) {
8626
+ if (i2 + 2 >= len2 || (buf[i2 + 1] & 192) !== 128 || (buf[i2 + 2] & 192) !== 128 || buf[i2] === 224 && (buf[i2 + 1] & 224) === 128 || // Overlong
8627
+ buf[i2] === 237 && (buf[i2 + 1] & 224) === 160) {
8628
8628
  return false;
8629
8629
  }
8630
- i += 3;
8631
- } else if ((buf[i] & 248) === 240) {
8632
- if (i + 3 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || (buf[i + 3] & 192) !== 128 || buf[i] === 240 && (buf[i + 1] & 240) === 128 || // Overlong
8633
- buf[i] === 244 && buf[i + 1] > 143 || buf[i] > 244) {
8630
+ i2 += 3;
8631
+ } else if ((buf[i2] & 248) === 240) {
8632
+ if (i2 + 3 >= len2 || (buf[i2 + 1] & 192) !== 128 || (buf[i2 + 2] & 192) !== 128 || (buf[i2 + 3] & 192) !== 128 || buf[i2] === 240 && (buf[i2 + 1] & 240) === 128 || // Overlong
8633
+ buf[i2] === 244 && buf[i2 + 1] > 143 || buf[i2] > 244) {
8634
8634
  return false;
8635
8635
  }
8636
- i += 4;
8636
+ i2 += 4;
8637
8637
  } else {
8638
8638
  return false;
8639
8639
  }
@@ -9263,7 +9263,7 @@ var require_sender = __commonJS({
9263
9263
  var { EMPTY_BUFFER, kWebSocket, NOOP } = require_constants();
9264
9264
  var { isBlob, isValidStatusCode } = require_validation();
9265
9265
  var { mask: applyMask, toBuffer } = require_buffer_util();
9266
- var kByteLength = Symbol("kByteLength");
9266
+ var kByteLength = /* @__PURE__ */ Symbol("kByteLength");
9267
9267
  var maskBuffer = Buffer.alloc(4);
9268
9268
  var RANDOM_POOL_SIZE = 8 * 1024;
9269
9269
  var randomPool;
@@ -9728,8 +9728,8 @@ var require_sender = __commonJS({
9728
9728
  module.exports = Sender2;
9729
9729
  function callCallbacks(sender, err, cb) {
9730
9730
  if (typeof cb === "function") cb(err);
9731
- for (let i = 0; i < sender._queue.length; i++) {
9732
- const params = sender._queue[i];
9731
+ for (let i2 = 0; i2 < sender._queue.length; i2++) {
9732
+ const params = sender._queue[i2];
9733
9733
  const callback = params[params.length - 1];
9734
9734
  if (typeof callback === "function") callback(err);
9735
9735
  }
@@ -9744,14 +9744,14 @@ var require_event_target = __commonJS({
9744
9744
  "../common/temp/node_modules/.pnpm/ws@8.18.0_bufferutil@4.0.9/node_modules/ws/lib/event-target.js"(exports, module) {
9745
9745
  "use strict";
9746
9746
  var { kForOnEventAttribute, kListener } = require_constants();
9747
- var kCode = Symbol("kCode");
9748
- var kData = Symbol("kData");
9749
- var kError = Symbol("kError");
9750
- var kMessage = Symbol("kMessage");
9751
- var kReason = Symbol("kReason");
9752
- var kTarget = Symbol("kTarget");
9753
- var kType = Symbol("kType");
9754
- var kWasClean = Symbol("kWasClean");
9747
+ var kCode = /* @__PURE__ */ Symbol("kCode");
9748
+ var kData = /* @__PURE__ */ Symbol("kData");
9749
+ var kError = /* @__PURE__ */ Symbol("kError");
9750
+ var kMessage = /* @__PURE__ */ Symbol("kMessage");
9751
+ var kReason = /* @__PURE__ */ Symbol("kReason");
9752
+ var kTarget = /* @__PURE__ */ Symbol("kTarget");
9753
+ var kType = /* @__PURE__ */ Symbol("kType");
9754
+ var kWasClean = /* @__PURE__ */ Symbol("kWasClean");
9755
9755
  var Event = class {
9756
9756
  /**
9757
9757
  * Create a new `Event`.
@@ -9986,19 +9986,19 @@ var require_extension = __commonJS({
9986
9986
  let start = -1;
9987
9987
  let code2 = -1;
9988
9988
  let end = -1;
9989
- let i = 0;
9990
- for (; i < header.length; i++) {
9991
- code2 = header.charCodeAt(i);
9989
+ let i2 = 0;
9990
+ for (; i2 < header.length; i2++) {
9991
+ code2 = header.charCodeAt(i2);
9992
9992
  if (extensionName === void 0) {
9993
9993
  if (end === -1 && tokenChars[code2] === 1) {
9994
- if (start === -1) start = i;
9995
- } else if (i !== 0 && (code2 === 32 || code2 === 9)) {
9996
- if (end === -1 && start !== -1) end = i;
9994
+ if (start === -1) start = i2;
9995
+ } else if (i2 !== 0 && (code2 === 32 || code2 === 9)) {
9996
+ if (end === -1 && start !== -1) end = i2;
9997
9997
  } else if (code2 === 59 || code2 === 44) {
9998
9998
  if (start === -1) {
9999
- throw new SyntaxError(`Unexpected character at index ${i}`);
9999
+ throw new SyntaxError(`Unexpected character at index ${i2}`);
10000
10000
  }
10001
- if (end === -1) end = i;
10001
+ if (end === -1) end = i2;
10002
10002
  const name = header.slice(start, end);
10003
10003
  if (code2 === 44) {
10004
10004
  push(offers, name, params);
@@ -10008,18 +10008,18 @@ var require_extension = __commonJS({
10008
10008
  }
10009
10009
  start = end = -1;
10010
10010
  } else {
10011
- throw new SyntaxError(`Unexpected character at index ${i}`);
10011
+ throw new SyntaxError(`Unexpected character at index ${i2}`);
10012
10012
  }
10013
10013
  } else if (paramName === void 0) {
10014
10014
  if (end === -1 && tokenChars[code2] === 1) {
10015
- if (start === -1) start = i;
10015
+ if (start === -1) start = i2;
10016
10016
  } else if (code2 === 32 || code2 === 9) {
10017
- if (end === -1 && start !== -1) end = i;
10017
+ if (end === -1 && start !== -1) end = i2;
10018
10018
  } else if (code2 === 59 || code2 === 44) {
10019
10019
  if (start === -1) {
10020
- throw new SyntaxError(`Unexpected character at index ${i}`);
10020
+ throw new SyntaxError(`Unexpected character at index ${i2}`);
10021
10021
  }
10022
- if (end === -1) end = i;
10022
+ if (end === -1) end = i2;
10023
10023
  push(params, header.slice(start, end), true);
10024
10024
  if (code2 === 44) {
10025
10025
  push(offers, extensionName, params);
@@ -10028,41 +10028,41 @@ var require_extension = __commonJS({
10028
10028
  }
10029
10029
  start = end = -1;
10030
10030
  } else if (code2 === 61 && start !== -1 && end === -1) {
10031
- paramName = header.slice(start, i);
10031
+ paramName = header.slice(start, i2);
10032
10032
  start = end = -1;
10033
10033
  } else {
10034
- throw new SyntaxError(`Unexpected character at index ${i}`);
10034
+ throw new SyntaxError(`Unexpected character at index ${i2}`);
10035
10035
  }
10036
10036
  } else {
10037
10037
  if (isEscaping) {
10038
10038
  if (tokenChars[code2] !== 1) {
10039
- throw new SyntaxError(`Unexpected character at index ${i}`);
10039
+ throw new SyntaxError(`Unexpected character at index ${i2}`);
10040
10040
  }
10041
- if (start === -1) start = i;
10041
+ if (start === -1) start = i2;
10042
10042
  else if (!mustUnescape) mustUnescape = true;
10043
10043
  isEscaping = false;
10044
10044
  } else if (inQuotes) {
10045
10045
  if (tokenChars[code2] === 1) {
10046
- if (start === -1) start = i;
10046
+ if (start === -1) start = i2;
10047
10047
  } else if (code2 === 34 && start !== -1) {
10048
10048
  inQuotes = false;
10049
- end = i;
10049
+ end = i2;
10050
10050
  } else if (code2 === 92) {
10051
10051
  isEscaping = true;
10052
10052
  } else {
10053
- throw new SyntaxError(`Unexpected character at index ${i}`);
10053
+ throw new SyntaxError(`Unexpected character at index ${i2}`);
10054
10054
  }
10055
- } else if (code2 === 34 && header.charCodeAt(i - 1) === 61) {
10055
+ } else if (code2 === 34 && header.charCodeAt(i2 - 1) === 61) {
10056
10056
  inQuotes = true;
10057
10057
  } else if (end === -1 && tokenChars[code2] === 1) {
10058
- if (start === -1) start = i;
10058
+ if (start === -1) start = i2;
10059
10059
  } else if (start !== -1 && (code2 === 32 || code2 === 9)) {
10060
- if (end === -1) end = i;
10060
+ if (end === -1) end = i2;
10061
10061
  } else if (code2 === 59 || code2 === 44) {
10062
10062
  if (start === -1) {
10063
- throw new SyntaxError(`Unexpected character at index ${i}`);
10063
+ throw new SyntaxError(`Unexpected character at index ${i2}`);
10064
10064
  }
10065
- if (end === -1) end = i;
10065
+ if (end === -1) end = i2;
10066
10066
  let value = header.slice(start, end);
10067
10067
  if (mustUnescape) {
10068
10068
  value = value.replace(/\\/g, "");
@@ -10077,14 +10077,14 @@ var require_extension = __commonJS({
10077
10077
  paramName = void 0;
10078
10078
  start = end = -1;
10079
10079
  } else {
10080
- throw new SyntaxError(`Unexpected character at index ${i}`);
10080
+ throw new SyntaxError(`Unexpected character at index ${i2}`);
10081
10081
  }
10082
10082
  }
10083
10083
  }
10084
10084
  if (start === -1 || inQuotes || code2 === 32 || code2 === 9) {
10085
10085
  throw new SyntaxError("Unexpected end of input");
10086
10086
  }
10087
- if (end === -1) end = i;
10087
+ if (end === -1) end = i2;
10088
10088
  const token2 = header.slice(start, end);
10089
10089
  if (extensionName === void 0) {
10090
10090
  push(offers, token2, params);
@@ -10149,7 +10149,7 @@ var require_websocket = __commonJS({
10149
10149
  var { format, parse } = require_extension();
10150
10150
  var { toBuffer } = require_buffer_util();
10151
10151
  var closeTimeout = 30 * 1e3;
10152
- var kAborted = Symbol("kAborted");
10152
+ var kAborted = /* @__PURE__ */ Symbol("kAborted");
10153
10153
  var protocolVersions = [8, 13];
10154
10154
  var readyStates = ["CONNECTING", "OPEN", "CLOSING", "CLOSED"];
10155
10155
  var subprotocolRegex = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;
@@ -11007,18 +11007,18 @@ var require_subprotocol = __commonJS({
11007
11007
  const protocols = /* @__PURE__ */ new Set();
11008
11008
  let start = -1;
11009
11009
  let end = -1;
11010
- let i = 0;
11011
- for (i; i < header.length; i++) {
11012
- const code2 = header.charCodeAt(i);
11010
+ let i2 = 0;
11011
+ for (i2; i2 < header.length; i2++) {
11012
+ const code2 = header.charCodeAt(i2);
11013
11013
  if (end === -1 && tokenChars[code2] === 1) {
11014
- if (start === -1) start = i;
11015
- } else if (i !== 0 && (code2 === 32 || code2 === 9)) {
11016
- if (end === -1 && start !== -1) end = i;
11014
+ if (start === -1) start = i2;
11015
+ } else if (i2 !== 0 && (code2 === 32 || code2 === 9)) {
11016
+ if (end === -1 && start !== -1) end = i2;
11017
11017
  } else if (code2 === 44) {
11018
11018
  if (start === -1) {
11019
- throw new SyntaxError(`Unexpected character at index ${i}`);
11019
+ throw new SyntaxError(`Unexpected character at index ${i2}`);
11020
11020
  }
11021
- if (end === -1) end = i;
11021
+ if (end === -1) end = i2;
11022
11022
  const protocol2 = header.slice(start, end);
11023
11023
  if (protocols.has(protocol2)) {
11024
11024
  throw new SyntaxError(`The "${protocol2}" subprotocol is duplicated`);
@@ -11026,13 +11026,13 @@ var require_subprotocol = __commonJS({
11026
11026
  protocols.add(protocol2);
11027
11027
  start = end = -1;
11028
11028
  } else {
11029
- throw new SyntaxError(`Unexpected character at index ${i}`);
11029
+ throw new SyntaxError(`Unexpected character at index ${i2}`);
11030
11030
  }
11031
11031
  }
11032
11032
  if (start === -1 || end !== -1) {
11033
11033
  throw new SyntaxError("Unexpected end of input");
11034
11034
  }
11035
- const protocol = header.slice(start, i);
11035
+ const protocol = header.slice(start, i2);
11036
11036
  if (protocols.has(protocol)) {
11037
11037
  throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`);
11038
11038
  }
@@ -12015,7 +12015,7 @@ async function pushTelemetry(apiKey2, data) {
12015
12015
  const c = getClient();
12016
12016
  if (!c) return;
12017
12017
  try {
12018
- await c.mutation(upsertTelemetryFromPlugin, { apiKeyHash: hashApiKey(apiKey2), ...data });
12018
+ await c.mutation(upsertTelemetryFromPlugin, { apiKeyHash: hashApiKey(apiKey2), runtime: "openclaw", ...data });
12019
12019
  } catch (err) {
12020
12020
  if (isUnauthorizedError(err)) {
12021
12021
  tripAuthCircuit();
@@ -12686,7 +12686,7 @@ async function startNotificationSubscription(port, cfg, hooksToken, logger, gwCl
12686
12686
  processing = true;
12687
12687
  try {
12688
12688
  for (const n of notifications) {
12689
- const failCount = deliveryFailures.get(n._id) ?? 0;
12689
+ const failCount = deliveryFailures.get(n.id) ?? 0;
12690
12690
  if (failCount >= MAX_DELIVERY_ATTEMPTS) {
12691
12691
  continue;
12692
12692
  }
@@ -12697,34 +12697,34 @@ async function startNotificationSubscription(port, cfg, hooksToken, logger, gwCl
12697
12697
  logger.info(`cohort-sync: injected notification for ${targetLabel} (${agentName})`);
12698
12698
  } else {
12699
12699
  throw new Error(
12700
- `no transport available for notification ${n._id} (gwClient alive: ${gwClient?.isAlive() ?? "null"}, hooksToken: ${!!hooksToken})`
12700
+ `no transport available for notification ${n.id} (gwClient alive: ${gwClient?.isAlive() ?? "null"}, hooksToken: ${!!hooksToken})`
12701
12701
  );
12702
12702
  }
12703
12703
  await c.mutation(markDeliveredByPlugin, {
12704
- notificationId: n._id,
12704
+ notificationId: n.id,
12705
12705
  apiKeyHash
12706
12706
  });
12707
- deliveryFailures.delete(n._id);
12707
+ deliveryFailures.delete(n.id);
12708
12708
  } catch (err) {
12709
12709
  const newFailCount = failCount + 1;
12710
- deliveryFailures.set(n._id, newFailCount);
12710
+ deliveryFailures.set(n.id, newFailCount);
12711
12711
  if (newFailCount >= MAX_DELIVERY_ATTEMPTS) {
12712
12712
  const targetLabel = n.type === "room_message" ? `room ${n.roomId ?? n.roomName ?? "unknown"}` : `task #${n.taskNumber}`;
12713
12713
  logger.error(
12714
- `cohort-sync: dead-letter notification ${n._id} for ${targetLabel} (${n.type} from ${n.actorName}) after ${MAX_DELIVERY_ATTEMPTS} failed delivery attempts: ${String(err)}`
12714
+ `cohort-sync: dead-letter notification ${n.id} for ${targetLabel} (${n.type} from ${n.actorName}) after ${MAX_DELIVERY_ATTEMPTS} failed delivery attempts: ${String(err)}`
12715
12715
  );
12716
12716
  try {
12717
12717
  await c.mutation(markDeliveredByPlugin, {
12718
- notificationId: n._id,
12718
+ notificationId: n.id,
12719
12719
  apiKeyHash
12720
12720
  });
12721
- deliveryFailures.delete(n._id);
12721
+ deliveryFailures.delete(n.id);
12722
12722
  } catch (markErr) {
12723
- logger.error(`cohort-sync: failed to dead-letter ${n._id}: ${String(markErr)}`);
12723
+ logger.error(`cohort-sync: failed to dead-letter ${n.id}: ${String(markErr)}`);
12724
12724
  }
12725
12725
  } else {
12726
12726
  logger.warn(
12727
- `cohort-sync: failed to inject notification ${n._id} (attempt ${newFailCount}/${MAX_DELIVERY_ATTEMPTS}): ${String(err)}`
12727
+ `cohort-sync: failed to inject notification ${n.id} (attempt ${newFailCount}/${MAX_DELIVERY_ATTEMPTS}): ${String(err)}`
12728
12728
  );
12729
12729
  }
12730
12730
  }
@@ -14119,7 +14119,7 @@ function dumpEvent(event) {
14119
14119
  function positiveNumber(value) {
14120
14120
  return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
14121
14121
  }
14122
- var PLUGIN_VERSION = true ? "0.34.1" : "unknown";
14122
+ var PLUGIN_VERSION = true ? "0.34.3" : "unknown";
14123
14123
  function resolveGatewayToken(api) {
14124
14124
  const token2 = api.config?.gateway?.auth?.token;
14125
14125
  return typeof token2 === "string" ? token2 : null;
@@ -15104,6 +15104,13 @@ var POCKET_GUIDE = `# Cohort Agent Guide (Pocket Version)
15104
15104
  - For code changes, work is not complete when it is implemented locally; push your branch, open a PR, enable auto-merge, watch CI until green or red, confirm the PR merged, verify the production deploy, then comment with the PR link, deploy result, and verification evidence.
15105
15105
  - Use GitHub for deployment: after opening the PR, run gh pr merge --auto --rebase --delete-branch, gh pr checks <PR> --watch, confirm the merge, then run gh run watch <deploy-run-id> for the Deploy Production workflow. Do not stop because Vercel CLI is not authenticated; Cohort deploys through GitHub Actions after merge.
15106
15106
 
15107
+ ## Working as a Team
15108
+ - Two modes: orchestrator and worker. As an orchestrator, break the goal into a task graph (create tasks, assign owners, relate dependencies), then report the graph and leave implementation to the assigned workers. As a worker, take one task, do it, and hand it back cleanly.
15109
+ - Relate dependent tasks with blockers so ordering is explicit. A blocked task stays gated until its blocker clears.
15110
+ - Before assigning, confirm the assignee is a real agent in the workspace, because a task assigned to a name that resolves to no one strands in its column.
15111
+ - The closing comment is the handoff: what you did, the evidence (links, PR, test output, artifact), and what is now unblocked or what the human must decide. Agents cannot set "done", so move to "waiting" and let a human close it.
15112
+ - Create a task when work spans multiple agents, needs to survive a restart, wants a human in the loop, or can run in parallel. For something you can finish right now, just do it.
15113
+
15107
15114
  ## Comments
15108
15115
  - Comment before every status transition explaining what happened.
15109
15116
  - Post progress updates every 15-30 minutes on long-running work.
@@ -15212,9 +15219,87 @@ function getStorageIdFromUploadResponse(body) {
15212
15219
  function formatMetric(metric) {
15213
15220
  return `${metric.current}/${metric.target} ${metric.unit}`;
15214
15221
  }
15222
+ function isRecord2(value) {
15223
+ return typeof value === "object" && value !== null;
15224
+ }
15215
15225
  function redactSecrets(text) {
15216
15226
  return text.replace(/ch_(?:live|test)_[A-Za-z0-9_-]+/g, "[redacted]");
15217
15227
  }
15228
+ function isTaskRelationSummary(value) {
15229
+ if (!isRecord2(value) || !isRecord2(value.task)) return false;
15230
+ return typeof value.id === "string" && (value.type === "blocks" || value.type === "related" || value.type === "duplicate_of") && (value.direction === "incoming" || value.direction === "outgoing") && (value.task.taskNumber === void 0 || typeof value.task.taskNumber === "number") && (value.task.title === void 0 || typeof value.task.title === "string") && typeof value.task.status === "string" && (typeof value.task.assignedTo === "string" || value.task.assignedTo === null);
15231
+ }
15232
+ function relationTaskLabel(relation) {
15233
+ const id = relation.task.taskNumber !== void 0 ? `#${relation.task.taskNumber}` : relation.task.title ?? "untitled task";
15234
+ return `${id} (${relation.task.status}, ${relation.task.assignedTo ?? "unassigned"})`;
15235
+ }
15236
+ function formatTaskRelationsSummary(relations) {
15237
+ if (!Array.isArray(relations)) return [];
15238
+ const rows = relations.filter(isTaskRelationSummary);
15239
+ if (rows.length === 0) return [];
15240
+ const groups = [
15241
+ { label: "Blocked by", rows: rows.filter((r) => r.type === "blocks" && r.direction === "incoming") },
15242
+ { label: "Blocks", rows: rows.filter((r) => r.type === "blocks" && r.direction === "outgoing") },
15243
+ { label: "Related", rows: rows.filter((r) => r.type === "related") },
15244
+ { label: "Duplicate of", rows: rows.filter((r) => r.type === "duplicate_of" && r.direction === "outgoing") },
15245
+ { label: "Duplicated by", rows: rows.filter((r) => r.type === "duplicate_of" && r.direction === "incoming") }
15246
+ ];
15247
+ return groups.filter((group) => group.rows.length > 0).map((group) => `${group.label}: ${group.rows.map(relationTaskLabel).join(", ")}`);
15248
+ }
15249
+ function blockerLine(blocker) {
15250
+ const id = blocker.taskNumber !== void 0 ? `#${blocker.taskNumber}` : "Unnumbered task";
15251
+ return `${id} ${blocker.title} (${blocker.status}, ${blocker.assignedTo ?? "unassigned"})`;
15252
+ }
15253
+ function getTaskBlockedErrorData(error) {
15254
+ if (!isRecord2(error) || !isRecord2(error.data)) return null;
15255
+ const data = error.data;
15256
+ if (data.code !== "CONFLICT" || data.subcode !== "TASK_BLOCKED" || typeof data.message !== "string") {
15257
+ return null;
15258
+ }
15259
+ const blockers = Array.isArray(data.blockers) ? data.blockers.flatMap((blocker) => {
15260
+ if (!isRecord2(blocker) || typeof blocker.title !== "string" || typeof blocker.status !== "string") {
15261
+ return [];
15262
+ }
15263
+ const assignedTo = typeof blocker.assignedTo === "string" ? blocker.assignedTo : null;
15264
+ return [{
15265
+ ...typeof blocker.taskNumber === "number" ? { taskNumber: blocker.taskNumber } : {},
15266
+ title: blocker.title,
15267
+ status: blocker.status,
15268
+ assignedTo
15269
+ }];
15270
+ }) : void 0;
15271
+ return {
15272
+ code: "CONFLICT",
15273
+ subcode: "TASK_BLOCKED",
15274
+ message: data.message,
15275
+ ...blockers ? { blockers } : {}
15276
+ };
15277
+ }
15278
+ function formatTaskBlockedError(error) {
15279
+ const data = getTaskBlockedErrorData(error);
15280
+ if (!data) return null;
15281
+ const lines = [data.message];
15282
+ if (data.blockers && data.blockers.length > 0) {
15283
+ lines.push("", "Open blockers:");
15284
+ for (const blocker of data.blockers) {
15285
+ lines.push(`- ${blockerLine(blocker)}`);
15286
+ }
15287
+ }
15288
+ return lines.join("\n");
15289
+ }
15290
+ function relationMatchesVerb(relation, relationVerb, otherTaskNumber) {
15291
+ if (relation.task.taskNumber !== otherTaskNumber) return false;
15292
+ switch (relationVerb) {
15293
+ case "blocked_by":
15294
+ return relation.type === "blocks" && relation.direction === "incoming";
15295
+ case "blocks":
15296
+ return relation.type === "blocks" && relation.direction === "outgoing";
15297
+ case "related":
15298
+ return relation.type === "related";
15299
+ case "duplicate_of":
15300
+ return relation.type === "duplicate_of" && relation.direction === "outgoing";
15301
+ }
15302
+ }
15218
15303
  async function safeHttpError(response) {
15219
15304
  try {
15220
15305
  const body = await response.text();
@@ -15394,7 +15479,7 @@ Do not attempt more comments until tomorrow.`);
15394
15479
  label: "cohort_room_message",
15395
15480
  description: "Post a message in a Cohort Room. Use this to reply when you are participating in a Room chat.",
15396
15481
  parameters: Type.Object({
15397
- room_id: Type.String({ description: "Room ID supplied by Cohort, e.g. rooms:abc123" }),
15482
+ room_id: Type.String({ description: 'The Room to post in. Prefer the exact room id from your prompt/notification (e.g. xs773mgqe3qd9h41pjwxndd755887b1x). The room name (e.g. "All Hands") is also accepted.' }),
15398
15483
  message: Type.String({ description: "Message text to post in the Room" }),
15399
15484
  turn_id: Type.Optional(Type.String({ description: "Moderation turn id to attribute this reply to (echo from your prompt)" }))
15400
15485
  }),
@@ -15421,7 +15506,7 @@ Do not attempt more comments until tomorrow.`);
15421
15506
  label: "cohort_room_prompt_agent",
15422
15507
  description: "Ask one agent in a Cohort Room to respond. Use this when you are the Room moderator and need controlled turn-taking.",
15423
15508
  parameters: Type.Object({
15424
- room_id: Type.String({ description: "Room ID supplied by Cohort, e.g. rooms:abc123" }),
15509
+ room_id: Type.String({ description: 'Room ID supplied by Cohort, e.g. xs773mgqe3qd9h41pjwxndd755887b1x (NOT prefixed with "rooms:").' }),
15425
15510
  agent_name: Type.String({ description: "Cohort agent name to prompt, e.g. iris" }),
15426
15511
  prompt: Type.String({ description: "Prompt to send to the target agent" })
15427
15512
  }),
@@ -15449,7 +15534,7 @@ Do not attempt more comments until tomorrow.`);
15449
15534
  label: "cohort_room_prompt_agents",
15450
15535
  description: "Ask multiple agents in a Cohort Room to respond in one controlled moderator action.",
15451
15536
  parameters: Type.Object({
15452
- room_id: Type.String({ description: "Room ID supplied by Cohort, e.g. rooms:abc123" }),
15537
+ room_id: Type.String({ description: 'Room ID supplied by Cohort, e.g. xs773mgqe3qd9h41pjwxndd755887b1x (NOT prefixed with "rooms:").' }),
15453
15538
  agent_names: Type.Array(Type.String({ description: "Cohort agent name to prompt" })),
15454
15539
  prompt: Type.String({ description: "Prompt to send to the target agents" })
15455
15540
  }),
@@ -15593,7 +15678,7 @@ Wire item: ${result.wireItemId}`, result);
15593
15678
  label: "cohort_room_start_moderation_session",
15594
15679
  description: 'Start a managed moderation session in a Cohort Room. Use round_robin = ask every participant to report in; use moderated_qna = route a question to one selected agent, wait for the answer, ask the asker whether it resolves the question, then complete. For multiple experts in Q&A, start with one best agent and use action: "followup" for additional experts one at a time. Returns the session state block. The returned block includes the session_id \u2014 pass it to cohort_room_advance_moderation_session for every subsequent action.',
15595
15680
  parameters: Type.Object({
15596
- room_id: Type.String({ description: "Room ID supplied by Cohort, e.g. rooms:abc123" }),
15681
+ room_id: Type.String({ description: 'Room ID supplied by Cohort, e.g. xs773mgqe3qd9h41pjwxndd755887b1x (NOT prefixed with "rooms:").' }),
15597
15682
  mode: Type.Union([
15598
15683
  Type.Literal("round_robin"),
15599
15684
  Type.Literal("moderated_qna")
@@ -15842,10 +15927,17 @@ ${body}`,
15842
15927
  `**Assigned to:** ${task.assignedTo ?? "unassigned"}`,
15843
15928
  `**Created:** ${task.createdAt}`
15844
15929
  ];
15930
+ if (task.blocked === true) {
15931
+ lines.push("**Blocked:** yes");
15932
+ }
15845
15933
  const contextBlock = renderTaskContext(task.context);
15846
15934
  if (contextBlock) {
15847
15935
  lines.push("", contextBlock);
15848
15936
  }
15937
+ const relationsSummary = formatTaskRelationsSummary(task.relations);
15938
+ if (relationsSummary.length > 0) {
15939
+ lines.push("", "## Relations", ...relationsSummary);
15940
+ }
15849
15941
  lines.push("", "## Description", task.description || "(no description)");
15850
15942
  if (params.include_comments !== false) {
15851
15943
  const limit = params.comment_limit ?? 10;
@@ -15961,7 +16053,145 @@ ${renderGoal(goal)}`, goal);
15961
16053
  });
15962
16054
  return textResult(`Task #${params.task_number} transitioned to "${params.status}".`);
15963
16055
  } catch (err) {
15964
- return textResult(`Failed to transition task #${params.task_number}: ${err instanceof Error ? err.message : String(err)}`);
16056
+ const blockedMessage = formatTaskBlockedError(err);
16057
+ if (blockedMessage) {
16058
+ return textResult(blockedMessage, getTaskBlockedErrorData(err));
16059
+ }
16060
+ const appMessage = getConvexAppErrorMessage(err);
16061
+ return textResult(`Failed to transition task #${params.task_number}: ${appMessage ?? (err instanceof Error ? err.message : String(err))}`);
16062
+ }
16063
+ }
16064
+ };
16065
+ });
16066
+ api.registerTool(() => {
16067
+ return {
16068
+ name: "cohort_triage",
16069
+ label: "cohort_triage",
16070
+ description: "Report your triage decision on a Cohort triage item back to Cohort. Pass the Triage item ID from your wake task as triage_item_id, the tier (trivial | judgment | feature | not_actionable), whether it is actionable, and your reasoning. SHADOW MODE: do NOT write code or open PRs.",
16071
+ parameters: Type.Object({
16072
+ triage_item_id: Type.String({ description: "Triage item ID from your wake task (e.g. triageItems:abc123)." }),
16073
+ tier: Type.Union([
16074
+ Type.Literal("trivial"),
16075
+ Type.Literal("judgment"),
16076
+ Type.Literal("feature"),
16077
+ Type.Literal("not_actionable")
16078
+ ], { description: "Triage tier for this feedback." }),
16079
+ actionable: Type.Boolean({ description: "Whether this feedback is actionable." }),
16080
+ reasoning: Type.String({ description: "Why you reached this decision." }),
16081
+ confidence: Type.Optional(Type.Number({ description: "Optional confidence in the decision, 0 to 1." }))
16082
+ }),
16083
+ async execute(_toolCallId, params) {
16084
+ const rt = getToolRuntime();
16085
+ if (!rt.isReady) {
16086
+ return textResult("cohort_triage is not ready yet \u2014 the plugin is still starting up.");
16087
+ }
16088
+ try {
16089
+ const response = await fetch(
16090
+ `${rt.apiUrl}/api/v1/plugin/triage/${encodeURIComponent(params.triage_item_id)}/decision`,
16091
+ {
16092
+ method: "POST",
16093
+ headers: {
16094
+ "Authorization": `Bearer ${rt.apiKey}`,
16095
+ "Content-Type": "application/json"
16096
+ },
16097
+ body: JSON.stringify({
16098
+ tier: params.tier,
16099
+ actionable: params.actionable,
16100
+ reasoning: params.reasoning,
16101
+ ...params.confidence !== void 0 ? { confidence: params.confidence } : {}
16102
+ }),
16103
+ signal: AbortSignal.timeout(1e4)
16104
+ }
16105
+ );
16106
+ if (!response.ok) {
16107
+ const message = await safeHttpError(response);
16108
+ return textResult(`Failed to record triage decision for ${params.triage_item_id}: ${response.status}${message}`);
16109
+ }
16110
+ const result = await response.json();
16111
+ const verdict = params.actionable ? "actionable" : "not actionable";
16112
+ return textResult(`Recorded triage decision for ${params.triage_item_id}: ${params.tier} (${verdict}).`, result);
16113
+ } catch (err) {
16114
+ return textResult(`Failed to record triage decision for ${params.triage_item_id}: ${err instanceof Error ? redactSecrets(err.message) : "Unknown error"}`);
16115
+ }
16116
+ }
16117
+ };
16118
+ });
16119
+ api.registerTool(() => {
16120
+ return {
16121
+ name: "cohort_relate",
16122
+ label: "cohort_relate",
16123
+ description: "Create or remove Cohort task relations by task number. This is THE way to decompose work into ordered blockers: create blocker tasks, then relate them with blocked_by or blocks so Cohort can sequence handoffs.",
16124
+ parameters: Type.Object({
16125
+ task_number: Type.Number({ description: "Primary task number (e.g. 214)." }),
16126
+ relation: Type.Union([
16127
+ Type.Literal("blocked_by"),
16128
+ Type.Literal("blocks"),
16129
+ Type.Literal("related"),
16130
+ Type.Literal("duplicate_of")
16131
+ ], { description: "Relation from task_number to other_task_number." }),
16132
+ other_task_number: Type.Number({ description: "Other task number to relate to the primary task." }),
16133
+ remove: Type.Optional(Type.Boolean({ description: "Set true to remove the matching relation instead of creating it." }))
16134
+ }),
16135
+ async execute(_toolCallId, params) {
16136
+ const rt = getToolRuntime();
16137
+ if (!rt.isReady) {
16138
+ return textResult("cohort_relate is not ready yet \u2014 the plugin is still starting up.");
16139
+ }
16140
+ if (params.task_number === params.other_task_number) {
16141
+ return textResult("Cannot relate a task to itself.");
16142
+ }
16143
+ try {
16144
+ if (!params.remove) {
16145
+ const response = await fetch(`${rt.apiUrl}/api/v1/tasks/${params.task_number}/relations`, {
16146
+ method: "POST",
16147
+ headers: {
16148
+ "Authorization": `Bearer ${rt.apiKey}`,
16149
+ "Content-Type": "application/json"
16150
+ },
16151
+ body: JSON.stringify({
16152
+ type: params.relation,
16153
+ taskNumber: params.other_task_number
16154
+ }),
16155
+ signal: AbortSignal.timeout(1e4)
16156
+ });
16157
+ if (!response.ok) {
16158
+ const message = await safeHttpError(response);
16159
+ return textResult(`Failed to relate task #${params.task_number}: ${response.status}${message}`);
16160
+ }
16161
+ const relation2 = await response.json();
16162
+ return textResult(`Related task #${params.task_number} ${params.relation} #${params.other_task_number}.`, relation2);
16163
+ }
16164
+ const taskResponse = await fetch(`${rt.apiUrl}/api/v1/tasks/${params.task_number}`, {
16165
+ headers: { "Authorization": `Bearer ${rt.apiKey}` },
16166
+ signal: AbortSignal.timeout(1e4)
16167
+ });
16168
+ if (!taskResponse.ok) {
16169
+ const message = await safeHttpError(taskResponse);
16170
+ return textResult(`Failed to inspect task #${params.task_number}: ${taskResponse.status}${message}`);
16171
+ }
16172
+ const task = await taskResponse.json();
16173
+ const relations = Array.isArray(task.relations) ? task.relations.filter(isTaskRelationSummary) : [];
16174
+ const relation = relations.find(
16175
+ (candidate) => relationMatchesVerb(candidate, params.relation, params.other_task_number)
16176
+ );
16177
+ if (!relation) {
16178
+ return textResult(`No ${params.relation} relation found between task #${params.task_number} and #${params.other_task_number}.`);
16179
+ }
16180
+ const deleteResponse = await fetch(
16181
+ `${rt.apiUrl}/api/v1/tasks/${params.task_number}/relations/${encodeURIComponent(relation.id)}`,
16182
+ {
16183
+ method: "DELETE",
16184
+ headers: { "Authorization": `Bearer ${rt.apiKey}` },
16185
+ signal: AbortSignal.timeout(1e4)
16186
+ }
16187
+ );
16188
+ if (!deleteResponse.ok) {
16189
+ const message = await safeHttpError(deleteResponse);
16190
+ return textResult(`Failed to remove relation from task #${params.task_number}: ${deleteResponse.status}${message}`);
16191
+ }
16192
+ return textResult(`Removed ${params.relation} relation between task #${params.task_number} and #${params.other_task_number}.`);
16193
+ } catch (err) {
16194
+ return textResult(`Failed to relate task #${params.task_number}: ${err instanceof Error ? redactSecrets(err.message) : "Unknown error"}`);
15965
16195
  }
15966
16196
  }
15967
16197
  };
@@ -24,6 +24,8 @@
24
24
  "cohort_task",
25
25
  "cohort_goal",
26
26
  "cohort_transition",
27
+ "cohort_triage",
28
+ "cohort_relate",
27
29
  "cohort_assign"
28
30
  ]
29
31
  },
@@ -82,5 +84,5 @@
82
84
  }
83
85
  }
84
86
  },
85
- "version": "0.34.1"
87
+ "version": "0.34.3"
86
88
  }
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cfio/cohort-sync",
3
- "version": "0.34.1",
3
+ "version": "0.34.3",
4
4
  "description": "OpenClaw plugin — syncs agent telemetry, sessions, and activity to the Cohort dashboard",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -22,6 +22,8 @@
22
22
  "cohort_task",
23
23
  "cohort_goal",
24
24
  "cohort_transition",
25
+ "cohort_triage",
26
+ "cohort_relate",
25
27
  "cohort_assign"
26
28
  ]
27
29
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cfio/cohort-sync",
3
- "version": "0.34.1",
3
+ "version": "0.34.3",
4
4
  "description": "OpenClaw plugin — syncs agent telemetry, sessions, and activity to the Cohort dashboard",
5
5
  "license": "MIT",
6
6
  "homepage": "https://docs.cohort.bot/gateway",
@@ -36,7 +36,7 @@
36
36
  "access": "public"
37
37
  },
38
38
  "devDependencies": {
39
- "esbuild": "^0.25.11",
39
+ "esbuild": "^0.28.1",
40
40
  "vitest": "^3.2.6"
41
41
  },
42
42
  "peerDependencies": {