@goplus/agentguard 1.1.10 → 1.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +6 -4
  2. package/dist/adapters/common.d.ts.map +1 -1
  3. package/dist/adapters/common.js +3 -1
  4. package/dist/adapters/common.js.map +1 -1
  5. package/dist/adapters/openclaw-plugin.d.ts.map +1 -1
  6. package/dist/adapters/openclaw-plugin.js +17 -3
  7. package/dist/adapters/openclaw-plugin.js.map +1 -1
  8. package/dist/cli.js +109 -5
  9. package/dist/cli.js.map +1 -1
  10. package/dist/config.d.ts +3 -1
  11. package/dist/config.d.ts.map +1 -1
  12. package/dist/config.js +12 -0
  13. package/dist/config.js.map +1 -1
  14. package/dist/feed/cron.d.ts +1 -0
  15. package/dist/feed/cron.d.ts.map +1 -1
  16. package/dist/feed/cron.js +366 -50
  17. package/dist/feed/cron.js.map +1 -1
  18. package/dist/installers.js +110 -16
  19. package/dist/installers.js.map +1 -1
  20. package/dist/postinstall.js +24 -4
  21. package/dist/postinstall.js.map +1 -1
  22. package/dist/registry/storage.d.ts.map +1 -1
  23. package/dist/registry/storage.js +5 -1
  24. package/dist/registry/storage.js.map +1 -1
  25. package/dist/tests/cli-init.test.js +90 -0
  26. package/dist/tests/cli-init.test.js.map +1 -1
  27. package/dist/tests/cli-subscribe.test.js +33 -0
  28. package/dist/tests/cli-subscribe.test.js.map +1 -1
  29. package/dist/tests/feed-cron.test.js +205 -15
  30. package/dist/tests/feed-cron.test.js.map +1 -1
  31. package/dist/tests/installer.test.js +26 -4
  32. package/dist/tests/installer.test.js.map +1 -1
  33. package/dist/tests/integration.test.js +9 -5
  34. package/dist/tests/integration.test.js.map +1 -1
  35. package/dist/tests/postinstall.test.js +8 -4
  36. package/dist/tests/postinstall.test.js.map +1 -1
  37. package/dist/tests/setup-script.test.d.ts +2 -0
  38. package/dist/tests/setup-script.test.d.ts.map +1 -0
  39. package/dist/tests/setup-script.test.js +63 -0
  40. package/dist/tests/setup-script.test.js.map +1 -0
  41. package/dist/tests/smoke.test.js +88 -1
  42. package/dist/tests/smoke.test.js.map +1 -1
  43. package/docs/codex.md +1 -1
  44. package/docs/hermes.md +3 -3
  45. package/package.json +1 -1
  46. package/skills/agentguard/SKILL.md +404 -199
  47. package/skills/agentguard/hermes-hooks.yaml +2 -2
  48. package/skills/agentguard/scan-rules.md +13 -2
  49. package/skills/agentguard/scripts/{action-cli.ts → action-cli.js} +13 -18
  50. package/skills/agentguard/scripts/auto-scan.js +3 -1
  51. package/skills/agentguard/scripts/checkup-score.js +369 -0
  52. package/skills/agentguard/scripts/hermes-hook.js +103 -16
  53. package/skills/agentguard/scripts/scan-to-sarif.js +195 -0
  54. package/skills/agentguard/scripts/{trust-cli.ts → trust-cli.js} +12 -16
  55. package/skills/agentguard/suppress.example.yaml +67 -0
