@openclaw/clickclack 2026.9.5 → 2026.9.7
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/assets/icon.png +0 -0
- package/dist/.setup/{channel-yIQ_PUDD.mjs → channel-Bcwtohk7.mjs} +326 -224
- package/dist/.setup/resolve-BHGLohni.mjs +336 -0
- package/dist/.setup/rolldown-runtime-B4FMCO8f.mjs +28 -0
- package/dist/.setup/{runtime-api-D9Bwyc44.mjs → runtime-api-BvP8DrPQ.mjs} +231 -164
- package/dist/.setup/{setup-claim-t5SbtvZy.mjs → setup-claim-Cx8knvXs.mjs} +1 -1
- package/dist/.setup/setup-plugin-api-BH_nw-AP.mjs +2 -0
- package/dist/.setup/{setup-plugin-api-BUwBPYpy.mjs → setup-plugin-api-C9QcBJuW.mjs} +1 -1
- package/dist/.setup/{setup-surface-BBl3rvVx.mjs → setup-surface-BW1Q06w5.mjs} +50 -503
- package/dist/.setup/setup-verify-Msgd70_M.mjs +111 -0
- package/dist/api.js +3 -2
- package/dist/channel-plugin-api.js +1 -1
- package/dist/doctor-contract-api.js +160 -3
- package/dist/index.js +1 -1
- package/dist/runtime-api.js +4 -3
- package/dist/setup-entry.js +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/node_modules/zod/README.md +2 -2
- package/node_modules/zod/compile.cjs +19 -0
- package/node_modules/zod/index.cjs +19 -0
- package/node_modules/zod/locales/index.cjs +19 -0
- package/node_modules/zod/mini/index.cjs +19 -0
- package/node_modules/zod/package.json +8 -7
- package/node_modules/zod/src/v3/helpers/errorUtil.ts +1 -1
- package/node_modules/zod/src/v4/classic/external.ts +2 -0
- package/node_modules/zod/src/v4/classic/from-json-schema.ts +248 -25
- package/node_modules/zod/src/v4/classic/schemas.ts +243 -168
- package/node_modules/zod/src/v4/classic/tests/assignability.test.ts +60 -9
- package/node_modules/zod/src/v4/classic/tests/bigint.test.ts +6 -0
- package/node_modules/zod/src/v4/classic/tests/continuability.test.ts +2 -2
- package/node_modules/zod/src/v4/classic/tests/cyclic-data.test.ts +265 -0
- package/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +112 -6
- package/node_modules/zod/src/v4/classic/tests/enum.test.ts +9 -0
- package/node_modules/zod/src/v4/classic/tests/error.test.ts +130 -1
- package/node_modules/zod/src/v4/classic/tests/from-json-schema.test.ts +157 -0
- package/node_modules/zod/src/v4/classic/tests/iban.test.ts +81 -0
- package/node_modules/zod/src/v4/classic/tests/instance-footprint.test.ts +40 -2
- package/node_modules/zod/src/v4/classic/tests/instanceof.test.ts +27 -7
- package/node_modules/zod/src/v4/classic/tests/issue-schema.test.ts +88 -56
- package/node_modules/zod/src/v4/classic/tests/number.test.ts +39 -0
- package/node_modules/zod/src/v4/classic/tests/object.test.ts +56 -0
- package/node_modules/zod/src/v4/classic/tests/optin-ladder.test.ts +3 -2
- package/node_modules/zod/src/v4/classic/tests/prefault.test.ts +70 -0
- package/node_modules/zod/src/v4/classic/tests/properties.test.ts +141 -0
- package/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +46 -1
- package/node_modules/zod/src/v4/classic/tests/standard-schema.test.ts +19 -0
- package/node_modules/zod/src/v4/classic/tests/string.test.ts +95 -1
- package/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +33 -1
- package/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +234 -38
- package/node_modules/zod/src/v4/classic/tests/validate.test.ts +569 -0
- package/node_modules/zod/src/v4/core/api.ts +44 -28
- package/node_modules/zod/src/v4/core/checks.ts +62 -102
- package/node_modules/zod/src/v4/core/compile.ts +218 -93
- package/node_modules/zod/src/v4/core/core.ts +1 -3
- package/node_modules/zod/src/v4/core/doc.ts +6 -2
- package/node_modules/zod/src/v4/core/errors.ts +3 -6
- package/node_modules/zod/src/v4/core/json-schema-generator.ts +2 -2
- package/node_modules/zod/src/v4/core/json-schema-processors.ts +185 -81
- package/node_modules/zod/src/v4/core/memoizer.ts +75 -28
- package/node_modules/zod/src/v4/core/parse.ts +37 -16
- package/node_modules/zod/src/v4/core/regexes.ts +14 -4
- package/node_modules/zod/src/v4/core/schemas.ts +296 -132
- package/node_modules/zod/src/v4/core/tests/cached.test.ts +54 -0
- package/node_modules/zod/src/v4/core/tests/compile-differential.test.ts +35 -0
- package/node_modules/zod/src/v4/core/tests/compile-generative.test.ts +445 -0
- package/node_modules/zod/src/v4/core/tests/compile.test.ts +399 -2
- package/node_modules/zod/src/v4/core/tests/email-regex.test.ts +140 -0
- package/node_modules/zod/src/v4/core/tests/locales/tg.test.ts +85 -0
- package/node_modules/zod/src/v4/core/tests/polyfill-collision.test.ts +46 -0
- package/node_modules/zod/src/v4/core/tests/url-no-canparse.test.ts +118 -16
- package/node_modules/zod/src/v4/core/to-json-schema.ts +9 -7
- package/node_modules/zod/src/v4/core/util.ts +218 -147
- package/node_modules/zod/src/v4/core/versions.ts +2 -2
- package/node_modules/zod/src/v4/locales/ar.ts +2 -0
- package/node_modules/zod/src/v4/locales/az.ts +2 -0
- package/node_modules/zod/src/v4/locales/be.ts +2 -0
- package/node_modules/zod/src/v4/locales/bg.ts +2 -0
- package/node_modules/zod/src/v4/locales/bn.ts +2 -0
- package/node_modules/zod/src/v4/locales/ca.ts +2 -0
- package/node_modules/zod/src/v4/locales/ckb.ts +2 -0
- package/node_modules/zod/src/v4/locales/cs.ts +2 -0
- package/node_modules/zod/src/v4/locales/da.ts +2 -0
- package/node_modules/zod/src/v4/locales/de.ts +2 -0
- package/node_modules/zod/src/v4/locales/el.ts +2 -0
- package/node_modules/zod/src/v4/locales/en.ts +2 -0
- package/node_modules/zod/src/v4/locales/eo.ts +2 -0
- package/node_modules/zod/src/v4/locales/es.ts +2 -0
- package/node_modules/zod/src/v4/locales/fa.ts +2 -0
- package/node_modules/zod/src/v4/locales/fi.ts +2 -0
- package/node_modules/zod/src/v4/locales/fr-CA.ts +2 -0
- package/node_modules/zod/src/v4/locales/fr.ts +2 -0
- package/node_modules/zod/src/v4/locales/gu.ts +2 -0
- package/node_modules/zod/src/v4/locales/he.ts +2 -0
- package/node_modules/zod/src/v4/locales/hi.ts +2 -0
- package/node_modules/zod/src/v4/locales/hr.ts +2 -0
- package/node_modules/zod/src/v4/locales/hu.ts +2 -0
- package/node_modules/zod/src/v4/locales/hy.ts +2 -0
- package/node_modules/zod/src/v4/locales/id.ts +2 -0
- package/node_modules/zod/src/v4/locales/index.ts +1 -0
- package/node_modules/zod/src/v4/locales/is.ts +2 -0
- package/node_modules/zod/src/v4/locales/it.ts +2 -0
- package/node_modules/zod/src/v4/locales/ja.ts +2 -0
- package/node_modules/zod/src/v4/locales/ka.ts +2 -0
- package/node_modules/zod/src/v4/locales/km.ts +2 -0
- package/node_modules/zod/src/v4/locales/kn.ts +2 -0
- package/node_modules/zod/src/v4/locales/ko.ts +2 -0
- package/node_modules/zod/src/v4/locales/lt.ts +2 -0
- package/node_modules/zod/src/v4/locales/mk.ts +2 -0
- package/node_modules/zod/src/v4/locales/ms.ts +2 -0
- package/node_modules/zod/src/v4/locales/ne.ts +2 -0
- package/node_modules/zod/src/v4/locales/nl.ts +2 -0
- package/node_modules/zod/src/v4/locales/nn.ts +2 -0
- package/node_modules/zod/src/v4/locales/no.ts +2 -0
- package/node_modules/zod/src/v4/locales/ota.ts +2 -0
- package/node_modules/zod/src/v4/locales/pl.ts +2 -0
- package/node_modules/zod/src/v4/locales/ps.ts +2 -0
- package/node_modules/zod/src/v4/locales/pt-BR.ts +2 -0
- package/node_modules/zod/src/v4/locales/pt.ts +2 -0
- package/node_modules/zod/src/v4/locales/ro.ts +2 -0
- package/node_modules/zod/src/v4/locales/ru.ts +2 -0
- package/node_modules/zod/src/v4/locales/sk.ts +2 -0
- package/node_modules/zod/src/v4/locales/sl.ts +2 -0
- package/node_modules/zod/src/v4/locales/sv.ts +2 -0
- package/node_modules/zod/src/v4/locales/ta.ts +2 -0
- package/node_modules/zod/src/v4/locales/tg.ts +135 -0
- package/node_modules/zod/src/v4/locales/th.ts +2 -0
- package/node_modules/zod/src/v4/locales/tk.ts +2 -0
- package/node_modules/zod/src/v4/locales/tr.ts +2 -0
- package/node_modules/zod/src/v4/locales/uk.ts +2 -0
- package/node_modules/zod/src/v4/locales/ur.ts +2 -0
- package/node_modules/zod/src/v4/locales/uz.ts +2 -0
- package/node_modules/zod/src/v4/locales/vi.ts +2 -0
- package/node_modules/zod/src/v4/locales/yo.ts +2 -0
- package/node_modules/zod/src/v4/locales/zh-CN.ts +2 -0
- package/node_modules/zod/src/v4/locales/zh-TW.ts +2 -0
- package/node_modules/zod/src/v4/mini/external.ts +2 -0
- package/node_modules/zod/src/v4/mini/schemas.ts +32 -7
- package/node_modules/zod/src/v4/mini/tests/checks.test.ts +1 -1
- package/node_modules/zod/src/v4/mini/tests/computed.test.ts +11 -17
- package/node_modules/zod/src/v4/mini/tests/index.test.ts +86 -0
- package/node_modules/zod/src/v4/mini/tests/recursive-types.test.ts +16 -0
- package/node_modules/zod/src/v4/mini/tests/string.test.ts +23 -0
- package/node_modules/zod/v3/ZodError.cjs +19 -0
- package/node_modules/zod/v3/errors.cjs +19 -0
- package/node_modules/zod/v3/external.cjs +19 -0
- package/node_modules/zod/v3/helpers/enumUtil.cjs +19 -0
- package/node_modules/zod/v3/helpers/errorUtil.cjs +20 -1
- package/node_modules/zod/v3/helpers/errorUtil.js +1 -1
- package/node_modules/zod/v3/helpers/parseUtil.cjs +19 -0
- package/node_modules/zod/v3/helpers/partialUtil.cjs +19 -0
- package/node_modules/zod/v3/helpers/typeAliases.cjs +19 -0
- package/node_modules/zod/v3/helpers/util.cjs +19 -0
- package/node_modules/zod/v3/index.cjs +19 -0
- package/node_modules/zod/v3/standard-schema.cjs +19 -0
- package/node_modules/zod/v3/types.cjs +19 -0
- package/node_modules/zod/v4/classic/checks.cjs +19 -0
- package/node_modules/zod/v4/classic/coerce.cjs +19 -0
- package/node_modules/zod/v4/classic/compat.cjs +19 -0
- package/node_modules/zod/v4/classic/deep-partial.cjs +19 -0
- package/node_modules/zod/v4/classic/errors.cjs +19 -0
- package/node_modules/zod/v4/classic/external.cjs +22 -1
- package/node_modules/zod/v4/classic/external.d.cts +1 -1
- package/node_modules/zod/v4/classic/external.d.ts +1 -1
- package/node_modules/zod/v4/classic/external.js +1 -1
- package/node_modules/zod/v4/classic/from-json-schema.cjs +264 -24
- package/node_modules/zod/v4/classic/from-json-schema.js +245 -24
- package/node_modules/zod/v4/classic/in-out.cjs +19 -0
- package/node_modules/zod/v4/classic/index.cjs +19 -0
- package/node_modules/zod/v4/classic/iso.cjs +19 -0
- package/node_modules/zod/v4/classic/parse.cjs +19 -0
- package/node_modules/zod/v4/classic/schemas.cjs +100 -35
- package/node_modules/zod/v4/classic/schemas.d.cts +15 -1
- package/node_modules/zod/v4/classic/schemas.d.ts +15 -1
- package/node_modules/zod/v4/classic/schemas.js +77 -33
- package/node_modules/zod/v4/core/api.cjs +45 -22
- package/node_modules/zod/v4/core/api.d.cts +12 -6
- package/node_modules/zod/v4/core/api.d.ts +12 -6
- package/node_modules/zod/v4/core/api.js +25 -22
- package/node_modules/zod/v4/core/checks.cjs +51 -97
- package/node_modules/zod/v4/core/checks.d.cts +17 -1
- package/node_modules/zod/v4/core/checks.d.ts +17 -1
- package/node_modules/zod/v4/core/checks.js +31 -96
- package/node_modules/zod/v4/core/compile.cjs +173 -78
- package/node_modules/zod/v4/core/compile.d.cts +18 -4
- package/node_modules/zod/v4/core/compile.d.ts +18 -4
- package/node_modules/zod/v4/core/compile.js +154 -79
- package/node_modules/zod/v4/core/core.cjs +20 -1
- package/node_modules/zod/v4/core/core.js +1 -1
- package/node_modules/zod/v4/core/doc.cjs +26 -2
- package/node_modules/zod/v4/core/doc.js +7 -2
- package/node_modules/zod/v4/core/errors.cjs +21 -5
- package/node_modules/zod/v4/core/errors.js +2 -5
- package/node_modules/zod/v4/core/index.cjs +19 -0
- package/node_modules/zod/v4/core/json-schema-generator.cjs +20 -1
- package/node_modules/zod/v4/core/json-schema-generator.js +2 -2
- package/node_modules/zod/v4/core/json-schema-processors.cjs +188 -72
- package/node_modules/zod/v4/core/json-schema-processors.d.cts +16 -0
- package/node_modules/zod/v4/core/json-schema-processors.d.ts +16 -0
- package/node_modules/zod/v4/core/json-schema-processors.js +170 -74
- package/node_modules/zod/v4/core/json-schema.cjs +19 -0
- package/node_modules/zod/v4/core/memoizer.cjs +111 -23
- package/node_modules/zod/v4/core/memoizer.js +69 -23
- package/node_modules/zod/v4/core/parse.cjs +56 -16
- package/node_modules/zod/v4/core/parse.js +37 -16
- package/node_modules/zod/v4/core/regexes.cjs +31 -6
- package/node_modules/zod/v4/core/regexes.d.cts +3 -0
- package/node_modules/zod/v4/core/regexes.d.ts +3 -0
- package/node_modules/zod/v4/core/regexes.js +10 -4
- package/node_modules/zod/v4/core/registries.cjs +19 -0
- package/node_modules/zod/v4/core/schemas.cjs +302 -114
- package/node_modules/zod/v4/core/schemas.d.cts +28 -8
- package/node_modules/zod/v4/core/schemas.d.ts +28 -8
- package/node_modules/zod/v4/core/schemas.js +279 -113
- package/node_modules/zod/v4/core/standard-schema.cjs +19 -0
- package/node_modules/zod/v4/core/to-json-schema.cjs +28 -7
- package/node_modules/zod/v4/core/to-json-schema.d.cts +4 -3
- package/node_modules/zod/v4/core/to-json-schema.d.ts +4 -3
- package/node_modules/zod/v4/core/to-json-schema.js +7 -6
- package/node_modules/zod/v4/core/util.cjs +177 -143
- package/node_modules/zod/v4/core/util.d.cts +25 -4
- package/node_modules/zod/v4/core/util.d.ts +25 -4
- package/node_modules/zod/v4/core/util.js +156 -143
- package/node_modules/zod/v4/core/versions.cjs +21 -2
- package/node_modules/zod/v4/core/versions.d.cts +1 -1
- package/node_modules/zod/v4/core/versions.d.ts +1 -1
- package/node_modules/zod/v4/core/versions.js +2 -2
- package/node_modules/zod/v4/core/visit.cjs +19 -0
- package/node_modules/zod/v4/index.cjs +19 -0
- package/node_modules/zod/v4/locales/ar.cjs +2 -0
- package/node_modules/zod/v4/locales/ar.js +2 -0
- package/node_modules/zod/v4/locales/az.cjs +2 -0
- package/node_modules/zod/v4/locales/az.js +2 -0
- package/node_modules/zod/v4/locales/be.cjs +2 -0
- package/node_modules/zod/v4/locales/be.js +2 -0
- package/node_modules/zod/v4/locales/bg.cjs +2 -0
- package/node_modules/zod/v4/locales/bg.js +2 -0
- package/node_modules/zod/v4/locales/bn.cjs +2 -0
- package/node_modules/zod/v4/locales/bn.js +2 -0
- package/node_modules/zod/v4/locales/ca.cjs +2 -0
- package/node_modules/zod/v4/locales/ca.js +2 -0
- package/node_modules/zod/v4/locales/ckb.cjs +2 -0
- package/node_modules/zod/v4/locales/ckb.js +2 -0
- package/node_modules/zod/v4/locales/cs.cjs +2 -0
- package/node_modules/zod/v4/locales/cs.js +2 -0
- package/node_modules/zod/v4/locales/da.cjs +2 -0
- package/node_modules/zod/v4/locales/da.js +2 -0
- package/node_modules/zod/v4/locales/de.cjs +2 -0
- package/node_modules/zod/v4/locales/de.js +2 -0
- package/node_modules/zod/v4/locales/el.cjs +2 -0
- package/node_modules/zod/v4/locales/el.js +2 -0
- package/node_modules/zod/v4/locales/en.cjs +2 -0
- package/node_modules/zod/v4/locales/en.js +2 -0
- package/node_modules/zod/v4/locales/eo.cjs +2 -0
- package/node_modules/zod/v4/locales/eo.js +2 -0
- package/node_modules/zod/v4/locales/es.cjs +2 -0
- package/node_modules/zod/v4/locales/es.js +2 -0
- package/node_modules/zod/v4/locales/fa.cjs +2 -0
- package/node_modules/zod/v4/locales/fa.js +2 -0
- package/node_modules/zod/v4/locales/fi.cjs +2 -0
- package/node_modules/zod/v4/locales/fi.js +2 -0
- package/node_modules/zod/v4/locales/fr-CA.cjs +2 -0
- package/node_modules/zod/v4/locales/fr-CA.js +2 -0
- package/node_modules/zod/v4/locales/fr.cjs +2 -0
- package/node_modules/zod/v4/locales/fr.js +2 -0
- package/node_modules/zod/v4/locales/gu.cjs +2 -0
- package/node_modules/zod/v4/locales/gu.js +2 -0
- package/node_modules/zod/v4/locales/he.cjs +2 -0
- package/node_modules/zod/v4/locales/he.js +2 -0
- package/node_modules/zod/v4/locales/hi.cjs +2 -0
- package/node_modules/zod/v4/locales/hi.js +2 -0
- package/node_modules/zod/v4/locales/hr.cjs +2 -0
- package/node_modules/zod/v4/locales/hr.js +2 -0
- package/node_modules/zod/v4/locales/hu.cjs +2 -0
- package/node_modules/zod/v4/locales/hu.js +2 -0
- package/node_modules/zod/v4/locales/hy.cjs +2 -0
- package/node_modules/zod/v4/locales/hy.js +2 -0
- package/node_modules/zod/v4/locales/id.cjs +2 -0
- package/node_modules/zod/v4/locales/id.js +2 -0
- package/node_modules/zod/v4/locales/index.cjs +22 -1
- package/node_modules/zod/v4/locales/index.d.cts +1 -0
- package/node_modules/zod/v4/locales/index.d.ts +1 -0
- package/node_modules/zod/v4/locales/index.js +1 -0
- package/node_modules/zod/v4/locales/is.cjs +2 -0
- package/node_modules/zod/v4/locales/is.js +2 -0
- package/node_modules/zod/v4/locales/it.cjs +2 -0
- package/node_modules/zod/v4/locales/it.js +2 -0
- package/node_modules/zod/v4/locales/ja.cjs +2 -0
- package/node_modules/zod/v4/locales/ja.js +2 -0
- package/node_modules/zod/v4/locales/ka.cjs +2 -0
- package/node_modules/zod/v4/locales/ka.js +2 -0
- package/node_modules/zod/v4/locales/km.cjs +2 -0
- package/node_modules/zod/v4/locales/km.js +2 -0
- package/node_modules/zod/v4/locales/kn.cjs +2 -0
- package/node_modules/zod/v4/locales/kn.js +2 -0
- package/node_modules/zod/v4/locales/ko.cjs +2 -0
- package/node_modules/zod/v4/locales/ko.js +2 -0
- package/node_modules/zod/v4/locales/lt.cjs +2 -0
- package/node_modules/zod/v4/locales/lt.js +2 -0
- package/node_modules/zod/v4/locales/mk.cjs +2 -0
- package/node_modules/zod/v4/locales/mk.js +2 -0
- package/node_modules/zod/v4/locales/ms.cjs +2 -0
- package/node_modules/zod/v4/locales/ms.js +2 -0
- package/node_modules/zod/v4/locales/ne.cjs +2 -0
- package/node_modules/zod/v4/locales/ne.js +2 -0
- package/node_modules/zod/v4/locales/nl.cjs +2 -0
- package/node_modules/zod/v4/locales/nl.js +2 -0
- package/node_modules/zod/v4/locales/nn.cjs +2 -0
- package/node_modules/zod/v4/locales/nn.js +2 -0
- package/node_modules/zod/v4/locales/no.cjs +2 -0
- package/node_modules/zod/v4/locales/no.js +2 -0
- package/node_modules/zod/v4/locales/ota.cjs +2 -0
- package/node_modules/zod/v4/locales/ota.js +2 -0
- package/node_modules/zod/v4/locales/pl.cjs +2 -0
- package/node_modules/zod/v4/locales/pl.js +2 -0
- package/node_modules/zod/v4/locales/ps.cjs +2 -0
- package/node_modules/zod/v4/locales/ps.js +2 -0
- package/node_modules/zod/v4/locales/pt-BR.cjs +2 -0
- package/node_modules/zod/v4/locales/pt-BR.js +2 -0
- package/node_modules/zod/v4/locales/pt.cjs +2 -0
- package/node_modules/zod/v4/locales/pt.js +2 -0
- package/node_modules/zod/v4/locales/ro.cjs +2 -0
- package/node_modules/zod/v4/locales/ro.js +2 -0
- package/node_modules/zod/v4/locales/ru.cjs +2 -0
- package/node_modules/zod/v4/locales/ru.js +2 -0
- package/node_modules/zod/v4/locales/sk.cjs +2 -0
- package/node_modules/zod/v4/locales/sk.js +2 -0
- package/node_modules/zod/v4/locales/sl.cjs +2 -0
- package/node_modules/zod/v4/locales/sl.js +2 -0
- package/node_modules/zod/v4/locales/sv.cjs +2 -0
- package/node_modules/zod/v4/locales/sv.js +2 -0
- package/node_modules/zod/v4/locales/ta.cjs +2 -0
- package/node_modules/zod/v4/locales/ta.js +2 -0
- package/node_modules/zod/v4/locales/tg.cjs +144 -0
- package/node_modules/zod/v4/locales/tg.d.cts +5 -0
- package/node_modules/zod/v4/locales/tg.d.ts +4 -0
- package/node_modules/zod/v4/locales/tg.js +117 -0
- package/node_modules/zod/v4/locales/th.cjs +2 -0
- package/node_modules/zod/v4/locales/th.js +2 -0
- package/node_modules/zod/v4/locales/tk.cjs +2 -0
- package/node_modules/zod/v4/locales/tk.js +2 -0
- package/node_modules/zod/v4/locales/tr.cjs +2 -0
- package/node_modules/zod/v4/locales/tr.js +2 -0
- package/node_modules/zod/v4/locales/uk.cjs +2 -0
- package/node_modules/zod/v4/locales/uk.js +2 -0
- package/node_modules/zod/v4/locales/ur.cjs +2 -0
- package/node_modules/zod/v4/locales/ur.js +2 -0
- package/node_modules/zod/v4/locales/uz.cjs +2 -0
- package/node_modules/zod/v4/locales/uz.js +2 -0
- package/node_modules/zod/v4/locales/vi.cjs +2 -0
- package/node_modules/zod/v4/locales/vi.js +2 -0
- package/node_modules/zod/v4/locales/yo.cjs +2 -0
- package/node_modules/zod/v4/locales/yo.js +2 -0
- package/node_modules/zod/v4/locales/zh-CN.cjs +2 -0
- package/node_modules/zod/v4/locales/zh-CN.js +2 -0
- package/node_modules/zod/v4/locales/zh-TW.cjs +2 -0
- package/node_modules/zod/v4/locales/zh-TW.js +2 -0
- package/node_modules/zod/v4/mini/checks.cjs +19 -0
- package/node_modules/zod/v4/mini/coerce.cjs +19 -0
- package/node_modules/zod/v4/mini/deep-partial.cjs +19 -0
- package/node_modules/zod/v4/mini/external.cjs +22 -1
- package/node_modules/zod/v4/mini/external.d.cts +1 -1
- package/node_modules/zod/v4/mini/external.d.ts +1 -1
- package/node_modules/zod/v4/mini/external.js +1 -1
- package/node_modules/zod/v4/mini/in-out.cjs +19 -0
- package/node_modules/zod/v4/mini/index.cjs +19 -0
- package/node_modules/zod/v4/mini/iso.cjs +19 -0
- package/node_modules/zod/v4/mini/parse.cjs +19 -0
- package/node_modules/zod/v4/mini/schemas.cjs +44 -8
- package/node_modules/zod/v4/mini/schemas.d.cts +6 -1
- package/node_modules/zod/v4/mini/schemas.d.ts +6 -1
- package/node_modules/zod/v4/mini/schemas.js +21 -6
- package/node_modules/zod/v4-mini/index.cjs +19 -0
- package/openclaw.plugin.json +31 -1
- package/package.json +5 -5
- package/dist/.setup/setup-plugin-api-B19mjQvl.mjs +0 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { C as slugifyDiscussionLabel, D as listPendingDiscussionOpens, E as clearPendingDiscussionOpen, O as recordPendingDiscussionOpen, S as resolveDiscussionLabel, T as clearDiscussionBindingGeneration, _ as getClickClackDiscussionBindingStore, b as fallbackDiscussionLabel, c as markClickClackDiscussionChannelIdentityRevoked, d as discussionInfoForBinding, f as normalizedServerBaseUrl, g as bindingMatchesActiveSessionIncarnation, h as attachBindingToCurrentActiveSession, k as reserveDiscussionBindingGeneration, l as markClickClackDiscussionChannelRevoked, o as clearClickClackDiscussionChannelRevoked, p as resolveDiscussionBindingAccount, s as isClickClackDiscussionChannelRevoked, u as discussionAccounts, v as discussionCredentialFingerprint, w as truncateDiscussionDisplayTitle, x as isDiscussionSessionKey, y as discussionExternalRef } from "./channel-
|
|
1
|
+
import { h as resolveClickClackAccount, p as listClickClackAccountIds } from "./setup-surface-BW1Q06w5.mjs";
|
|
2
|
+
import { C as slugifyDiscussionLabel, D as listPendingDiscussionOpens, E as clearPendingDiscussionOpen, O as recordPendingDiscussionOpen, S as resolveDiscussionLabel, T as clearDiscussionBindingGeneration, _ as getClickClackDiscussionBindingStore, b as fallbackDiscussionLabel, c as markClickClackDiscussionChannelIdentityRevoked, d as discussionInfoForBinding, f as normalizedServerBaseUrl, g as bindingMatchesActiveSessionIncarnation, h as attachBindingToCurrentActiveSession, k as reserveDiscussionBindingGeneration, l as markClickClackDiscussionChannelRevoked, o as clearClickClackDiscussionChannelRevoked, p as resolveDiscussionBindingAccount, s as isClickClackDiscussionChannelRevoked, u as discussionAccounts, v as discussionCredentialFingerprint, w as truncateDiscussionDisplayTitle, x as isDiscussionSessionKey, y as discussionExternalRef } from "./channel-Bcwtohk7.mjs";
|
|
3
|
+
import { a as isClickClackChannelNameConflict, i as createClickClackClient, r as ClickClackHttpError } from "./resolve-BHGLohni.mjs";
|
|
3
4
|
import "../api.js";
|
|
4
5
|
import { randomUUID } from "node:crypto";
|
|
5
6
|
import { buildControlUiSessionPath, registerSessionDiscussionProvider } from "openclaw/plugin-sdk/session-discussion";
|
|
@@ -253,10 +254,10 @@ async function openClickClackDiscussionBinding(params) {
|
|
|
253
254
|
if (!workspace.route_id) throw new Error("ClickClack discussions workspace is missing its route id");
|
|
254
255
|
const serverBaseUrl = normalizedServerBaseUrl(account);
|
|
255
256
|
const credentialFingerprint = discussionCredentialFingerprint(account.token);
|
|
256
|
-
const unresolved = listPendingDiscussionOpens(runtime).find((pending) => pending.sessionKey === sessionKey);
|
|
257
|
+
const unresolved = (await listPendingDiscussionOpens(runtime)).find((pending) => pending.sessionKey === sessionKey);
|
|
257
258
|
if (unresolved && (unresolved.accountId !== account.accountId || unresolved.credentialFingerprint !== credentialFingerprint || unresolved.serverBaseUrl !== serverBaseUrl || unresolved.workspaceId !== workspace.id)) {
|
|
258
259
|
await params.reconcilePendingOpen(unresolved);
|
|
259
|
-
if (listPendingDiscussionOpens(runtime).some((pending) => pending.sessionKey === sessionKey)) throw new Error("A previous ClickClack discussion open is still unresolved; restore its credential and retry");
|
|
260
|
+
if ((await listPendingDiscussionOpens(runtime)).some((pending) => pending.sessionKey === sessionKey)) throw new Error("A previous ClickClack discussion open is still unresolved; restore its credential and retry");
|
|
260
261
|
}
|
|
261
262
|
const config = runtime.config.current();
|
|
262
263
|
const agentId = resolveSessionAgentIdStrict({
|
|
@@ -268,12 +269,21 @@ async function openClickClackDiscussionBinding(params) {
|
|
|
268
269
|
const displayTitle = label === fallback ? "" : truncateDiscussionDisplayTitle(label);
|
|
269
270
|
const section = entry.category?.trim() || account.discussions.section;
|
|
270
271
|
const externalUrl = controlSessionUrl(account.discussions.controlUrlBase, sessionKey, account.agentId ?? agentId, config.session?.mainKey, label);
|
|
272
|
+
const assertCurrentAuthority = () => {
|
|
273
|
+
const currentAccounts = discussionAccounts(runtime.config.current());
|
|
274
|
+
const currentAccount = currentAccounts.length === 1 ? currentAccounts[0] : void 0;
|
|
275
|
+
const currentEntry = runtime.agent.session.getSessionEntry({
|
|
276
|
+
sessionKey,
|
|
277
|
+
readConsistency: "latest"
|
|
278
|
+
});
|
|
279
|
+
if (!currentAccount || currentAccount.accountId !== account.accountId || normalizedServerBaseUrl(currentAccount) !== serverBaseUrl || currentAccount.apiEndpoint !== account.apiEndpoint || discussionCredentialFingerprint(currentAccount.token) !== credentialFingerprint || currentAccount.discussions.workspace !== account.discussions.workspace || !currentEntry?.sessionId || currentEntry.archivedAt !== void 0) throw new Error("ClickClack discussion authority changed while opening the channel");
|
|
280
|
+
};
|
|
271
281
|
return await params.withChannelMutationLock(async () => {
|
|
272
282
|
params.ensureBindingCapacity(sessionKey);
|
|
273
283
|
let channels = await client.channels(workspace.id);
|
|
274
284
|
assertManagedChannelListContract(channels);
|
|
275
285
|
const destinationIdentity = [serverBaseUrl, workspace.id].join("\0");
|
|
276
|
-
const bindingGeneration = reserveDiscussionBindingGeneration({
|
|
286
|
+
const bindingGeneration = await reserveDiscussionBindingGeneration({
|
|
277
287
|
runtime,
|
|
278
288
|
sessionKey,
|
|
279
289
|
accountId: account.accountId,
|
|
@@ -303,7 +313,7 @@ async function openClickClackDiscussionBinding(params) {
|
|
|
303
313
|
sidebar_section: section,
|
|
304
314
|
display_title: displayTitle
|
|
305
315
|
};
|
|
306
|
-
recordPendingDiscussionOpen({
|
|
316
|
+
await recordPendingDiscussionOpen({
|
|
307
317
|
runtime,
|
|
308
318
|
sessionKey,
|
|
309
319
|
generation: bindingGeneration,
|
|
@@ -316,7 +326,8 @@ async function openClickClackDiscussionBinding(params) {
|
|
|
316
326
|
credentialFingerprint
|
|
317
327
|
}
|
|
318
328
|
});
|
|
319
|
-
params.ensureTimer();
|
|
329
|
+
await params.ensureTimer();
|
|
330
|
+
assertCurrentAuthority();
|
|
320
331
|
try {
|
|
321
332
|
if (adopted) {
|
|
322
333
|
markClickClackDiscussionChannelIdentityRevoked({
|
|
@@ -358,16 +369,17 @@ async function openClickClackDiscussionBinding(params) {
|
|
|
358
369
|
serverBaseUrl,
|
|
359
370
|
channelId: recovered.id
|
|
360
371
|
});
|
|
372
|
+
assertCurrentAuthority();
|
|
361
373
|
resolved = await client.updateChannel(recovered.id, managedFields);
|
|
362
374
|
break;
|
|
363
375
|
}
|
|
364
|
-
if (definitiveNoCreate) clearDiscussionBindingGeneration({
|
|
376
|
+
if (definitiveNoCreate) await clearDiscussionBindingGeneration({
|
|
365
377
|
runtime,
|
|
366
378
|
sessionKey,
|
|
367
379
|
expectedGeneration: bindingGeneration
|
|
368
380
|
});
|
|
369
381
|
} catch {
|
|
370
|
-
if (definitiveNoCreate && !adopted) clearDiscussionBindingGeneration({
|
|
382
|
+
if (definitiveNoCreate && !adopted) await clearDiscussionBindingGeneration({
|
|
371
383
|
runtime,
|
|
372
384
|
sessionKey,
|
|
373
385
|
expectedGeneration: bindingGeneration
|
|
@@ -387,7 +399,7 @@ async function openClickClackDiscussionBinding(params) {
|
|
|
387
399
|
});
|
|
388
400
|
if (adopted) assertChannelPatch(resolved, managedFields);
|
|
389
401
|
} catch (error) {
|
|
390
|
-
clearPendingDiscussionOpen({
|
|
402
|
+
await clearPendingDiscussionOpen({
|
|
391
403
|
runtime,
|
|
392
404
|
sessionKey,
|
|
393
405
|
expectedGeneration: bindingGeneration
|
|
@@ -396,7 +408,7 @@ async function openClickClackDiscussionBinding(params) {
|
|
|
396
408
|
throw error;
|
|
397
409
|
}
|
|
398
410
|
if (!resolved.route_id) {
|
|
399
|
-
clearPendingDiscussionOpen({
|
|
411
|
+
await clearPendingDiscussionOpen({
|
|
400
412
|
runtime,
|
|
401
413
|
sessionKey,
|
|
402
414
|
expectedGeneration: bindingGeneration
|
|
@@ -410,7 +422,7 @@ async function openClickClackDiscussionBinding(params) {
|
|
|
410
422
|
readConsistency: "latest"
|
|
411
423
|
});
|
|
412
424
|
if (!currentEntry?.sessionId || currentEntry.archivedAt !== void 0) {
|
|
413
|
-
clearPendingDiscussionOpen({
|
|
425
|
+
await clearPendingDiscussionOpen({
|
|
414
426
|
runtime,
|
|
415
427
|
sessionKey,
|
|
416
428
|
expectedGeneration: bindingGeneration
|
|
@@ -440,6 +452,7 @@ async function openClickClackDiscussionBinding(params) {
|
|
|
440
452
|
display_title: currentDisplayTitle
|
|
441
453
|
};
|
|
442
454
|
try {
|
|
455
|
+
assertCurrentAuthority();
|
|
443
456
|
currentChannel = await client.updateChannel(channel.id, latestManagedFields);
|
|
444
457
|
assertChannelPatch(currentChannel, latestManagedFields);
|
|
445
458
|
break;
|
|
@@ -448,7 +461,7 @@ async function openClickClackDiscussionBinding(params) {
|
|
|
448
461
|
}
|
|
449
462
|
}
|
|
450
463
|
} catch (error) {
|
|
451
|
-
clearPendingDiscussionOpen({
|
|
464
|
+
await clearPendingDiscussionOpen({
|
|
452
465
|
runtime,
|
|
453
466
|
sessionKey,
|
|
454
467
|
expectedGeneration: bindingGeneration
|
|
@@ -475,9 +488,10 @@ async function openClickClackDiscussionBinding(params) {
|
|
|
475
488
|
...currentChannel.display_title !== void 0 ? { displayTitle: currentChannel.display_title } : {}
|
|
476
489
|
};
|
|
477
490
|
try {
|
|
491
|
+
assertCurrentAuthority();
|
|
478
492
|
store.set(sessionKey, nextBinding);
|
|
479
493
|
} catch (error) {
|
|
480
|
-
clearPendingDiscussionOpen({
|
|
494
|
+
await clearPendingDiscussionOpen({
|
|
481
495
|
runtime,
|
|
482
496
|
sessionKey,
|
|
483
497
|
expectedGeneration: bindingGeneration
|
|
@@ -485,10 +499,59 @@ async function openClickClackDiscussionBinding(params) {
|
|
|
485
499
|
params.warn(`unbound discussion channel remains quarantined: ${channel.id}`);
|
|
486
500
|
throw error;
|
|
487
501
|
}
|
|
488
|
-
params.finalizePendingBinding(sessionKey, nextBinding);
|
|
502
|
+
await params.finalizePendingBinding(sessionKey, nextBinding);
|
|
489
503
|
return nextBinding;
|
|
490
504
|
});
|
|
491
505
|
}
|
|
506
|
+
async function reconcilePendingDiscussionOpen(params) {
|
|
507
|
+
const { pending } = params;
|
|
508
|
+
const currentBinding = params.store.get(pending.sessionKey);
|
|
509
|
+
if (currentBinding?.externalRef === pending.externalRef) {
|
|
510
|
+
await params.finalizePendingBinding(pending.sessionKey, currentBinding);
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
const cfg = params.runtime.config.current();
|
|
514
|
+
const account = listClickClackAccountIds(cfg).map((accountId) => resolveClickClackAccount({
|
|
515
|
+
cfg,
|
|
516
|
+
accountId
|
|
517
|
+
})).find((candidate) => candidate.configured && normalizedServerBaseUrl(candidate) === pending.serverBaseUrl && discussionCredentialFingerprint(candidate.token) === pending.credentialFingerprint);
|
|
518
|
+
if (!account) return;
|
|
519
|
+
const client = params.clientFactory(account);
|
|
520
|
+
const entry = params.runtime.agent.session.getSessionEntry({
|
|
521
|
+
sessionKey: pending.sessionKey,
|
|
522
|
+
readConsistency: "latest"
|
|
523
|
+
});
|
|
524
|
+
const activeAccounts = discussionAccounts(cfg);
|
|
525
|
+
const retryAccount = activeAccounts.length === 1 ? activeAccounts[0] : void 0;
|
|
526
|
+
if (params.allowRetry !== false && entry?.sessionId && entry.archivedAt === void 0 && retryAccount && normalizedServerBaseUrl(retryAccount) === pending.serverBaseUrl && discussionCredentialFingerprint(retryAccount.token) === pending.credentialFingerprint) {
|
|
527
|
+
if ((await params.clientFactory(retryAccount).workspaces()).find((candidate) => candidate.id === retryAccount.discussions.workspace || candidate.slug === retryAccount.discussions.workspace || candidate.name === retryAccount.discussions.workspace)?.id === pending.workspaceId) {
|
|
528
|
+
await params.open(pending.sessionKey);
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
const channels = await client.channels(pending.workspaceId);
|
|
533
|
+
assertManagedChannelListContract(channels);
|
|
534
|
+
const channel = channels.find((candidate) => candidate.external_managed === true && candidate.external_ref === pending.externalRef);
|
|
535
|
+
if (channel) {
|
|
536
|
+
markClickClackDiscussionChannelIdentityRevoked({
|
|
537
|
+
runtime: params.runtime,
|
|
538
|
+
accountId: pending.accountId,
|
|
539
|
+
serverBaseUrl: pending.serverBaseUrl,
|
|
540
|
+
channelId: channel.id
|
|
541
|
+
});
|
|
542
|
+
await clearPendingDiscussionOpen({
|
|
543
|
+
runtime: params.runtime,
|
|
544
|
+
sessionKey: pending.sessionKey,
|
|
545
|
+
expectedGeneration: pending.generation
|
|
546
|
+
});
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
await clearDiscussionBindingGeneration({
|
|
550
|
+
runtime: params.runtime,
|
|
551
|
+
sessionKey: pending.sessionKey,
|
|
552
|
+
expectedGeneration: pending.generation
|
|
553
|
+
});
|
|
554
|
+
}
|
|
492
555
|
//#endregion
|
|
493
556
|
//#region extensions/clickclack/src/discussions/service.ts
|
|
494
557
|
const RECONCILE_INTERVAL_MS = 6e4;
|
|
@@ -503,7 +566,7 @@ var ClickClackDiscussionService = class {
|
|
|
503
566
|
#timersEnabled;
|
|
504
567
|
#sessionLocks = /* @__PURE__ */ new Map();
|
|
505
568
|
#reconcileScheduler = new DiscussionReconcileScheduler({
|
|
506
|
-
shouldSchedule: (
|
|
569
|
+
shouldSchedule: () => !this.#closed,
|
|
507
570
|
run: async (sessionKey) => await this.reconcile(sessionKey),
|
|
508
571
|
warn: (message) => this.#logger().warn(message)
|
|
509
572
|
});
|
|
@@ -512,6 +575,9 @@ var ClickClackDiscussionService = class {
|
|
|
512
575
|
#reconcileAllPromise;
|
|
513
576
|
#unsubscribeSessionsChanged;
|
|
514
577
|
#closed = false;
|
|
578
|
+
#activation = 0;
|
|
579
|
+
#cleanupPromise;
|
|
580
|
+
#operations = /* @__PURE__ */ new Set();
|
|
515
581
|
constructor(runtime, options = {}) {
|
|
516
582
|
this.#runtime = runtime;
|
|
517
583
|
this.#store = getClickClackDiscussionBindingStore(runtime);
|
|
@@ -532,24 +598,43 @@ var ClickClackDiscussionService = class {
|
|
|
532
598
|
info: async ({ sessionKey }) => await this.info(sessionKey),
|
|
533
599
|
open: async ({ sessionKey }) => await this.open(sessionKey)
|
|
534
600
|
};
|
|
535
|
-
if (options.gatewayEvents) this.bindGatewayEvents(options.gatewayEvents)
|
|
536
|
-
|
|
601
|
+
if (options.gatewayEvents) this.bindGatewayEvents(options.gatewayEvents).catch((error) => {
|
|
602
|
+
this.#logger().warn(`discussion activation failed: ${String(error)}`);
|
|
603
|
+
});
|
|
604
|
+
if (this.#timersEnabled && !options.gatewayEvents) this.#withOperation(() => this.#ensureTimer()).catch((error) => {
|
|
605
|
+
this.#logger().warn(`discussion timer initialization failed: ${String(error)}`);
|
|
606
|
+
});
|
|
537
607
|
}
|
|
538
|
-
bindGatewayEvents(gatewayEvents) {
|
|
608
|
+
async bindGatewayEvents(gatewayEvents) {
|
|
609
|
+
const activation = ++this.#activation;
|
|
610
|
+
if (this.#cleanupPromise) await this.#cleanupPromise;
|
|
611
|
+
if (activation !== this.#activation) return;
|
|
612
|
+
this.#cleanupPromise = void 0;
|
|
539
613
|
this.#unsubscribeSessionsChanged?.();
|
|
540
614
|
this.#closed = false;
|
|
541
615
|
this.#reconcileScheduler.supersede();
|
|
542
616
|
this.#unsubscribeSessionsChanged = gatewayEvents?.onSessionsChanged((event) => {
|
|
543
|
-
this.#
|
|
617
|
+
this.#withOperation(async () => {
|
|
618
|
+
if (this.#store.get(event.sessionKey) || (await listPendingDiscussionOpens(this.#runtime)).some((pending) => pending.sessionKey === event.sessionKey)) {
|
|
619
|
+
if (activation === this.#activation) this.#reconcileScheduler.schedule(event.sessionKey);
|
|
620
|
+
}
|
|
621
|
+
}).catch((error) => {
|
|
622
|
+
this.#logger().warn(`discussion event admission failed: ${String(error)}`);
|
|
623
|
+
});
|
|
624
|
+
});
|
|
625
|
+
await this.#withOperation(async () => {
|
|
626
|
+
for (const sessionKey of await this.#listReconcileSessionKeys()) {
|
|
627
|
+
if (activation !== this.#activation) return;
|
|
628
|
+
this.#reconcileScheduler.schedule(sessionKey, 0);
|
|
629
|
+
}
|
|
630
|
+
await this.#ensureTimer();
|
|
544
631
|
});
|
|
545
|
-
for (const sessionKey of this.#listReconcileSessionKeys()) this.#reconcileScheduler.schedule(sessionKey, 0);
|
|
546
|
-
if (this.#timersEnabled) this.#ensureTimer();
|
|
547
632
|
}
|
|
548
633
|
hasEnabledAccount() {
|
|
549
634
|
return discussionAccounts(this.#currentConfig()).length === 1;
|
|
550
635
|
}
|
|
551
636
|
async info(sessionKey) {
|
|
552
|
-
return await this.#withSessionLock(sessionKey, async () => {
|
|
637
|
+
return await this.#withOperation(() => this.#withSessionLock(sessionKey, async () => {
|
|
553
638
|
if (discussionAccounts(this.#currentConfig()).length !== 1) return { state: "none" };
|
|
554
639
|
const existing = this.#store.get(sessionKey);
|
|
555
640
|
if (existing) {
|
|
@@ -563,104 +648,117 @@ var ClickClackDiscussionService = class {
|
|
|
563
648
|
return { state: "available" };
|
|
564
649
|
}
|
|
565
650
|
if (resolved.state !== "active") return { state: "none" };
|
|
566
|
-
this.#finalizePendingBinding(sessionKey, existing);
|
|
651
|
+
await this.#finalizePendingBinding(sessionKey, existing);
|
|
567
652
|
await this.#reconcileBinding(sessionKey, existing, resolved.account);
|
|
568
653
|
const current = this.#store.get(sessionKey);
|
|
569
654
|
if (!current) return { state: this.hasEnabledAccount() ? "available" : "none" };
|
|
570
655
|
return discussionInfoForBinding(current, resolved.account);
|
|
571
656
|
}
|
|
572
657
|
return { state: "available" };
|
|
573
|
-
});
|
|
658
|
+
}));
|
|
574
659
|
}
|
|
575
660
|
async open(sessionKey) {
|
|
576
|
-
return await this.#withSessionLock(sessionKey,
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
let binding;
|
|
595
|
-
try {
|
|
596
|
-
binding = await openClickClackDiscussionBinding({
|
|
597
|
-
runtime: this.#runtime,
|
|
598
|
-
store: this.#store,
|
|
599
|
-
account,
|
|
600
|
-
clientFactory: this.#clientFactory,
|
|
601
|
-
installationId: this.#installationId,
|
|
602
|
-
bindingGenerationFactory: this.#bindingGenerationFactory,
|
|
603
|
-
sessionKey,
|
|
604
|
-
ensureTimer: () => this.#ensureTimer(),
|
|
605
|
-
reconcilePendingOpen: async (pending) => await this.#reconcilePendingOpen(pending, { allowRetry: false }),
|
|
606
|
-
withChannelMutationLock: async (run) => await this.#withChannelMutationLock(run),
|
|
607
|
-
ensureBindingCapacity: (key) => this.#detachedBindings.ensureCapacity(key),
|
|
608
|
-
finalizePendingBinding: (key, nextBinding) => this.#finalizePendingBinding(key, nextBinding),
|
|
609
|
-
warn: (message) => this.#logger().warn(message)
|
|
610
|
-
});
|
|
611
|
-
} finally {
|
|
612
|
-
this.#ensureTimer();
|
|
661
|
+
return await this.#withOperation(() => this.#withSessionLock(sessionKey, () => this.#open(sessionKey)));
|
|
662
|
+
}
|
|
663
|
+
async #open(sessionKey) {
|
|
664
|
+
this.#installationId ??= await getClickClackDiscussionInstallationId(this.#runtime);
|
|
665
|
+
const accounts = discussionAccounts(this.#currentConfig());
|
|
666
|
+
if (accounts.length > 1) throw new Error("ClickClack discussions require exactly one enabled discussion account");
|
|
667
|
+
const account = accounts[0];
|
|
668
|
+
if (!account) return { state: "none" };
|
|
669
|
+
const existing = this.#store.get(sessionKey);
|
|
670
|
+
if (existing) {
|
|
671
|
+
const resolved = await this.#resolveBindingForUse(existing);
|
|
672
|
+
if (resolved.state === "retargeted") this.#revokeAndDeleteBinding(sessionKey, existing);
|
|
673
|
+
else if (resolved.state === "stale") await this.#releaseStaleBinding(sessionKey, existing);
|
|
674
|
+
else if (resolved.state === "active") {
|
|
675
|
+
await this.#finalizePendingBinding(sessionKey, existing);
|
|
676
|
+
await this.#reconcileBinding(sessionKey, existing, resolved.account);
|
|
677
|
+
const current = this.#store.get(sessionKey);
|
|
678
|
+
if (current) return discussionInfoForBinding(current, resolved.account);
|
|
613
679
|
}
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
680
|
+
}
|
|
681
|
+
let binding;
|
|
682
|
+
try {
|
|
683
|
+
binding = await openClickClackDiscussionBinding({
|
|
684
|
+
runtime: this.#runtime,
|
|
685
|
+
store: this.#store,
|
|
686
|
+
account,
|
|
687
|
+
clientFactory: this.#clientFactory,
|
|
688
|
+
installationId: this.#installationId,
|
|
689
|
+
bindingGenerationFactory: this.#bindingGenerationFactory,
|
|
690
|
+
sessionKey,
|
|
691
|
+
ensureTimer: () => this.#ensureTimer(),
|
|
692
|
+
reconcilePendingOpen: async (pending) => await this.#reconcilePendingOpen(pending, { allowRetry: false }),
|
|
693
|
+
withChannelMutationLock: async (run) => await this.#withChannelMutationLock(run),
|
|
694
|
+
ensureBindingCapacity: (key) => this.#detachedBindings.ensureCapacity(key),
|
|
695
|
+
finalizePendingBinding: (key, nextBinding) => this.#finalizePendingBinding(key, nextBinding),
|
|
696
|
+
warn: (message) => this.#logger().warn(message)
|
|
697
|
+
});
|
|
698
|
+
} finally {
|
|
699
|
+
await this.#ensureTimer();
|
|
700
|
+
}
|
|
701
|
+
if (!binding) return { state: "available" };
|
|
702
|
+
return discussionInfoForBinding(binding, account);
|
|
617
703
|
}
|
|
618
704
|
async reconcile(sessionKey) {
|
|
705
|
+
return await this.#withOperation(() => this.#reconcile(sessionKey));
|
|
706
|
+
}
|
|
707
|
+
async #reconcile(sessionKey) {
|
|
619
708
|
try {
|
|
620
709
|
await this.#withSessionLock(sessionKey, async () => {
|
|
621
710
|
const binding = this.#store.get(sessionKey);
|
|
622
711
|
if (binding) await this.#reconcileBinding(sessionKey, binding);
|
|
712
|
+
const pending = (await listPendingDiscussionOpens(this.#runtime)).find((candidate) => candidate.sessionKey === sessionKey);
|
|
713
|
+
if (pending) await this.#reconcilePendingOpen(pending);
|
|
623
714
|
});
|
|
624
|
-
const pending = listPendingDiscussionOpens(this.#runtime).find((candidate) => candidate.sessionKey === sessionKey);
|
|
625
|
-
if (pending) await this.#reconcilePendingOpen(pending);
|
|
626
715
|
} finally {
|
|
627
|
-
this.#ensureTimer();
|
|
716
|
+
await this.#ensureTimer();
|
|
628
717
|
}
|
|
629
718
|
}
|
|
630
719
|
async reconcileAll() {
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
720
|
+
return await this.#withOperation(async () => {
|
|
721
|
+
if (this.#reconcileAllPromise) return await this.#reconcileAllPromise;
|
|
722
|
+
this.#reconcileAllPromise = (async () => {
|
|
723
|
+
try {
|
|
724
|
+
for (const sessionKey of await this.#listReconcileSessionKeys()) try {
|
|
725
|
+
await this.#reconcile(sessionKey);
|
|
726
|
+
} catch (error) {
|
|
727
|
+
this.#logger().warn(`discussion reconcile failed for ${sessionKey}: ${String(error)}`);
|
|
728
|
+
}
|
|
729
|
+
} finally {
|
|
730
|
+
await this.#ensureTimer();
|
|
731
|
+
}
|
|
732
|
+
})().finally(() => {
|
|
733
|
+
this.#reconcileAllPromise = void 0;
|
|
734
|
+
});
|
|
735
|
+
return await this.#reconcileAllPromise;
|
|
640
736
|
});
|
|
641
|
-
return await this.#reconcileAllPromise;
|
|
642
737
|
}
|
|
643
738
|
async readLatestMessages(sessionKey, limit) {
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
739
|
+
return await this.#withOperation(() => this.#withSessionLock(sessionKey, async () => {
|
|
740
|
+
const binding = this.#store.get(sessionKey);
|
|
741
|
+
if (!binding) return { text: "No discussion is bound to this session." };
|
|
742
|
+
const resolved = await this.#resolveBindingForUse(binding);
|
|
743
|
+
if (resolved.state === "retargeted") return { text: "No discussion is bound to this session." };
|
|
744
|
+
if (resolved.state === "stale") return { text: "No discussion is bound to this session." };
|
|
745
|
+
if (resolved.state !== "active") return { text: "No discussion is bound to this session." };
|
|
746
|
+
const attached = this.#refreshSessionAttachment(sessionKey, binding);
|
|
747
|
+
if (!attached) return { text: "No discussion is bound to this session." };
|
|
748
|
+
if (isClickClackDiscussionChannelRevoked({
|
|
749
|
+
runtime: this.#runtime,
|
|
750
|
+
serverBaseUrl: binding.serverBaseUrl,
|
|
751
|
+
channelId: binding.channelId
|
|
752
|
+
})) return { text: "No discussion is bound to this session." };
|
|
753
|
+
return {
|
|
754
|
+
binding: attached,
|
|
755
|
+
text: formatDiscussionHistory(await this.#clientFactory(resolved.account).latestChannelMessages(attached.channelId, limit)) || "The bound discussion has no messages yet."
|
|
756
|
+
};
|
|
757
|
+
}));
|
|
661
758
|
}
|
|
662
759
|
cleanup() {
|
|
663
760
|
this.#closed = true;
|
|
761
|
+
this.#activation += 1;
|
|
664
762
|
this.#unsubscribeSessionsChanged?.();
|
|
665
763
|
this.#unsubscribeSessionsChanged = void 0;
|
|
666
764
|
this.#reconcileScheduler.supersede();
|
|
@@ -669,9 +767,11 @@ var ClickClackDiscussionService = class {
|
|
|
669
767
|
clearInterval(this.#timer);
|
|
670
768
|
this.#timer = void 0;
|
|
671
769
|
}
|
|
770
|
+
this.#cleanupPromise ??= Promise.allSettled(this.#operations).then(() => void 0);
|
|
771
|
+
return this.#cleanupPromise;
|
|
672
772
|
}
|
|
673
773
|
async #reconcileBinding(sessionKey, binding, resolvedAccount) {
|
|
674
|
-
this.#finalizePendingBinding(sessionKey, binding);
|
|
774
|
+
await this.#finalizePendingBinding(sessionKey, binding);
|
|
675
775
|
if (isClickClackDiscussionChannelRevoked({
|
|
676
776
|
runtime: this.#runtime,
|
|
677
777
|
serverBaseUrl: binding.serverBaseUrl,
|
|
@@ -690,10 +790,7 @@ var ClickClackDiscussionService = class {
|
|
|
690
790
|
}
|
|
691
791
|
const activeBinding = this.#detachedBindings.clear(sessionKey, binding);
|
|
692
792
|
if (!activeBinding) return;
|
|
693
|
-
const resolved = resolvedAccount ?
|
|
694
|
-
state: "active",
|
|
695
|
-
account: resolvedAccount
|
|
696
|
-
} : await this.#resolveBindingForUse(activeBinding);
|
|
793
|
+
const resolved = resolvedAccount ? resolveDiscussionBindingAccount(this.#currentConfig(), activeBinding) : await this.#resolveBindingForUse(activeBinding);
|
|
697
794
|
if (resolved.state === "retargeted") {
|
|
698
795
|
this.#revokeAndDeleteBinding(sessionKey, activeBinding);
|
|
699
796
|
return;
|
|
@@ -774,55 +871,18 @@ var ClickClackDiscussionService = class {
|
|
|
774
871
|
}
|
|
775
872
|
}
|
|
776
873
|
async #reconcilePendingOpen(pending, options = {}) {
|
|
777
|
-
|
|
778
|
-
if (currentBinding?.externalRef === pending.externalRef) {
|
|
779
|
-
this.#finalizePendingBinding(pending.sessionKey, currentBinding);
|
|
780
|
-
return;
|
|
781
|
-
}
|
|
782
|
-
const cfg = this.#currentConfig();
|
|
783
|
-
const account = listClickClackAccountIds(cfg).map((accountId) => resolveClickClackAccount({
|
|
784
|
-
cfg,
|
|
785
|
-
accountId
|
|
786
|
-
})).find((candidate) => candidate.configured && normalizedServerBaseUrl(candidate) === pending.serverBaseUrl && discussionCredentialFingerprint(candidate.token) === pending.credentialFingerprint);
|
|
787
|
-
if (!account) return;
|
|
788
|
-
const client = this.#clientFactory(account);
|
|
789
|
-
const entry = this.#runtime.agent.session.getSessionEntry({
|
|
790
|
-
sessionKey: pending.sessionKey,
|
|
791
|
-
readConsistency: "latest"
|
|
792
|
-
});
|
|
793
|
-
const activeAccounts = discussionAccounts(cfg);
|
|
794
|
-
const retryAccount = activeAccounts.length === 1 ? activeAccounts[0] : void 0;
|
|
795
|
-
if (options.allowRetry !== false && entry?.sessionId && entry.archivedAt === void 0 && retryAccount && normalizedServerBaseUrl(retryAccount) === pending.serverBaseUrl && discussionCredentialFingerprint(retryAccount.token) === pending.credentialFingerprint) {
|
|
796
|
-
if ((await this.#clientFactory(retryAccount).workspaces()).find((candidate) => candidate.id === retryAccount.discussions.workspace || candidate.slug === retryAccount.discussions.workspace || candidate.name === retryAccount.discussions.workspace)?.id === pending.workspaceId) {
|
|
797
|
-
await this.open(pending.sessionKey);
|
|
798
|
-
return;
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
const channels = await client.channels(pending.workspaceId);
|
|
802
|
-
assertManagedChannelListContract(channels);
|
|
803
|
-
const channel = channels.find((candidate) => candidate.external_managed === true && candidate.external_ref === pending.externalRef);
|
|
804
|
-
if (channel) {
|
|
805
|
-
markClickClackDiscussionChannelIdentityRevoked({
|
|
806
|
-
runtime: this.#runtime,
|
|
807
|
-
accountId: pending.accountId,
|
|
808
|
-
serverBaseUrl: pending.serverBaseUrl,
|
|
809
|
-
channelId: channel.id
|
|
810
|
-
});
|
|
811
|
-
clearPendingDiscussionOpen({
|
|
812
|
-
runtime: this.#runtime,
|
|
813
|
-
sessionKey: pending.sessionKey,
|
|
814
|
-
expectedGeneration: pending.generation
|
|
815
|
-
});
|
|
816
|
-
return;
|
|
817
|
-
}
|
|
818
|
-
clearDiscussionBindingGeneration({
|
|
874
|
+
await reconcilePendingDiscussionOpen({
|
|
819
875
|
runtime: this.#runtime,
|
|
820
|
-
|
|
821
|
-
|
|
876
|
+
store: this.#store,
|
|
877
|
+
clientFactory: this.#clientFactory,
|
|
878
|
+
pending,
|
|
879
|
+
...options,
|
|
880
|
+
finalizePendingBinding: (key, binding) => this.#finalizePendingBinding(key, binding),
|
|
881
|
+
open: (key) => this.#open(key)
|
|
822
882
|
});
|
|
823
883
|
}
|
|
824
884
|
async #releaseStaleBinding(sessionKey, binding) {
|
|
825
|
-
clearDiscussionBindingGeneration({
|
|
885
|
+
await clearDiscussionBindingGeneration({
|
|
826
886
|
runtime: this.#runtime,
|
|
827
887
|
sessionKey
|
|
828
888
|
});
|
|
@@ -832,15 +892,15 @@ var ClickClackDiscussionService = class {
|
|
|
832
892
|
markClickClackDiscussionChannelRevoked(this.#runtime, binding);
|
|
833
893
|
this.#store.delete(sessionKey);
|
|
834
894
|
}
|
|
835
|
-
#finalizePendingBinding(sessionKey, binding) {
|
|
836
|
-
const pending = listPendingDiscussionOpens(this.#runtime).find((candidate) => candidate.sessionKey === sessionKey && candidate.externalRef === binding.externalRef);
|
|
895
|
+
async #finalizePendingBinding(sessionKey, binding) {
|
|
896
|
+
const pending = (await listPendingDiscussionOpens(this.#runtime)).find((candidate) => candidate.sessionKey === sessionKey && candidate.externalRef === binding.externalRef);
|
|
837
897
|
if (pending) {
|
|
838
898
|
clearClickClackDiscussionChannelRevoked({
|
|
839
899
|
runtime: this.#runtime,
|
|
840
900
|
serverBaseUrl: binding.serverBaseUrl,
|
|
841
901
|
channelId: binding.channelId
|
|
842
902
|
});
|
|
843
|
-
clearDiscussionBindingGeneration({
|
|
903
|
+
await clearDiscussionBindingGeneration({
|
|
844
904
|
runtime: this.#runtime,
|
|
845
905
|
sessionKey,
|
|
846
906
|
expectedGeneration: pending.generation
|
|
@@ -850,13 +910,17 @@ var ClickClackDiscussionService = class {
|
|
|
850
910
|
async #resolveBindingForUse(binding) {
|
|
851
911
|
const resolved = resolveDiscussionBindingAccount(this.#currentConfig(), binding);
|
|
852
912
|
if (resolved.state !== "active") return resolved;
|
|
853
|
-
|
|
913
|
+
const workspace = (await this.#clientFactory(resolved.account).workspaces()).find((candidate) => candidate.id === resolved.account.discussions.workspace || candidate.slug === resolved.account.discussions.workspace || candidate.name === resolved.account.discussions.workspace);
|
|
914
|
+
const current = resolveDiscussionBindingAccount(this.#currentConfig(), binding);
|
|
915
|
+
if (current.state !== "active") return current;
|
|
916
|
+
return workspace?.id === binding.workspaceId ? current : { state: "retargeted" };
|
|
854
917
|
}
|
|
855
918
|
#currentConfig() {
|
|
856
919
|
return this.#runtime.config.current();
|
|
857
920
|
}
|
|
858
|
-
#ensureTimer() {
|
|
859
|
-
|
|
921
|
+
async #ensureTimer() {
|
|
922
|
+
if (this.#closed) return;
|
|
923
|
+
const hasPendingOpens = (await listPendingDiscussionOpens(this.#runtime)).length > 0;
|
|
860
924
|
const needsBindingPoll = this.#unsubscribeSessionsChanged === void 0 && this.#store.count() > 0;
|
|
861
925
|
if (this.#closed || !hasPendingOpens && !needsBindingPoll) {
|
|
862
926
|
if (this.#timer) {
|
|
@@ -869,14 +933,12 @@ var ClickClackDiscussionService = class {
|
|
|
869
933
|
this.#timer = setInterval(() => {
|
|
870
934
|
this.reconcileAll().catch((error) => {
|
|
871
935
|
this.#logger().warn(`discussion reconcile pass failed: ${String(error)}`);
|
|
872
|
-
}).finally(() => {
|
|
873
|
-
this.#ensureTimer();
|
|
874
936
|
});
|
|
875
937
|
}, RECONCILE_INTERVAL_MS);
|
|
876
938
|
this.#timer.unref?.();
|
|
877
939
|
}
|
|
878
|
-
#listReconcileSessionKeys() {
|
|
879
|
-
return /* @__PURE__ */ new Set([...this.#store.entries().map(({ sessionKey }) => sessionKey), ...listPendingDiscussionOpens(this.#runtime).map(({ sessionKey }) => sessionKey)]);
|
|
940
|
+
async #listReconcileSessionKeys() {
|
|
941
|
+
return /* @__PURE__ */ new Set([...this.#store.entries().map(({ sessionKey }) => sessionKey), ...(await listPendingDiscussionOpens(this.#runtime)).map(({ sessionKey }) => sessionKey)]);
|
|
880
942
|
}
|
|
881
943
|
#logger() {
|
|
882
944
|
return this.#runtime.logging.getChildLogger({
|
|
@@ -884,6 +946,13 @@ var ClickClackDiscussionService = class {
|
|
|
884
946
|
feature: "discussions"
|
|
885
947
|
});
|
|
886
948
|
}
|
|
949
|
+
#withOperation(run) {
|
|
950
|
+
if (this.#closed) return Promise.reject(/* @__PURE__ */ new Error("ClickClack discussion service is stopped"));
|
|
951
|
+
const operation = Promise.resolve().then(run);
|
|
952
|
+
this.#operations.add(operation);
|
|
953
|
+
operation.then(() => this.#operations.delete(operation), () => this.#operations.delete(operation));
|
|
954
|
+
return operation;
|
|
955
|
+
}
|
|
887
956
|
async #withSessionLock(sessionKey, run) {
|
|
888
957
|
const current = (this.#sessionLocks.get(sessionKey) ?? Promise.resolve()).catch(() => void 0).then(run);
|
|
889
958
|
this.#sessionLocks.set(sessionKey, current);
|
|
@@ -981,12 +1050,8 @@ function registerClickClackDiscussions(api) {
|
|
|
981
1050
|
const service = new ClickClackDiscussionService(api.runtime);
|
|
982
1051
|
api.registerService({
|
|
983
1052
|
id: "clickclack-discussion-session-events",
|
|
984
|
-
start: ({ gatewayEvents }) =>
|
|
985
|
-
|
|
986
|
-
},
|
|
987
|
-
stop: () => {
|
|
988
|
-
service.cleanup();
|
|
989
|
-
}
|
|
1053
|
+
start: ({ gatewayEvents }) => service.bindGatewayEvents(gatewayEvents),
|
|
1054
|
+
stop: () => service.cleanup()
|
|
990
1055
|
});
|
|
991
1056
|
api.registerTool((context) => createClickClackDiscussionTool({
|
|
992
1057
|
service,
|
|
@@ -1009,9 +1074,11 @@ function registerClickClackDiscussions(api) {
|
|
|
1009
1074
|
api.lifecycle.registerRuntimeLifecycle({
|
|
1010
1075
|
id: "clickclack-discussions",
|
|
1011
1076
|
description: "Stops the lifecycle reconciler for managed ClickClack discussions.",
|
|
1012
|
-
cleanup: () => {
|
|
1013
|
-
|
|
1014
|
-
|
|
1077
|
+
cleanup: ({ reason, sessionKey, runId }) => {
|
|
1078
|
+
if (sessionKey === void 0 && runId === void 0 && (reason === "restart" || reason === "disable")) {
|
|
1079
|
+
unregisterSessionAccess();
|
|
1080
|
+
return service.cleanup();
|
|
1081
|
+
}
|
|
1015
1082
|
}
|
|
1016
1083
|
});
|
|
1017
1084
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as isClickClackSetupLoopbackHost, i as buildClickClackSetupClaimUrl, o as requireClickClackSetupApiBaseUrl } from "./setup-surface-
|
|
1
|
+
import { a as isClickClackSetupLoopbackHost, i as buildClickClackSetupClaimUrl, o as requireClickClackSetupApiBaseUrl } from "./setup-surface-BW1Q06w5.mjs";
|
|
2
2
|
import { withTimeout } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
3
3
|
import { createProviderOperationDeadline, readProviderJsonResponse, readResponseTextLimited, resolveProviderOperationTimeoutMs } from "openclaw/plugin-sdk/provider-http";
|
|
4
4
|
import { fetchWithSsrFGuard, resolvePinnedHostnameWithPolicy, ssrfPolicyFromHttpBaseUrlAllowedHostname } from "openclaw/plugin-sdk/ssrf-runtime";
|