@useorgx/openclaw-plugin 0.4.8 → 0.7.0

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 (284) hide show
  1. package/README.md +35 -0
  2. package/dashboard/dist/assets/BJgZIVUQ.js +53 -0
  3. package/dashboard/dist/assets/BJgZIVUQ.js.br +0 -0
  4. package/dashboard/dist/assets/BJgZIVUQ.js.gz +0 -0
  5. package/dashboard/dist/assets/BXWDRGm-.js +1 -0
  6. package/dashboard/dist/assets/BXWDRGm-.js.br +0 -0
  7. package/dashboard/dist/assets/BXWDRGm-.js.gz +0 -0
  8. package/dashboard/dist/assets/BgOYB78t.js +4 -0
  9. package/dashboard/dist/assets/BgOYB78t.js.br +0 -0
  10. package/dashboard/dist/assets/BgOYB78t.js.gz +0 -0
  11. package/dashboard/dist/assets/C-KIc3Wc.js.br +0 -0
  12. package/dashboard/dist/assets/C-KIc3Wc.js.gz +0 -0
  13. package/dashboard/dist/assets/CE38zU4U.js +1 -0
  14. package/dashboard/dist/assets/CE38zU4U.js.br +0 -0
  15. package/dashboard/dist/assets/CE38zU4U.js.gz +0 -0
  16. package/dashboard/dist/assets/CFGKRAzG.js +1 -0
  17. package/dashboard/dist/assets/CFGKRAzG.js.br +0 -0
  18. package/dashboard/dist/assets/CFGKRAzG.js.gz +0 -0
  19. package/dashboard/dist/assets/CGGR2GZh.js +1 -0
  20. package/dashboard/dist/assets/CGGR2GZh.js.br +0 -0
  21. package/dashboard/dist/assets/CGGR2GZh.js.gz +0 -0
  22. package/dashboard/dist/assets/CL_wXqR7.js +1 -0
  23. package/dashboard/dist/assets/CL_wXqR7.js.br +0 -0
  24. package/dashboard/dist/assets/CL_wXqR7.js.gz +0 -0
  25. package/dashboard/dist/assets/CPFiTmlw.js +8 -0
  26. package/dashboard/dist/assets/CPFiTmlw.js.br +0 -0
  27. package/dashboard/dist/assets/CPFiTmlw.js.gz +0 -0
  28. package/dashboard/dist/assets/CZZTvkQZ.js +1 -0
  29. package/dashboard/dist/assets/CZZTvkQZ.js.br +0 -0
  30. package/dashboard/dist/assets/CZZTvkQZ.js.gz +0 -0
  31. package/dashboard/dist/assets/{CpJsfbXo.js → CxQ08qFN.js} +2 -2
  32. package/dashboard/dist/assets/CxQ08qFN.js.br +0 -0
  33. package/dashboard/dist/assets/CxQ08qFN.js.gz +0 -0
  34. package/dashboard/dist/assets/D-bf6hEI.js +213 -0
  35. package/dashboard/dist/assets/D-bf6hEI.js.br +0 -0
  36. package/dashboard/dist/assets/D-bf6hEI.js.gz +0 -0
  37. package/dashboard/dist/assets/DG6y9wJI.js +2 -0
  38. package/dashboard/dist/assets/DG6y9wJI.js.br +0 -0
  39. package/dashboard/dist/assets/DG6y9wJI.js.gz +0 -0
  40. package/dashboard/dist/assets/DNxKz-GV.js +1 -0
  41. package/dashboard/dist/assets/DNxKz-GV.js.br +0 -0
  42. package/dashboard/dist/assets/DNxKz-GV.js.gz +0 -0
  43. package/dashboard/dist/assets/DW_rKUic.js +11 -0
  44. package/dashboard/dist/assets/DW_rKUic.js.br +0 -0
  45. package/dashboard/dist/assets/DW_rKUic.js.gz +0 -0
  46. package/dashboard/dist/assets/DbNoijHm.js +1 -0
  47. package/dashboard/dist/assets/DbNoijHm.js.br +0 -0
  48. package/dashboard/dist/assets/DbNoijHm.js.gz +0 -0
  49. package/dashboard/dist/assets/DjcdE6jC.js +2 -0
  50. package/dashboard/dist/assets/DjcdE6jC.js.br +0 -0
  51. package/dashboard/dist/assets/DjcdE6jC.js.gz +0 -0
  52. package/dashboard/dist/assets/FZYuCDnt.js +1 -0
  53. package/dashboard/dist/assets/FZYuCDnt.js.br +0 -0
  54. package/dashboard/dist/assets/FZYuCDnt.js.gz +0 -0
  55. package/dashboard/dist/assets/PAUiij_z.js +1 -0
  56. package/dashboard/dist/assets/PAUiij_z.js.br +0 -0
  57. package/dashboard/dist/assets/PAUiij_z.js.gz +0 -0
  58. package/dashboard/dist/assets/cNrhgGc1.js +8 -0
  59. package/dashboard/dist/assets/cNrhgGc1.js.br +0 -0
  60. package/dashboard/dist/assets/cNrhgGc1.js.gz +0 -0
  61. package/dashboard/dist/assets/h5biQs2I.css +1 -0
  62. package/dashboard/dist/assets/h5biQs2I.css.br +0 -0
  63. package/dashboard/dist/assets/h5biQs2I.css.gz +0 -0
  64. package/dashboard/dist/assets/ic2FaMnh.js +1 -0
  65. package/dashboard/dist/assets/ic2FaMnh.js.br +0 -0
  66. package/dashboard/dist/assets/ic2FaMnh.js.gz +0 -0
  67. package/dashboard/dist/assets/nByHNHoW.js +1 -0
  68. package/dashboard/dist/assets/nByHNHoW.js.br +0 -0
  69. package/dashboard/dist/assets/nByHNHoW.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/tS9mbYZi.js +1 -0
  74. package/dashboard/dist/assets/tS9mbYZi.js.br +0 -0
  75. package/dashboard/dist/assets/tS9mbYZi.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 +38 -26
  88. package/dist/agent-context-store.js +84 -42
  89. package/dist/agent-run-store.js +49 -28
  90. package/dist/agent-suite.d.ts +9 -0
  91. package/dist/agent-suite.js +150 -17
  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/auth/flows.d.ts +47 -0
  97. package/dist/auth/flows.js +169 -0
  98. package/dist/auth-store.js +6 -26
  99. package/dist/byok-store.js +5 -19
  100. package/dist/chat-store.d.ts +157 -0
  101. package/dist/chat-store.js +586 -0
  102. package/dist/cli/orgx.d.ts +66 -0
  103. package/dist/cli/orgx.js +102 -0
  104. package/dist/config/refresh.d.ts +32 -0
  105. package/dist/config/refresh.js +55 -0
  106. package/dist/config/resolution.d.ts +37 -0
  107. package/dist/config/resolution.js +178 -0
  108. package/dist/contracts/client.d.ts +43 -3
  109. package/dist/contracts/client.js +159 -30
  110. package/dist/contracts/retro-schema.d.ts +81 -0
  111. package/dist/contracts/retro-schema.js +80 -0
  112. package/dist/contracts/shared-types.d.ts +306 -0
  113. package/dist/contracts/shared-types.js +179 -0
  114. package/dist/contracts/skill-pack-schema.d.ts +192 -0
  115. package/dist/contracts/skill-pack-schema.js +180 -0
  116. package/dist/contracts/types.d.ts +224 -132
  117. package/dist/contracts/types.js +5 -0
  118. package/dist/entities/auto-assignment.d.ts +36 -0
  119. package/dist/entities/auto-assignment.js +141 -0
  120. package/dist/entity-comment-store.js +5 -25
  121. package/dist/event-sanitization.d.ts +11 -0
  122. package/dist/event-sanitization.js +113 -0
  123. package/dist/fs-utils.js +13 -1
  124. package/dist/gateway-watchdog.d.ts +5 -0
  125. package/dist/gateway-watchdog.js +50 -0
  126. package/dist/hash-utils.d.ts +2 -0
  127. package/dist/hash-utils.js +12 -0
  128. package/dist/hooks/post-reporting-event.mjs +1 -5
  129. package/dist/http/helpers/activity-headline.d.ts +10 -0
  130. package/dist/http/helpers/activity-headline.js +73 -0
  131. package/dist/http/helpers/artifact-fallback.d.ts +13 -0
  132. package/dist/http/helpers/artifact-fallback.js +148 -0
  133. package/dist/http/helpers/auto-continue-engine.d.ts +486 -0
  134. package/dist/http/helpers/auto-continue-engine.js +3563 -0
  135. package/dist/http/helpers/autopilot-operations.d.ts +176 -0
  136. package/dist/http/helpers/autopilot-operations.js +554 -0
  137. package/dist/http/helpers/autopilot-runtime.d.ts +43 -0
  138. package/dist/http/helpers/autopilot-runtime.js +607 -0
  139. package/dist/http/helpers/autopilot-slice-utils.d.ts +56 -0
  140. package/dist/http/helpers/autopilot-slice-utils.js +899 -0
  141. package/dist/http/helpers/decision-mapper.d.ts +52 -0
  142. package/dist/http/helpers/decision-mapper.js +260 -0
  143. package/dist/http/helpers/dispatch-lifecycle.d.ts +119 -0
  144. package/dist/http/helpers/dispatch-lifecycle.js +809 -0
  145. package/dist/http/helpers/hash-utils.d.ts +1 -0
  146. package/dist/http/helpers/hash-utils.js +1 -0
  147. package/dist/http/helpers/kickoff-context.d.ts +12 -0
  148. package/dist/http/helpers/kickoff-context.js +228 -0
  149. package/dist/http/helpers/llm-client.d.ts +47 -0
  150. package/dist/http/helpers/llm-client.js +256 -0
  151. package/dist/http/helpers/mission-control.d.ts +193 -0
  152. package/dist/http/helpers/mission-control.js +1383 -0
  153. package/dist/http/helpers/openclaw-cli.d.ts +37 -0
  154. package/dist/http/helpers/openclaw-cli.js +283 -0
  155. package/dist/http/helpers/runtime-sse.d.ts +20 -0
  156. package/dist/http/helpers/runtime-sse.js +110 -0
  157. package/dist/http/helpers/sentinel-catalog.d.ts +23 -0
  158. package/dist/http/helpers/sentinel-catalog.js +193 -0
  159. package/dist/http/helpers/session-classification.d.ts +9 -0
  160. package/dist/http/helpers/session-classification.js +564 -0
  161. package/dist/http/helpers/slice-experience-v2.d.ts +137 -0
  162. package/dist/http/helpers/slice-experience-v2.js +677 -0
  163. package/dist/http/helpers/slice-run-projections.d.ts +72 -0
  164. package/dist/http/helpers/slice-run-projections.js +860 -0
  165. package/dist/http/helpers/triage-mapper.d.ts +43 -0
  166. package/dist/http/helpers/triage-mapper.js +549 -0
  167. package/dist/http/helpers/value-utils.d.ts +6 -0
  168. package/dist/http/helpers/value-utils.js +72 -0
  169. package/dist/http/helpers/workspace-scope.d.ts +15 -0
  170. package/dist/http/helpers/workspace-scope.js +170 -0
  171. package/dist/http/index.d.ts +88 -0
  172. package/dist/http/index.js +3610 -0
  173. package/dist/http/router.d.ts +23 -0
  174. package/dist/http/router.js +23 -0
  175. package/dist/http/routes/agent-control.d.ts +79 -0
  176. package/dist/http/routes/agent-control.js +684 -0
  177. package/dist/http/routes/agent-suite.d.ts +38 -0
  178. package/dist/http/routes/agent-suite.js +397 -0
  179. package/dist/http/routes/agents-catalog.d.ts +40 -0
  180. package/dist/http/routes/agents-catalog.js +128 -0
  181. package/dist/http/routes/billing.d.ts +23 -0
  182. package/dist/http/routes/billing.js +55 -0
  183. package/dist/http/routes/chat.d.ts +19 -0
  184. package/dist/http/routes/chat.js +522 -0
  185. package/dist/http/routes/debug.d.ts +14 -0
  186. package/dist/http/routes/debug.js +21 -0
  187. package/dist/http/routes/decision-actions.d.ts +20 -0
  188. package/dist/http/routes/decision-actions.js +103 -0
  189. package/dist/http/routes/delegation.d.ts +19 -0
  190. package/dist/http/routes/delegation.js +32 -0
  191. package/dist/http/routes/dispatch-gateway-envelope.d.ts +25 -0
  192. package/dist/http/routes/dispatch-gateway-envelope.js +26 -0
  193. package/dist/http/routes/entities.d.ts +63 -0
  194. package/dist/http/routes/entities.js +440 -0
  195. package/dist/http/routes/entity-dynamic.d.ts +25 -0
  196. package/dist/http/routes/entity-dynamic.js +191 -0
  197. package/dist/http/routes/health.d.ts +22 -0
  198. package/dist/http/routes/health.js +49 -0
  199. package/dist/http/routes/live-legacy.d.ts +115 -0
  200. package/dist/http/routes/live-legacy.js +112 -0
  201. package/dist/http/routes/live-misc.d.ts +81 -0
  202. package/dist/http/routes/live-misc.js +426 -0
  203. package/dist/http/routes/live-snapshot.d.ts +136 -0
  204. package/dist/http/routes/live-snapshot.js +916 -0
  205. package/dist/http/routes/live-terminal.d.ts +11 -0
  206. package/dist/http/routes/live-terminal.js +261 -0
  207. package/dist/http/routes/live-triage.d.ts +61 -0
  208. package/dist/http/routes/live-triage.js +248 -0
  209. package/dist/http/routes/mission-control-actions.d.ts +131 -0
  210. package/dist/http/routes/mission-control-actions.js +1791 -0
  211. package/dist/http/routes/mission-control-read.d.ts +73 -0
  212. package/dist/http/routes/mission-control-read.js +1640 -0
  213. package/dist/http/routes/onboarding.d.ts +34 -0
  214. package/dist/http/routes/onboarding.js +101 -0
  215. package/dist/http/routes/realtime-orchestrator.d.ts +10 -0
  216. package/dist/http/routes/realtime-orchestrator.js +74 -0
  217. package/dist/http/routes/run-control.d.ts +27 -0
  218. package/dist/http/routes/run-control.js +96 -0
  219. package/dist/http/routes/runtime-hooks.d.ts +69 -0
  220. package/dist/http/routes/runtime-hooks.js +437 -0
  221. package/dist/http/routes/sentinels-catalog.d.ts +7 -0
  222. package/dist/http/routes/sentinels-catalog.js +24 -0
  223. package/dist/http/routes/settings-byok.d.ts +23 -0
  224. package/dist/http/routes/settings-byok.js +163 -0
  225. package/dist/http/routes/summary.d.ts +18 -0
  226. package/dist/http/routes/summary.js +49 -0
  227. package/dist/http/routes/usage.d.ts +24 -0
  228. package/dist/http/routes/usage.js +362 -0
  229. package/dist/http/routes/work-artifacts.d.ts +9 -0
  230. package/dist/http/routes/work-artifacts.js +55 -0
  231. package/dist/http/shared-state.d.ts +16 -0
  232. package/dist/http/shared-state.js +1 -0
  233. package/dist/http-handler.d.ts +1 -88
  234. package/dist/http-handler.js +1 -10605
  235. package/dist/index.js +287 -2284
  236. package/dist/json-utils.d.ts +1 -0
  237. package/dist/json-utils.js +8 -0
  238. package/dist/local-openclaw.js +29 -6
  239. package/dist/mcp-client-setup.js +3 -3
  240. package/dist/mcp-http-handler.js +33 -59
  241. package/dist/next-up-queue-store.d.ts +16 -1
  242. package/dist/next-up-queue-store.js +93 -25
  243. package/dist/outbox.d.ts +5 -0
  244. package/dist/outbox.js +113 -9
  245. package/dist/paths.js +24 -5
  246. package/dist/reporting/rollups.d.ts +53 -0
  247. package/dist/reporting/rollups.js +148 -0
  248. package/dist/retro/domain-templates.d.ts +45 -0
  249. package/dist/retro/domain-templates.js +297 -0
  250. package/dist/retro/quality-rubric.d.ts +33 -0
  251. package/dist/retro/quality-rubric.js +213 -0
  252. package/dist/runtime-cleanup.d.ts +18 -0
  253. package/dist/runtime-cleanup.js +87 -0
  254. package/dist/runtime-instance-store.js +5 -31
  255. package/dist/services/background.d.ts +34 -0
  256. package/dist/services/background.js +45 -0
  257. package/dist/services/experiment-randomization.d.ts +21 -0
  258. package/dist/services/experiment-randomization.js +63 -0
  259. package/dist/services/instrumentation.d.ts +29 -0
  260. package/dist/services/instrumentation.js +136 -0
  261. package/dist/skill-pack-state.d.ts +36 -5
  262. package/dist/skill-pack-state.js +273 -29
  263. package/dist/snapshot-store.js +5 -25
  264. package/dist/stores/json-store.d.ts +11 -0
  265. package/dist/stores/json-store.js +42 -0
  266. package/dist/sync/local-agent-telemetry.d.ts +13 -0
  267. package/dist/sync/local-agent-telemetry.js +128 -0
  268. package/dist/sync/outbox-replay.d.ts +55 -0
  269. package/dist/sync/outbox-replay.js +621 -0
  270. package/dist/team-context-store.d.ts +23 -0
  271. package/dist/team-context-store.js +116 -0
  272. package/dist/telemetry/posthog.js +4 -2
  273. package/dist/tools/core-tools.d.ts +72 -0
  274. package/dist/tools/core-tools.js +2270 -0
  275. package/dist/types.d.ts +2 -0
  276. package/dist/types.js +2 -0
  277. package/dist/worker-supervisor.js +23 -0
  278. package/package.json +14 -4
  279. package/dashboard/dist/assets/B3ziCA02.js +0 -8
  280. package/dashboard/dist/assets/BNeJ0kpF.js +0 -1
  281. package/dashboard/dist/assets/BzkiMPmM.js +0 -215
  282. package/dashboard/dist/assets/CUV9IHHi.js +0 -1
  283. package/dashboard/dist/assets/Ie7d9Iq2.css +0 -1
  284. package/dashboard/dist/assets/sAhvFnpk.js +0 -4