package/dist/config.js CHANGED
@@ -63,6 +63,7 @@ function loadConfig() {
63
63
  version: 1,
64
64
  level: normalizeLevel(parsed.level) ?? fallback.level,
65
65
  agentHost: normalizeAgentHost(parsed.agentHost),
66
+ agentHosts: normalizeAgentHosts(parsed.agentHosts),
66
67
  cloudUrl: parsed.cloudUrl || fallback.cloudUrl,
67
68
  policyCachePath: parsed.policyCachePath || fallback.policyCachePath,
68
69
  auditPath: parsed.auditPath || fallback.auditPath,
@@ -139,6 +140,17 @@ function normalizeAgentHost(value) {
139
140
  ? value
140
141
  : undefined;
141
142
  }
143
+ function normalizeAgentHosts(value) {
144
+ if (!Array.isArray(value))
145
+ return undefined;
146
+ const seen = new Set();
147
+ for (const item of value) {
148
+ const host = normalizeAgentHost(item);
149
+ if (host)
150
+ seen.add(host);
151
+ }
152
+ return seen.size > 0 ? [...seen] : undefined;
153
+ }
142
154
  function chmodBestEffort(path, mode) {
143
155
  try {
144
156
  (0, node_fs_1.chmodSync)(path, mode);
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;AA2BA,gDASC;AAED,sCAUC;AAED,oDAKC;AAED,oCAQC;AAED,gCAmBC;AAED,gCAKC;AAED,oCAWC;AAED,0CASC;AAED,gCAIC;AAED,wCAIC;AAID,8CAeC;AApJD,qCAAgG;AAChG,yCAA0C;AAC1C,qCAAkC;AAsBlC,MAAM,iBAAiB,GAAG,kCAAkC,CAAC;AAC7D,MAAM,eAAe,GAAG,6BAA6B,CAAC;AAEtD,SAAgB,kBAAkB;IAChC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAA,gBAAI,EAAC,IAAA,iBAAO,GAAE,EAAE,aAAa,CAAC,CAAC;IAC3E,OAAO;QACL,IAAI;QACJ,UAAU,EAAE,IAAA,gBAAI,EAAC,IAAI,EAAE,aAAa,CAAC;QACrC,eAAe,EAAE,IAAA,gBAAI,EAAC,IAAI,EAAE,mBAAmB,CAAC;QAChD,SAAS,EAAE,IAAA,gBAAI,EAAC,IAAI,EAAE,aAAa,CAAC;QACpC,cAAc,EAAE,IAAA,gBAAI,EAAC,IAAI,EAAE,oBAAoB,CAAC;KACjD,CAAC;AACJ,CAAC;AAED,SAAgB,aAAa;IAC3B,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;IACnC,OAAO;QACL,OAAO,EAAE,CAAC;QACV,KAAK,EAAE,UAAU;QACjB,QAAQ,EAAE,iBAAiB;QAC3B,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,cAAc,EAAE,KAAK,CAAC,cAAc;KACrC,CAAC;AACJ,CAAC;AAED,SAAgB,oBAAoB;IAClC,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;IACnC,IAAA,mBAAS,EAAC,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAgB,YAAY;IAC1B,MAAM,KAAK,GAAG,oBAAoB,EAAE,CAAC;IACrC,IAAI,CAAC,IAAA,oBAAU,EAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;QAC/B,UAAU,CAAC,MAAM,CAAC,CAAC;QACnB,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,UAAU,EAAE,CAAC;AACtB,CAAC;AAED,SAAgB,UAAU;IACxB,MAAM,QAAQ,GAAG,aAAa,EAAE,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,CAA8B,CAAC;QAC/F,OAAO;YACL,GAAG,QAAQ;YACX,GAAG,MAAM;YACT,OAAO,EAAE,CAAC;YACV,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,KAAK;YACrD,SAAS,EAAE,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC;YAC/C,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ;YAC9C,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,QAAQ,CAAC,eAAe;YACnE,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,QAAQ,CAAC,SAAS;YACjD,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,QAAQ,CAAC,cAAc;SACjE,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAgB,UAAU,CAAC,MAAwB;IACjD,MAAM,KAAK,GAAG,oBAAoB,EAAE,CAAC;IACrC,IAAA,mBAAS,EAAC,IAAA,mBAAO,EAAC,KAAK,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,IAAA,uBAAa,EAAC,KAAK,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACzF,eAAe,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;AAC3C,CAAC;AAED,SAAgB,YAAY,CAAC,OAA8C;IACzE,MAAM,OAAO,GAAG,YAAY,EAAE,CAAC;IAC/B,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAqB;QAC7B,GAAG,OAAO;QACV,QAAQ,EAAE,iBAAiB,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,IAAI,iBAAiB,CAAC;QACtF,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACtC,CAAC;IACF,UAAU,CAAC,IAAI,CAAC,CAAC;IACjB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,eAAe;IAC7B,MAAM,OAAO,GAAG,YAAY,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAqB,EAAE,GAAG,OAAO,EAAE,CAAC;IAC9C,OAAO,IAAI,CAAC,MAAM,CAAC;IACnB,OAAO,IAAI,CAAC,WAAW,CAAC;IACxB,IAAA,gBAAM,EAAC,OAAO,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,IAAA,gBAAM,EAAC,OAAO,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,UAAU,CAAC,IAAI,CAAC,CAAC;IACjB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,UAAU,CAAC,MAAe;IACxC,IAAI,CAAC,MAAM;QAAE,OAAO,gBAAgB,CAAC;IACrC,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE;QAAE,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC;IACzD,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACrD,CAAC;AAED,SAAgB,cAAc,CAAC,MAAc;IAC3C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;AACH,CAAC;AAED,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;AAE7E,SAAgB,iBAAiB,CAAC,KAAa;IAC7C,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC7C,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACxC,CAAC;IACD,MAAM,UAAU,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACvD,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,UAAU,CAAC,EAAE,CAAC;QACjF,MAAM,IAAI,KAAK,CACb,uGAAuG,CACxG,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,YAAY;QACzE,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,OAAO,KAAK,KAAK,aAAa,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO;QACpH,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,SAAS,eAAe,CAAC,IAAY,EAAE,IAAY;IACjD,IAAI,CAAC;QACH,IAAA,mBAAS,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,sEAAsE;IACxE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,7 @@ export interface OpenClawCronInstallResult {
13
13
  export interface OpenClawGatewayOptions {
14
14
  host?: string;
15
15
  port?: number;
16
+ url?: string;
16
17
  label?: string;
17
18
  timeoutMs?: number;
18
19
  request?: (method: string, params: unknown) => Promise<unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../../src/feed/cron.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC9E,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,kBAAkB,GAAG,eAAe,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC1G,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEtF,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACjE;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;AAExG,UAAU,eAAe;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAU5D;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAsB,qBAAqB,CACzC,OAAO,EAAE;IACP,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,EACD,QAAQ,GAAE;IACR,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,UAAU,CAAC,EAAE,aAAa,CAAC;CACvB,GACL,OAAO,CAAC,yBAAyB,CAAC,CAkDpC;AAED,wBAAsB,6BAA6B,CACjD,OAAO,EAAE;IACP,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,EACD,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,yBAAyB,CAAC,CA6DpC;AAmYD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,EAAE,CAczE;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,OAAO,CAAC,CA+ElB"}
1
+ {"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../../src/feed/cron.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC9E,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,kBAAkB,GAAG,eAAe,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC1G,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEtF,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACjE;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;AAExG,UAAU,eAAe;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAID,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAU5D;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAsB,qBAAqB,CACzC,OAAO,EAAE;IACP,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,EACD,QAAQ,GAAE;IACR,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,UAAU,CAAC,EAAE,aAAa,CAAC;CACvB,GACL,OAAO,CAAC,yBAAyB,CAAC,CAkDpC;AAED,wBAAsB,6BAA6B,CACjD,OAAO,EAAE;IACP,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,EACD,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,yBAAyB,CAAC,CA4DpC;AAuYD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,EAAE,CAczE;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,OAAO,CAAC,CAmBlB"}
package/dist/feed/cron.js CHANGED
@@ -9,11 +9,15 @@ exports.installThreatFeedCron = installThreatFeedCron;
9
9
  exports.installOpenClawThreatFeedCron = installOpenClawThreatFeedCron;
10
10
  exports.extractOpenClawCronJobs = extractOpenClawCronJobs;
11
11
  exports.openClawGatewayRequest = openClawGatewayRequest;
12
- const node_http_1 = __importDefault(require("node:http"));
13
12
  const node_child_process_1 = require("node:child_process");
13
+ const node_crypto_1 = require("node:crypto");
14
14
  const promises_1 = require("node:fs/promises");
15
+ const node_http_1 = __importDefault(require("node:http"));
16
+ const node_net_1 = __importDefault(require("node:net"));
15
17
  const node_os_1 = require("node:os");
16
18
  const node_path_1 = require("node:path");
19
+ class GatewayHttpFallbackError extends Error {
20
+ }
17
21
  function validateCronExpression(value) {
18
22
  const expr = value.trim();
19
23
  const fields = expr.split(/\s+/);
@@ -72,7 +76,7 @@ async function installThreatFeedCron(options, adapters = {}) {
72
76
  async function installOpenClawThreatFeedCron(options, gateway = {}) {
73
77
  const schedule = validateCronExpression(options.cronExpression);
74
78
  const timezone = options.timezone ?? localTimeZone();
75
- const command = threatFeedCommand(options.quiet);
79
+ const command = threatFeedCommand(options.quiet, { notifyRun: true });
76
80
  const existing = await findOpenClawCronJobsByName(options.name, gateway);
77
81
  if (existing.length > 0 && !options.force) {
78
82
  return {
@@ -90,31 +94,30 @@ async function installOpenClawThreatFeedCron(options, gateway = {}) {
90
94
  if (existing.length > 0) {
91
95
  await removeOpenClawCronJobs(existing, gateway);
92
96
  }
93
- await openClawGatewayRequest('cron.add', [
94
- {
95
- name: options.name,
96
- description,
97
- enabled: true,
98
- schedule: {
99
- kind: 'cron',
100
- expr: schedule,
101
- tz: timezone,
102
- },
103
- sessionTarget: 'isolated',
104
- payload: {
105
- kind: 'agentTurn',
106
- message,
107
- timeoutSeconds: 300,
108
- agentguard: {
109
- mode,
110
- command,
111
- },
112
- },
113
- delivery: {
114
- mode: 'none',
97
+ await openClawGatewayRequest('cron.add', {
98
+ name: options.name,
99
+ description,
100
+ enabled: true,
101
+ schedule: {
102
+ kind: 'cron',
103
+ expr: schedule,
104
+ tz: timezone,
105
+ },
106
+ sessionTarget: 'isolated',
107
+ payload: {
108
+ kind: 'agentTurn',
109
+ message,
110
+ timeoutSeconds: 300,
111
+ agentguard: {
112
+ mode,
113
+ command,
115
114
  },
116
115
  },
117
- ], gateway);
116
+ delivery: {
117
+ mode: 'announce',
118
+ channel: 'last',
119
+ },
120
+ }, gateway);
118
121
  return {
119
122
  name: options.name,
120
123
  schedule,
@@ -131,7 +134,7 @@ async function findOpenClawCronJobsByName(name, gateway) {
131
134
  async function installOpenClawNativeThreatFeedCron(options, runCommand = execCommand) {
132
135
  const schedule = validateCronExpression(options.cronExpression);
133
136
  const timezone = options.timezone ?? localTimeZone();
134
- const command = threatFeedCommand(options.quiet);
137
+ const command = threatFeedCommand(options.quiet, { notifyRun: true });
135
138
  const message = openClawCronMessage(options.quiet);
136
139
  let existing;
137
140
  try {
@@ -167,6 +170,9 @@ async function installOpenClawNativeThreatFeedCron(options, runCommand = execCom
167
170
  message,
168
171
  '--timeout-seconds',
169
172
  '300',
173
+ '--announce',
174
+ '--channel',
175
+ 'last',
170
176
  '--thinking',
171
177
  'off',
172
178
  ];
@@ -301,8 +307,9 @@ async function installSystemThreatFeedCron(options, runCommand = execCommand) {
301
307
  script,
302
308
  };
303
309
  }
304
- function threatFeedCommand(quiet) {
305
- return `agentguard subscribe${quiet ? ' --quiet' : ''} --json --cron-run`;
310
+ function threatFeedCommand(quiet, options = {}) {
311
+ const modeFlag = options.notifyRun ? '--cron-notify-run' : '--json --cron-run';
312
+ return `agentguard subscribe${quiet ? ' --quiet' : ''} ${modeFlag}`;
306
313
  }
307
314
  function qclawGatewayOptions(gateway = {}) {
308
315
  return {
@@ -367,17 +374,17 @@ function shellQuote(value) {
367
374
  }
368
375
  function openClawCronMessage(quiet) {
369
376
  const mode = quiet ? 'quiet' : 'manual';
370
- const command = threatFeedCommand(quiet);
377
+ const command = threatFeedCommand(quiet, { notifyRun: true });
371
378
  return [
372
379
  `Mode: ${mode}.`,
373
380
  `Command: \`${command}\`.`,
374
381
  `Run exactly the command above.`,
375
382
  '',
376
383
  'Rules:',
377
- '- If the JSON field `hardFailures` is greater than 0, output a short error summary and do not send a notification.',
378
- '- If the JSON field `shouldNotify` is true, send `notification.body` exactly as-is using the current session notification context.',
379
- '- If `shouldNotify` is false, output "skipped" and finish without sending any message.',
380
- '- If the command fails or the JSON cannot be parsed, output a short error summary and do not send a notification.',
384
+ '- The command prints either the exact notification body or `NO_REPLY`.',
385
+ '- Output the command stdout exactly as your final response.',
386
+ '- Do not summarize, transform, add labels, or send a separate message.',
387
+ '- If the command fails or prints no stdout, output `NO_REPLY`.',
381
388
  '',
382
389
  'Follow these rules exactly.',
383
390
  ].join('\n');
@@ -464,16 +471,27 @@ function openClawGatewayRequest(method, params, options = {}) {
464
471
  if (options.request) {
465
472
  return options.request(method, params);
466
473
  }
467
- const payload = JSON.stringify({
468
- jsonrpc: '2.0',
469
- method,
470
- params,
471
- id: 1,
472
- });
473
474
  const host = options.host ?? '127.0.0.1';
474
475
  const port = options.port ?? 18789;
475
476
  const label = options.label ?? 'OpenClaw Gateway';
476
477
  const timeoutMs = options.timeoutMs ?? 5000;
478
+ if (options.url) {
479
+ return openClawGatewayWebSocketRequest({ url: options.url, method, params, label, timeoutMs });
480
+ }
481
+ return openClawGatewayHttpRequest({ host, port, method, params, label, timeoutMs }).catch((err) => {
482
+ if (err instanceof GatewayHttpFallbackError) {
483
+ return openClawGatewayWebSocketRequest({ url: `ws://${host}:${port}`, method, params, label, timeoutMs });
484
+ }
485
+ throw err;
486
+ });
487
+ }
488
+ function openClawGatewayHttpRequest(options) {
489
+ const payload = JSON.stringify({
490
+ jsonrpc: '2.0',
491
+ method: options.method,
492
+ params: legacyGatewayParams(options.method, options.params),
493
+ id: 1,
494
+ });
477
495
  return new Promise((resolve, reject) => {
478
496
  let settled = false;
479
497
  const fail = (err) => {
@@ -489,8 +507,8 @@ function openClawGatewayRequest(method, params, options = {}) {
489
507
  resolve(value);
490
508
  };
491
509
  const req = node_http_1.default.request({
492
- hostname: host,
493
- port,
510
+ hostname: options.host,
511
+ port: options.port,
494
512
  path: '/',
495
513
  method: 'POST',
496
514
  headers: {
@@ -501,7 +519,7 @@ function openClawGatewayRequest(method, params, options = {}) {
501
519
  let data = '';
502
520
  res.setEncoding('utf8');
503
521
  res.on('error', (err) => {
504
- fail(new Error(`${label} ${method} response failed: ${err.message}`));
522
+ fail(new Error(`${options.label} ${options.method} response failed: ${err.message}`));
505
523
  });
506
524
  res.on('data', (chunk) => {
507
525
  data += chunk;
@@ -512,25 +530,25 @@ function openClawGatewayRequest(method, params, options = {}) {
512
530
  parsed = data ? JSON.parse(data) : null;
513
531
  }
514
532
  catch {
515
- fail(new Error(`${label} returned non-JSON response: ${data}`));
533
+ fail(new GatewayHttpFallbackError(`${options.label} returned non-JSON response: ${data}`));
516
534
  return;
517
535
  }
518
- if (parsed?.error) {
519
- fail(new Error(`${label} ${method} failed: ${parsed.error.message ?? JSON.stringify(parsed.error)}`));
536
+ if (res.statusCode && res.statusCode >= 400) {
537
+ fail(new GatewayHttpFallbackError(`${options.label} ${options.method} failed with HTTP ${res.statusCode}`));
520
538
  return;
521
539
  }
522
- if (res.statusCode && res.statusCode >= 400) {
523
- fail(new Error(`${label} ${method} failed with HTTP ${res.statusCode}`));
540
+ if (parsed?.error) {
541
+ fail(new Error(`${options.label} ${options.method} failed: ${parsed.error.message ?? JSON.stringify(parsed.error)}`));
524
542
  return;
525
543
  }
526
544
  succeed(parsed?.result ?? parsed);
527
545
  });
528
546
  });
529
547
  req.on('error', (err) => {
530
- fail(new Error(`Could not reach ${label} at ${host}:${port}: ${err.message}`));
548
+ fail(new GatewayHttpFallbackError(`Could not reach ${options.label} at ${options.host}:${options.port}: ${err.message}`));
531
549
  });
532
- req.setTimeout(timeoutMs, () => {
533
- const err = new Error(`${label} ${method} request timed out after ${timeoutMs}ms`);
550
+ req.setTimeout(options.timeoutMs, () => {
551
+ const err = new GatewayHttpFallbackError(`${options.label} ${options.method} request timed out after ${options.timeoutMs}ms`);
534
552
  fail(err);
535
553
  req.destroy(err);
536
554
  });
@@ -538,4 +556,302 @@ function openClawGatewayRequest(method, params, options = {}) {
538
556
  req.end();
539
557
  });
540
558
  }
559
+ function legacyGatewayParams(method, params) {
560
+ if (method === 'cron.add' && !Array.isArray(params))
561
+ return [params];
562
+ return params;
563
+ }
564
+ function openClawGatewayWebSocketRequest(options) {
565
+ const endpoint = parseGatewayWebSocketUrl(options.url, options.label);
566
+ return new Promise((resolve, reject) => {
567
+ const connectRequestId = (0, node_crypto_1.randomUUID)();
568
+ const methodRequestId = (0, node_crypto_1.randomUUID)();
569
+ const websocketKey = (0, node_crypto_1.randomBytes)(16).toString('base64');
570
+ let handshakeComplete = false;
571
+ let connected = false;
572
+ let settled = false;
573
+ let buffer = Buffer.alloc(0);
574
+ let fragmentedText = null;
575
+ const fail = (err) => {
576
+ if (settled)
577
+ return;
578
+ settled = true;
579
+ clearTimeout(timeout);
580
+ socket.destroy();
581
+ reject(err);
582
+ };
583
+ const succeed = (value) => {
584
+ if (settled)
585
+ return;
586
+ settled = true;
587
+ clearTimeout(timeout);
588
+ socket.end();
589
+ resolve(value);
590
+ };
591
+ const socket = node_net_1.default.createConnection({ host: endpoint.hostname, port: endpoint.port }, () => {
592
+ socket.write(buildWebSocketHandshake(endpoint, websocketKey));
593
+ });
594
+ const timeout = setTimeout(() => {
595
+ fail(new Error(`${options.label} ${options.method} request timed out after ${options.timeoutMs}ms`));
596
+ }, options.timeoutMs);
597
+ socket.on('error', (err) => {
598
+ fail(new Error(`Could not reach ${options.label} at ${endpoint.hostname}:${endpoint.port}: ${err.message}`));
599
+ });
600
+ socket.on('data', (chunk) => {
601
+ buffer = Buffer.concat([buffer, chunk]);
602
+ if (!handshakeComplete) {
603
+ const headerEnd = buffer.indexOf('\r\n\r\n');
604
+ if (headerEnd === -1)
605
+ return;
606
+ const header = buffer.subarray(0, headerEnd + 4).toString('utf8');
607
+ buffer = buffer.subarray(headerEnd + 4);
608
+ try {
609
+ validateWebSocketHandshake(header, websocketKey, options.label);
610
+ }
611
+ catch (err) {
612
+ fail(err);
613
+ return;
614
+ }
615
+ handshakeComplete = true;
616
+ }
617
+ while (true) {
618
+ let parsed;
619
+ try {
620
+ parsed = readWebSocketFrame(buffer);
621
+ }
622
+ catch (err) {
623
+ fail(err);
624
+ return;
625
+ }
626
+ if (!parsed)
627
+ break;
628
+ buffer = parsed.rest;
629
+ if (parsed.opcode === 0x8) {
630
+ fail(new Error(`${options.label} closed the WebSocket before ${options.method} completed`));
631
+ return;
632
+ }
633
+ if (parsed.opcode === 0x9) {
634
+ socket.write(encodeWebSocketFrame(parsed.payload.toString('utf8'), 0xA));
635
+ continue;
636
+ }
637
+ if (parsed.opcode === 0xA)
638
+ continue;
639
+ if (parsed.opcode === 0x1) {
640
+ if (fragmentedText) {
641
+ fail(new Error(`${options.label} started a new WebSocket text message before completing the previous one`));
642
+ return;
643
+ }
644
+ if (parsed.fin) {
645
+ handleGatewayFrame(parsed.payload.toString('utf8'));
646
+ }
647
+ else {
648
+ fragmentedText = [parsed.payload];
649
+ }
650
+ continue;
651
+ }
652
+ if (parsed.opcode === 0x0) {
653
+ if (!fragmentedText) {
654
+ fail(new Error(`${options.label} returned an unexpected WebSocket continuation frame`));
655
+ return;
656
+ }
657
+ fragmentedText.push(parsed.payload);
658
+ if (parsed.fin) {
659
+ const complete = Buffer.concat(fragmentedText);
660
+ fragmentedText = null;
661
+ handleGatewayFrame(complete.toString('utf8'));
662
+ }
663
+ }
664
+ }
665
+ });
666
+ function handleGatewayFrame(raw) {
667
+ let frame;
668
+ try {
669
+ frame = JSON.parse(raw);
670
+ }
671
+ catch {
672
+ fail(new Error(`${options.label} returned non-JSON WebSocket frame: ${raw}`));
673
+ return;
674
+ }
675
+ if (frame?.type === 'event' && frame.event === 'connect.challenge') {
676
+ socket.write(encodeWebSocketFrame(JSON.stringify({
677
+ type: 'req',
678
+ id: connectRequestId,
679
+ method: 'connect',
680
+ params: openClawConnectParams(),
681
+ })));
682
+ return;
683
+ }
684
+ if (frame?.type !== 'res')
685
+ return;
686
+ if (frame.id === connectRequestId) {
687
+ if (!frame.ok) {
688
+ fail(new Error(`${options.label} connect failed: ${gatewayFrameErrorMessage(frame)}`));
689
+ return;
690
+ }
691
+ connected = true;
692
+ socket.write(encodeWebSocketFrame(JSON.stringify({
693
+ type: 'req',
694
+ id: methodRequestId,
695
+ method: options.method,
696
+ params: options.params,
697
+ })));
698
+ return;
699
+ }
700
+ if (connected && frame.id === methodRequestId) {
701
+ if (!frame.ok) {
702
+ fail(new Error(`${options.label} ${options.method} failed: ${gatewayFrameErrorMessage(frame)}`));
703
+ return;
704
+ }
705
+ succeed(frame.payload);
706
+ }
707
+ }
708
+ });
709
+ }
710
+ function parseGatewayWebSocketUrl(raw, label) {
711
+ let parsed;
712
+ try {
713
+ parsed = new URL(raw);
714
+ }
715
+ catch {
716
+ throw new Error(`${label} URL is invalid: ${raw}`);
717
+ }
718
+ if (parsed.protocol !== 'ws:') {
719
+ throw new Error(`${label} URL must use ws:// for Gateway WebSocket RPC.`);
720
+ }
721
+ const port = parsed.port ? Number(parsed.port) : 80;
722
+ if (!Number.isInteger(port) || port <= 0 || port > 65535) {
723
+ throw new Error(`${label} URL has an invalid port: ${raw}`);
724
+ }
725
+ const path = `${parsed.pathname || '/'}${parsed.search}`;
726
+ const hostname = parsed.hostname;
727
+ const hostHeader = parsed.port ? parsed.host : `${parsed.hostname}:${port}`;
728
+ return { hostname, port, path, hostHeader };
729
+ }
730
+ function buildWebSocketHandshake(endpoint, key) {
731
+ return [
732
+ `GET ${endpoint.path || '/'} HTTP/1.1`,
733
+ `Host: ${endpoint.hostHeader}`,
734
+ 'Upgrade: websocket',
735
+ 'Connection: Upgrade',
736
+ `Sec-WebSocket-Key: ${key}`,
737
+ 'Sec-WebSocket-Version: 13',
738
+ '',
739
+ '',
740
+ ].join('\r\n');
741
+ }
742
+ function validateWebSocketHandshake(header, key, label) {
743
+ const [statusLine, ...lines] = header.split(/\r\n/);
744
+ if (!/^HTTP\/1\.[01] 101\b/.test(statusLine ?? '')) {
745
+ throw new Error(`${label} WebSocket upgrade failed: ${statusLine || 'empty response'}`);
746
+ }
747
+ const headers = new Map();
748
+ for (const line of lines) {
749
+ const index = line.indexOf(':');
750
+ if (index === -1)
751
+ continue;
752
+ headers.set(line.slice(0, index).trim().toLowerCase(), line.slice(index + 1).trim());
753
+ }
754
+ const expected = (0, node_crypto_1.createHash)('sha1')
755
+ .update(`${key}258EAFA5-E914-47DA-95CA-C5AB0DC85B11`)
756
+ .digest('base64');
757
+ if (headers.get('sec-websocket-accept') !== expected) {
758
+ throw new Error(`${label} WebSocket upgrade returned an invalid accept key.`);
759
+ }
760
+ }
761
+ function readWebSocketFrame(buffer) {
762
+ if (buffer.length < 2)
763
+ return null;
764
+ const first = buffer[0];
765
+ const second = buffer[1];
766
+ const fin = (first & 0x80) !== 0;
767
+ const opcode = first & 0x0f;
768
+ const masked = (second & 0x80) !== 0;
769
+ if (masked) {
770
+ throw new Error('WebSocket server frames must not be masked.');
771
+ }
772
+ if (opcode >= 0x8 && !fin) {
773
+ throw new Error('WebSocket control frames must not be fragmented.');
774
+ }
775
+ let length = second & 0x7f;
776
+ let offset = 2;
777
+ if (length === 126) {
778
+ if (buffer.length < offset + 2)
779
+ return null;
780
+ length = buffer.readUInt16BE(offset);
781
+ offset += 2;
782
+ }
783
+ else if (length === 127) {
784
+ if (buffer.length < offset + 8)
785
+ return null;
786
+ const longLength = buffer.readBigUInt64BE(offset);
787
+ if (longLength > BigInt(Number.MAX_SAFE_INTEGER)) {
788
+ throw new Error('WebSocket frame is too large.');
789
+ }
790
+ length = Number(longLength);
791
+ offset += 8;
792
+ }
793
+ if (opcode >= 0x8 && length > 125) {
794
+ throw new Error('WebSocket control frames must not exceed 125 bytes.');
795
+ }
796
+ const mask = masked ? buffer.subarray(offset, offset + 4) : null;
797
+ if (masked)
798
+ offset += 4;
799
+ if (buffer.length < offset + length)
800
+ return null;
801
+ const payload = Buffer.from(buffer.subarray(offset, offset + length));
802
+ if (mask) {
803
+ for (let i = 0; i < payload.length; i += 1) {
804
+ payload[i] = payload[i] ^ mask[i % 4];
805
+ }
806
+ }
807
+ return { fin, opcode, payload, rest: buffer.subarray(offset + length) };
808
+ }
809
+ function encodeWebSocketFrame(text, opcode = 0x1) {
810
+ const payload = Buffer.from(text, 'utf8');
811
+ const mask = (0, node_crypto_1.randomBytes)(4);
812
+ const headerLength = payload.length < 126 ? 2 : payload.length <= 0xffff ? 4 : 10;
813
+ const header = Buffer.alloc(headerLength);
814
+ header[0] = 0x80 | opcode;
815
+ if (payload.length < 126) {
816
+ header[1] = 0x80 | payload.length;
817
+ }
818
+ else if (payload.length <= 0xffff) {
819
+ header[1] = 0x80 | 126;
820
+ header.writeUInt16BE(payload.length, 2);
821
+ }
822
+ else {
823
+ header[1] = 0x80 | 127;
824
+ header.writeBigUInt64BE(BigInt(payload.length), 2);
825
+ }
826
+ const masked = Buffer.from(payload);
827
+ for (let i = 0; i < masked.length; i += 1) {
828
+ masked[i] = masked[i] ^ mask[i % 4];
829
+ }
830
+ return Buffer.concat([header, mask, masked]);
831
+ }
832
+ function openClawConnectParams() {
833
+ return {
834
+ minProtocol: 3,
835
+ maxProtocol: 3,
836
+ client: {
837
+ id: 'cli',
838
+ version: 'agentguard',
839
+ platform: process.platform,
840
+ mode: 'cli',
841
+ },
842
+ caps: [],
843
+ role: 'operator',
844
+ scopes: [
845
+ 'operator.admin',
846
+ 'operator.read',
847
+ 'operator.write',
848
+ 'operator.approvals',
849
+ 'operator.pairing',
850
+ 'operator.talk.secrets',
851
+ ],
852
+ };
853
+ }
854
+ function gatewayFrameErrorMessage(frame) {
855
+ return frame?.error?.message ?? JSON.stringify(frame?.error ?? frame);
856
+ }
541
857
  //# sourceMappingURL=cron.js.map