@useorgx/openclaw-plugin 0.4.9 → 0.7.2

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 (224) hide show
  1. package/README.md +77 -11
  2. package/dashboard/dist/assets/6mILZQ2a.js +1 -0
  3. package/dashboard/dist/assets/6mILZQ2a.js.br +0 -0
  4. package/dashboard/dist/assets/6mILZQ2a.js.gz +0 -0
  5. package/dashboard/dist/assets/8dksYiq4.js +2 -0
  6. package/dashboard/dist/assets/8dksYiq4.js.br +0 -0
  7. package/dashboard/dist/assets/8dksYiq4.js.gz +0 -0
  8. package/dashboard/dist/assets/B5zYRHc3.js +1 -0
  9. package/dashboard/dist/assets/B5zYRHc3.js.br +0 -0
  10. package/dashboard/dist/assets/B5zYRHc3.js.gz +0 -0
  11. package/dashboard/dist/assets/B6wPWJ35.js +1 -0
  12. package/dashboard/dist/assets/B6wPWJ35.js.br +0 -0
  13. package/dashboard/dist/assets/B6wPWJ35.js.gz +0 -0
  14. package/dashboard/dist/assets/BJgZIVUQ.js +53 -0
  15. package/dashboard/dist/assets/BJgZIVUQ.js.br +0 -0
  16. package/dashboard/dist/assets/BJgZIVUQ.js.gz +0 -0
  17. package/dashboard/dist/assets/BWEwjt1W.js +1 -0
  18. package/dashboard/dist/assets/BWEwjt1W.js.br +0 -0
  19. package/dashboard/dist/assets/BWEwjt1W.js.gz +0 -0
  20. package/dashboard/dist/assets/BgOYB78t.js +4 -0
  21. package/dashboard/dist/assets/BgOYB78t.js.br +0 -0
  22. package/dashboard/dist/assets/BgOYB78t.js.gz +0 -0
  23. package/dashboard/dist/assets/BzRbDCAD.css +1 -0
  24. package/dashboard/dist/assets/BzRbDCAD.css.br +0 -0
  25. package/dashboard/dist/assets/BzRbDCAD.css.gz +0 -0
  26. package/dashboard/dist/assets/C-KIc3Wc.js.br +0 -0
  27. package/dashboard/dist/assets/C-KIc3Wc.js.gz +0 -0
  28. package/dashboard/dist/assets/C8uM3AX8.js +1 -0
  29. package/dashboard/dist/assets/C8uM3AX8.js.br +0 -0
  30. package/dashboard/dist/assets/C8uM3AX8.js.gz +0 -0
  31. package/dashboard/dist/assets/C9jy61eu.js +212 -0
  32. package/dashboard/dist/assets/C9jy61eu.js.br +0 -0
  33. package/dashboard/dist/assets/C9jy61eu.js.gz +0 -0
  34. package/dashboard/dist/assets/CC63EwFD.js +1 -0
  35. package/dashboard/dist/assets/CC63EwFD.js.br +0 -0
  36. package/dashboard/dist/assets/CC63EwFD.js.gz +0 -0
  37. package/dashboard/dist/assets/CL_wXqR7.js +1 -0
  38. package/dashboard/dist/assets/CL_wXqR7.js.br +0 -0
  39. package/dashboard/dist/assets/CL_wXqR7.js.gz +0 -0
  40. package/dashboard/dist/assets/CZaT3ob_.js +1 -0
  41. package/dashboard/dist/assets/CZaT3ob_.js.br +0 -0
  42. package/dashboard/dist/assets/CZaT3ob_.js.gz +0 -0
  43. package/dashboard/dist/assets/CgaottFX.js +1 -0
  44. package/dashboard/dist/assets/CgaottFX.js.br +0 -0
  45. package/dashboard/dist/assets/CgaottFX.js.gz +0 -0
  46. package/dashboard/dist/assets/{CpJsfbXo.js → CxQ08qFN.js} +2 -2
  47. package/dashboard/dist/assets/CxQ08qFN.js.br +0 -0
  48. package/dashboard/dist/assets/CxQ08qFN.js.gz +0 -0
  49. package/dashboard/dist/assets/CzCxAZlW.js +1 -0
  50. package/dashboard/dist/assets/CzCxAZlW.js.br +0 -0
  51. package/dashboard/dist/assets/CzCxAZlW.js.gz +0 -0
  52. package/dashboard/dist/assets/D3iMTYEj.js +1 -0
  53. package/dashboard/dist/assets/D3iMTYEj.js.br +0 -0
  54. package/dashboard/dist/assets/D3iMTYEj.js.gz +0 -0
  55. package/dashboard/dist/assets/D8JNX8kq.js +2 -0
  56. package/dashboard/dist/assets/D8JNX8kq.js.br +0 -0
  57. package/dashboard/dist/assets/D8JNX8kq.js.gz +0 -0
  58. package/dashboard/dist/assets/DnA8dpj6.js +1 -0
  59. package/dashboard/dist/assets/DnA8dpj6.js.br +0 -0
  60. package/dashboard/dist/assets/DnA8dpj6.js.gz +0 -0
  61. package/dashboard/dist/assets/IUexzymk.js +1 -0
  62. package/dashboard/dist/assets/IUexzymk.js.br +0 -0
  63. package/dashboard/dist/assets/IUexzymk.js.gz +0 -0
  64. package/dashboard/dist/assets/cNrhgGc1.js +8 -0
  65. package/dashboard/dist/assets/cNrhgGc1.js.br +0 -0
  66. package/dashboard/dist/assets/cNrhgGc1.js.gz +0 -0
  67. package/dashboard/dist/assets/ic2FaMnh.js +1 -0
  68. package/dashboard/dist/assets/ic2FaMnh.js.br +0 -0
  69. package/dashboard/dist/assets/ic2FaMnh.js.gz +0 -0
  70. package/dashboard/dist/assets/qm8xLgv-.css +1 -0
  71. package/dashboard/dist/assets/qm8xLgv-.css.br +0 -0
  72. package/dashboard/dist/assets/qm8xLgv-.css.gz +0 -0
  73. package/dashboard/dist/assets/rttbDbEx.js +1 -0
  74. package/dashboard/dist/assets/rttbDbEx.js.br +0 -0
  75. package/dashboard/dist/assets/rttbDbEx.js.gz +0 -0
  76. package/dashboard/dist/brand/anthropic-mark.svg.br +0 -0
  77. package/dashboard/dist/brand/anthropic-mark.svg.gz +0 -0
  78. package/dashboard/dist/brand/openai-mark.svg.br +0 -0
  79. package/dashboard/dist/brand/openai-mark.svg.gz +0 -0
  80. package/dashboard/dist/brand/openclaw-mark.svg.br +0 -0
  81. package/dashboard/dist/brand/openclaw-mark.svg.gz +0 -0
  82. package/dashboard/dist/brand/xandy-orchestrator.png +0 -0
  83. package/dashboard/dist/index.html +7 -5
  84. package/dashboard/dist/index.html.br +0 -0
  85. package/dashboard/dist/index.html.gz +0 -0
  86. package/dist/activity-actor-fields.js +26 -4
  87. package/dist/activity-store.js +34 -8
  88. package/dist/agent-context-store.js +79 -17
  89. package/dist/agent-run-store.js +44 -3
  90. package/dist/agent-suite.d.ts +9 -0
  91. package/dist/agent-suite.js +149 -9
  92. package/dist/artifacts/artifact-domain-schemas.d.ts +66 -0
  93. package/dist/artifacts/artifact-domain-schemas.js +357 -0
  94. package/dist/artifacts/register-artifact.d.ts +4 -3
  95. package/dist/artifacts/register-artifact.js +170 -57
  96. package/dist/chat-store.d.ts +157 -0
  97. package/dist/chat-store.js +586 -0
  98. package/dist/cli/orgx.js +11 -0
  99. package/dist/contracts/client.d.ts +43 -3
  100. package/dist/contracts/client.js +159 -30
  101. package/dist/contracts/practice-exercise-schema.d.ts +216 -0
  102. package/dist/contracts/practice-exercise-schema.js +314 -0
  103. package/dist/contracts/retro-schema.d.ts +81 -0
  104. package/dist/contracts/retro-schema.js +80 -0
  105. package/dist/contracts/shared-types.d.ts +159 -0
  106. package/dist/contracts/shared-types.js +199 -1
  107. package/dist/contracts/skill-pack-schema.d.ts +192 -0
  108. package/dist/contracts/skill-pack-schema.js +180 -0
  109. package/dist/contracts/types.d.ts +247 -2
  110. package/dist/entities/auto-assignment.js +43 -17
  111. package/dist/event-sanitization.d.ts +11 -0
  112. package/dist/event-sanitization.js +113 -0
  113. package/dist/gateway-watchdog.d.ts +5 -0
  114. package/dist/gateway-watchdog.js +50 -0
  115. package/dist/hooks/post-reporting-event.mjs +1 -5
  116. package/dist/http/helpers/activity-headline.js +13 -132
  117. package/dist/http/helpers/auto-continue-engine.d.ts +198 -10
  118. package/dist/http/helpers/auto-continue-engine.js +3145 -186
  119. package/dist/http/helpers/autopilot-operations.d.ts +19 -0
  120. package/dist/http/helpers/autopilot-operations.js +182 -31
  121. package/dist/http/helpers/autopilot-runtime.d.ts +1 -0
  122. package/dist/http/helpers/autopilot-runtime.js +328 -25
  123. package/dist/http/helpers/autopilot-slice-utils.d.ts +18 -0
  124. package/dist/http/helpers/autopilot-slice-utils.js +514 -93
  125. package/dist/http/helpers/decision-mapper.d.ts +40 -0
  126. package/dist/http/helpers/decision-mapper.js +223 -7
  127. package/dist/http/helpers/dispatch-lifecycle.d.ts +19 -2
  128. package/dist/http/helpers/dispatch-lifecycle.js +242 -37
  129. package/dist/http/helpers/kickoff-context.js +104 -0
  130. package/dist/http/helpers/llm-client.d.ts +47 -0
  131. package/dist/http/helpers/llm-client.js +256 -0
  132. package/dist/http/helpers/mission-control.d.ts +102 -3
  133. package/dist/http/helpers/mission-control.js +498 -9
  134. package/dist/http/helpers/sentinel-catalog.d.ts +23 -0
  135. package/dist/http/helpers/sentinel-catalog.js +193 -0
  136. package/dist/http/helpers/session-classification.d.ts +9 -0
  137. package/dist/http/helpers/session-classification.js +564 -0
  138. package/dist/http/helpers/slice-experience-v2.d.ts +137 -0
  139. package/dist/http/helpers/slice-experience-v2.js +677 -0
  140. package/dist/http/helpers/slice-run-projections.d.ts +72 -0
  141. package/dist/http/helpers/slice-run-projections.js +877 -0
  142. package/dist/http/helpers/triage-mapper.d.ts +43 -0
  143. package/dist/http/helpers/triage-mapper.js +549 -0
  144. package/dist/http/helpers/value-utils.js +7 -2
  145. package/dist/http/helpers/workspace-scope.d.ts +15 -0
  146. package/dist/http/helpers/workspace-scope.js +170 -0
  147. package/dist/http/index.js +1420 -105
  148. package/dist/http/routes/agent-suite.d.ts +9 -0
  149. package/dist/http/routes/agent-suite.js +294 -8
  150. package/dist/http/routes/agents-catalog.js +64 -19
  151. package/dist/http/routes/chat.d.ts +19 -0
  152. package/dist/http/routes/chat.js +522 -0
  153. package/dist/http/routes/decision-actions.d.ts +8 -1
  154. package/dist/http/routes/decision-actions.js +42 -5
  155. package/dist/http/routes/dispatch-gateway-envelope.d.ts +25 -0
  156. package/dist/http/routes/dispatch-gateway-envelope.js +26 -0
  157. package/dist/http/routes/entities.d.ts +16 -0
  158. package/dist/http/routes/entities.js +232 -6
  159. package/dist/http/routes/live-legacy.d.ts +5 -0
  160. package/dist/http/routes/live-legacy.js +23 -509
  161. package/dist/http/routes/live-misc.d.ts +12 -0
  162. package/dist/http/routes/live-misc.js +251 -31
  163. package/dist/http/routes/live-snapshot.d.ts +49 -2
  164. package/dist/http/routes/live-snapshot.js +653 -23
  165. package/dist/http/routes/live-terminal.d.ts +11 -0
  166. package/dist/http/routes/live-terminal.js +154 -0
  167. package/dist/http/routes/live-triage.d.ts +61 -0
  168. package/dist/http/routes/live-triage.js +192 -0
  169. package/dist/http/routes/mission-control-actions.d.ts +49 -1
  170. package/dist/http/routes/mission-control-actions.js +1246 -84
  171. package/dist/http/routes/mission-control-read.d.ts +48 -3
  172. package/dist/http/routes/mission-control-read.js +1658 -20
  173. package/dist/http/routes/realtime-orchestrator.d.ts +10 -0
  174. package/dist/http/routes/realtime-orchestrator.js +74 -0
  175. package/dist/http/routes/run-control.d.ts +5 -2
  176. package/dist/http/routes/run-control.js +10 -0
  177. package/dist/http/routes/sentinels-catalog.d.ts +7 -0
  178. package/dist/http/routes/sentinels-catalog.js +24 -0
  179. package/dist/http/routes/summary.js +10 -3
  180. package/dist/http/routes/usage.d.ts +24 -0
  181. package/dist/http/routes/usage.js +362 -0
  182. package/dist/http/routes/work-artifacts.js +28 -9
  183. package/dist/index.js +165 -27
  184. package/dist/local-openclaw.js +29 -6
  185. package/dist/mcp-client-setup.js +3 -3
  186. package/dist/mcp-http-handler.d.ts +3 -0
  187. package/dist/mcp-http-handler.js +34 -60
  188. package/dist/next-up-queue-store.d.ts +16 -1
  189. package/dist/next-up-queue-store.js +89 -7
  190. package/dist/outbox.d.ts +5 -0
  191. package/dist/outbox.js +113 -9
  192. package/dist/paths.js +36 -5
  193. package/dist/reporting/rollups.d.ts +41 -0
  194. package/dist/reporting/rollups.js +113 -0
  195. package/dist/retro/domain-templates.d.ts +45 -0
  196. package/dist/retro/domain-templates.js +297 -0
  197. package/dist/retro/quality-rubric.d.ts +33 -0
  198. package/dist/retro/quality-rubric.js +213 -0
  199. package/dist/runtime-cleanup.d.ts +18 -0
  200. package/dist/runtime-cleanup.js +87 -0
  201. package/dist/services/background.d.ts +11 -0
  202. package/dist/services/background.js +22 -0
  203. package/dist/services/experiment-randomization.d.ts +21 -0
  204. package/dist/services/experiment-randomization.js +63 -0
  205. package/dist/skill-pack-state.d.ts +36 -5
  206. package/dist/skill-pack-state.js +273 -29
  207. package/dist/sync/local-agent-telemetry.d.ts +13 -0
  208. package/dist/sync/local-agent-telemetry.js +128 -0
  209. package/dist/sync/outbox-replay.js +131 -24
  210. package/dist/team-context-store.d.ts +23 -0
  211. package/dist/team-context-store.js +116 -0
  212. package/dist/telemetry/posthog.js +4 -2
  213. package/dist/tools/core-tools.d.ts +10 -14
  214. package/dist/tools/core-tools.js +1289 -24
  215. package/dist/types.d.ts +2 -0
  216. package/dist/types.js +2 -0
  217. package/dist/worker-supervisor.js +23 -0
  218. package/package.json +20 -6
  219. package/dashboard/dist/assets/B3ziCA02.js +0 -8
  220. package/dashboard/dist/assets/B5NEElEI.css +0 -1
  221. package/dashboard/dist/assets/BhapSNAs.js +0 -215
  222. package/dashboard/dist/assets/iFdvE7lx.js +0 -1
  223. package/dashboard/dist/assets/jRJsmpYM.js +0 -1
  224. package/dashboard/dist/assets/sAhvFnpk.js +0 -4
