forge-openclaw-plugin 0.2.25 → 0.2.27

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 (237) hide show
  1. package/README.md +59 -3
  2. package/dist/assets/{board-VmF4FAfr.js → board-C6jCchjI.js} +3 -3
  3. package/dist/assets/{board-VmF4FAfr.js.map → board-C6jCchjI.js.map} +1 -1
  4. package/dist/assets/index-DVvS8iiU.css +1 -0
  5. package/dist/assets/index-zYB-9Dfo.js +85 -0
  6. package/dist/assets/index-zYB-9Dfo.js.map +1 -0
  7. package/dist/assets/knowledge-graph-layout.worker-DRvzPxhP.js +2 -0
  8. package/dist/assets/knowledge-graph-layout.worker-DRvzPxhP.js.map +1 -0
  9. package/dist/assets/{motion-DvkU14p-.js → motion-DFHrH2rd.js} +2 -2
  10. package/dist/assets/{motion-DvkU14p-.js.map → motion-DFHrH2rd.js.map} +1 -1
  11. package/dist/assets/{table-DgiPof9E.js → table-ZL7Di_u3.js} +2 -2
  12. package/dist/assets/{table-DgiPof9E.js.map → table-ZL7Di_u3.js.map} +1 -1
  13. package/dist/assets/{ui-nYfoC0Gq.js → ui-CKNPpz7q.js} +2 -2
  14. package/dist/assets/{ui-nYfoC0Gq.js.map → ui-CKNPpz7q.js.map} +1 -1
  15. package/dist/assets/vendor-DoNZuFhn.js +1247 -0
  16. package/dist/assets/vendor-DoNZuFhn.js.map +1 -0
  17. package/dist/index.html +7 -8
  18. package/dist/openclaw/local-runtime.d.ts +3 -1
  19. package/dist/openclaw/local-runtime.js +67 -15
  20. package/dist/openclaw/plugin-entry-shared.js +24 -2
  21. package/dist/openclaw/plugin-sdk-types.d.ts +17 -0
  22. package/dist/openclaw/routes.d.ts +27 -0
  23. package/dist/openclaw/routes.js +16 -12
  24. package/dist/openclaw/tools.js +0 -3
  25. package/dist/server/server/migrations/001_core.sql +411 -0
  26. package/dist/server/server/migrations/002_psyche.sql +392 -0
  27. package/dist/server/server/migrations/003_habits.sql +30 -0
  28. package/dist/server/server/migrations/004_habit_links.sql +8 -0
  29. package/dist/server/server/migrations/005_habit_psyche_links.sql +24 -0
  30. package/dist/server/server/migrations/006_work_adjustments.sql +14 -0
  31. package/dist/server/server/migrations/007_weekly_review_closures.sql +17 -0
  32. package/dist/server/server/migrations/008_calendar_execution.sql +147 -0
  33. package/dist/server/server/migrations/009_true_calendar_events.sql +195 -0
  34. package/dist/server/server/migrations/010_calendar_selection_state.sql +6 -0
  35. package/dist/server/server/migrations/011_calendar_timezone_backfill.sql +11 -0
  36. package/dist/server/server/migrations/012_work_block_ranges.sql +7 -0
  37. package/dist/server/server/migrations/013_microsoft_local_auth_settings.sql +8 -0
  38. package/dist/server/server/migrations/014_note_tags_and_ephemeral.sql +8 -0
  39. package/dist/server/server/migrations/015_multi_user_and_strategies.sql +244 -0
  40. package/dist/server/server/migrations/016_health_companion.sql +158 -0
  41. package/dist/server/server/migrations/016_strategy_contracts_and_user_graph.sql +22 -0
  42. package/dist/server/server/migrations/017_preferences.sql +131 -0
  43. package/dist/server/server/migrations/018_preference_catalogs.sql +31 -0
  44. package/dist/server/server/migrations/019_wiki_memory.sql +255 -0
  45. package/dist/server/server/migrations/020_wiki_page_hierarchy.sql +11 -0
  46. package/dist/server/server/migrations/021_hide_evidence_from_wiki_index.sql +3 -0
  47. package/dist/server/server/migrations/022_wiki_ingest_background.sql +85 -0
  48. package/dist/server/server/migrations/023_diagnostic_logs.sql +28 -0
  49. package/dist/server/server/migrations/024_questionnaires.sql +96 -0
  50. package/dist/server/server/migrations/025_ai_model_connections.sql +26 -0
  51. package/dist/server/server/migrations/026_custom_theme_settings.sql +2 -0
  52. package/dist/server/server/migrations/027_ai_processors.sql +31 -0
  53. package/dist/server/server/migrations/028_movement_domain.sql +136 -0
  54. package/dist/server/server/migrations/029_watch_micro_capture.sql +23 -0
  55. package/dist/server/server/migrations/030_surface_layouts.sql +5 -0
  56. package/dist/server/server/migrations/031_ai_processor_runtime_upgrades.sql +10 -0
  57. package/dist/server/server/migrations/032_ai_connectors.sql +44 -0
  58. package/dist/server/server/migrations/033_movement_trip_point_sync.sql +36 -0
  59. package/dist/server/server/migrations/034_movement_segment_sync.sql +49 -0
  60. package/dist/server/server/migrations/035_google_local_auth_settings.sql +2 -0
  61. package/dist/server/server/migrations/036_google_local_auth_client_secret.sql +2 -0
  62. package/dist/server/server/migrations/037_workbench_public_inputs_and_run_inputs.sql +5 -0
  63. package/dist/server/server/migrations/038_data_management_settings.sql +11 -0
  64. package/dist/server/server/migrations/039_life_force_and_action_points.sql +114 -0
  65. package/dist/server/server/migrations/040_screen_time_domain.sql +89 -0
  66. package/dist/server/server/migrations/041_companion_source_states.sql +21 -0
  67. package/dist/server/server/migrations/042_movement_boxes.sql +47 -0
  68. package/dist/server/server/migrations/043_movement_box_overlap_overrides.sql +26 -0
  69. package/dist/server/{app.js → server/src/app.js} +2112 -414
  70. package/dist/server/server/src/connectors/box-registry.js +223 -0
  71. package/dist/server/server/src/data-management-types.js +107 -0
  72. package/dist/server/{db.js → server/src/db.js} +72 -4
  73. package/dist/server/server/src/debug.js +19 -0
  74. package/dist/server/{demo-data.js → server/src/demo-data.js} +2 -2
  75. package/dist/server/{health.js → server/src/health.js} +702 -18
  76. package/dist/server/{managers → server/src/managers}/platform/llm-manager.js +7 -4
  77. package/dist/server/server/src/managers/platform/mock-workbench-provider.js +149 -0
  78. package/dist/server/{managers → server/src/managers}/platform/secrets-manager.js +18 -1
  79. package/dist/server/{managers → server/src/managers}/runtime.js +9 -0
  80. package/dist/server/{movement.js → server/src/movement.js} +1971 -112
  81. package/dist/server/{openapi.js → server/src/openapi.js} +491 -3
  82. package/dist/server/{psyche-types.js → server/src/psyche-types.js} +9 -1
  83. package/dist/server/{repositories → server/src/repositories}/activity-events.js +8 -0
  84. package/dist/server/{repositories → server/src/repositories}/ai-connectors.js +758 -47
  85. package/dist/server/{repositories → server/src/repositories}/calendar.js +1 -1
  86. package/dist/server/{repositories → server/src/repositories}/habits.js +37 -1
  87. package/dist/server/{repositories → server/src/repositories}/model-settings.js +13 -3
  88. package/dist/server/{repositories → server/src/repositories}/notes.js +3 -0
  89. package/dist/server/{repositories → server/src/repositories}/settings.js +431 -21
  90. package/dist/server/{repositories → server/src/repositories}/tasks.js +170 -10
  91. package/dist/server/server/src/runtime-data-root.js +82 -0
  92. package/dist/server/server/src/screen-time.js +802 -0
  93. package/dist/server/{services → server/src/services}/calendar-runtime.js +775 -58
  94. package/dist/server/server/src/services/data-management.js +788 -0
  95. package/dist/server/{services → server/src/services}/entity-crud.js +205 -2
  96. package/dist/server/server/src/services/google-calendar-oauth-config.js +176 -0
  97. package/dist/server/server/src/services/knowledge-graph.js +1455 -0
  98. package/dist/server/server/src/services/life-force-model.js +197 -0
  99. package/dist/server/server/src/services/life-force.js +1270 -0
  100. package/dist/server/server/src/services/psyche-observation-calendar.js +413 -0
  101. package/dist/server/{types.js → server/src/types.js} +420 -29
  102. package/dist/server/server/src/web.js +332 -0
  103. package/dist/server/src/components/customization/utility-widgets.js +439 -0
  104. package/dist/server/src/components/ui/info-tooltip.js +25 -0
  105. package/dist/server/src/components/workbench-boxes/calendar/calendar-boxes.js +78 -0
  106. package/dist/server/src/components/workbench-boxes/goals/goals-boxes.js +62 -0
  107. package/dist/server/src/components/workbench-boxes/habits/habits-boxes.js +62 -0
  108. package/dist/server/src/components/workbench-boxes/health/health-boxes.js +147 -0
  109. package/dist/server/src/components/workbench-boxes/insights/insights-boxes.js +50 -0
  110. package/dist/server/src/components/workbench-boxes/kanban/kanban-boxes.js +136 -0
  111. package/dist/server/src/components/workbench-boxes/movement/movement-boxes.js +47 -0
  112. package/dist/server/src/components/workbench-boxes/notes/notes-boxes.js +132 -0
  113. package/dist/server/src/components/workbench-boxes/overview/overview-boxes.js +65 -0
  114. package/dist/server/src/components/workbench-boxes/preferences/preferences-boxes.js +78 -0
  115. package/dist/server/src/components/workbench-boxes/projects/projects-boxes.js +62 -0
  116. package/dist/server/src/components/workbench-boxes/psyche/psyche-boxes.js +88 -0
  117. package/dist/server/src/components/workbench-boxes/questionnaires/questionnaires-boxes.js +61 -0
  118. package/dist/server/src/components/workbench-boxes/review/review-boxes.js +53 -0
  119. package/dist/server/src/components/workbench-boxes/shared/define-workbench-box.js +6 -0
  120. package/dist/server/src/components/workbench-boxes/shared/generic-node-view.js +49 -0
  121. package/dist/server/src/components/workbench-boxes/strategies/strategies-boxes.js +62 -0
  122. package/dist/server/src/components/workbench-boxes/tasks/tasks-boxes.js +76 -0
  123. package/dist/server/src/components/workbench-boxes/today/today-boxes.js +78 -0
  124. package/dist/server/src/components/workbench-boxes/wiki/wiki-boxes.js +60 -0
  125. package/dist/server/src/lib/api-error.js +37 -0
  126. package/dist/server/src/lib/api.js +2118 -0
  127. package/dist/server/src/lib/calendar-name-deduper.js +144 -0
  128. package/dist/server/src/lib/data-management-types.js +1 -0
  129. package/dist/server/src/lib/diagnostics.js +67 -0
  130. package/dist/server/src/lib/entity-visuals.js +279 -0
  131. package/dist/server/src/lib/knowledge-graph-types.js +276 -0
  132. package/dist/server/src/lib/knowledge-graph.js +470 -0
  133. package/dist/server/src/lib/psyche-types.js +1 -0
  134. package/dist/server/src/lib/questionnaire-types.js +1 -0
  135. package/dist/server/src/lib/runtime-paths.js +24 -0
  136. package/dist/server/src/lib/schemas.js +238 -0
  137. package/dist/server/src/lib/snapshot-normalizer.js +416 -0
  138. package/dist/server/src/lib/theme-system.js +319 -0
  139. package/dist/server/src/lib/types.js +1 -0
  140. package/dist/server/src/lib/utils.js +22 -0
  141. package/dist/server/src/lib/workbench/boxes.js +16 -0
  142. package/dist/server/src/lib/workbench/contracts.js +229 -0
  143. package/dist/server/src/lib/workbench/nodes.js +215 -0
  144. package/dist/server/src/lib/workbench/registry.js +120 -0
  145. package/dist/server/src/lib/workbench/runtime.js +397 -0
  146. package/dist/server/src/lib/workbench/tool-catalog.js +68 -0
  147. package/openclaw.plugin.json +1 -1
  148. package/package.json +1 -1
  149. package/server/index.js +68 -0
  150. package/server/migrations/035_google_local_auth_settings.sql +2 -0
  151. package/server/migrations/036_google_local_auth_client_secret.sql +2 -0
  152. package/server/migrations/037_workbench_public_inputs_and_run_inputs.sql +5 -0
  153. package/server/migrations/038_data_management_settings.sql +11 -0
  154. package/server/migrations/039_life_force_and_action_points.sql +114 -0
  155. package/server/migrations/040_screen_time_domain.sql +89 -0
  156. package/server/migrations/041_companion_source_states.sql +21 -0
  157. package/server/migrations/042_movement_boxes.sql +47 -0
  158. package/server/migrations/043_movement_box_overlap_overrides.sql +26 -0
  159. package/skills/forge-openclaw/SKILL.md +27 -11
  160. package/skills/forge-openclaw/entity_conversation_playbooks.md +411 -46
  161. package/skills/forge-openclaw/psyche_entity_playbooks.md +195 -20
  162. package/dist/assets/index-CFCKDIMH.js +0 -67
  163. package/dist/assets/index-CFCKDIMH.js.map +0 -1
  164. package/dist/assets/index-ZPY6U1TU.css +0 -1
  165. package/dist/assets/vendor-D9PTEPSB.js +0 -824
  166. package/dist/assets/vendor-D9PTEPSB.js.map +0 -1
  167. package/dist/assets/viz-Cqb6s--o.js +0 -34
  168. package/dist/assets/viz-Cqb6s--o.js.map +0 -1
  169. package/dist/server/connectors/box-registry.js +0 -257
  170. package/dist/server/services/psyche-observation-calendar.js +0 -46
  171. package/dist/server/web.js +0 -98
  172. /package/dist/server/{discovery-advertiser.js → server/src/discovery-advertiser.js} +0 -0
  173. /package/dist/server/{e2e-server.js → server/src/e2e-server.js} +0 -0
  174. /package/dist/server/{errors.js → server/src/errors.js} +0 -0
  175. /package/dist/server/{index.js → server/src/index.js} +0 -0
  176. /package/dist/server/{managers → server/src/managers}/base.js +0 -0
  177. /package/dist/server/{managers → server/src/managers}/contracts.js +0 -0
  178. /package/dist/server/{managers → server/src/managers}/platform/api-gateway-manager.js +0 -0
  179. /package/dist/server/{managers → server/src/managers}/platform/audit-manager.js +0 -0
  180. /package/dist/server/{managers → server/src/managers}/platform/authentication-manager.js +0 -0
  181. /package/dist/server/{managers → server/src/managers}/platform/authorization-manager.js +0 -0
  182. /package/dist/server/{managers → server/src/managers}/platform/background-job-manager.js +0 -0
  183. /package/dist/server/{managers → server/src/managers}/platform/configuration-manager.js +0 -0
  184. /package/dist/server/{managers → server/src/managers}/platform/database-manager.js +0 -0
  185. /package/dist/server/{managers → server/src/managers}/platform/event-bus-manager.js +0 -0
  186. /package/dist/server/{managers → server/src/managers}/platform/external-service-manager.js +0 -0
  187. /package/dist/server/{managers → server/src/managers}/platform/health-manager.js +0 -0
  188. /package/dist/server/{managers → server/src/managers}/platform/migration-manager.js +0 -0
  189. /package/dist/server/{managers → server/src/managers}/platform/openai-responses-provider.js +0 -0
  190. /package/dist/server/{managers → server/src/managers}/platform/search-index-manager.js +0 -0
  191. /package/dist/server/{managers → server/src/managers}/platform/session-manager.js +0 -0
  192. /package/dist/server/{managers → server/src/managers}/platform/storage-manager.js +0 -0
  193. /package/dist/server/{managers → server/src/managers}/platform/token-manager.js +0 -0
  194. /package/dist/server/{managers → server/src/managers}/platform/transaction-manager.js +0 -0
  195. /package/dist/server/{managers → server/src/managers}/platform/trusted-network.js +0 -0
  196. /package/dist/server/{managers → server/src/managers}/type-guards.js +0 -0
  197. /package/dist/server/{preferences-seeds.js → server/src/preferences-seeds.js} +0 -0
  198. /package/dist/server/{preferences-types.js → server/src/preferences-types.js} +0 -0
  199. /package/dist/server/{questionnaire-flow.js → server/src/questionnaire-flow.js} +0 -0
  200. /package/dist/server/{questionnaire-seeds.js → server/src/questionnaire-seeds.js} +0 -0
  201. /package/dist/server/{questionnaire-types.js → server/src/questionnaire-types.js} +0 -0
  202. /package/dist/server/{repositories → server/src/repositories}/ai-processors.js +0 -0
  203. /package/dist/server/{repositories → server/src/repositories}/collaboration.js +0 -0
  204. /package/dist/server/{repositories → server/src/repositories}/deleted-entities.js +0 -0
  205. /package/dist/server/{repositories → server/src/repositories}/diagnostic-logs.js +0 -0
  206. /package/dist/server/{repositories → server/src/repositories}/domains.js +0 -0
  207. /package/dist/server/{repositories → server/src/repositories}/entity-ownership.js +0 -0
  208. /package/dist/server/{repositories → server/src/repositories}/event-log.js +0 -0
  209. /package/dist/server/{repositories → server/src/repositories}/goals.js +0 -0
  210. /package/dist/server/{repositories → server/src/repositories}/preferences.js +0 -0
  211. /package/dist/server/{repositories → server/src/repositories}/projects.js +0 -0
  212. /package/dist/server/{repositories → server/src/repositories}/psyche.js +0 -0
  213. /package/dist/server/{repositories → server/src/repositories}/questionnaires.js +0 -0
  214. /package/dist/server/{repositories → server/src/repositories}/rewards.js +0 -0
  215. /package/dist/server/{repositories → server/src/repositories}/strategies.js +0 -0
  216. /package/dist/server/{repositories → server/src/repositories}/surface-layouts.js +0 -0
  217. /package/dist/server/{repositories → server/src/repositories}/tags.js +0 -0
  218. /package/dist/server/{repositories → server/src/repositories}/task-runs.js +0 -0
  219. /package/dist/server/{repositories → server/src/repositories}/users.js +0 -0
  220. /package/dist/server/{repositories → server/src/repositories}/weekly-reviews.js +0 -0
  221. /package/dist/server/{repositories → server/src/repositories}/wiki-memory.js +0 -0
  222. /package/dist/server/{repositories → server/src/repositories}/work-adjustments.js +0 -0
  223. /package/dist/server/{seed-demo.js → server/src/seed-demo.js} +0 -0
  224. /package/dist/server/{services → server/src/services}/context.js +0 -0
  225. /package/dist/server/{services → server/src/services}/dashboard.js +0 -0
  226. /package/dist/server/{services → server/src/services}/gamification.js +0 -0
  227. /package/dist/server/{services → server/src/services}/insights.js +0 -0
  228. /package/dist/server/{services → server/src/services}/openai-codex-oauth.js +0 -0
  229. /package/dist/server/{services → server/src/services}/projects.js +0 -0
  230. /package/dist/server/{services → server/src/services}/psyche.js +0 -0
  231. /package/dist/server/{services → server/src/services}/relations.js +0 -0
  232. /package/dist/server/{services → server/src/services}/reviews.js +0 -0
  233. /package/dist/server/{services → server/src/services}/run-recovery.js +0 -0
  234. /package/dist/server/{services → server/src/services}/tagging.js +0 -0
  235. /package/dist/server/{services → server/src/services}/task-run-watchdog.js +0 -0
  236. /package/dist/server/{services → server/src/services}/work-time.js +0 -0
  237. /package/dist/server/{watch-mobile.js → server/src/watch-mobile.js} +0 -0
