forge-openclaw-plugin 0.2.24 → 0.2.26

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 (208) hide show
  1. package/README.md +13 -0
  2. package/dist/assets/{board-_C6oMy5w.js → board-ta0rUHOf.js} +3 -3
  3. package/dist/assets/{board-_C6oMy5w.js.map → board-ta0rUHOf.js.map} +1 -1
  4. package/dist/assets/index-Ro0ZF_az.css +1 -0
  5. package/dist/assets/index-ytlpSj23.js +79 -0
  6. package/dist/assets/index-ytlpSj23.js.map +1 -0
  7. package/dist/assets/{motion-D4sZgCHd.js → motion-fBKPB6yw.js} +3 -3
  8. package/dist/assets/motion-fBKPB6yw.js.map +1 -0
  9. package/dist/assets/{table-BWzTaky1.js → table-C-IGTQni.js} +2 -2
  10. package/dist/assets/{table-BWzTaky1.js.map → table-C-IGTQni.js.map} +1 -1
  11. package/dist/assets/{ui-BzK4azQb.js → ui-DInOpaYF.js} +2 -2
  12. package/dist/assets/{ui-BzK4azQb.js.map → ui-DInOpaYF.js.map} +1 -1
  13. package/dist/assets/vendor-lE3tZJcC.js +876 -0
  14. package/dist/assets/vendor-lE3tZJcC.js.map +1 -0
  15. package/dist/index.html +7 -8
  16. package/dist/openclaw/local-runtime.d.ts +3 -1
  17. package/dist/openclaw/local-runtime.js +51 -15
  18. package/dist/openclaw/parity.d.ts +1 -1
  19. package/dist/openclaw/parity.js +29 -0
  20. package/dist/openclaw/plugin-entry-shared.d.ts +1 -0
  21. package/dist/openclaw/plugin-entry-shared.js +31 -6
  22. package/dist/openclaw/plugin-sdk-types.d.ts +29 -0
  23. package/dist/openclaw/routes.js +236 -0
  24. package/dist/openclaw/session-bootstrap.d.ts +78 -0
  25. package/dist/openclaw/session-bootstrap.js +240 -0
  26. package/dist/openclaw/tools.js +279 -6
  27. package/dist/server/server/migrations/001_core.sql +411 -0
  28. package/dist/server/server/migrations/002_psyche.sql +392 -0
  29. package/dist/server/server/migrations/003_habits.sql +30 -0
  30. package/dist/server/server/migrations/004_habit_links.sql +8 -0
  31. package/dist/server/server/migrations/005_habit_psyche_links.sql +24 -0
  32. package/dist/server/server/migrations/006_work_adjustments.sql +14 -0
  33. package/dist/server/server/migrations/007_weekly_review_closures.sql +17 -0
  34. package/dist/server/server/migrations/008_calendar_execution.sql +147 -0
  35. package/dist/server/server/migrations/009_true_calendar_events.sql +195 -0
  36. package/dist/server/server/migrations/010_calendar_selection_state.sql +6 -0
  37. package/dist/server/server/migrations/011_calendar_timezone_backfill.sql +11 -0
  38. package/dist/server/server/migrations/012_work_block_ranges.sql +7 -0
  39. package/dist/server/server/migrations/013_microsoft_local_auth_settings.sql +8 -0
  40. package/dist/server/server/migrations/014_note_tags_and_ephemeral.sql +8 -0
  41. package/dist/server/server/migrations/015_multi_user_and_strategies.sql +244 -0
  42. package/dist/server/server/migrations/016_health_companion.sql +158 -0
  43. package/dist/server/server/migrations/016_strategy_contracts_and_user_graph.sql +22 -0
  44. package/dist/server/server/migrations/017_preferences.sql +131 -0
  45. package/dist/server/server/migrations/018_preference_catalogs.sql +31 -0
  46. package/dist/server/server/migrations/019_wiki_memory.sql +255 -0
  47. package/dist/server/server/migrations/020_wiki_page_hierarchy.sql +11 -0
  48. package/dist/server/server/migrations/021_hide_evidence_from_wiki_index.sql +3 -0
  49. package/dist/server/server/migrations/022_wiki_ingest_background.sql +85 -0
  50. package/dist/server/server/migrations/023_diagnostic_logs.sql +28 -0
  51. package/dist/server/server/migrations/024_questionnaires.sql +96 -0
  52. package/dist/server/server/migrations/025_ai_model_connections.sql +26 -0
  53. package/dist/server/server/migrations/026_custom_theme_settings.sql +2 -0
  54. package/dist/server/server/migrations/027_ai_processors.sql +31 -0
  55. package/dist/server/server/migrations/028_movement_domain.sql +136 -0
  56. package/dist/server/server/migrations/029_watch_micro_capture.sql +23 -0
  57. package/dist/server/server/migrations/030_surface_layouts.sql +5 -0
  58. package/dist/server/server/migrations/031_ai_processor_runtime_upgrades.sql +10 -0
  59. package/dist/server/server/migrations/032_ai_connectors.sql +44 -0
  60. package/dist/server/server/migrations/033_movement_trip_point_sync.sql +36 -0
  61. package/dist/server/server/migrations/034_movement_segment_sync.sql +49 -0
  62. package/dist/server/server/migrations/035_google_local_auth_settings.sql +2 -0
  63. package/dist/server/server/migrations/036_google_local_auth_client_secret.sql +2 -0
  64. package/dist/server/{app.js → server/src/app.js} +992 -25
  65. package/dist/server/server/src/connectors/box-registry.js +188 -0
  66. package/dist/server/{db.js → server/src/db.js} +6 -0
  67. package/dist/server/server/src/debug.js +19 -0
  68. package/dist/server/server/src/discovery-advertiser.js +114 -0
  69. package/dist/server/{health.js → server/src/health.js} +39 -11
  70. package/dist/server/{index.js → server/src/index.js} +4 -0
  71. package/dist/server/{managers → server/src/managers}/platform/llm-manager.js +40 -4
  72. package/dist/server/{managers → server/src/managers}/platform/openai-responses-provider.js +129 -19
  73. package/dist/server/server/src/movement.js +2935 -0
  74. package/dist/server/{openapi.js → server/src/openapi.js} +628 -5
  75. package/dist/server/{psyche-types.js → server/src/psyche-types.js} +15 -1
  76. package/dist/server/server/src/questionnaire-flow.js +552 -0
  77. package/dist/server/server/src/questionnaire-seeds.js +853 -0
  78. package/dist/server/server/src/questionnaire-types.js +340 -0
  79. package/dist/server/server/src/repositories/ai-connectors.js +1207 -0
  80. package/dist/server/server/src/repositories/ai-processors.js +547 -0
  81. package/dist/server/{repositories → server/src/repositories}/calendar.js +1 -1
  82. package/dist/server/{repositories → server/src/repositories}/entity-ownership.js +9 -1
  83. package/dist/server/{repositories → server/src/repositories}/habits.js +69 -5
  84. package/dist/server/server/src/repositories/model-settings.js +216 -0
  85. package/dist/server/{repositories → server/src/repositories}/notes.js +57 -15
  86. package/dist/server/{repositories → server/src/repositories}/preferences.js +124 -0
  87. package/dist/server/server/src/repositories/questionnaires.js +1338 -0
  88. package/dist/server/{repositories → server/src/repositories}/settings.js +156 -12
  89. package/dist/server/server/src/repositories/surface-layouts.js +76 -0
  90. package/dist/server/{repositories → server/src/repositories}/wiki-memory.js +5 -1
  91. package/dist/server/{services → server/src/services}/calendar-runtime.js +775 -58
  92. package/dist/server/{services → server/src/services}/entity-crud.js +81 -2
  93. package/dist/server/server/src/services/google-calendar-oauth-config.js +176 -0
  94. package/dist/server/server/src/services/openai-codex-oauth.js +153 -0
  95. package/dist/server/server/src/services/psyche-observation-calendar.js +46 -0
  96. package/dist/server/{types.js → server/src/types.js} +621 -14
  97. package/dist/server/server/src/watch-mobile.js +562 -0
  98. package/dist/server/{web.js → server/src/web.js} +30 -4
  99. package/dist/server/src/components/customization/utility-widgets.js +330 -0
  100. package/dist/server/src/components/workbench-boxes/health/health-boxes.js +92 -0
  101. package/dist/server/src/components/workbench-boxes/kanban/kanban-boxes.js +128 -0
  102. package/dist/server/src/components/workbench-boxes/movement/movement-boxes.js +37 -0
  103. package/dist/server/src/components/workbench-boxes/notes/notes-boxes.js +114 -0
  104. package/dist/server/src/components/workbench-boxes/projects/projects-boxes.js +57 -0
  105. package/dist/server/src/components/workbench-boxes/shared/define-workbench-box.js +4 -0
  106. package/dist/server/src/components/workbench-boxes/shared/generic-node-view.js +13 -0
  107. package/dist/server/src/components/workbench-boxes/today/today-boxes.js +63 -0
  108. package/dist/server/src/lib/api-error.js +37 -0
  109. package/dist/server/src/lib/api.js +1859 -0
  110. package/dist/server/src/lib/calendar-name-deduper.js +144 -0
  111. package/dist/server/src/lib/diagnostics.js +67 -0
  112. package/dist/server/src/lib/psyche-types.js +1 -0
  113. package/dist/server/src/lib/questionnaire-types.js +1 -0
  114. package/dist/server/src/lib/runtime-paths.js +24 -0
  115. package/dist/server/src/lib/schemas.js +234 -0
  116. package/dist/server/src/lib/snapshot-normalizer.js +374 -0
  117. package/dist/server/src/lib/theme-system.js +319 -0
  118. package/dist/server/src/lib/types.js +1 -0
  119. package/dist/server/src/lib/utils.js +22 -0
  120. package/dist/server/src/lib/workbench/boxes.js +16 -0
  121. package/dist/server/src/lib/workbench/nodes.js +15 -0
  122. package/dist/server/src/lib/workbench/registry.js +73 -0
  123. package/dist/server/src/lib/workbench/runtime.js +181 -0
  124. package/openclaw.plugin.json +1 -1
  125. package/package.json +6 -1
  126. package/server/index.js +68 -0
  127. package/server/migrations/024_questionnaires.sql +96 -0
  128. package/server/migrations/025_ai_model_connections.sql +26 -0
  129. package/server/migrations/026_custom_theme_settings.sql +2 -0
  130. package/server/migrations/027_ai_processors.sql +31 -0
  131. package/server/migrations/028_movement_domain.sql +136 -0
  132. package/server/migrations/029_watch_micro_capture.sql +23 -0
  133. package/server/migrations/030_surface_layouts.sql +5 -0
  134. package/server/migrations/031_ai_processor_runtime_upgrades.sql +10 -0
  135. package/server/migrations/032_ai_connectors.sql +44 -0
  136. package/server/migrations/033_movement_trip_point_sync.sql +36 -0
  137. package/server/migrations/034_movement_segment_sync.sql +49 -0
  138. package/server/migrations/035_google_local_auth_settings.sql +2 -0
  139. package/server/migrations/036_google_local_auth_client_secret.sql +2 -0
  140. package/skills/forge-openclaw/SKILL.md +15 -1
  141. package/skills/forge-openclaw/entity_conversation_playbooks.md +523 -87
  142. package/skills/forge-openclaw/psyche_entity_playbooks.md +331 -221
  143. package/dist/assets/index-DTCwBWAs.js +0 -65
  144. package/dist/assets/index-DTCwBWAs.js.map +0 -1
  145. package/dist/assets/index-DttXlAgi.css +0 -1
  146. package/dist/assets/motion-D4sZgCHd.js.map +0 -1
  147. package/dist/assets/vendor-De38P6YR.js +0 -729
  148. package/dist/assets/vendor-De38P6YR.js.map +0 -1
  149. package/dist/assets/viz-C6hfyqzu.js +0 -34
  150. package/dist/assets/viz-C6hfyqzu.js.map +0 -1
  151. package/skills/forge-openclaw/cron_jobs.md +0 -395
  152. /package/dist/server/{demo-data.js → server/src/demo-data.js} +0 -0
  153. /package/dist/server/{e2e-server.js → server/src/e2e-server.js} +0 -0
  154. /package/dist/server/{errors.js → server/src/errors.js} +0 -0
  155. /package/dist/server/{managers → server/src/managers}/base.js +0 -0
  156. /package/dist/server/{managers → server/src/managers}/contracts.js +0 -0
  157. /package/dist/server/{managers → server/src/managers}/platform/api-gateway-manager.js +0 -0
  158. /package/dist/server/{managers → server/src/managers}/platform/audit-manager.js +0 -0
  159. /package/dist/server/{managers → server/src/managers}/platform/authentication-manager.js +0 -0
  160. /package/dist/server/{managers → server/src/managers}/platform/authorization-manager.js +0 -0
  161. /package/dist/server/{managers → server/src/managers}/platform/background-job-manager.js +0 -0
  162. /package/dist/server/{managers → server/src/managers}/platform/configuration-manager.js +0 -0
  163. /package/dist/server/{managers → server/src/managers}/platform/database-manager.js +0 -0
  164. /package/dist/server/{managers → server/src/managers}/platform/event-bus-manager.js +0 -0
  165. /package/dist/server/{managers → server/src/managers}/platform/external-service-manager.js +0 -0
  166. /package/dist/server/{managers → server/src/managers}/platform/health-manager.js +0 -0
  167. /package/dist/server/{managers → server/src/managers}/platform/migration-manager.js +0 -0
  168. /package/dist/server/{managers → server/src/managers}/platform/search-index-manager.js +0 -0
  169. /package/dist/server/{managers → server/src/managers}/platform/secrets-manager.js +0 -0
  170. /package/dist/server/{managers → server/src/managers}/platform/session-manager.js +0 -0
  171. /package/dist/server/{managers → server/src/managers}/platform/storage-manager.js +0 -0
  172. /package/dist/server/{managers → server/src/managers}/platform/token-manager.js +0 -0
  173. /package/dist/server/{managers → server/src/managers}/platform/transaction-manager.js +0 -0
  174. /package/dist/server/{managers → server/src/managers}/platform/trusted-network.js +0 -0
  175. /package/dist/server/{managers → server/src/managers}/runtime.js +0 -0
  176. /package/dist/server/{managers → server/src/managers}/type-guards.js +0 -0
  177. /package/dist/server/{preferences-seeds.js → server/src/preferences-seeds.js} +0 -0
  178. /package/dist/server/{preferences-types.js → server/src/preferences-types.js} +0 -0
  179. /package/dist/server/{repositories → server/src/repositories}/activity-events.js +0 -0
  180. /package/dist/server/{repositories → server/src/repositories}/collaboration.js +0 -0
  181. /package/dist/server/{repositories → server/src/repositories}/deleted-entities.js +0 -0
  182. /package/dist/server/{repositories → server/src/repositories}/diagnostic-logs.js +0 -0
  183. /package/dist/server/{repositories → server/src/repositories}/domains.js +0 -0
  184. /package/dist/server/{repositories → server/src/repositories}/event-log.js +0 -0
  185. /package/dist/server/{repositories → server/src/repositories}/goals.js +0 -0
  186. /package/dist/server/{repositories → server/src/repositories}/projects.js +0 -0
  187. /package/dist/server/{repositories → server/src/repositories}/psyche.js +0 -0
  188. /package/dist/server/{repositories → server/src/repositories}/rewards.js +0 -0
  189. /package/dist/server/{repositories → server/src/repositories}/strategies.js +0 -0
  190. /package/dist/server/{repositories → server/src/repositories}/tags.js +0 -0
  191. /package/dist/server/{repositories → server/src/repositories}/task-runs.js +0 -0
  192. /package/dist/server/{repositories → server/src/repositories}/tasks.js +0 -0
  193. /package/dist/server/{repositories → server/src/repositories}/users.js +0 -0
  194. /package/dist/server/{repositories → server/src/repositories}/weekly-reviews.js +0 -0
  195. /package/dist/server/{repositories → server/src/repositories}/work-adjustments.js +0 -0
  196. /package/dist/server/{seed-demo.js → server/src/seed-demo.js} +0 -0
  197. /package/dist/server/{services → server/src/services}/context.js +0 -0
  198. /package/dist/server/{services → server/src/services}/dashboard.js +0 -0
  199. /package/dist/server/{services → server/src/services}/gamification.js +0 -0
  200. /package/dist/server/{services → server/src/services}/insights.js +0 -0
  201. /package/dist/server/{services → server/src/services}/projects.js +0 -0
  202. /package/dist/server/{services → server/src/services}/psyche.js +0 -0
  203. /package/dist/server/{services → server/src/services}/relations.js +0 -0
  204. /package/dist/server/{services → server/src/services}/reviews.js +0 -0
  205. /package/dist/server/{services → server/src/services}/run-recovery.js +0 -0
  206. /package/dist/server/{services → server/src/services}/tagging.js +0 -0
  207. /package/dist/server/{services → server/src/services}/task-run-watchdog.js +0 -0
  208. /package/dist/server/{services → server/src/services}/work-time.js +0 -0