package/dist/index.js CHANGED
@@ -23,20 +23,26 @@ import { clearPersistedSnapshot, readPersistedSnapshot, writePersistedSnapshot,
23
23
  import { appendToOutbox, readOutboxSummary, } from "./outbox.js";
24
24
  import { getAgentContext, readAgentContexts } from "./agent-context-store.js";
25
25
  import { readAgentRuns, markAgentRunStopped } from "./agent-run-store.js";
26
- import { ensureGatewayWatchdog } from "./gateway-watchdog.js";
26
+ import { ensureGatewayWatchdog, stopGatewayWatchdog } from "./gateway-watchdog.js";
27
27
  import { createMcpHttpHandler, } from "./mcp-http-handler.js";
28
28
  import { posthogCapture } from "./telemetry/posthog.js";
29
- import { readSkillPackState, refreshSkillPackState } from "./skill-pack-state.js";
30
- import { resolveConfig, resolveRuntimeUserId, } from "./config/resolution.js";
29
+ import { readSkillPackState, refreshSkillPackState, rollbackSkillPackPolicy, updateSkillPackPolicy, } from "./skill-pack-state.js";
30
+ import { resolveConfig, resolveDocsUrl, resolveRuntimeUserId, } from "./config/resolution.js";
31
31
  import { refreshResolvedConfig } from "./config/refresh.js";
32
32
  import { applyRuntimeApiKey, buildManualKeyConnectUrl as buildManualKeyConnectUrlForBase, fetchOrgxJson as fetchOrgxJsonRequest, isAuthRequiredError, } from "./auth/flows.js";
33
33
  import { registerOrgxCli } from "./cli/orgx.js";
34
34
  import { instrumentPluginApi } from "./services/instrumentation.js";
35
35
  import { registerSyncService } from "./services/background.js";
36
+ import { stopDetachedProcess } from "./http/helpers/openclaw-cli.js";
36
37
  import { createOutboxReplayer } from "./sync/outbox-replay.js";
38
+ import { buildLocalAgentMirrorsFromSnapshot, buildLocalSyncAgentsFromRuns, } from "./sync/local-agent-telemetry.js";
37
39
  import { registerCoreTools } from "./tools/core-tools.js";
38
40
  import { stableHash } from "./hash-utils.js";
41
+ import { RETRO_ARTIFACT_SCHEMA_VERSION } from "./contracts/retro-schema.js";
42
+ import { buildRetroWithLlm } from "./retro/domain-templates.js";
43
+ import { computeRetroQualityRubricScore } from "./retro/quality-rubric.js";
39
44
  export { OrgXClient } from "./api.js";
45
+ const ORGX_CANONICAL_BASE_URL = "https://www.useorgx.com";
40
46
  // =============================================================================
41
47
  // HELPERS
42
48
  // =============================================================================
@@ -333,6 +339,29 @@ export default function register(api) {
333
339
  toErrorMessage,
334
340
  });