@@ -0,0 +1,397 @@
1
+ function asRecord(value) {
2
+ return value && typeof value === "object" && !Array.isArray(value)
3
+ ? value
4
+ : null;
5
+ }
6
+ function readTextValue(...values) {
7
+ for (const value of values) {
8
+ if (typeof value === "string") {
9
+ return value;
10
+ }
11
+ }
12
+ return "";
13
+ }
14
+ function readNumberValue(...values) {
15
+ for (const value of values) {
16
+ if (typeof value === "number" && Number.isFinite(value)) {
17
+ return value;
18
+ }
19
+ if (typeof value === "string") {
20
+ const parsed = Number(value);
21
+ if (Number.isFinite(parsed)) {
22
+ return parsed;
23
+ }
24
+ }
25
+ }
26
+ return null;
27
+ }
28
+ function readStringArrayValue(...values) {
29
+ for (const value of values) {
30
+ if (Array.isArray(value)) {
31
+ const normalized = value.filter((entry) => typeof entry === "string" && entry.trim().length > 0);
32
+ if (normalized.length > 0) {
33
+ return normalized;
34
+ }
35
+ continue;
36
+ }
37
+ if (typeof value === "string") {
38
+ const trimmed = value.trim();
39
+ if (!trimmed) {
40
+ continue;
41
+ }
42
+ try {
43
+ const parsed = JSON.parse(trimmed);
44
+ if (Array.isArray(parsed)) {
45
+ const normalized = parsed.filter((entry) => typeof entry === "string" && entry.trim().length > 0);
46
+ if (normalized.length > 0) {
47
+ return normalized;
48
+ }
49
+ }
50
+ }
51
+ catch {
52
+ const normalized = trimmed
53
+ .split(",")
54
+ .map((entry) => entry.trim())
55
+ .filter((entry) => entry.length > 0);
56
+ if (normalized.length > 0) {
57
+ return normalized;
58
+ }
59
+ }
60
+ }
61
+ }
62
+ return [];
63
+ }
64
+ export function buildWorkbenchOutputMap(text, json, outputs) {
65
+ const outputMap = {};
66
+ const declaredOutputs = outputs.length > 0 ? outputs : [{ key: "summary" }];
67
+ declaredOutputs.forEach((output, index) => {
68
+ const rawValue = json && output.key in json
69
+ ? json[output.key]
70
+ : index === 0 || output.key === "summary"
71
+ ? text
72
+ : null;
73
+ outputMap[output.key] = {
74
+ text: typeof rawValue === "string"
75
+ ? rawValue
76
+ : Array.isArray(rawValue) || asRecord(rawValue)
77
+ ? JSON.stringify(rawValue, null, 2)
78
+ : String(rawValue ?? ""),
79
+ json: asRecord(rawValue)
80
+ };
81
+ });
82
+ return outputMap;
83
+ }
84
+ function normalizeWorkbenchOutputPayload(definition, output, primaryText) {
85
+ const declaredOutputs = definition.output ?? [];
86
+ if (!output && declaredOutputs.length === 0) {
87
+ return null;
88
+ }
89
+ const normalized = output ? { ...output } : {};
90
+ if (declaredOutputs.length > 0) {
91
+ const leadKey = declaredOutputs[0]?.key;
92
+ if (leadKey && !(leadKey in normalized)) {
93
+ normalized[leadKey] = primaryText;
94
+ }
95
+ if (declaredOutputs.some((entry) => entry.key === "summary") &&
96
+ !("summary" in normalized)) {
97
+ normalized.summary = primaryText;
98
+ }
99
+ }
100
+ return normalized;
101
+ }
102
+ export function buildWorkbenchExecutionEnvelope(input, value) {
103
+ const payload = normalizeWorkbenchOutputPayload(input.definition, value.output, value.primaryText);
104
+ return {
105
+ primaryText: value.primaryText,
106
+ payload,
107
+ logs: value.logs ?? [],
108
+ outputMap: buildWorkbenchOutputMap(value.primaryText, payload, input.definition.output)
109
+ };
110
+ }
111
+ export function buildStaticWorkbenchExecution(input, output, primaryText, logs) {
112
+ return buildWorkbenchExecutionEnvelope(input, {
113
+ primaryText: primaryText ??
114
+ `${input.definition.title}\n${input.definition.description}\nRoute: ${input.definition.routePath ?? "n/a"}`,
115
+ output,
116
+ logs
117
+ });
118
+ }
119
+ export function searchWorkbenchEntities(context, definition, input) {
120
+ const limit = Math.max(1, Math.min(50, Math.round(input.limit ?? 12)));
121
+ const result = context.services.entities.search({
122
+ searches: [
123
+ {
124
+ query: input.query,
125
+ entityTypes: input.entityTypes,
126
+ limit
127
+ }
128
+ ]
129
+ }).results[0];
130
+ const matches = result?.ok ? result.matches ?? [] : [];
131
+ const summaryLines = matches
132
+ .slice(0, limit)
133
+ .map((match) => {
134
+ const title = typeof match.title === "string"
135
+ ? match.title
136
+ : typeof match.name === "string"
137
+ ? match.name
138
+ : typeof match.id === "string"
139
+ ? match.id
140
+ : "Untitled";
141
+ const entityType = typeof match.entityType === "string" ? match.entityType : "entity";
142
+ return `${entityType}: ${title}`;
143
+ });
144
+ return {
145
+ title: definition.title,
146
+ matches,
147
+ summaryText: summaryLines.length > 0
148
+ ? summaryLines.join("\n")
149
+ : `No ${definition.title.toLowerCase()} matches found.`,
150
+ limit,
151
+ query: input.query
152
+ };
153
+ }
154
+ export function buildSearchWorkbenchExecution(input, config) {
155
+ const query = readTextValue(input.inputs.query, input.params.query, config.query).trim();
156
+ const entityTypes = readStringArrayValue(input.inputs.entityTypes, input.params.entityTypes, config.entityTypes);
157
+ const limit = readNumberValue(input.inputs.limit, input.params.limit, config.limit) ?? config.limit ?? 12;
158
+ const summary = searchWorkbenchEntities(input.context, input.definition, {
159
+ query,
160
+ entityTypes,
161
+ limit
162
+ });
163
+ return buildWorkbenchExecutionEnvelope(input, {
164
+ primaryText: summary.summaryText,
165
+ output: {
166
+ summary: summary.summaryText,
167
+ matches: summary.matches,
168
+ matchCount: summary.matches.length
169
+ }
170
+ });
171
+ }
172
+ export function buildMovementPlacesExecution(input) {
173
+ const places = input.context.services.movement.listPlaces?.() ?? [];
174
+ return buildWorkbenchExecutionEnvelope(input, {
175
+ primaryText: places.length > 0
176
+ ? places
177
+ .slice(0, 24)
178
+ .map((place) => typeof place.label === "string"
179
+ ? place.label
180
+ : typeof place.name === "string"
181
+ ? place.name
182
+ : typeof place.id === "string"
183
+ ? place.id
184
+ : "Place")
185
+ .join("\n")
186
+ : "No known places are stored yet.",
187
+ output: {
188
+ summary: places.length > 0
189
+ ? `${places.length} place${places.length === 1 ? "" : "s"} available.`
190
+ : "No known places are stored yet.",
191
+ places
192
+ }
193
+ });
194
+ }
195
+ export function buildSleepWorkbenchExecution(input) {
196
+ const payload = input.context.services.health.getSleepViewData?.() ?? null;
197
+ return buildWorkbenchExecutionEnvelope(input, {
198
+ primaryText: payload && typeof payload === "object"
199
+ ? "Sleep history and derived patterns are available."
200
+ : "No sleep data is available.",
201
+ output: payload && typeof payload === "object"
202
+ ? {
203
+ summary: "Sleep history and derived patterns are available.",
204
+ sleepView: payload
205
+ }
206
+ : {
207
+ summary: "No sleep data is available."
208
+ }
209
+ });
210
+ }
211
+ export function buildSportsWorkbenchExecution(input) {
212
+ const payload = input.context.services.health.getFitnessViewData?.() ?? null;
213
+ return buildWorkbenchExecutionEnvelope(input, {
214
+ primaryText: payload && typeof payload === "object"
215
+ ? "Workout history and composition are available."
216
+ : "No sports data is available.",
217
+ output: payload && typeof payload === "object"
218
+ ? {
219
+ summary: "Workout history and composition are available.",
220
+ sportsView: payload
221
+ }
222
+ : {
223
+ summary: "No sports data is available."
224
+ }
225
+ });
226
+ }
227
+ export function buildOverviewWorkbenchExecution(input) {
228
+ const payload = input.context.services.overview.getContext?.() ?? null;
229
+ const record = asRecord(payload);
230
+ const summary = record
231
+ ? [
232
+ `Projects: ${Array.isArray(record.projects) ? record.projects.length : 0}`,
233
+ `Goals: ${Array.isArray(record.activeGoals) ? record.activeGoals.length : 0}`,
234
+ `Top tasks: ${Array.isArray(record.topTasks) ? record.topTasks.length : 0}`,
235
+ `Due habits: ${Array.isArray(record.dueHabits) ? record.dueHabits.length : 0}`
236
+ ].join("\n")
237
+ : "No overview context is available.";
238
+ return buildWorkbenchExecutionEnvelope(input, {
239
+ primaryText: summary,
240
+ output: record
241
+ ? {
242
+ summary,
243
+ context: record
244
+ }
245
+ : {
246
+ summary
247
+ }
248
+ });
249
+ }
250
+ export function buildInsightsWorkbenchExecution(input) {
251
+ const payload = input.context.services.overview.getInsights?.() ?? null;
252
+ const record = asRecord(payload);
253
+ const status = asRecord(record?.status);
254
+ const coaching = asRecord(record?.coaching);
255
+ const summary = record
256
+ ? [
257
+ typeof status?.systemStatus === "string" ? status.systemStatus : "Insights ready",
258
+ typeof coaching?.title === "string" ? coaching.title : null,
259
+ typeof coaching?.summary === "string" ? coaching.summary : null
260
+ ]
261
+ .filter(Boolean)
262
+ .join("\n")
263
+ : "No insights payload is available.";
264
+ return buildWorkbenchExecutionEnvelope(input, {
265
+ primaryText: summary,
266
+ output: record
267
+ ? {
268
+ summary,
269
+ insights: record
270
+ }
271
+ : {
272
+ summary
273
+ }
274
+ });
275
+ }
276
+ export function buildWeeklyReviewWorkbenchExecution(input) {
277
+ const payload = input.context.services.overview.getWeeklyReview?.() ?? null;
278
+ const record = asRecord(payload);
279
+ const momentum = asRecord(record?.momentumSummary);
280
+ const summary = record
281
+ ? [
282
+ typeof record.windowLabel === "string" ? record.windowLabel : "Weekly review",
283
+ typeof momentum?.totalXp === "number" ? `${momentum.totalXp} XP` : null,
284
+ typeof momentum?.focusHours === "number"
285
+ ? `${momentum.focusHours} focus hours`
286
+ : null
287
+ ]
288
+ .filter(Boolean)
289
+ .join("\n")
290
+ : "No weekly review payload is available.";
291
+ return buildWorkbenchExecutionEnvelope(input, {
292
+ primaryText: summary,
293
+ output: record
294
+ ? {
295
+ summary,
296
+ weeklyReview: record
297
+ }
298
+ : {
299
+ summary
300
+ }
301
+ });
302
+ }
303
+ export function buildWikiPagesWorkbenchExecution(input) {
304
+ const pages = input.context.services.wiki.listPages?.() ?? [];
305
+ const summary = pages.length > 0
306
+ ? pages
307
+ .slice(0, 12)
308
+ .map((page) => typeof page.title === "string"
309
+ ? page.title
310
+ : typeof page.slug === "string"
311
+ ? page.slug
312
+ : typeof page.id === "string"
313
+ ? page.id
314
+ : "Wiki page")
315
+ .join("\n")
316
+ : "No wiki pages are available.";
317
+ return buildWorkbenchExecutionEnvelope(input, {
318
+ primaryText: summary,
319
+ output: {
320
+ summary,
321
+ pages
322
+ }
323
+ });
324
+ }
325
+ export function buildWikiHealthWorkbenchExecution(input) {
326
+ const payload = input.context.services.wiki.getHealth?.() ?? null;
327
+ const record = asRecord(payload);
328
+ const unresolvedLinks = Array.isArray(record?.unresolvedLinks)
329
+ ? record.unresolvedLinks.length
330
+ : null;
331
+ const orphanPages = Array.isArray(record?.orphanPages)
332
+ ? record.orphanPages.length
333
+ : null;
334
+ const summary = record
335
+ ? [
336
+ "Wiki health summary",
337
+ unresolvedLinks !== null ? `${unresolvedLinks} unresolved links` : null,
338
+ orphanPages !== null ? `${orphanPages} orphan pages` : null
339
+ ]
340
+ .filter(Boolean)
341
+ .join("\n")
342
+ : "No wiki health payload is available.";
343
+ return buildWorkbenchExecutionEnvelope(input, {
344
+ primaryText: summary,
345
+ output: record
346
+ ? {
347
+ summary,
348
+ health: record
349
+ }
350
+ : {
351
+ summary
352
+ }
353
+ });
354
+ }
355
+ export function mapWorkbenchTools(tools) {
356
+ return tools.map((tool) => tool);
357
+ }
358
+ export function executeCommonWorkbenchTool(context, definition, toolKey, args) {
359
+ if (toolKey === "forge.search_entities") {
360
+ const query = typeof args.query === "string" ? args.query.trim() : "";
361
+ const entityTypes = Array.isArray(args.entityTypes)
362
+ ? args.entityTypes.filter((entry) => typeof entry === "string" && entry.length > 0)
363
+ : [];
364
+ const limit = typeof args.limit === "number" && Number.isFinite(args.limit)
365
+ ? args.limit
366
+ : 12;
367
+ return searchWorkbenchEntities(context, definition, {
368
+ query,
369
+ entityTypes,
370
+ limit
371
+ });
372
+ }
373
+ if (toolKey === "forge.update_task_status") {
374
+ const taskId = typeof args.taskId === "string" ? args.taskId : "";
375
+ const status = typeof args.status === "string" ? args.status : "";
376
+ if (!context.services.tasks.update) {
377
+ throw new Error("Task update service is not available.");
378
+ }
379
+ return context.services.tasks.update(taskId, { status });
380
+ }
381
+ if (toolKey === "forge.create_note") {
382
+ if (!context.services.notes.create) {
383
+ throw new Error("Note creation service is not available.");
384
+ }
385
+ return context.services.notes.create({
386
+ kind: "evidence",
387
+ title: typeof args.title === "string" ? args.title : "Workbench note",
388
+ contentMarkdown: typeof args.markdown === "string" ? args.markdown : "",
389
+ summary: typeof args.summary === "string" ? args.summary : "",
390
+ links: [],
391
+ tags: [],
392
+ sourcePath: "workbench",
393
+ author: "Workbench"
394
+ });
395
+ }
396
+ throw new Error(`Unsupported Workbench tool: ${toolKey}`);
397
+ }
@@ -0,0 +1,68 @@
1
+ function rankAccessMode(mode) {
2
+ switch (mode) {
3
+ case "exec":
4
+ return 4;
5
+ case "read_write":
6
+ return 3;
7
+ case "write":
8
+ return 2;
9
+ case "read":
10
+ default:
11
+ return 1;
12
+ }
13
+ }
14
+ function preferAccessMode(left, right) {
15
+ return rankAccessMode(left) >= rankAccessMode(right) ? left : right;
16
+ }
17
+ function normalizeToolDescription(toolKey, descriptions) {
18
+ if (toolKey === "forge.search_entities") {
19
+ return "Search across Forge entities. You can optionally narrow the search to specific entity types.";
20
+ }
21
+ if (toolKey === "forge.create_note") {
22
+ return "Create a Forge note from generated content or captured markdown.";
23
+ }
24
+ if (toolKey === "forge.update_task_status") {
25
+ return "Move a task between execution states such as backlog, focus, in progress, blocked, and done.";
26
+ }
27
+ return descriptions.sort((left, right) => right.length - left.length)[0] ?? "Workbench tool";
28
+ }
29
+ export function buildWorkbenchToolCatalog(boxes) {
30
+ const byKey = new Map();
31
+ for (const box of boxes) {
32
+ for (const tool of box.tools) {
33
+ const current = byKey.get(tool.key);
34
+ if (!current) {
35
+ byKey.set(tool.key, {
36
+ key: tool.key,
37
+ label: tool.label,
38
+ description: normalizeToolDescription(tool.key, [tool.description]),
39
+ accessMode: tool.accessMode,
40
+ argsSchema: tool.argsSchema,
41
+ sources: [box.title],
42
+ sourceSurfaceIds: box.surfaceId ? [box.surfaceId] : []
43
+ });
44
+ continue;
45
+ }
46
+ current.accessMode = preferAccessMode(current.accessMode, tool.accessMode);
47
+ current.label = current.label.length >= tool.label.length ? current.label : tool.label;
48
+ current.description = normalizeToolDescription(tool.key, [
49
+ current.description,
50
+ tool.description
51
+ ]);
52
+ current.argsSchema = current.argsSchema ?? tool.argsSchema;
53
+ if (!current.sources.includes(box.title)) {
54
+ current.sources.push(box.title);
55
+ }
56
+ if (box.surfaceId && !current.sourceSurfaceIds.includes(box.surfaceId)) {
57
+ current.sourceSurfaceIds.push(box.surfaceId);
58
+ }
59
+ }
60
+ }
61
+ return [...byKey.values()].sort((left, right) => {
62
+ const accessDelta = rankAccessMode(right.accessMode) - rankAccessMode(left.accessMode);
63
+ if (accessDelta !== 0) {
64
+ return accessDelta;
65
+ }
66
+ return left.label.localeCompare(right.label);
67
+ });
68
+ }
@@ -2,7 +2,7 @@
2
2
  "id": "forge-openclaw-plugin",
