cclawd 2026.3.37 → 2026.3.38

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/.buildstamp CHANGED
@@ -1 +1 @@
1
- {"builtAt":1779772831735,"head":"4d285bed5bc28747fa2fac8c0483add371947d16"}
1
+ {"builtAt":1779847731292,"head":"130310d3504f3dbf6c85523f813ceef7e406e463"}
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2026.3.37",
3
- "commit": "4d285bed5bc28747fa2fac8c0483add371947d16",
4
- "builtAt": "2026-05-26T05:20:52.974Z"
2
+ "version": "2026.3.38",
3
+ "commit": "130310d3504f3dbf6c85523f813ceef7e406e463",
4
+ "builtAt": "2026-05-27T02:09:12.325Z"
5
5
  }
@@ -561,17 +561,27 @@ var BehaviorDetector = class {
561
561
  this.pendingQuotaMessage = null;
562
562
  return msg;
563
563
  }
564
+ /**
565
+ * Update current-turn user intent from a raw user message (message_received only).
566
+ * Do not call with agent prompts — they may include channel envelopes/system injection.
567
+ */
564
568
  setUserIntent(sessionKey, message) {
565
569
  const state = this.getOrCreate(sessionKey);
566
- const hasBypassMarker = message.includes(REAL_PERSON_AUTH_BYPASS_MARKER);
567
- const effectiveMessage = message.replace(REAL_PERSON_AUTH_BYPASS_MARKER, "").trim() || message;
568
- if (hasBypassMarker) {
570
+ if (message.includes(REAL_PERSON_AUTH_BYPASS_MARKER)) {
569
571
  state.realPersonAuthBypassOncePending = true;
570
572
  this.log.info("Detected real-person-auth bypass marker; next tool call will be allowed once.");
571
573
  }
572
- if (!state.userIntent) state.userIntent = effectiveMessage.slice(0, 500);
574
+ const effectiveMessage = this.stripBypassMarker(message);
575
+ state.userIntent = effectiveMessage.slice(0, 500);
573
576
  state.recentUserMessages = [...state.recentUserMessages.slice(-4), effectiveMessage.slice(0, 200)];
574
577
  }
578
+ /** Detect real-person-auth one-shot bypass marker in the agent prompt (before_agent_start). */
579
+ handleAuthBypassMarker(sessionKey, message) {
580
+ if (!message.includes(REAL_PERSON_AUTH_BYPASS_MARKER)) return;
581
+ const state = this.getOrCreate(sessionKey);
582
+ state.realPersonAuthBypassOncePending = true;
583
+ this.log.info("Detected real-person-auth bypass marker; next tool call will be allowed once.");
584
+ }
575
585
  clearSession(sessionKey) {
576
586
  this.sessions.delete(sessionKey);
577
587
  }
@@ -796,6 +806,9 @@ var BehaviorDetector = class {
796
806
  clearTimeout(timer);
797
807
  }
798
808
  }