@@ -0,0 +1,22 @@
1
+ import { clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+ export function cn(...inputs) {
4
+ return twMerge(clsx(inputs));
5
+ }
6
+ export function formatDateTime(value) {
7
+ return new Intl.DateTimeFormat(undefined, {
8
+ month: "short",
9
+ day: "numeric",
10
+ hour: "numeric",
11
+ minute: "2-digit"
12
+ }).format(new Date(value));
13
+ }
14
+ export function formatDate(value) {
15
+ if (!value) {
16
+ return "No date";
17
+ }
18
+ return new Intl.DateTimeFormat(undefined, {
19
+ month: "short",
20
+ day: "numeric"
21
+ }).format(new Date(`${value}T00:00:00.000Z`));
22
+ }
@@ -0,0 +1,16 @@
1
+ import { getWorkbenchNodeCatalog, getWorkbenchNodeDefinition, listWorkbenchNodeDefinitions } from "./registry.js";
2
+ export function listWorkbenchBoxDefinitions() {
3
+ return listWorkbenchNodeDefinitions();
4
+ }
5
+ export function getWorkbenchBoxDefinition(boxId) {
6
+ return getWorkbenchNodeDefinition(boxId);
7
+ }
8
+ export function getWorkbenchBoxDefinitionForSurfaceWidget(surfaceId, widgetId) {
9
+ return getWorkbenchBoxDefinition(`surface:${surfaceId}:${widgetId}`);
10
+ }
11
+ export function getWorkbenchBoxDefinitionForRouteMain(surfaceId) {
12
+ return getWorkbenchBoxDefinition(`surface:${surfaceId}:main`);
13
+ }
14
+ export function listWorkbenchBoxCatalogEntries() {
15
+ return getWorkbenchNodeCatalog();
16
+ }
@@ -0,0 +1,15 @@
1
+ export function defineWorkbenchComponent(component, workbench) {
2
+ return Object.assign(component, {
3
+ workbench: {
4
+ ...workbench,
5
+ WebView: component
6
+ }
7
+ });
8
+ }
9
+ export function isWorkbenchRegisteredComponent(value) {
10
+ const candidate = value;
11
+ return Boolean(candidate &&
12
+ typeof value === "function" &&
13
+ candidate.workbench &&
14
+ typeof candidate.workbench.id === "string");
15
+ }
@@ -0,0 +1,73 @@
1
+ import { MiniCalendarWidget, QuickCaptureWidget, SpotifyWidget, TimeWidget, WeatherWidget } from "../../components/customization/utility-widgets.js";
2
+ import { KanbanBoardBox, KanbanFiltersBox, KanbanSummaryBox } from "../../components/workbench-boxes/kanban/kanban-boxes.js";
3
+ import { SleepBrowserBox, SleepPatternsBox, SleepSummaryBox, SportsBrowserBox, SportsCompositionBox, SportsSummaryBox } from "../../components/workbench-boxes/health/health-boxes.js";
4
+ import { MovementDataBrowserBox, MovementPlacesBox, MovementSelectionBox, MovementSummaryBox, MovementTimelineBox } from "../../components/workbench-boxes/movement/movement-boxes.js";
5
+ import { NoteComposerBox, NoteFiltersBox, NotesLibraryBox } from "../../components/workbench-boxes/notes/notes-boxes.js";
6
+ import { ProjectsHeroBox, ProjectsSearchResultsBox, ProjectsSummaryBox } from "../../components/workbench-boxes/projects/projects-boxes.js";
7
+ import { TodayCalendarBox, TodayFocusBox, TodayHeroBox, TodayMetricsBox, TodayRunwayBox } from "../../components/workbench-boxes/today/today-boxes.js";
8
+ export const WORKBENCH_COMPONENT_AUTOLOAD = [
9
+ TimeWidget,
10
+ MiniCalendarWidget,
11
+ SpotifyWidget,
12
+ WeatherWidget,
13
+ QuickCaptureWidget,
14
+ KanbanSummaryBox,
15
+ KanbanFiltersBox,
16
+ KanbanBoardBox,
17
+ NoteFiltersBox,
18
+ NoteComposerBox,
19
+ NotesLibraryBox,
20
+ MovementSummaryBox,
21
+ MovementSelectionBox,
22
+ MovementTimelineBox,
23
+ MovementPlacesBox,
24
+ MovementDataBrowserBox,
25
+ SleepSummaryBox,
26
+ SleepPatternsBox,
27
+ SleepBrowserBox,
28
+ SportsSummaryBox,
29
+ SportsCompositionBox,
30
+ SportsBrowserBox,
31
+ ProjectsHeroBox,
32
+ ProjectsSearchResultsBox,
33
+ ProjectsSummaryBox,
34
+ TodayHeroBox,
35
+ TodayMetricsBox,
36
+ TodayRunwayBox,
37
+ TodayCalendarBox,
38
+ TodayFocusBox
39
+ ];
40
+ const REGISTRY = new Map(WORKBENCH_COMPONENT_AUTOLOAD
41
+ .filter((component) => component.workbench)
42
+ .map((component) => [component.workbench.id, component.workbench]));
43
+ export function listWorkbenchNodeDefinitions() {
44
+ return Array.from(REGISTRY.values());
45
+ }
46
+ export function getWorkbenchNodeDefinition(nodeId) {
47
+ return REGISTRY.get(nodeId) ?? null;
48
+ }
49
+ export function getWorkbenchNodeCatalog() {
50
+ return listWorkbenchNodeDefinitions().map((definition) => ({
51
+ id: definition.id,
52
+ boxId: definition.id,
53
+ surfaceId: definition.surfaceId,
54
+ routePath: definition.routePath,
55
+ title: definition.title,
56
+ label: definition.title,
57
+ icon: definition.icon ?? null,
58
+ description: definition.description,
59
+ category: definition.category,
60
+ tags: definition.tags,
61
+ capabilityModes: [
62
+ "content",
63
+ ...(definition.tools.length > 0 ? ["tool"] : [])
64
+ ],
65
+ inputs: definition.inputs,
66
+ params: definition.params,
67
+ output: definition.output,
68
+ tools: definition.tools,
69
+ outputs: definition.output,
70
+ toolAdapters: definition.tools,
71
+ snapshotResolverKey: undefined
72
+ }));
73
+ }
@@ -0,0 +1,181 @@
1
+ function asRecord(value) {
2
+ return value && typeof value === "object" && !Array.isArray(value)
3
+ ? value
4
+ : null;
5
+ }
6
+ export function buildWorkbenchOutputMap(text, json, keys) {
7
+ const outputMap = {
8
+ primary: {
9
+ text,
10
+ json
11
+ }
12
+ };
13
+ for (const key of keys) {
14
+ if (!json || !(key in json)) {
15
+ outputMap[key] = {
16
+ text,
17
+ json
18
+ };
19
+ continue;
20
+ }
21
+ const value = json[key];
22
+ outputMap[key] = {
23
+ text: typeof value === "string"
24
+ ? value
25
+ : Array.isArray(value) || asRecord(value)
26
+ ? JSON.stringify(value, null, 2)
27
+ : String(value ?? ""),
28
+ json: asRecord(value)
29
+ };
30
+ }
31
+ return outputMap;
32
+ }
33
+ export function buildWorkbenchExecutionEnvelope(input, value) {
34
+ const payload = {
35
+ nodeId: input.nodeId,
36
+ nodeType: input.definition.id,
37
+ title: input.definition.title,
38
+ inputs: input.inputs,
39
+ params: input.params,
40
+ output: value.output,
41
+ logs: value.logs ?? []
42
+ };
43
+ return {
44
+ primaryText: value.primaryText,
45
+ payload,
46
+ logs: value.logs ?? [],
47
+ outputMap: buildWorkbenchOutputMap(value.primaryText, payload, Object.keys(value.output ?? {}))
48
+ };
49
+ }
50
+ export function buildStaticWorkbenchExecution(input, output, primaryText, logs) {
51
+ return buildWorkbenchExecutionEnvelope(input, {
52
+ primaryText: primaryText ??
53
+ `${input.definition.title}\n${input.definition.description}\nRoute: ${input.definition.routePath ?? "n/a"}`,
54
+ output,
55
+ logs
56
+ });
57
+ }
58
+ export function searchWorkbenchEntities(context, definition, input) {
59
+ const limit = Math.max(1, Math.min(50, Math.round(input.limit ?? 12)));
60
+ const result = context.services.entities.search({
61
+ searches: [
62
+ {
63
+ query: input.query,
64
+ entityTypes: input.entityTypes,
65
+ limit
66
+ }
67
+ ]
68
+ }).results[0];
69
+ const matches = result?.ok ? result.matches ?? [] : [];
70
+ const summaryLines = matches
71
+ .slice(0, limit)
72
+ .map((match) => {
73
+ const title = typeof match.title === "string"
74
+ ? match.title
75
+ : typeof match.name === "string"
76
+ ? match.name
77
+ : typeof match.id === "string"
78
+ ? match.id
79
+ : "Untitled";
80
+ const entityType = typeof match.entityType === "string" ? match.entityType : "entity";
81
+ return `${entityType}: ${title}`;
82
+ });
83
+ return {
84
+ title: definition.title,
85
+ matches,
86
+ summaryText: summaryLines.length > 0
87
+ ? summaryLines.join("\n")
88
+ : `No ${definition.title.toLowerCase()} matches found.`,
89
+ limit
90
+ };
91
+ }
92
+ export function buildSearchWorkbenchExecution(input, config) {
93
+ const summary = searchWorkbenchEntities(input.context, input.definition, config);
94
+ return buildWorkbenchExecutionEnvelope(input, {
95
+ primaryText: summary.summaryText,
96
+ output: {
97
+ matches: summary.matches,
98
+ limit: summary.limit,
99
+ entityTypes: config.entityTypes
100
+ }
101
+ });
102
+ }
103
+ export function buildMovementPlacesExecution(input) {
104
+ const places = input.context.services.movement.listPlaces?.() ?? [];
105
+ return buildWorkbenchExecutionEnvelope(input, {
106
+ primaryText: places.length > 0
107
+ ? places
108
+ .slice(0, 24)
109
+ .map((place) => typeof place.label === "string"
110
+ ? place.label
111
+ : typeof place.name === "string"
112
+ ? place.name
113
+ : typeof place.id === "string"
114
+ ? place.id
115
+ : "Place")
116
+ .join("\n")
117
+ : "No known places are stored yet.",
118
+ output: {
119
+ places
120
+ }
121
+ });
122
+ }
123
+ export function buildSleepWorkbenchExecution(input) {
124
+ const payload = input.context.services.health.getSleepViewData?.() ?? null;
125
+ return buildWorkbenchExecutionEnvelope(input, {
126
+ primaryText: payload && typeof payload === "object"
127
+ ? "Sleep history and derived patterns are available."
128
+ : "No sleep data is available.",
129
+ output: asRecord(payload)
130
+ });
131
+ }
132
+ export function buildSportsWorkbenchExecution(input) {
133
+ const payload = input.context.services.health.getFitnessViewData?.() ?? null;
134
+ return buildWorkbenchExecutionEnvelope(input, {
135
+ primaryText: payload && typeof payload === "object"
136
+ ? "Workout history and composition are available."
137
+ : "No sports data is available.",
138
+ output: asRecord(payload)
139
+ });
140
+ }
141
+ export function mapWorkbenchTools(tools) {
142
+ return tools.map(({ argsSchema: _argsSchema, ...tool }) => tool);
143
+ }
144
+ export function executeCommonWorkbenchTool(context, definition, toolKey, args) {
145
+ if (toolKey === "forge.search_entities") {
146
+ const query = typeof args.query === "string" ? args.query.trim() : "";
147
+ const entityTypes = Array.isArray(args.entityTypes)
148
+ ? args.entityTypes.filter((entry) => typeof entry === "string" && entry.length > 0)
149
+ : [];
150
+ const limit = typeof args.limit === "number" && Number.isFinite(args.limit)
151
+ ? args.limit
152
+ : 12;
153
+ return searchWorkbenchEntities(context, definition, {
154
+ query,
155
+ entityTypes,
156
+ limit
157
+ });
158
+ }
159
+ if (toolKey === "forge.update_task_status") {
160
+ const taskId = typeof args.taskId === "string" ? args.taskId : "";
161
+ const status = typeof args.status === "string" ? args.status : "";
162
+ if (!context.services.tasks.update) {
163
+ throw new Error("Task update service is not available.");
164
+ }
165
+ return context.services.tasks.update(taskId, { status });
166
+ }
167
+ if (toolKey === "forge.create_note") {
168
+ if (!context.services.notes.create) {
169
+ throw new Error("Note creation service is not available.");
170
+ }
171
+ return context.services.notes.create({
172
+ kind: "evidence",
173
+ title: typeof args.title === "string" ? args.title : "Workbench note",
174
+ contentMarkdown: typeof args.markdown === "string" ? args.markdown : "",
175
+ summary: typeof args.summary === "string" ? args.summary : "",
176
+ sourcePath: "workbench",
177
+ author: "Workbench"
178
+ });
179
+ }
180
+ throw new Error(`Unsupported Workbench tool: ${toolKey}`);
181
+ }
@@ -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.24",
5
+ "version": "0.2.26",
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.24",
3
+ "version": "0.2.26",
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",
@@ -44,9 +44,14 @@
44
44
  "openclaw": "^2026.3.22"
45
45
  },