335
341
  }
342
+ function looksLikeTransientFetchFailure(message) {
343
+ const normalized = message.toLowerCase();
344
+ return (normalized.includes("fetch failed") ||
345
+ normalized.includes("networkerror") ||
346
+ normalized.includes("econnrefused") ||
347
+ normalized.includes("enotfound") ||
348
+ normalized.includes("eai_again"));
349
+ }
350
+ function applyRuntimeBaseUrl(nextBaseUrl) {
351
+ const normalized = nextBaseUrl.trim().replace(/\/+$/, "");
352
+ if (!normalized)
353
+ return;
354
+ if (config.baseUrl === normalized && baseApiUrl === normalized)
355
+ return;
356
+ config.baseUrl = normalized;
357
+ baseApiUrl = normalized;
358
+ client.setCredentials({
359
+ apiKey: config.apiKey,
360
+ userId: config.userId,
361
+ baseUrl: config.baseUrl,
362
+ });
363
+ updateOnboardingState({ docsUrl: resolveDocsUrl(config.baseUrl) });
364
+ }
336
365
  function setRuntimeApiKey(input) {
337
366
  applyRuntimeApiKey({
338
367
  config,
@@ -353,6 +382,7 @@ export default function register(api) {
353
382
  let syncTimer = null;
354
383
  let syncInFlight = null;
355
384
  let syncServiceRunning = false;
385
+ let localAgentMirrors = [];
356
386
  let outboxReplayState = {
357
387
  status: "idle",
358
388
  lastReplayAttemptAt: null,
@@ -661,6 +691,24 @@ export default function register(api) {
661
691
  const completedAt = stopped.stoppedAt ?? new Date().toISOString();
662
692
  const success = !summary.hadError;
663
693
  const correlationId = stopped.runId;
694
+ const retroTemplate = await buildRetroWithLlm({
695
+ agentId: stopped.agentId,
696
+ success,
697
+ taskId: stopped.taskId,
698
+ runId: stopped.runId,
699
+ errorMessage: summary.errorMessage,
700
+ });
701
+ const retroSummary = retroTemplate.summary;
702
+ const retroQuality = computeRetroQualityRubricScore({
703
+ success,
704
+ hadError: summary.hadError,
705
+ errorMessage: summary.errorMessage,
706
+ tokens: summary.tokens,
707
+ costUsd: summary.costUsd,
708
+ decisionsCount: retroTemplate.decisions.length,
709
+ followUpsCount: retroTemplate.followUps.length,
710
+ whatWentWrongCount: retroTemplate.whatWentWrong.length,
711
+ });
664
712
  const outcomePayload = {
665
713
  initiative_id: initiativeId,
666
714
  correlation_id: correlationId,
@@ -682,6 +730,7 @@ export default function register(api) {
682
730
  },
683
731
  steps: [],
684
732
  success,
733
+ quality_score: retroQuality.score,
685
734
  human_interventions: 0,
686
735
  errors: summary.errorMessage ? [summary.errorMessage] : [],
687
736
  metadata: {
@@ -696,9 +745,6 @@ export default function register(api) {
696
745
  ? "task"
697
746
  : "initiative";
698
747
  const retroEntityId = stopped.taskId ?? initiativeId;
699
- const retroSummary = stopped.taskId
700
- ? `OpenClaw ${success ? "completed" : "blocked"} task ${stopped.taskId}.`
701
- : `OpenClaw run ${success ? "completed" : "blocked"} (session ${stopped.runId}).`;
702
748
  const retroPayload = {
703
749
  initiative_id: initiativeId,
704
750
  correlation_id: correlationId,
@@ -708,21 +754,12 @@ export default function register(api) {
708
754
  title: stopped.taskId ?? stopped.runId,
709
755
  idempotency_key: `retro:${stopped.runId}`,
710
756
  retro: {
757
+ schema_version: RETRO_ARTIFACT_SCHEMA_VERSION,
711
758
  summary: retroSummary,
712
- what_went_well: success ? ["Completed without runtime error."] : [],
713
- what_went_wrong: success
714
- ? []
715
- : [summary.errorMessage ?? "Session ended with error."],
716
- decisions: [],
717
- follow_ups: success
718
- ? []
719
- : [
720
- {
721
- title: "Investigate OpenClaw session failure and unblock task",
722
- priority: "p0",
723
- reason: summary.errorMessage ?? "Session ended with error.",
724
- },
725
- ],
759
+ what_went_well: retroTemplate.whatWentWell,
760
+ what_went_wrong: retroTemplate.whatWentWrong,
761
+ decisions: retroTemplate.decisions,
762
+ follow_ups: retroTemplate.followUps,
726
763
  signals: {
727
764
  tokens: summary.tokens,
728
765
  cost_usd: summary.costUsd,
@@ -731,8 +768,11 @@ export default function register(api) {
731
768
  session_id: stopped.runId,
732
769
  task_id: stopped.taskId,
733
770
  workstream_id: stopped.workstreamId,
771
+ domain: retroTemplate.domain,
734
772
  provider: stopped.provider,
735
773
  model: stopped.model,
774
+ quality_score: retroQuality.score,
775
+ quality_rubric_reasons: retroQuality.reasons,
736
776
  source: "openclaw_agent_run_reconcile",
737
777
  },
738
778
  },
@@ -848,7 +888,11 @@ export default function register(api) {
848
888
  await reconcileStoppedAgentRuns();
849
889
  let snapshotError = null;
850
890
  try {
851
- updateCachedSnapshot(await client.getOrgSnapshot());
891
+ const snapshot = await client.getOrgSnapshot();
892
+ updateCachedSnapshot(snapshot);
893
+ localAgentMirrors = buildLocalAgentMirrorsFromSnapshot({
894
+ agents: snapshot.agents,
895
+ });
852
896
  }
853
897
  catch (err) {
854
898
  if (isAuthFailure(err)) {
@@ -859,6 +903,24 @@ export default function register(api) {
859
903
  error: snapshotError,
860
904
  });
861
905
  }
906
+ const localAgents = buildLocalSyncAgentsFromRuns({
907
+ ...readAgentRuns(),
908
+ mirrors: localAgentMirrors,
909
+ });
910
+ if (localAgents.length > 0) {
911
+ try {
912
+ await client.syncMemory({ agents: localAgents });
913
+ }
914
+ catch (err) {
915
+ if (isAuthFailure(err)) {
916
+ throw err;
917
+ }
918
+ api.log?.warn?.("[orgx] Local agent telemetry sync failed (continuing)", {
919
+ error: toErrorMessage(err),
920
+ count: localAgents.length,
921
+ });
922
+ }
923
+ }
862
924
  // Best-effort: poll the canonical OrgX SkillPack so the dashboard/install path
863
925
  // can apply it without blocking on an on-demand fetch.
864
926
  try {
@@ -987,16 +1049,48 @@ export default function register(api) {
987
1049
  lastError: null,
988
1050
  nextAction: "connect",
989
1051
  });
990
- const started = await fetchOrgxJson("POST", "/api/plugin/openclaw/pairings", {
1052
+ const pairingPayload = {
991
1053
  installationId: config.installationId,
992
1054
  pluginVersion: config.pluginVersion,
993
1055
  openclawVersion: input.openclawVersion,
994
1056
  platform: input.platform || process.platform,
995
1057
  deviceName: input.deviceName,
996
- },
997
- // Pairing can hit a cold serverless boot + supabase insert + rate-limit checks.
998
- // Give it more headroom than typical lightweight API calls.
999
- { timeoutMs: 30_000 });
1058
+ };
1059
+ const requestPairing = (targetBaseApiUrl) => fetchOrgxJsonRequest({
1060
+ baseApiUrl: targetBaseApiUrl,
1061
+ method: "POST",
1062
+ path: "/api/plugin/openclaw/pairings",
1063
+ body: pairingPayload,
1064
+ // Pairing can hit a cold serverless boot + supabase insert + rate-limit checks.
1065
+ // Give it more headroom than typical lightweight API calls.
1066
+ options: { timeoutMs: 30_000 },
1067
+ toErrorMessage,
1068
+ });
1069
+ let started = await requestPairing(baseApiUrl);
1070
+ const shouldRetryAgainstCanonical = !started.ok &&
1071
+ started.status === 0 &&
1072
+ looksLikeTransientFetchFailure(started.error) &&
1073
+ baseApiUrl.replace(/\/+$/, "") !== ORGX_CANONICAL_BASE_URL;
1074
+ if (shouldRetryAgainstCanonical) {
1075
+ const initialStatus = started.ok ? 0 : started.status;
1076
+ const initialError = started.ok ? "Pairing request failed" : started.error;
1077
+ const fallbackStarted = await requestPairing(ORGX_CANONICAL_BASE_URL);
1078
+ if (fallbackStarted.ok) {
1079
+ api.log?.info?.("[orgx] Pairing start succeeded via canonical OrgX base URL", {
1080
+ previousBaseUrl: baseApiUrl,
1081
+ nextBaseUrl: ORGX_CANONICAL_BASE_URL,
1082
+ });
1083
+ applyRuntimeBaseUrl(ORGX_CANONICAL_BASE_URL);
1084
+ started = fallbackStarted;
1085
+ }
1086
+ else {
1087
+ started = {
1088
+ ok: false,
1089
+ status: fallbackStarted.status || initialStatus,
1090
+ error: `${initialError}; fallback via ${ORGX_CANONICAL_BASE_URL} failed: ${fallbackStarted.error}`,
1091
+ };
1092
+ }
1093
+ }
1000
1094
  if (!started.ok) {
1001
1095
  if (isAuthRequiredError(started)) {
1002
1096
  clearPairingState();
@@ -1021,7 +1115,10 @@ export default function register(api) {
1021
1115
  };
1022
1116
  }
1023
1117
  const statusLabel = started.status ? ` (HTTP ${started.status})` : "";
1024
- const message = `Pairing start failed${statusLabel}: ${started.error}`;
1118
+ const networkHint = started.status === 0
1119
+ ? ` Could not reach OrgX at ${baseApiUrl}. Check network/VPN/firewall or update ORGX_BASE_URL.`
1120
+ : "";
1121
+ const message = `Pairing start failed${statusLabel}: ${started.error}${networkHint}`;
1025
1122
  updateOnboardingState({
1026
1123
  status: "error",
1027
1124
  hasApiKey: Boolean(config.apiKey),
@@ -1194,10 +1291,49 @@ export default function register(api) {
1194
1291
  keySource: "none",
1195
1292
  });
1196
1293
  }
1294
+ async function stopTrackedAgentRunsOnPluginStop() {
1295
+ const runs = Object.values(readAgentRuns().runs ?? {}).filter((run) => run?.status === "running");
1296
+ let attempted = 0;
1297
+ let stopped = 0;
1298
+ let failed = 0;
1299
+ let markedStopped = 0;
1300
+ for (const run of runs) {
1301
+ if (!run || typeof run !== "object")
1302
+ continue;
1303
+ attempted += 1;
1304
+ let runStopped = false;
1305
+ if (typeof run.pid === "number" && Number.isFinite(run.pid) && run.pid > 0) {
1306
+ try {
1307
+ const result = await stopDetachedProcess(run.pid);
1308
+ runStopped = Boolean(result.stopped);
1309
+ }
1310
+ catch {
1311
+ runStopped = false;
1312
+ }
1313
+ }
1314
+ else {
1315
+ // No tracked PID means there is no local process to stop.
1316
+ runStopped = true;
1317
+ }
1318
+ if (runStopped) {
1319
+ stopped += 1;
1320
+ }
1321
+ else {
1322
+ failed += 1;
1323
+ }
1324
+ const marked = markAgentRunStopped(run.runId);
1325
+ if (marked) {
1326
+ markedStopped += 1;
1327
+ }
1328
+ }
1329
+ return { attempted, stopped, failed, markedStopped };
1330
+ }
1197
1331
  registerSyncService({
1198
1332
  api,
1199
1333
  syncIntervalMs: config.syncIntervalMs,
1200
1334
  ensureGatewayWatchdog: (logger) => ensureGatewayWatchdog(logger),
1335
+ stopGatewayWatchdog: () => stopGatewayWatchdog((api.log ?? {})),
1336
+ stopTrackedAgentRuns: stopTrackedAgentRunsOnPluginStop,
1201
1337
  doSync,
1202
1338
  scheduleNextSync,
1203
1339
  setSyncServiceRunning: (running) => {
@@ -1236,6 +1372,8 @@ export default function register(api) {
1236
1372
  pickNonEmptyString,
1237
1373
  resolveReportingContext,
1238
1374
  readSkillPackState,
1375
+ updateSkillPackPolicy,
1376
+ rollbackSkillPackPolicy,
1239
1377
  randomUUID,
1240
1378
  });
1241
1379
  // ---------------------------------------------------------------------------
@@ -1,6 +1,7 @@
1
1
  import { homedir } from "node:os";
2
2
  import { join } from "node:path";
3
3
  import { readFile, stat, writeFile } from "node:fs/promises";
4
+ import { callLlm } from "./http/helpers/llm-client.js";
4
5
  const ACTIVE_WINDOW_MS = 30 * 60_000;
5
6
  const LOCAL_SNAPSHOT_CACHE_TTL_MS = 1_500;
6
7
  let localSnapshotCache = null;
@@ -475,9 +476,9 @@ function groupEventsIntoTurns(events, maxTurns, limits) {
475
476
  return turns;
476
477
  }
477
478
  // ---------------------------------------------------------------------------
478
- // Rule-based turn summarization (fallback — LLM digest in Phase 1B)
479
+ // Turn summarization — LLM with heuristic fallback
479
480
  // ---------------------------------------------------------------------------
480
- function summarizeTurn(turn, _agentLabel) {
481
+ function heuristicSummarizeTurn(turn, _agentLabel) {
481
482
  const normalize = (value) => value.replace(/\s+/g, " ").trim();
482
483
  if (turn.errorMessage) {
483
484
  return `Error: ${normalize(turn.errorMessage)}`;
@@ -503,6 +504,28 @@ function summarizeTurn(turn, _agentLabel) {
503
504
  }
504
505
  return "Activity";
505
506
  }
507
+ async function summarizeTurnWithLlm(turn, agentLabel) {
508
+ const parts = [];
509
+ if (turn.userPrompt)
510
+ parts.push(`User: ${turn.userPrompt}`);
511
+ if (turn.toolNames.length > 0)
512
+ parts.push(`Tools: ${turn.toolNames.join(", ")}`);
513
+ if (turn.assistantResponse)
514
+ parts.push(`Assistant: ${turn.assistantResponse}`);
515
+ if (turn.errorMessage)
516
+ parts.push(`Error: ${turn.errorMessage}`);
517
+ const compact = parts.join("\n").slice(0, 4000);
518
+ const response = await callLlm({
519
+ taskId: "turn_summary",
520
+ systemPrompt: "You summarize agent session turns for a dashboard activity feed. " +
521
+ "Write one clear sentence (max 120 chars) describing what happened. " +
522
+ "Focus on the action and outcome, not internal details. No markdown.",
523
+ userPrompt: compact,
524
+ maxTokens: 64,
525
+ temperature: 0.15,
526
+ }, () => heuristicSummarizeTurn(turn, agentLabel));
527
+ return response.result;
528
+ }
506
529
  function isDigestSummaryStale(cached, fresh) {
507
530
  if (!cached)
508
531
  return true;
@@ -552,9 +575,9 @@ async function writeDigestCache(baseDir, agentId, sessionId, cache) {
552
575
  // ---------------------------------------------------------------------------
553
576
  // Turn → LiveActivityItem mapping
554
577
  // ---------------------------------------------------------------------------
555
- function turnToActivity(turn, session, cachedSummary, index) {
578
+ async function turnToActivity(turn, session, cachedSummary, index) {
556
579
  const agentLabel = session.agentName ?? session.agentId ?? "OpenClaw";
557
- const summary = cachedSummary ?? summarizeTurn(turn, agentLabel);
580
+ const summary = cachedSummary ?? await summarizeTurnWithLlm(turn, agentLabel);
558
581
  // Determine activity type
559
582
  let type = "delegation";
560
583
  if (turn.errorMessage) {
@@ -663,11 +686,11 @@ export async function toLocalLiveActivity(snapshot, limit = 200) {
663
686
  const turn = turns[i];
664
687
  const cached = cachedMap.get(turn.id) ?? null;
665
688
  const agentLabel = session.agentName ?? session.agentId ?? "OpenClaw";
666
- const computedSummary = summarizeTurn(turn, agentLabel);
689
+ const computedSummary = await summarizeTurnWithLlm(turn, agentLabel);
667
690
  const fallbackSummary = isDigestSummaryStale(cached, computedSummary)
668
691
  ? computedSummary
669
692
  : cached;
670
- allActivities.push(turnToActivity(turn, session, fallbackSummary, i));
693
+ allActivities.push(await turnToActivity(turn, session, fallbackSummary, i));
671
694
  // Track for cache
672
695
  if (isDigestSummaryStale(cached, computedSummary)) {
673
696
  newCacheEntries.push({ turnId: turn.id, summary: fallbackSummary });
@@ -126,7 +126,7 @@ function upsertCodexMcpServerSection(input) {
126
126
  const currentText = input.current;
127
127
  const lines = currentText.split(/\r?\n/);
128
128
  const escapedKey = escapeRegExp(input.key);
129
- const headerRegex = new RegExp(`^\\[mcp_servers\\.(?:"${escapedKey}"|${escapedKey})\\]\\s*$`);
129
+ const headerRegex = new RegExp(`^\\[mcp_servers\\.(?:"${escapedKey}"|'${escapedKey}'|${escapedKey})\\]\\s*$`);
130
130
  let headerIndex = -1;
131
131
  for (let i = 0; i < lines.length; i += 1) {
132
132
  if (headerRegex.test(lines[i].trim())) {
@@ -193,12 +193,12 @@ function removeCodexLegacyScopedMcpSections(input) {
193
193
  let index = 0;
194
194
  while (index < lines.length) {
195
195
  const trimmed = lines[index].trim();
196
- const headerMatch = trimmed.match(/^\[mcp_servers\.(?:"([^"]+)"|([A-Za-z0-9_]+))\]\s*$/);
196
+ const headerMatch = trimmed.match(/^\[mcp_servers\.(?:"([^"]+)"|'([^']+)'|([A-Za-z0-9_]+))\]\s*$/);
197
197
  if (!headerMatch) {
198
198
  index += 1;
199
199
  continue;
200
200
  }
201
- const key = (headerMatch[1] ?? headerMatch[2] ?? "").trim();
201
+ const key = (headerMatch[1] ?? headerMatch[2] ?? headerMatch[3] ?? "").trim();
202
202
  const isLegacyScoped = key !== input.baseKey &&
203
203
  key.startsWith(scopedPrefix);
204
204
  if (!isLegacyScoped) {
@@ -45,6 +45,9 @@ export type RegisteredPrompt = {
45
45
  }>;
46
46
  messages: PromptMessage[];
47
47
  };
48
+ type OrgxMcpScopeKey = "engineering" | "product" | "design" | "marketing" | "sales" | "operations" | "orchestration";
49
+ export declare const ORGX_BASE_TOOLS: readonly ["orgx_status", "orgx_sync", "list_agent_configs", "get_agent_config", "orgx_emit_activity", "orgx_report_progress", "update_stream_progress", "orgx_register_artifact", "orgx_request_decision", "orgx_spawn_check", "orgx_quality_score", "orgx_proof_status", "orgx_record_outcome", "orgx_get_outcome_attribution", "orgx_verify_completion"];
50
+ export declare const ORGX_MCP_ALLOWED_TOOLS_BY_SCOPE: Record<OrgxMcpScopeKey, string[]>;
48
51
  export declare function createMcpHttpHandler(input: {
49
52
  tools: Map<string, RegisteredTool>;
50
53
  prompts?: Map<string, RegisteredPrompt>;
@@ -5,73 +5,47 @@ const DEFAULT_PROTOCOL_VERSION = "2024-11-05";
5
5
  //
6
6
  // NOTE: This scopes only the tools exposed by this plugin (OrgX reporting + mutation).
7
7
  // It cannot restrict OpenClaw-native tools (filesystem, shell, etc).
8
- const ORGX_MCP_ALLOWED_TOOLS_BY_SCOPE = {
9
- engineering: [
10
- "orgx_status",
11
- "orgx_sync",
12
- "orgx_emit_activity",
13
- "orgx_report_progress",
14
- "orgx_register_artifact",
15
- "orgx_request_decision",
16
- "orgx_spawn_check",
17
- ],
18
- product: [
19
- "orgx_status",
20
- "orgx_sync",
21
- "orgx_emit_activity",
22
- "orgx_report_progress",
23
- "orgx_register_artifact",
24
- "orgx_request_decision",
25
- "orgx_spawn_check",
26
- ],
27
- design: [
28
- "orgx_status",
29
- "orgx_sync",
30
- "orgx_emit_activity",
31
- "orgx_report_progress",
32
- "orgx_register_artifact",
33
- "orgx_request_decision",
34
- "orgx_spawn_check",
35
- ],
36
- marketing: [
37
- "orgx_status",
38
- "orgx_sync",
39
- "orgx_emit_activity",
40
- "orgx_report_progress",
41
- "orgx_register_artifact",
42
- "orgx_request_decision",
43
- "orgx_spawn_check",
44
- ],
45
- sales: [
46
- "orgx_status",
47
- "orgx_sync",
48
- "orgx_emit_activity",
49
- "orgx_report_progress",
50
- "orgx_register_artifact",
51
- "orgx_request_decision",
52
- "orgx_spawn_check",
53
- ],
8
+ // Base tools available to all domain scopes
9
+ export const ORGX_BASE_TOOLS = [
10
+ "orgx_status",
11
+ "orgx_sync",
12
+ "list_agent_configs",
13
+ "get_agent_config",
14
+ "orgx_emit_activity",
15
+ "orgx_report_progress",
16
+ "update_stream_progress",
17
+ "orgx_register_artifact",
18
+ "orgx_request_decision",
19
+ "orgx_spawn_check",
20
+ // Proof ladder tools (all domains)
21
+ "orgx_quality_score",
22
+ "orgx_proof_status",
23
+ "orgx_record_outcome",
24
+ "orgx_get_outcome_attribution",
25
+ "orgx_verify_completion",
26
+ ];
27
+ export const ORGX_MCP_ALLOWED_TOOLS_BY_SCOPE = {
28
+ engineering: [...ORGX_BASE_TOOLS],
29
+ product: [...ORGX_BASE_TOOLS],
30
+ design: [...ORGX_BASE_TOOLS],
31
+ marketing: [...ORGX_BASE_TOOLS],
32
+ sales: [...ORGX_BASE_TOOLS],
54
33
  operations: [
55
- "orgx_status",
56
- "orgx_sync",
57
- "orgx_emit_activity",
58
- "orgx_report_progress",
59
- "orgx_register_artifact",
60
- "orgx_request_decision",
61
- "orgx_spawn_check",
34
+ ...ORGX_BASE_TOOLS,
35
+ "update_agent_config",
62
36
  // Operations is allowed to do explicit changesets for remediation/runbooks.
63
37
  "orgx_apply_changeset",
38
+ // Stream reassignment is a targeted operational mutation.
39
+ "orgx_reassign_stream",
40
+ "orgx_reassign_streams",
64
41
  ],
65
42
  orchestration: [
66
- "orgx_status",
67
- "orgx_sync",
68
- "orgx_emit_activity",
69
- "orgx_report_progress",
70
- "orgx_register_artifact",
71
- "orgx_request_decision",
72
- "orgx_spawn_check",
43
+ ...ORGX_BASE_TOOLS,
44
+ "update_agent_config",
73
45
  // Orchestrator is the primary mutation surface by design.
74
46
  "orgx_apply_changeset",
47
+ "orgx_reassign_stream",
48
+ "orgx_reassign_streams",
75
49
  ],
76
50
  };
77
51
  function isRecord(value) {
@@ -6,10 +6,17 @@ export type NextUpPinnedEntry = {
6
6
  createdAt: string;
7
7
  updatedAt: string;
8
8
  };
9
+ export type NextUpSuppressedEntry = {
10
+ initiativeId: string;
11
+ workstreamId: string;
12
+ createdAt: string;
13
+ updatedAt: string;
14
+ };
9
15
  type PersistedNextUpQueue = {
10
- version: 1;
16
+ version: 1 | 2;
11
17
  updatedAt: string;
12
18
  pins: NextUpPinnedEntry[];
19
+ suppressions: NextUpSuppressedEntry[];
13
20
  };
14
21
  export declare function readNextUpQueuePins(): PersistedNextUpQueue;
15
22
  export declare function upsertNextUpQueuePin(input: {
@@ -28,4 +35,12 @@ export declare function setNextUpQueuePinOrder(input: {
28
35
  workstreamId: string;
29
36
  }>;
30
37
  }): PersistedNextUpQueue;
38
+ export declare function suppressNextUpQueueItem(input: {
39
+ initiativeId: string;
40
+ workstreamId: string;
41
+ }): PersistedNextUpQueue;
42
+ export declare function unsuppressNextUpQueueItem(input: {
43
+ initiativeId: string;
44
+ workstreamId: string;
45
+ }): PersistedNextUpQueue;
31
46
  export {};