809
+ stripBypassMarker(message) {
810
+ return message.replace(REAL_PERSON_AUTH_BYPASS_MARKER, "").trim() || message;
811
+ }
799
812
  detectLocalHardBlock(userIntent, toolName, params) {
800
813
  const paramsText = JSON.stringify(params ?? {}).toLowerCase();
801
814
  const context = [
@@ -1875,7 +1888,7 @@ const openClawGuardPlugin = {
1875
1888
  const text = typeof event.prompt === "string" ? event.prompt : JSON.stringify(event.prompt ?? "");
1876
1889
  const runId = `run-${randomBytes(8).toString("hex")}`;
1877
1890
  globalEventReporter?.setRunId(sessionKey, runId);
1878
- if (globalBehaviorDetector && event.prompt) globalBehaviorDetector.setUserIntent(sessionKey, text);
1891
+ if (globalBehaviorDetector && event.prompt) globalBehaviorDetector.handleAuthBypassMarker(sessionKey, text);
1879
1892
  globalEventReporter?.report(sessionKey, "before_agent_start", {
1880
1893
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1881
1894
  prompt: text,
@@ -3,9 +3,9 @@
3
3
  "requires": true,
4
4
  "packages": {
5
5
  "node_modules/@larksuiteoapi/node-sdk": {
6
- "version": "1.65.0",
7
- "resolved": "https://registry.npmjs.org/@larksuiteoapi/node-sdk/-/node-sdk-1.65.0.tgz",
8
- "integrity": "sha512-SkMeiFvi4mMVGrmBBh50vWPOgAvfbcpdcAW+iryheFFHUmji49aDch/YtxsKGFtzFlL/rseQXFzNFL8+LdQQ5Q==",
6
+ "version": "1.66.0",
7
+ "resolved": "https://registry.npmjs.org/@larksuiteoapi/node-sdk/-/node-sdk-1.66.0.tgz",
8
+ "integrity": "sha512-ueKbbdvmVGVie3KvKbvHZqvDC/gg3M0rRDeyQanQWK+i2bQgiiTpIfpqVWvxuTgprV31yqV7HPMjN6KegWSCfA==",
9
9
  "license": "MIT",
10
10
  "dependencies": {
11
11
  "axios": "~1.13.3",
@@ -691,6 +691,10 @@ try {
691
691
  | signal | `AbortSignal` to cancel the polling | AbortSignal | No | - |
692
692
  | onQRCodeReady | Callback when the verification URL is ready. Receives `{ url, expireIn }`. You can render the URL as a QR code for users to scan, or display it as a link | function | Yes | - |
693
693
  | onStatusChange | Callback on polling status changes. Receives `{ status, interval? }`. Status values: `polling`, `slow_down`, `domain_switched` | function | No | - |
694
+ | appPreset | Pre-fill values for the app-creation page. All fields are optional; users can still edit them on the page | AppPreset | No | - |
695
+ | appPreset.avatar | App avatar URL(s). 1-6 URLs supported; the first one is selected by default. Allowed formats: png / jpg / jpeg / webp / gif (gif is sampled to a single frame, not animated) | string \| string[] | No | - |
696
+ | appPreset.name | App name. Supports the `{user}` placeholder (replaced with the scanning user's name) | string | No | - |
697
+ | appPreset.desc | App description. Supports the `{user}` placeholder | string | No | - |
694
698
 
695
699
  #### Return value
696
700
 
@@ -753,6 +753,10 @@ try {
753
753
  | signal | 用于取消轮询的 `AbortSignal` | AbortSignal | 否 | - |
754
754
  | onQRCodeReady | 验证链接就绪时的回调,参数为 `{ url, expireIn }`。可将 URL 渲染为二维码供用户扫码,或直接作为链接展示 | function | 是 | - |
755
755
  | onStatusChange | 轮询状态变化时的回调,参数为 `{ status, interval? }`。status 取值:`polling`、`slow_down`、`domain_switched` | function | 否 | - |
756
+ | appPreset | 预设应用信息(头像、名称、描述)。所有字段都是可选的,用户扫码后仍可在页面手动修改 | AppPreset | 否 | - |
757
+ | appPreset.avatar | 应用头像 URL,支持 1-6 个;传多个时默认选中第一个。支持 png / jpg / jpeg / webp / gif(gif 自动取一帧,不保留动图) | string \| string[] | 否 | - |
758
+ | appPreset.name | 应用名称,支持 `{user}` 占位符(替换为扫码用户名称) | string | 否 | - |
759
+ | appPreset.desc | 应用描述,支持 `{user}` 占位符 | string | 否 | - |
756
760
 
757
761
  #### 返回值
758
762
 
@@ -89750,6 +89750,35 @@ const SDK_NAME = 'node-sdk';
89750
89750
  const DEFAULT_FEISHU_DOMAIN = 'accounts.feishu.cn';
89751
89751
  const DEFAULT_LARK_DOMAIN = 'accounts.larksuite.com';
89752
89752
  const ENDPOINT = '/oauth/v1/app/registration';
89753
+ const AVATAR_MAX_COUNT = 6;
89754
+ /**
89755
+ * Append `avatar` / `name` / `desc` query params to the QR code URL.
89756
+ * `URLSearchParams` handles URL encoding automatically.
89757
+ */
89758
+ function applyAppPreset(qrCodeUrl, preset) {
89759
+ const { avatar, name, desc } = preset;
89760
+ if (avatar !== undefined) {
89761
+ const avatars = Array.isArray(avatar) ? avatar : [avatar];
89762
+ if (avatars.length === 0) {
89763
+ throw new Error('appPreset.avatar must contain at least 1 URL');
89764
+ }
89765
+ if (avatars.length > AVATAR_MAX_COUNT) {
89766
+ throw new Error(`appPreset.avatar supports at most ${AVATAR_MAX_COUNT} URLs, got ${avatars.length}`);
89767
+ }
89768
+ avatars.forEach((url, idx) => {
89769
+ if (typeof url !== 'string' || url === '') {
89770
+ throw new Error(`appPreset.avatar[${idx}] must be a non-empty string`);
89771
+ }
89772
+ qrCodeUrl.searchParams.append('avatar', url);
89773
+ });
89774
+ }
89775
+ if (name !== undefined) {
89776
+ qrCodeUrl.searchParams.set('name', name);
89777
+ }
89778
+ if (desc !== undefined) {
89779
+ qrCodeUrl.searchParams.set('desc', desc);
89780
+ }
89781
+ }
89753
89782
  function requestRegistration(baseUrl, params) {
89754
89783
  var _a;
89755
89784
  return __awaiter(this, void 0, void 0, function* () {
@@ -89867,13 +89896,16 @@ function startPolling(ctx) {
89867
89896
  function registerApp(options) {
89868
89897
  var _a, _b, _c, _d;
89869
89898
  return __awaiter(this, void 0, void 0, function* () {
89870
- const { domain, source, signal, onQRCodeReady, onStatusChange } = options;
89899
+ const { domain, source, signal, onQRCodeReady, onStatusChange, appPreset } = options;
89871
89900
  const baseUrl = `https://${domain !== null && domain !== void 0 ? domain : DEFAULT_FEISHU_DOMAIN}`;
89872
89901
  const beginRes = yield begin(baseUrl);
89873
89902
  const qrCodeUrl = new URL(beginRes.verification_uri_complete);
89874
89903
  qrCodeUrl.searchParams.set('from', 'sdk');
89875
89904
  qrCodeUrl.searchParams.set('source', source ? `${SDK_NAME}/${source}` : SDK_NAME);
89876
89905
  qrCodeUrl.searchParams.set('tp', 'sdk');
89906
+ if (appPreset) {
89907
+ applyAppPreset(qrCodeUrl, appPreset);
89908
+ }
89877
89909
  onQRCodeReady({
89878
89910
  url: qrCodeUrl.toString(),
89879
89911
  expireIn: (_a = beginRes.expires_in) !== null && _a !== void 0 ? _a : 600,
@@ -89768,6 +89768,35 @@ const SDK_NAME = 'node-sdk';
89768
89768
  const DEFAULT_FEISHU_DOMAIN = 'accounts.feishu.cn';
89769
89769
  const DEFAULT_LARK_DOMAIN = 'accounts.larksuite.com';
89770
89770
  const ENDPOINT = '/oauth/v1/app/registration';
89771
+ const AVATAR_MAX_COUNT = 6;
89772
+ /**
89773
+ * Append `avatar` / `name` / `desc` query params to the QR code URL.
89774
+ * `URLSearchParams` handles URL encoding automatically.
89775
+ */
89776
+ function applyAppPreset(qrCodeUrl, preset) {
89777
+ const { avatar, name, desc } = preset;
89778
+ if (avatar !== undefined) {
89779
+ const avatars = Array.isArray(avatar) ? avatar : [avatar];
89780
+ if (avatars.length === 0) {
89781
+ throw new Error('appPreset.avatar must contain at least 1 URL');
89782
+ }
89783
+ if (avatars.length > AVATAR_MAX_COUNT) {
89784
+ throw new Error(`appPreset.avatar supports at most ${AVATAR_MAX_COUNT} URLs, got ${avatars.length}`);
89785
+ }
89786
+ avatars.forEach((url, idx) => {
89787
+ if (typeof url !== 'string' || url === '') {
89788
+ throw new Error(`appPreset.avatar[${idx}] must be a non-empty string`);
89789
+ }
89790
+ qrCodeUrl.searchParams.append('avatar', url);
89791
+ });
89792
+ }
89793
+ if (name !== undefined) {
89794
+ qrCodeUrl.searchParams.set('name', name);
89795
+ }
89796
+ if (desc !== undefined) {
89797
+ qrCodeUrl.searchParams.set('desc', desc);
89798
+ }
89799
+ }
89771
89800
  function requestRegistration(baseUrl, params) {
89772
89801
  var _a;
89773
89802
  return __awaiter(this, void 0, void 0, function* () {
@@ -89885,13 +89914,16 @@ function startPolling(ctx) {
89885
89914
  function registerApp(options) {
89886
89915
  var _a, _b, _c, _d;
89887
89916
  return __awaiter(this, void 0, void 0, function* () {
89888
- const { domain, source, signal, onQRCodeReady, onStatusChange } = options;
89917
+ const { domain, source, signal, onQRCodeReady, onStatusChange, appPreset } = options;
89889
89918
  const baseUrl = `https://${domain !== null && domain !== void 0 ? domain : DEFAULT_FEISHU_DOMAIN}`;
89890
89919
  const beginRes = yield begin(baseUrl);
89891
89920
  const qrCodeUrl = new URL(beginRes.verification_uri_complete);
89892
89921
  qrCodeUrl.searchParams.set('from', 'sdk');
89893
89922
  qrCodeUrl.searchParams.set('source', source ? `${SDK_NAME}/${source}` : SDK_NAME);
89894
89923
  qrCodeUrl.searchParams.set('tp', 'sdk');
89924
+ if (appPreset) {
89925
+ applyAppPreset(qrCodeUrl, appPreset);
89926
+ }
89895
89927
  onQRCodeReady({
89896
89928
  url: qrCodeUrl.toString(),
89897
89929
  expireIn: (_a = beginRes.expires_in) !== null && _a !== void 0 ? _a : 600,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@larksuiteoapi/node-sdk",
3
- "version": "1.65.0",
3
+ "version": "1.66.0",
4
4
  "description": "larksuite open sdk for nodejs",
5
5
  "keywords": [
6
6
  "feishu",
@@ -300741,6 +300741,23 @@ interface StatusChangeInfo {
300741
300741
  status: 'polling' | 'slow_down' | 'domain_switched';
300742
300742
  interval?: number;
300743
300743
  }
300744
+ /**
300745
+ * Pre-fill values shown on the app-creation page after the user scans the QR
300746
+ * code. All fields are optional and the user can still edit them on the page;
300747
+ * the final values are whatever the user submits.
300748
+ */
300749
+ interface AppPreset {
300750
+ /**
300751
+ * App avatar URL(s). Pass a single URL or 1-6 URLs. The first one is the
300752
+ * default selection. Each URL must point to a publicly reachable image
300753
+ * (png / jpg / jpeg / webp / gif).
300754
+ */
300755
+ avatar?: string | string[];
300756
+ /** App name. Supports `{user}` placeholder, replaced with the scanning user's name. */
300757
+ name?: string;
300758
+ /** App description. Supports `{user}` placeholder. */
300759
+ desc?: string;
300760
+ }
300744
300761
  interface RegisterAppOptions {
300745
300762
  domain?: string;
300746
300763
  larkDomain?: string;
@@ -300748,6 +300765,8 @@ interface RegisterAppOptions {
300748
300765
  signal?: AbortSignal;
300749
300766
  onQRCodeReady: (info: QRCodeInfo) => void;
300750
300767
  onStatusChange?: (info: StatusChangeInfo) => void;
300768
+ /** Pre-fill values for the app-creation page. See {@link AppPreset}. */
300769
+ appPreset?: AppPreset;
300751
300770
  }
300752
300771
  interface UserInfo {
300753
300772
  open_id?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cclawd",
3
- "version": "2026.3.37",
3
+ "version": "2026.3.38",
4
4
  "description": "Multi-channel AI gateway with extensible messaging integrations",
5
5
  "keywords": [],
6
6
  "homepage": "https://github.com/openclaw/openclaw#readme",