46
46
  "dependencies": {
47
+ "@azure/msal-node": "^5.1.2",
47
48
  "@fastify/cors": "^10.0.1",
49
+ "@fastify/multipart": "^9.4.0",
48
50
  "@sinclair/typebox": "^0.34.48",
51
+ "adm-zip": "^0.5.17",
49
52
  "fastify": "^5.2.1",
53
+ "node-ical": "^0.20.1",
54
+ "tsdav": "^2.1.8",
50
55
  "zod": "^3.25.67"
51
56
  },
52
57
  "scripts": {
@@ -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,96 @@
1
+ CREATE TABLE IF NOT EXISTS questionnaire_instruments (
2
+ id TEXT PRIMARY KEY,
3
+ key TEXT NOT NULL UNIQUE,
4
+ slug TEXT NOT NULL UNIQUE,
5
+ title TEXT NOT NULL,
6
+ subtitle TEXT NOT NULL DEFAULT '',
7
+ description TEXT NOT NULL DEFAULT '',
8
+ aliases_json TEXT NOT NULL DEFAULT '[]',
9
+ symptom_domains_json TEXT NOT NULL DEFAULT '[]',
10
+ tags_json TEXT NOT NULL DEFAULT '[]',
11
+ source_class TEXT NOT NULL,
12
+ availability TEXT NOT NULL,
13
+ is_self_report INTEGER NOT NULL DEFAULT 1,
14
+ is_system INTEGER NOT NULL DEFAULT 0,
15
+ status TEXT NOT NULL DEFAULT 'active',
16
+ owner_user_id TEXT,
17
+ current_draft_version_id TEXT,
18
+ current_published_version_id TEXT,
19
+ created_at TEXT NOT NULL,
20
+ updated_at TEXT NOT NULL
21
+ );
22
+
23
+ CREATE TABLE IF NOT EXISTS questionnaire_versions (
24
+ id TEXT PRIMARY KEY,
25
+ instrument_id TEXT NOT NULL REFERENCES questionnaire_instruments(id) ON DELETE CASCADE,
26
+ version_number INTEGER NOT NULL,
27
+ status TEXT NOT NULL,
28
+ label TEXT NOT NULL DEFAULT '',
29
+ definition_json TEXT NOT NULL,
30
+ scoring_json TEXT NOT NULL,
31
+ provenance_json TEXT NOT NULL,
32
+ is_read_only INTEGER NOT NULL DEFAULT 0,
33
+ created_by TEXT,
34
+ created_at TEXT NOT NULL,
35
+ updated_at TEXT NOT NULL,
36
+ published_at TEXT,
37
+ UNIQUE (instrument_id, version_number)
38
+ );
39
+
40
+ CREATE TABLE IF NOT EXISTS questionnaire_runs (
41
+ id TEXT PRIMARY KEY,
42
+ instrument_id TEXT NOT NULL REFERENCES questionnaire_instruments(id) ON DELETE CASCADE,
43
+ version_id TEXT NOT NULL REFERENCES questionnaire_versions(id) ON DELETE CASCADE,
44
+ user_id TEXT,
45
+ status TEXT NOT NULL,
46
+ progress_index INTEGER NOT NULL DEFAULT 0,
47
+ started_at TEXT NOT NULL,
48
+ updated_at TEXT NOT NULL,
49
+ completed_at TEXT
50
+ );
51
+
52
+ CREATE TABLE IF NOT EXISTS questionnaire_answers (
53
+ id TEXT PRIMARY KEY,
54
+ run_id TEXT NOT NULL REFERENCES questionnaire_runs(id) ON DELETE CASCADE,
55
+ item_id TEXT NOT NULL,
56
+ option_key TEXT,
57
+ value_text TEXT NOT NULL DEFAULT '',
58
+ numeric_value REAL,
59
+ answer_json TEXT NOT NULL DEFAULT '{}',
60
+ created_at TEXT NOT NULL,
61
+ updated_at TEXT NOT NULL,
62
+ UNIQUE (run_id, item_id)
63
+ );
64
+
65
+ CREATE TABLE IF NOT EXISTS questionnaire_run_scores (
66
+ id TEXT PRIMARY KEY,
67
+ run_id TEXT NOT NULL REFERENCES questionnaire_runs(id) ON DELETE CASCADE,
68
+ score_key TEXT NOT NULL,
69
+ label TEXT NOT NULL,
70
+ value_numeric REAL,
71
+ value_text TEXT,
72
+ band_label TEXT NOT NULL DEFAULT '',
73
+ severity TEXT NOT NULL DEFAULT '',
74
+ sort_order INTEGER NOT NULL DEFAULT 0,
75
+ details_json TEXT NOT NULL DEFAULT '{}',
76
+ created_at TEXT NOT NULL,
77
+ UNIQUE (run_id, score_key)
78
+ );
79
+
80
+ CREATE INDEX IF NOT EXISTS idx_questionnaire_versions_instrument
81
+ ON questionnaire_versions (instrument_id, version_number);
82
+
83
+ CREATE INDEX IF NOT EXISTS idx_questionnaire_runs_instrument
84
+ ON questionnaire_runs (instrument_id, updated_at DESC);
85
+
86
+ CREATE INDEX IF NOT EXISTS idx_questionnaire_runs_version
87
+ ON questionnaire_runs (version_id, updated_at DESC);
88
+
89
+ CREATE INDEX IF NOT EXISTS idx_questionnaire_runs_user
90
+ ON questionnaire_runs (user_id, updated_at DESC);
91
+
92
+ CREATE INDEX IF NOT EXISTS idx_questionnaire_answers_run
93
+ ON questionnaire_answers (run_id, item_id);
94
+
95
+ CREATE INDEX IF NOT EXISTS idx_questionnaire_run_scores_run
96
+ ON questionnaire_run_scores (run_id, sort_order, score_key);
@@ -0,0 +1,26 @@
1
+ CREATE TABLE IF NOT EXISTS ai_model_connections (
2
+ id TEXT PRIMARY KEY,
3
+ label TEXT NOT NULL,
4
+ provider TEXT NOT NULL,
5
+ auth_mode TEXT NOT NULL,
6
+ base_url TEXT NOT NULL,
7
+ model TEXT NOT NULL,
8
+ account_label TEXT,
9
+ secret_id TEXT,
10
+ enabled INTEGER NOT NULL DEFAULT 1,
11
+ metadata_json TEXT NOT NULL DEFAULT '{}',
12
+ created_at TEXT NOT NULL,
13
+ updated_at TEXT NOT NULL
14
+ );
15
+
16
+ ALTER TABLE app_settings
17
+ ADD COLUMN forge_basic_chat_connection_id TEXT NOT NULL DEFAULT '';
18
+
19
+ ALTER TABLE app_settings
20
+ ADD COLUMN forge_basic_chat_model TEXT NOT NULL DEFAULT 'gpt-5.4-mini';
21
+
22
+ ALTER TABLE app_settings
23
+ ADD COLUMN forge_wiki_connection_id TEXT NOT NULL DEFAULT '';
24
+
25
+ ALTER TABLE app_settings
26
+ ADD COLUMN forge_wiki_model TEXT NOT NULL DEFAULT 'gpt-5.4-mini';
@@ -0,0 +1,2 @@
1
+ ALTER TABLE app_settings
2
+ ADD COLUMN custom_theme_json TEXT NOT NULL DEFAULT '';
@@ -0,0 +1,31 @@
1
+ CREATE TABLE IF NOT EXISTS ai_processors (
2
+ id TEXT PRIMARY KEY,
3
+ surface_id TEXT NOT NULL,
4
+ title TEXT NOT NULL,
5
+ prompt_flow TEXT NOT NULL DEFAULT '',
6
+ context_input TEXT NOT NULL DEFAULT '',
7
+ tool_config_json TEXT NOT NULL DEFAULT '[]',
8
+ agent_ids_json TEXT NOT NULL DEFAULT '[]',
9
+ trigger_mode TEXT NOT NULL DEFAULT 'manual',
10
+ cron_expression TEXT NOT NULL DEFAULT '',
11
+ machine_access_json TEXT NOT NULL DEFAULT '{"read":false,"write":false,"exec":false}',
12
+ endpoint_enabled INTEGER NOT NULL DEFAULT 1,
13
+ last_run_at TEXT,
14
+ last_run_status TEXT,
15
+ last_run_output_json TEXT,
16
+ created_at TEXT NOT NULL,
17
+ updated_at TEXT NOT NULL
18
+ );
19
+
20
+ CREATE TABLE IF NOT EXISTS ai_processor_links (
21
+ id TEXT PRIMARY KEY,
22
+ surface_id TEXT NOT NULL,
23
+ source_widget_id TEXT NOT NULL,
24
+ target_processor_id TEXT NOT NULL,
25
+ access_mode TEXT NOT NULL DEFAULT 'read',
26
+ capability_mode TEXT NOT NULL DEFAULT 'content',
27
+ metadata_json TEXT NOT NULL DEFAULT '{}',
28
+ created_at TEXT NOT NULL,
29
+ updated_at TEXT NOT NULL,
30
+ FOREIGN KEY (target_processor_id) REFERENCES ai_processors(id) ON DELETE CASCADE
31
+ );