@@ -1,8 +1,25 @@
1
1
  import { randomUUID } from "node:crypto";
2
+ import { stableHash } from "../hash-utils.js";
3
+ import { validateArtifactMetadata, normalizeArtifactType, } from "./artifact-domain-schemas.js";
4
+ const ALLOWED_ENTITY_TYPES = new Set([
5
+ "initiative",
6
+ "workstream",
7
+ "milestone",
8
+ "task",
9
+ "decision",
10
+ "project",
11
+ ]);
2
12
  const MAX_PREVIEW_MARKDOWN = 25_000;
3
13
  function normalizeText(value) {
4
14
  return typeof value === "string" ? value.trim() : "";
5
15
  }
16
+ function normalizeConfidenceScore(value) {
17
+ if (typeof value !== "number" || !Number.isFinite(value))
18
+ return null;
19
+ if (value < 0 || value > 1)
20
+ return null;
21
+ return value;
22
+ }
6
23
  function isUuid(value) {
7
24
  return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
8
25
  }
@@ -28,6 +45,9 @@ export function validateRegisterArtifactInput(input) {
28
45
  const entityType = normalizeText(input.entity_type);
29
46
  if (!entityType)
30
47
  errors.push("entity_type is required");
48
+ else if (!ALLOWED_ENTITY_TYPES.has(entityType)) {
49
+ errors.push("entity_type must be one of: initiative, workstream, milestone, task, decision, project");
50
+ }
31
51
  const entityId = normalizeText(input.entity_id);
32
52
  if (!entityId)
33
53
  errors.push("entity_id is required");
@@ -39,6 +59,10 @@ export function validateRegisterArtifactInput(input) {
39
59
  const artifactType = normalizeText(input.artifact_type);
40
60
  if (!artifactType)
41
61
  errors.push("artifact_type is required");
62
+ if (typeof input.confidence_score !== "undefined" &&
63
+ normalizeConfidenceScore(input.confidence_score) == null) {
64
+ errors.push("confidence_score must be a number between 0 and 1 when provided");
65
+ }
42
66
  const createdByType = normalizeText(input.created_by_type);
43
67
  if (createdByType && createdByType !== "human" && createdByType !== "agent") {
44
68
  errors.push("created_by_type must be 'human' or 'agent' when provided");
@@ -60,6 +84,44 @@ function isArtifactTypeConstraintError(err) {
60
84
  return (msg.includes("artifact_type") &&
61
85
  (msg.includes("constraint") || msg.includes("foreign") || msg.includes("violat")));
62
86
  }
87
+ function isRecord(value) {
88
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
89
+ }
90
+ function extractArtifactFromCreateResponse(payload) {
91
+ if (!isRecord(payload))
92
+ return null;
93
+ if (isRecord(payload.artifact))
94
+ return payload.artifact;
95
+ if (isRecord(payload.data) && isRecord(payload.data.artifact)) {
96
+ return payload.data.artifact;
97
+ }
98
+ if (isRecord(payload.data))
99
+ return payload.data;
100
+ return null;
101
+ }
102
+ function extractArtifactFromDetailResponse(payload) {
103
+ if (!isRecord(payload))
104
+ return null;
105
+ if (isRecord(payload.artifact))
106
+ return payload.artifact;
107
+ if (isRecord(payload.data) && isRecord(payload.data.artifact)) {
108
+ return payload.data.artifact;
109
+ }
110
+ if (isRecord(payload.data))
111
+ return payload.data;
112
+ return null;
113
+ }
114
+ function extractArtifactsFromListResponse(payload) {
115
+ if (!isRecord(payload))
116
+ return [];
117
+ const direct = payload.artifacts;
118
+ if (Array.isArray(direct))
119
+ return direct.filter(isRecord);
120
+ if (isRecord(payload.data) && Array.isArray(payload.data.artifacts)) {
121
+ return payload.data.artifacts.filter(isRecord);
122
+ }
123
+ return [];
124
+ }
63
125
  function normalizeBaseUrl(baseUrl) {
64
126
  return baseUrl.replace(/\/+$/, "");
65
127
  }
@@ -67,18 +129,20 @@ async function sleep(ms) {
67
129
  await new Promise((r) => setTimeout(r, ms));
68
130
  }
69
131
  async function validateArtifactPersistence(client, input) {
70
- // Use API-key compatible entity CRUD endpoints for validation.
71
- // The web UI endpoints (/api/artifacts/*, /api/work-artifacts/*) are session-authenticated (401 for API keys).
72
- const detail = await client.rawRequest("GET", `/api/entities?type=artifact&id=${encodeURIComponent(input.artifactId)}`);
73
- const rows = detail && typeof detail === "object" ? detail.data : null;
74
- const artifact = Array.isArray(rows) ? rows.find((r) => r && typeof r === "object" && r.id === input.artifactId) : null;
75
- const artifactOk = artifact && typeof artifact === "object" && typeof artifact.id === "string" && artifact.id === input.artifactId;
76
- const linkedOk = artifactOk &&
77
- typeof artifact.entity_type === "string" &&
78
- typeof artifact.entity_id === "string" &&
79
- artifact.entity_type === input.entity_type &&
80
- artifact.entity_id === input.entity_id;
81
- return { artifact_detail_ok: Boolean(artifactOk), linked_ok: Boolean(linkedOk) };
132
+ const detail = await client.rawRequest("GET", `/api/client/artifacts/${encodeURIComponent(input.artifactId)}`);
133
+ const detailArtifact = extractArtifactFromDetailResponse(detail);
134
+ const detailOk = Boolean(detailArtifact && typeof detailArtifact.id === "string" && detailArtifact.id === input.artifactId);
135
+ const list = await client.rawRequest("GET", `/api/client/artifacts/by-entity?entity_type=${encodeURIComponent(input.entity_type)}&entity_id=${encodeURIComponent(input.entity_id)}&limit=25`);
136
+ const artifacts = extractArtifactsFromListResponse(list);
137
+ const linkedArtifact = artifacts.find((artifact) => {
138
+ return (typeof artifact.id === "string" &&
139
+ artifact.id === input.artifactId &&
140
+ typeof artifact.entity_type === "string" &&
141
+ artifact.entity_type === input.entity_type &&
142
+ typeof artifact.entity_id === "string" &&
143
+ artifact.entity_id === input.entity_id);
144
+ });
145
+ return { artifact_detail_ok: detailOk, linked_ok: Boolean(linkedArtifact) };
82
146
  }
83
147
  export async function registerArtifact(client, baseUrl, input) {
84
148
  const warnings = [];
@@ -111,6 +175,9 @@ export async function registerArtifact(client, baseUrl, input) {
111
175
  ? input.metadata
112
176
  : {}),
113
177
  };
178
+ const confidenceScore = normalizeConfidenceScore(input.confidence_score);
179
+ if (confidenceScore != null)
180
+ metadata.confidence_score = confidenceScore;
114
181
  if (input.external_url)
115
182
  metadata.external_url = String(input.external_url);
116
183
  if (input.preview_markdown) {
@@ -122,20 +189,102 @@ export async function registerArtifact(client, baseUrl, input) {
122
189
  if (preview.length > MAX_PREVIEW_MARKDOWN)
123
190
  metadata.preview_truncated = true;
124
191
  }
192
+ // --- Proof Ladder: atomic unit normalization + schema validation ---
193
+ const explicitAtomicType = typeof metadata.atomic_unit_type === "string"
194
+ ? metadata.atomic_unit_type.trim()
195
+ : null;
196
+ const inferredAtomicType = normalizeArtifactType(input.artifact_type);
197
+ const atomicUnitType = explicitAtomicType || inferredAtomicType;
198
+ if (atomicUnitType) {
199
+ metadata.atomic_unit_type = atomicUnitType;
200
+ const validation = validateArtifactMetadata(atomicUnitType, metadata);
201
+ metadata.schema_validated = validation.valid;
202
+ if (!validation.valid) {
203
+ warnings.push(...validation.warnings);
204
+ }
205
+ }
206
+ // --- Proof Ladder: artifact content hash ---
207
+ const hashSource = input.preview_markdown || input.external_url || input.name;
208
+ if (hashSource && !metadata.artifact_hash) {
209
+ metadata.artifact_hash = stableHash(String(hashSource));
210
+ }
211
+ // --- Proof Ladder: queue_ref from environment / caller ---
212
+ if (!metadata.queue_ref) {
213
+ const queueRef = {};
214
+ const envInitId = normalizeText(process.env.ORGX_INITIATIVE_ID);
215
+ const envWsId = normalizeText(process.env.ORGX_WORKSTREAM_ID);
216
+ const envTaskId = normalizeText(process.env.ORGX_TASK_ID);
217
+ if (envInitId)
218
+ queueRef.initiative_id = envInitId;
219
+ if (envWsId)
220
+ queueRef.workstream_id = envWsId;
221
+ if (envTaskId)
222
+ queueRef.task_id = envTaskId;
223
+ if (Object.keys(queueRef).length > 0) {
224
+ metadata.queue_ref = queueRef;
225
+ }
226
+ }
227
+ // --- Proof Ladder: run_ref from environment / caller ---
228
+ if (!metadata.run_ref) {
229
+ const runRef = {};
230
+ const envRunId = normalizeText(process.env.ORGX_RUN_ID);
231
+ const envCorrId = normalizeText(process.env.ORGX_CORRELATION_ID);
232
+ const envSessionId = normalizeText(process.env.ORGX_SESSION_ID);
233
+ if (envRunId)
234
+ runRef.run_id = envRunId;
235
+ if (envCorrId)
236
+ runRef.correlation_id = envCorrId;
237
+ if (envSessionId)
238
+ runRef.session_id = envSessionId;
239
+ if (Object.keys(runRef).length > 0) {
240
+ metadata.run_ref = runRef;
241
+ }
242
+ }
125
243
  const metadataInitiativeId = typeof metadata.initiative_id === "string" && metadata.initiative_id.trim().length > 0
126
244
  ? metadata.initiative_id.trim()
127
245
  : null;
128
246
  const initiativeIdHint = input.entity_type === "initiative" ? input.entity_id : metadataInitiativeId;
129
247
  let entity = null;
130
248
  let created = false;
131
- // Attempt idempotent create using a client-provided UUID id (preferred).
249
+ let usedLegacyCreate = false;
250
+ // Primary path: canonical client artifact contract.
132
251
  try {
252
+ const response = await client.rawRequest("POST", "/api/client/artifacts", {
253
+ artifact_id: desiredId,
254
+ entity_type: input.entity_type,
255
+ entity_id: input.entity_id,
256
+ name: input.name,
257
+ artifact_type: input.artifact_type,
258
+ description: input.description ?? undefined,
259
+ artifact_url: artifactUrl,
260
+ external_url: input.external_url ?? undefined,
261
+ preview_markdown: input.preview_markdown ?? undefined,
262
+ status,
263
+ metadata,
264
+ ...(initiativeIdHint ? { initiative_id: initiativeIdHint } : {}),
265
+ ...createdBy,
266
+ });
267
+ entity = extractArtifactFromCreateResponse(response);
268
+ if (!entity) {
269
+ warnings.push("client artifact create returned an unexpected payload shape");
270
+ }
271
+ else {
272
+ created = true;
273
+ }
274
+ }
275
+ catch (err) {
276
+ warnings.push(`client artifact create failed; falling back to legacy entities route: ${safeErrorMessage(err)}`);
277
+ }
278
+ // Compatibility path for older OrgX servers.
279
+ if (!entity) {
280
+ usedLegacyCreate = true;
133
281
  try {
134
282
  entity = await client.createEntity("artifact", {
135
283
  id: desiredId,
136
284
  name: input.name,
137
285
  description: input.description ?? undefined,
138
286
  artifact_type: input.artifact_type,
287
+ confidence_score: confidenceScore ?? undefined,
139
288
  entity_type: input.entity_type,
140
289
  entity_id: input.entity_id,
141
290
  ...(initiativeIdHint ? { initiative_id: initiativeIdHint } : {}),
@@ -150,13 +299,14 @@ export async function registerArtifact(client, baseUrl, input) {
150
299
  if (!isArtifactTypeConstraintError(err)) {
151
300
  throw err;
152
301
  }
153
- warnings.push(`artifact_type rejected; retrying with shared.project_handbook`);
302
+ warnings.push(`artifact_type rejected on legacy route; retrying with shared.project_handbook`);
154
303
  metadata.requested_artifact_type = input.artifact_type;
155
304
  entity = await client.createEntity("artifact", {
156
305
  id: desiredId,
157
306
  name: input.name,
158
307
  description: input.description ?? undefined,
159
308
  artifact_type: "shared.project_handbook",
309
+ confidence_score: confidenceScore ?? undefined,
160
310
  entity_type: input.entity_type,
161
311
  entity_id: input.entity_id,
162
312
  ...(initiativeIdHint ? { initiative_id: initiativeIdHint } : {}),
@@ -168,52 +318,15 @@ export async function registerArtifact(client, baseUrl, input) {
168
318
  created = true;
169
319
  }
170
320
  }
171
- catch (err) {
172
- warnings.push(`artifact create with explicit id failed: ${safeErrorMessage(err)}`);
173
- // Fallback: create without id, then patch artifact_url once we know the server id.
174
- try {
175
- entity = await client.createEntity("artifact", {
176
- name: input.name,
177
- description: input.description ?? undefined,
178
- artifact_type: input.artifact_type,
179
- entity_type: input.entity_type,
180
- entity_id: input.entity_id,
181
- ...(initiativeIdHint ? { initiative_id: initiativeIdHint } : {}),
182
- artifact_url: input.external_url ?? `${normalizeBaseUrl(baseUrl)}/artifacts/pending`,
183
- status,
184
- metadata,
185
- ...createdBy,
186
- });
187
- created = true;
188
- }
189
- catch (inner) {
190
- if (!isArtifactTypeConstraintError(inner)) {
191
- throw inner;
192
- }
193
- warnings.push(`artifact_type rejected; retrying with shared.project_handbook`);
194
- metadata.requested_artifact_type = input.artifact_type;
195
- entity = await client.createEntity("artifact", {
196
- name: input.name,
197
- description: input.description ?? undefined,
198
- artifact_type: "shared.project_handbook",
199
- entity_type: input.entity_type,
200
- entity_id: input.entity_id,
201
- ...(initiativeIdHint ? { initiative_id: initiativeIdHint } : {}),
202
- artifact_url: input.external_url ?? `${normalizeBaseUrl(baseUrl)}/artifacts/pending`,
203
- status,
204
- metadata,
205
- ...createdBy,
206
- });
207
- created = true;
208
- }
209
- }
210
321
  const artifactId = entity && typeof entity === "object" && typeof entity.id === "string"
211
322
  ? String(entity.id)
212
323
  : null;
213
- let finalArtifactUrl = artifactId
214
- ? `${normalizeBaseUrl(baseUrl)}/artifacts/${artifactId}`
215
- : null;
216
- if (artifactId) {
324
+ let finalArtifactUrl = entity && typeof entity === "object" && typeof entity.artifact_url === "string"
325
+ ? String(entity.artifact_url)
326
+ : artifactId
327
+ ? `${normalizeBaseUrl(baseUrl)}/artifacts/${artifactId}`
328
+ : null;
329
+ if (artifactId && usedLegacyCreate) {
217
330
  try {
218
331
  await client.updateEntity("artifact", artifactId, {
219
332
  artifact_url: finalArtifactUrl,
@@ -0,0 +1,47 @@
1
+ import { type ResolvedConfig } from "../config/resolution.js";
2
+ import type { OnboardingState } from "../types.js";
3
+ type LoggerLike = {
4
+ info?: (msg: string, meta?: Record<string, unknown>) => void;
5
+ warn?: (msg: string, meta?: Record<string, unknown>) => void;
6
+ debug?: (msg: string, meta?: Record<string, unknown>) => void;
7
+ };
8
+ type RuntimeConfigState = Pick<ResolvedConfig, "apiKey" | "apiKeySource" | "userId" | "baseUrl" | "installationId">;
9
+ export declare function applyRuntimeApiKey(input: {
10
+ config: RuntimeConfigState;
11
+ apiKey: string;
12
+ source: "manual" | "browser_pairing";
13
+ workspaceName?: string | null;
14
+ keyPrefix?: string | null;
15
+ userId?: string | null;
16
+ currentWorkspaceName: string | null;
17
+ updateOnboardingState: (updates: Partial<OnboardingState>) => unknown;
18
+ setCredentials: (credentials: {
19
+ apiKey: string;
20
+ userId: string;
21
+ baseUrl: string;
22
+ }) => void;
23
+ logger?: LoggerLike;
24
+ }): void;
25
+ export declare function isAuthRequiredError(result: {
26
+ status: number;
27
+ error: string;
28
+ }): boolean;
29
+ export declare function buildManualKeyConnectUrl(baseApiUrl: string): string;
30
+ export declare function fetchOrgxJson<T>(input: {
31
+ baseApiUrl: string;
32
+ method: "GET" | "POST";
33
+ path: string;
34
+ body?: unknown;
35
+ options?: {
36
+ timeoutMs?: number;
37
+ };
38
+ toErrorMessage: (err: unknown) => string;
39
+ }): Promise<{
40
+ ok: true;
41
+ data: T;
42
+ } | {
43
+ ok: false;
44
+ status: number;
45
+ error: string;
46
+ }>;
47
+ export {};
@@ -0,0 +1,169 @@
1
+ import { saveAuthStore } from "../auth-store.js";
2
+ import { resolveRuntimeUserId, } from "../config/resolution.js";
3
+ import { autoConfigureDetectedMcpClients } from "../mcp-client-setup.js";
4
+ import { readOpenClawGatewayPort, readOpenClawSettingsSnapshot, } from "../openclaw-settings.js";
5
+ export function applyRuntimeApiKey(input) {
6
+ const nextApiKey = input.apiKey.trim();
7
+ input.config.apiKey = nextApiKey;
8
+ input.config.apiKeySource = "persisted";
9
+ input.config.userId = resolveRuntimeUserId(nextApiKey, [input.userId, input.config.userId]);
10
+ input.setCredentials({
11
+ apiKey: input.config.apiKey,
12
+ userId: input.config.userId,
13
+ baseUrl: input.config.baseUrl,
14
+ });
15
+ saveAuthStore({
16
+ installationId: input.config.installationId,
17
+ apiKey: nextApiKey,
18
+ userId: input.config.userId || null,
19
+ workspaceName: input.workspaceName ?? null,
20
+ keyPrefix: input.keyPrefix ?? null,
21
+ source: input.source,
22
+ });
23
+ input.updateOnboardingState({
24
+ hasApiKey: true,
25
+ keySource: "persisted",
26
+ installationId: input.config.installationId,
27
+ workspaceName: input.workspaceName ?? input.currentWorkspaceName,
28
+ });
29
+ if (input.source === "browser_pairing" &&
30
+ process.env.ORGX_DISABLE_MCP_CLIENT_AUTOCONFIG !== "1") {
31
+ try {
32
+ const snapshot = readOpenClawSettingsSnapshot();
33
+ const port = readOpenClawGatewayPort(snapshot.raw);
34
+ const localMcpUrl = `http://127.0.0.1:${port}/orgx/mcp`;
35
+ void autoConfigureDetectedMcpClients({
36
+ localMcpUrl,
37
+ logger: input.logger ?? {},
38
+ }).catch(() => {
39
+ // best effort
40
+ });
41
+ }
42
+ catch {
43
+ // best effort
44
+ }
45
+ }
46
+ }
47
+ export function isAuthRequiredError(result) {
48
+ if (result.status !== 401) {
49
+ return false;
50
+ }
51
+ return /auth|unauthorized|token/i.test(result.error);
52
+ }
53
+ export function buildManualKeyConnectUrl(baseApiUrl) {
54
+ try {
55
+ // Deep-link into the Security section where API keys live.
56
+ return new URL("/settings#security", baseApiUrl).toString();
57
+ }
58
+ catch {
59
+ return "https://www.useorgx.com/settings#security";
60
+ }
61
+ }
62
+ export async function fetchOrgxJson(input) {
63
+ try {
64
+ const controller = new AbortController();
65
+ const timeoutMs = typeof input.options?.timeoutMs === "number" &&
66
+ Number.isFinite(input.options.timeoutMs)
67
+ ? Math.max(1_000, Math.floor(input.options.timeoutMs))
68
+ : 12_000;
69
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
70
+ let response;
71
+ let rawText = "";
72
+ try {
73
+ response = await fetch(`${input.baseApiUrl}${input.path}`, {
74
+ method: input.method,
75
+ signal: controller.signal,
76
+ headers: {
77
+ Accept: "application/json",
78
+ "Content-Type": "application/json",
79
+ },
80
+ body: input.body ? JSON.stringify(input.body) : undefined,
81
+ });
82
+ rawText = await response.text().catch(() => "");
83
+ }
84
+ finally {
85
+ clearTimeout(timeout);
86
+ }
87
+ const payload = (() => {
88
+ if (!rawText)
89
+ return null;
90
+ try {
91
+ return JSON.parse(rawText);
92
+ }
93
+ catch {
94
+ return null;
95
+ }
96
+ })();
97
+ if (!response.ok) {
98
+ const rawError = payload?.error ?? payload?.message;
99
+ let errorMessage;
100
+ if (typeof rawError === "string") {
101
+ errorMessage = rawError;
102
+ }
103
+ else if (rawError &&
104
+ typeof rawError === "object" &&
105
+ "message" in rawError &&
106
+ typeof rawError.message === "string") {
107
+ errorMessage = rawError.message;
108
+ }
109
+ else if (rawText && rawText.trim().length > 0) {
110
+ // Avoid dumping HTML (Cloudflare / Next.js error pages) into UI; keep it short.
111
+ const sanitized = rawText
112
+ .replace(/\s+/g, " ")
113
+ .replace(/<[^>]+>/g, "")
114
+ .trim();
115
+ errorMessage =
116
+ sanitized.length > 0
117
+ ? sanitized.slice(0, 180)
118
+ : `OrgX request failed (${response.status})`;
119
+ }
120
+ else {
121
+ errorMessage = `OrgX request failed (${response.status})`;
122
+ }
123
+ const statusToken = `HTTP ${response.status}`;
124
+ if (response.status &&
125
+ !errorMessage.toLowerCase().includes(statusToken.toLowerCase()) &&
126
+ !errorMessage.includes(`(${response.status})`)) {
127
+ errorMessage = `${errorMessage} (HTTP ${response.status})`;
128
+ }
129
+ const debugParts = [];
130
+ const requestId = response.headers.get("x-request-id");
131
+ const vercelId = response.headers.get("x-vercel-id");
132
+ const cfRay = response.headers.get("cf-ray");
133
+ const clerkStatus = response.headers.get("x-clerk-auth-status");
134
+ const clerkReason = response.headers.get("x-clerk-auth-reason");
135
+ if (requestId)
136
+ debugParts.push(`req=${requestId}`);
137
+ if (vercelId && vercelId !== requestId)
138
+ debugParts.push(`vercel=${vercelId}`);
139
+ if (cfRay)
140
+ debugParts.push(`cf-ray=${cfRay}`);
141
+ if (clerkStatus)
142
+ debugParts.push(`clerk=${clerkStatus}`);
143
+ if (clerkReason)
144
+ debugParts.push(`clerk_reason=${clerkReason}`);
145
+ const debugSuffix = debugParts.length > 0 ? ` (${debugParts.join(", ")})` : "";
146
+ return {
147
+ ok: false,
148
+ status: response.status,
149
+ error: `${errorMessage}${debugSuffix}`,
150
+ };
151
+ }
152
+ if (payload?.data !== undefined) {
153
+ return { ok: true, data: payload.data };
154
+ }
155
+ if (payload !== null) {
156
+ return { ok: true, data: payload };
157
+ }
158
+ return { ok: true, data: rawText };
159
+ }
160
+ catch (err) {
161
+ const message = err &&
162
+ typeof err === "object" &&
163
+ "name" in err &&
164
+ err.name === "AbortError"
165
+ ? `OrgX request timed out (method=${input.method}, path=${input.path})`
166
+ : input.toErrorMessage(err);
167
+ return { ok: false, status: 0, error: message };
168
+ }
169
+ }
@@ -1,7 +1,8 @@
1
- import { mkdirSync, readFileSync, chmodSync, existsSync, rmSync } from 'node:fs';
1
+ import { existsSync, readFileSync } from "node:fs";
2
2
  import { randomUUID } from 'node:crypto';
3
3
  import { getOrgxPluginConfigDir, getOrgxPluginConfigPath } from './paths.js';
4
4
  import { backupCorruptFileSync, writeJsonFileAtomicSync } from './fs-utils.js';
5
+ import { clearStoreFileSync, ensureStoreDirSync, parseJsonSafe, } from "./stores/json-store.js";
5
6
  function authDir() {
6
7
  return getOrgxPluginConfigDir();
7
8
  }
@@ -18,22 +19,7 @@ function isUuid(value) {
18
19
  return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
19
20
  }
20
21
  function ensureAuthDir() {
21
- const dir = authDir();
22
- mkdirSync(dir, { recursive: true, mode: 0o700 });
23
- try {
24
- chmodSync(dir, 0o700);
25
- }
26
- catch {
27
- // best effort
28
- }
29
- }
30
- function parseJson(value) {
31
- try {
32
- return JSON.parse(value);
33
- }
34
- catch {
35
- return null;
36
- }
22
+ ensureStoreDirSync(authDir());
37
23
  }
38
24
  export function getAuthFilePath() {
39
25
  return authFile();
@@ -44,7 +30,7 @@ export function readPersistedAuth() {
44
30
  if (!existsSync(file))
45
31
  return null;
46
32
  const raw = readFileSync(file, 'utf8');
47
- const parsed = parseJson(raw);
33
+ const parsed = parseJsonSafe(raw);
48
34
  if (!parsed) {
49
35
  backupCorruptFileSync(file);
50
36
  return null;
@@ -83,13 +69,7 @@ export function writePersistedAuth(input) {
83
69
  return next;
84
70
  }
85
71
  export function clearPersistedAuth() {
86
- const file = authFile();
87
- try {
88
- rmSync(file, { force: true });
89
- }
90
- catch {
91
- // best effort
92
- }
72
+ clearStoreFileSync(authFile());
93
73
  }
94
74
  function readInstallationRecord() {
95
75
  const file = installationFile();
@@ -97,7 +77,7 @@ function readInstallationRecord() {
97
77
  if (!existsSync(file))
98
78
  return null;
99
79
  const raw = readFileSync(file, 'utf8');
100
- const parsed = parseJson(raw);
80
+ const parsed = parseJsonSafe(raw);
101
81
  if (!parsed) {
102
82
  backupCorruptFileSync(file);
103
83
  return null;
@@ -1,7 +1,8 @@
1
- import { chmodSync, existsSync, mkdirSync, readFileSync, statSync } from "node:fs";
1
+ import { existsSync, readFileSync, statSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { getOpenClawDir } from "./paths.js";
4
4
  import { backupCorruptFileSync, writeJsonFileAtomicSync } from "./fs-utils.js";
5
+ import { ensureStoreDirSync, parseJsonSafe, } from "./stores/json-store.js";
5
6
  const PROVIDER_PROFILE_MAP = {
6
7
  openaiApiKey: { profileId: "openai-codex", provider: "openai-codex" },
7
8
  anthropicApiKey: { profileId: "anthropic", provider: "anthropic" },
@@ -18,14 +19,6 @@ function isSafePathSegment(value) {
18
19
  return false;
19
20
  return true;
20
21
  }
21
- function parseJson(value) {
22
- try {
23
- return JSON.parse(value);
24
- }
25
- catch {
26
- return null;
27
- }
28
- }
29
22
  function readObject(value) {
30
23
  return value && typeof value === "object" && !Array.isArray(value)
31
24
  ? value
@@ -36,7 +29,7 @@ function resolveDefaultAgentId() {
36
29
  const configPath = join(getOpenClawDir(), "openclaw.json");
37
30
  if (!existsSync(configPath))
38
31
  return "main";
39
- const raw = parseJson(readFileSync(configPath, "utf8"));
32
+ const raw = parseJsonSafe(readFileSync(configPath, "utf8"));
40
33
  const agents = readObject(raw?.agents);
41
34
  const list = Array.isArray(agents.list) ? agents.list : [];
42
35
  for (const entry of list) {
@@ -70,14 +63,7 @@ function authProfilesFile() {
70
63
  return join(authProfilesDir(), "auth-profiles.json");
71
64
  }
72
65
  function ensureAuthProfilesDir() {
73
- const dir = authProfilesDir();
74
- mkdirSync(dir, { recursive: true, mode: 0o700 });
75
- try {
76
- chmodSync(dir, 0o700);
77
- }
78
- catch {
79
- // best effort
80
- }
66
+ ensureStoreDirSync(authProfilesDir());
81
67
  }
82
68
  function normalizeAuthProfileEntry(value) {
83
69
  if (!value || typeof value !== "object")
@@ -96,7 +82,7 @@ function readAuthProfiles() {
96
82
  if (!existsSync(file))
97
83
  return { file, parsed: null };
98
84
  const raw = readFileSync(file, "utf8");
99
- const parsed = parseJson(raw);
85
+ const parsed = parseJsonSafe(raw);
100
86
  if (!parsed || typeof parsed !== "object") {
101
87
  backupCorruptFileSync(file);
102
88
  return { file, parsed: null };