3
3
  "name": "Forge",
4
4
  "description": "Curated OpenClaw adapter for the Forge collaboration API, UI entrypoint, and localhost auto-start runtime.",
5
- "version": "0.2.25",
5
+ "version": "0.2.27",
6
6
  "skills": [
7
7
  "./skills"
8
8
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forge-openclaw-plugin",
3
- "version": "0.2.25",
3
+ "version": "0.2.27",
4
4
  "description": "Curated OpenClaw adapter for the Forge collaboration API, UI entrypoint, and localhost auto-start runtime.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -0,0 +1,68 @@
1
+ import { existsSync } from "node:fs";
2
+ import { spawn } from "node:child_process";
3
+ import path from "node:path";
4
+ import { fileURLToPath, pathToFileURL } from "node:url";
5
+
6
+ const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
7
+ const repoRoot = path.resolve(packageRoot, "..");
8
+ const builtRuntimeEntry = path.join(packageRoot, "dist", "server", "server", "src", "index.js");
9
+ const devRuntimeEntry = path.join(repoRoot, "server", "src", "index.ts");
10
+ const devDataRootWrapper = path.join(repoRoot, "scripts", "with-openclaw-plugin-data-root.mjs");
11
+ const tsxCliEntry = path.join(repoRoot, "node_modules", "tsx", "dist", "cli.mjs");
12
+ const devModeFlag = (process.env.FORGE_OPENCLAW_DEV ?? "").trim().toLowerCase();
13
+ const useDevRuntime = devModeFlag === "1" || devModeFlag === "true" || devModeFlag === "yes";
14
+
15
+ if (!useDevRuntime) {
16
+ await import(pathToFileURL(builtRuntimeEntry).href);
17
+ } else {
18
+ if (!existsSync(devRuntimeEntry) || !existsSync(devDataRootWrapper) || !existsSync(tsxCliEntry)) {
19
+ throw new Error(
20
+ "FORGE_OPENCLAW_DEV is enabled, but the Forge repo dev runtime was not found. " +
21
+ "Run this from the Forge repository checkout or disable FORGE_OPENCLAW_DEV."
22
+ );
23
+ }
24
+
25
+ console.log("[forge-openclaw-plugin] starting source-backed dev runtime on port", process.env.PORT ?? "4317");
26
+
27
+ const child = spawn(
28
+ process.execPath,
29
+ [devDataRootWrapper, process.execPath, tsxCliEntry, "watch", devRuntimeEntry],
30
+ {
31
+ cwd: repoRoot,
32
+ stdio: "inherit",
33
+ env: {
34
+ ...process.env,
35
+ FORGE_DEV_WEB_ORIGIN:
36
+ process.env.FORGE_DEV_WEB_ORIGIN ?? "http://127.0.0.1:3027/forge/",
37
+ HOST: process.env.HOST ?? "0.0.0.0",
38
+ PORT: process.env.PORT ?? "4317"
39
+ }
40
+ }
41
+ );
42
+
43
+ const forwardSignal = (signal) => {
44
+ if (!child.killed) {
45
+ child.kill(signal);
46
+ }
47
+ };
48
+
49
+ process.on("SIGINT", forwardSignal);
50
+ process.on("SIGTERM", forwardSignal);
51
+
52
+ await new Promise((resolve, reject) => {
53
+ child.once("error", reject);
54
+ child.once("exit", (code, signal) => {
55
+ if (signal) {
56
+ process.exitCode = signal === "SIGINT" || signal === "SIGTERM" ? 0 : 1;
57
+ resolve();
58
+ return;
59
+ }
60
+ if (code === 0) {
61
+ resolve();
62
+ return;
63
+ }
64
+ reject(new Error(`Forge OpenClaw dev runtime exited with code ${code ?? "unknown"}.`));
65
+ });
66
+ });
67
+ }
68
+
@@ -0,0 +1,2 @@
1
+ ALTER TABLE app_settings
2
+ ADD COLUMN google_client_id TEXT NOT NULL DEFAULT '';
@@ -0,0 +1,2 @@
1
+ ALTER TABLE app_settings
2
+ ADD COLUMN google_client_secret TEXT NOT NULL DEFAULT '';
@@ -0,0 +1,5 @@
1
+ ALTER TABLE ai_connectors
2
+ ADD COLUMN public_inputs_json TEXT NOT NULL DEFAULT '[]';
3
+
4
+ ALTER TABLE ai_connector_runs
5
+ ADD COLUMN inputs_json TEXT NOT NULL DEFAULT '{}';
@@ -0,0 +1,11 @@
1
+ CREATE TABLE IF NOT EXISTS data_management_settings (
2
+ id INTEGER PRIMARY KEY CHECK (id = 1),
3
+ preferred_data_root TEXT NOT NULL DEFAULT '',
4
+ backup_directory TEXT NOT NULL DEFAULT '',
5
+ backup_frequency_hours INTEGER,
6
+ auto_repair_enabled INTEGER NOT NULL DEFAULT 1,
7
+ last_auto_backup_at TEXT,
8
+ last_manual_backup_at TEXT,
9
+ created_at TEXT NOT NULL,
10
+ updated_at TEXT NOT NULL
11
+ );
@@ -0,0 +1,114 @@
1
+ ALTER TABLE tasks
2
+ ADD COLUMN resolution_kind TEXT;
3
+
4
+ ALTER TABLE tasks
5
+ ADD COLUMN split_parent_task_id TEXT;
6
+
7
+ CREATE TABLE IF NOT EXISTS life_force_profiles (
8
+ user_id TEXT PRIMARY KEY,
9
+ base_daily_ap INTEGER NOT NULL DEFAULT 200,
10
+ readiness_multiplier REAL NOT NULL DEFAULT 1.0,
11
+ life_force_level INTEGER NOT NULL DEFAULT 1,
12
+ activation_level INTEGER NOT NULL DEFAULT 1,
13
+ focus_level INTEGER NOT NULL DEFAULT 1,
14
+ vigor_level INTEGER NOT NULL DEFAULT 1,
15
+ composure_level INTEGER NOT NULL DEFAULT 1,
16
+ flow_level INTEGER NOT NULL DEFAULT 1,
17
+ created_at TEXT NOT NULL,
18
+ updated_at TEXT NOT NULL
19
+ );
20
+
21
+ CREATE TABLE IF NOT EXISTS life_force_weekday_templates (
22
+ id TEXT PRIMARY KEY,
23
+ user_id TEXT NOT NULL,
24
+ weekday INTEGER NOT NULL,
25
+ baseline_daily_ap INTEGER NOT NULL DEFAULT 200,
26
+ points_json TEXT NOT NULL,
27
+ created_at TEXT NOT NULL,
28
+ updated_at TEXT NOT NULL,
29
+ UNIQUE(user_id, weekday)
30
+ );
31
+
32
+ CREATE TABLE IF NOT EXISTS life_force_day_snapshots (
33
+ id TEXT PRIMARY KEY,
34
+ user_id TEXT NOT NULL,
35
+ date_key TEXT NOT NULL,
36
+ daily_budget_ap REAL NOT NULL,
37
+ sleep_recovery_multiplier REAL NOT NULL DEFAULT 1.0,
38
+ readiness_multiplier REAL NOT NULL DEFAULT 1.0,
39
+ fatigue_debt_carry REAL NOT NULL DEFAULT 0,
40
+ points_json TEXT NOT NULL,
41
+ created_at TEXT NOT NULL,
42
+ updated_at TEXT NOT NULL,
43
+ UNIQUE(user_id, date_key)
44
+ );
45
+
46
+ CREATE TABLE IF NOT EXISTS action_profile_templates (
47
+ id TEXT PRIMARY KEY,
48
+ profile_key TEXT NOT NULL UNIQUE,
49
+ entity_type TEXT,
50
+ title TEXT NOT NULL,
51
+ profile_json TEXT NOT NULL,
52
+ created_at TEXT NOT NULL,
53
+ updated_at TEXT NOT NULL
54
+ );
55
+
56
+ CREATE TABLE IF NOT EXISTS entity_action_profiles (
57
+ id TEXT PRIMARY KEY,
58
+ entity_type TEXT NOT NULL,
59
+ entity_id TEXT NOT NULL,
60
+ profile_json TEXT NOT NULL,
61
+ created_at TEXT NOT NULL,
62
+ updated_at TEXT NOT NULL,
63
+ UNIQUE(entity_type, entity_id)
64
+ );
65
+
66
+ CREATE TABLE IF NOT EXISTS ap_ledger_events (
67
+ id TEXT PRIMARY KEY,
68
+ user_id TEXT NOT NULL,
69
+ date_key TEXT NOT NULL,
70
+ entity_type TEXT NOT NULL,
71
+ entity_id TEXT NOT NULL,
72
+ event_kind TEXT NOT NULL,
73
+ source_kind TEXT NOT NULL,
74
+ starts_at TEXT,
75
+ ends_at TEXT,
76
+ total_ap REAL NOT NULL,
77
+ rate_ap_per_hour REAL,
78
+ metadata_json TEXT NOT NULL DEFAULT '{}',
79
+ created_at TEXT NOT NULL
80
+ );
81
+
82
+ CREATE INDEX IF NOT EXISTS idx_ap_ledger_user_date
83
+ ON ap_ledger_events(user_id, date_key, created_at DESC);
84
+
85
+ CREATE INDEX IF NOT EXISTS idx_ap_ledger_entity
86
+ ON ap_ledger_events(entity_type, entity_id, created_at DESC);
87
+
88
+ CREATE TABLE IF NOT EXISTS stat_xp_events (
89
+ id TEXT PRIMARY KEY,
90
+ user_id TEXT NOT NULL,
91
+ stat_key TEXT NOT NULL,
92
+ delta_xp REAL NOT NULL,
93
+ entity_type TEXT,
94
+ entity_id TEXT,
95
+ metadata_json TEXT NOT NULL DEFAULT '{}',
96
+ created_at TEXT NOT NULL
97
+ );
98
+
99
+ CREATE INDEX IF NOT EXISTS idx_stat_xp_user_stat
100
+ ON stat_xp_events(user_id, stat_key, created_at DESC);
101
+
102
+ CREATE TABLE IF NOT EXISTS fatigue_signals (
103
+ id TEXT PRIMARY KEY,
104
+ user_id TEXT NOT NULL,
105
+ date_key TEXT NOT NULL,
106
+ signal_type TEXT NOT NULL,
107
+ observed_at TEXT NOT NULL,
108
+ note TEXT NOT NULL DEFAULT '',
109
+ delta REAL NOT NULL DEFAULT 0,
110
+ created_at TEXT NOT NULL
111
+ );
112
+
113
+ CREATE INDEX IF NOT EXISTS idx_fatigue_signals_user_date
114
+ ON fatigue_signals(user_id, date_key, observed_at DESC);