forge-openclaw-plugin 0.2.26 → 0.2.28

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 (109) hide show
  1. package/README.md +60 -3
  2. package/dist/assets/{board-ta0rUHOf.js → board-DPFvZf-D.js} +2 -2
  3. package/dist/assets/{board-ta0rUHOf.js.map → board-DPFvZf-D.js.map} +1 -1
  4. package/dist/assets/index-Auw3JrdE.css +1 -0
  5. package/dist/assets/index-D1H7myQH.js +85 -0
  6. package/dist/assets/index-D1H7myQH.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-fBKPB6yw.js → motion-Bvwc85ch.js} +2 -2
  10. package/dist/assets/{motion-fBKPB6yw.js.map → motion-Bvwc85ch.js.map} +1 -1
  11. package/dist/assets/{table-C-IGTQni.js → table-FJQTJvUR.js} +2 -2
  12. package/dist/assets/{table-C-IGTQni.js.map → table-FJQTJvUR.js.map} +1 -1
  13. package/dist/assets/{ui-DInOpaYF.js → ui-GXFcgvSw.js} +2 -2
  14. package/dist/assets/{ui-DInOpaYF.js.map → ui-GXFcgvSw.js.map} +1 -1
  15. package/dist/assets/vendor-Cwf49UMz.js +1247 -0
  16. package/dist/assets/vendor-Cwf49UMz.js.map +1 -0
  17. package/dist/index.html +7 -7
  18. package/dist/openclaw/local-runtime.js +16 -0
  19. package/dist/openclaw/routes.d.ts +27 -0
  20. package/dist/openclaw/routes.js +16 -12
  21. package/dist/server/server/migrations/037_workbench_public_inputs_and_run_inputs.sql +5 -0
  22. package/dist/server/server/migrations/038_data_management_settings.sql +11 -0
  23. package/dist/server/server/migrations/039_life_force_and_action_points.sql +114 -0
  24. package/dist/server/server/migrations/040_screen_time_domain.sql +89 -0
  25. package/dist/server/server/migrations/041_companion_source_states.sql +21 -0
  26. package/dist/server/server/migrations/042_movement_boxes.sql +47 -0
  27. package/dist/server/server/migrations/043_movement_box_overlap_overrides.sql +26 -0
  28. package/dist/server/server/src/app.js +1900 -91
  29. package/dist/server/server/src/connectors/box-registry.js +44 -9
  30. package/dist/server/server/src/data-management-types.js +107 -0
  31. package/dist/server/server/src/db.js +68 -4
  32. package/dist/server/server/src/demo-data.js +2 -2
  33. package/dist/server/server/src/health.js +702 -18
  34. package/dist/server/server/src/managers/platform/llm-manager.js +7 -4
  35. package/dist/server/server/src/managers/platform/mock-workbench-provider.js +149 -0
  36. package/dist/server/server/src/managers/platform/secrets-manager.js +18 -1
  37. package/dist/server/server/src/managers/runtime.js +9 -0
  38. package/dist/server/server/src/movement.js +1971 -112
  39. package/dist/server/server/src/openapi.js +1390 -105
  40. package/dist/server/server/src/psyche-types.js +9 -1
  41. package/dist/server/server/src/repositories/activity-events.js +8 -0
  42. package/dist/server/server/src/repositories/ai-connectors.js +522 -74
  43. package/dist/server/server/src/repositories/calendar.js +151 -0
  44. package/dist/server/server/src/repositories/habits.js +37 -1
  45. package/dist/server/server/src/repositories/model-settings.js +13 -3
  46. package/dist/server/server/src/repositories/notes.js +3 -0
  47. package/dist/server/server/src/repositories/settings.js +380 -18
  48. package/dist/server/server/src/repositories/tasks.js +170 -10
  49. package/dist/server/server/src/runtime-data-root.js +82 -0
  50. package/dist/server/server/src/screen-time.js +802 -0
  51. package/dist/server/server/src/services/data-management.js +788 -0
  52. package/dist/server/server/src/services/entity-crud.js +205 -2
  53. package/dist/server/server/src/services/knowledge-graph.js +1455 -0
  54. package/dist/server/server/src/services/life-force-model.js +217 -0
  55. package/dist/server/server/src/services/life-force.js +2506 -0
  56. package/dist/server/server/src/services/psyche-observation-calendar.js +383 -16
  57. package/dist/server/server/src/types.js +307 -14
  58. package/dist/server/server/src/web.js +228 -13
  59. package/dist/server/src/components/customization/utility-widgets.js +136 -27
  60. package/dist/server/src/components/ui/info-tooltip.js +25 -0
  61. package/dist/server/src/components/workbench-boxes/calendar/calendar-boxes.js +78 -0
  62. package/dist/server/src/components/workbench-boxes/goals/goals-boxes.js +62 -0
  63. package/dist/server/src/components/workbench-boxes/habits/habits-boxes.js +62 -0
  64. package/dist/server/src/components/workbench-boxes/health/health-boxes.js +63 -8
  65. package/dist/server/src/components/workbench-boxes/insights/insights-boxes.js +50 -0
  66. package/dist/server/src/components/workbench-boxes/kanban/kanban-boxes.js +62 -54
  67. package/dist/server/src/components/workbench-boxes/movement/movement-boxes.js +18 -8
  68. package/dist/server/src/components/workbench-boxes/notes/notes-boxes.js +56 -38
  69. package/dist/server/src/components/workbench-boxes/overview/overview-boxes.js +65 -0
  70. package/dist/server/src/components/workbench-boxes/preferences/preferences-boxes.js +78 -0
  71. package/dist/server/src/components/workbench-boxes/projects/projects-boxes.js +35 -30
  72. package/dist/server/src/components/workbench-boxes/psyche/psyche-boxes.js +88 -0
  73. package/dist/server/src/components/workbench-boxes/questionnaires/questionnaires-boxes.js +61 -0
  74. package/dist/server/src/components/workbench-boxes/review/review-boxes.js +53 -0
  75. package/dist/server/src/components/workbench-boxes/shared/define-workbench-box.js +3 -1
  76. package/dist/server/src/components/workbench-boxes/shared/generic-node-view.js +39 -3
  77. package/dist/server/src/components/workbench-boxes/strategies/strategies-boxes.js +62 -0
  78. package/dist/server/src/components/workbench-boxes/tasks/tasks-boxes.js +76 -0
  79. package/dist/server/src/components/workbench-boxes/today/today-boxes.js +47 -32
  80. package/dist/server/src/components/workbench-boxes/wiki/wiki-boxes.js +60 -0
  81. package/dist/server/src/lib/api.js +280 -21
  82. package/dist/server/src/lib/data-management-types.js +1 -0
  83. package/dist/server/src/lib/entity-visuals.js +279 -0
  84. package/dist/server/src/lib/knowledge-graph-types.js +276 -0
  85. package/dist/server/src/lib/knowledge-graph.js +470 -0
  86. package/dist/server/src/lib/schemas.js +4 -0
  87. package/dist/server/src/lib/snapshot-normalizer.js +45 -1
  88. package/dist/server/src/lib/workbench/contracts.js +229 -0
  89. package/dist/server/src/lib/workbench/nodes.js +200 -0
  90. package/dist/server/src/lib/workbench/registry.js +52 -5
  91. package/dist/server/src/lib/workbench/runtime.js +254 -38
  92. package/dist/server/src/lib/workbench/tool-catalog.js +68 -0
  93. package/openclaw.plugin.json +1 -1
  94. package/package.json +1 -1
  95. package/server/migrations/037_workbench_public_inputs_and_run_inputs.sql +5 -0
  96. package/server/migrations/038_data_management_settings.sql +11 -0
  97. package/server/migrations/039_life_force_and_action_points.sql +114 -0
  98. package/server/migrations/040_screen_time_domain.sql +89 -0
  99. package/server/migrations/041_companion_source_states.sql +21 -0
  100. package/server/migrations/042_movement_boxes.sql +47 -0
  101. package/server/migrations/043_movement_box_overlap_overrides.sql +26 -0
  102. package/skills/forge-openclaw/SKILL.md +41 -11
  103. package/skills/forge-openclaw/entity_conversation_playbooks.md +448 -34
  104. package/skills/forge-openclaw/psyche_entity_playbooks.md +170 -17
  105. package/dist/assets/index-Ro0ZF_az.css +0 -1
  106. package/dist/assets/index-ytlpSj23.js +0 -79
  107. package/dist/assets/index-ytlpSj23.js.map +0 -1
  108. package/dist/assets/vendor-lE3tZJcC.js +0 -876
  109. package/dist/assets/vendor-lE3tZJcC.js.map +0 -1
@@ -0,0 +1,62 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import { buildSearchWorkbenchExecution, buildStaticWorkbenchExecution } from "../../../lib/workbench/runtime.js";
3
+ import { createSearchEntitiesTool, createSearchInputs, createSearchOutputs, createSearchParams, createSummaryOutput } from "../../../lib/workbench/contracts.js";
4
+ import { createGenericWorkbenchNodeView } from "../shared/generic-node-view.js";
5
+ import { defineWorkbenchBox } from "../shared/define-workbench-box.js";
6
+ function Slot({ children }) {
7
+ return _jsx(_Fragment, { children: children });
8
+ }
9
+ function defineGoalBox(id, title, description, tags, execute, output, tools = [], options) {
10
+ const inputs = options?.inputs ?? [];
11
+ const params = options?.params ?? [];
12
+ return defineWorkbenchBox(Slot, {
13
+ id,
14
+ surfaceId: "goals",
15
+ routePath: "/goals",
16
+ title,
17
+ icon: "goal",
18
+ description,
19
+ category: "Goals",
20
+ tags,
21
+ inputs,
22
+ params,
23
+ output,
24
+ tools,
25
+ NodeView: createGenericWorkbenchNodeView({
26
+ title,
27
+ description,
28
+ inputs,
29
+ params,
30
+ output,
31
+ tools
32
+ }),
33
+ execute
34
+ });
35
+ }
36
+ export const GoalsHeroBox = defineGoalBox("surface:goals:hero", "Goals hero", "Goals page header and long-horizon direction context.", ["goals", "hero"], (input) => buildStaticWorkbenchExecution(input, null, "Goals page header."), [createSummaryOutput({ label: "Goals summary", description: "High-level goals page framing." })]);
37
+ export const GoalsSearchResultsBox = defineGoalBox("surface:goals:search-results", "Goals list and results", "Goal browser, linked context, and search results.", ["goals", "search"], (input) => buildSearchWorkbenchExecution(input, {
38
+ query: "",
39
+ entityTypes: ["goal"],
40
+ limit: 20
41
+ }), createSearchOutputs({
42
+ itemKind: "goal",
43
+ itemLabel: "Goal"
44
+ }), [createSearchEntitiesTool("Search goal entities by query and entity types.")], {
45
+ inputs: createSearchInputs({
46
+ itemKind: "goal",
47
+ itemLabel: "Goal",
48
+ defaultEntityTypes: ["goal"],
49
+ defaultLimit: 20
50
+ }),
51
+ params: createSearchParams({
52
+ itemKind: "goal",
53
+ defaultEntityTypes: ["goal"],
54
+ defaultLimit: 20
55
+ })
56
+ });
57
+ export const GoalsSummaryBox = defineGoalBox("surface:goals:summary", "Goals summary", "Goal collection summary and state context.", ["goals", "summary"], (input) => buildStaticWorkbenchExecution(input, null, "Goal collection summary."), [
58
+ createSummaryOutput({
59
+ label: "Goals summary",
60
+ description: "Summary of the goal collection and its current state."
61
+ })
62
+ ]);
@@ -0,0 +1,62 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import { buildSearchWorkbenchExecution, buildStaticWorkbenchExecution } from "../../../lib/workbench/runtime.js";
3
+ import { createSearchEntitiesTool, createSearchInputs, createSearchOutputs, createSearchParams, createSummaryOutput } from "../../../lib/workbench/contracts.js";
4
+ import { createGenericWorkbenchNodeView } from "../shared/generic-node-view.js";
5
+ import { defineWorkbenchBox } from "../shared/define-workbench-box.js";
6
+ function Slot({ children }) {
7
+ return _jsx(_Fragment, { children: children });
8
+ }
9
+ function defineHabitBox(id, title, description, tags, execute, output, tools = [], options) {
10
+ const inputs = options?.inputs ?? [];
11
+ const params = options?.params ?? [];
12
+ return defineWorkbenchBox(Slot, {
13
+ id,
14
+ surfaceId: "habits",
15
+ routePath: "/habits",
16
+ title,
17
+ icon: "habit",
18
+ description,
19
+ category: "Habits",
20
+ tags,
21
+ inputs,
22
+ params,
23
+ output,
24
+ tools,
25
+ NodeView: createGenericWorkbenchNodeView({
26
+ title,
27
+ description,
28
+ inputs,
29
+ params,
30
+ output,
31
+ tools
32
+ }),
33
+ execute
34
+ });
35
+ }
36
+ export const HabitsHeroBox = defineHabitBox("surface:habits:hero", "Habits hero", "Habits page header and recurring execution context.", ["habits", "hero"], (input) => buildStaticWorkbenchExecution(input, null, "Habits page header."), [createSummaryOutput({ label: "Habits summary", description: "High-level habits page framing." })]);
37
+ export const HabitsSearchResultsBox = defineHabitBox("surface:habits:search-results", "Habits list and results", "Habit browser, due habits, and recurring check-in context.", ["habits", "search", "check-ins"], (input) => buildSearchWorkbenchExecution(input, {
38
+ query: "",
39
+ entityTypes: ["habit"],
40
+ limit: 20
41
+ }), createSearchOutputs({
42
+ itemKind: "habit",
43
+ itemLabel: "Habit"
44
+ }), [createSearchEntitiesTool("Search habit entities by query and entity types.")], {
45
+ inputs: createSearchInputs({
46
+ itemKind: "habit",
47
+ itemLabel: "Habit",
48
+ defaultEntityTypes: ["habit"],
49
+ defaultLimit: 20
50
+ }),
51
+ params: createSearchParams({
52
+ itemKind: "habit",
53
+ defaultEntityTypes: ["habit"],
54
+ defaultLimit: 20
55
+ })
56
+ });
57
+ export const HabitsSummaryBox = defineHabitBox("surface:habits:summary", "Habits summary", "Habit streaks, due state, and collection-level rhythm context.", ["habits", "summary", "streaks"], (input) => buildStaticWorkbenchExecution(input, null, "Habit collection summary."), [
58
+ createSummaryOutput({
59
+ label: "Habit summary",
60
+ description: "Summary of habit streaks, due state, and collection rhythm."
61
+ })
62
+ ]);
@@ -1,5 +1,6 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
2
  import { buildSleepWorkbenchExecution, buildSportsWorkbenchExecution } from "../../../lib/workbench/runtime.js";
3
+ import { createContextOutput, createSummaryOutput } from "../../../lib/workbench/contracts.js";
3
4
  import { createGenericWorkbenchNodeView } from "../shared/generic-node-view.js";
4
5
  import { defineWorkbenchBox } from "../shared/define-workbench-box.js";
5
6
  function Slot({ children }) {
@@ -17,14 +18,14 @@ function defineHealthBox(input) {
17
18
  tags: input.tags,
18
19
  inputs: [],
19
20
  params: [],
20
- output: [{ key: "primary", label: input.title, kind: "content" }],
21
+ output: input.output,
21
22
  tools: [],
22
23
  NodeView: createGenericWorkbenchNodeView({
23
24
  title: input.title,
24
25
  description: input.description,
25
26
  inputs: [],
26
27
  params: [],
27
- output: [{ key: "primary", label: input.title, kind: "content" }],
28
+ output: input.output,
28
29
  tools: []
29
30
  }),
30
31
  execute: input.execute
@@ -38,7 +39,16 @@ export const SleepSummaryBox = defineHealthBox({
38
39
  description: "Recent nightly sleep metrics and recovery posture.",
39
40
  category: "Sleep",
40
41
  tags: ["sleep", "summary"],
41
- execute: (input) => buildSleepWorkbenchExecution(input)
42
+ execute: (input) => buildSleepWorkbenchExecution(input),
43
+ output: [
44
+ createSummaryOutput({ label: "Sleep summary", description: "Summary of recent sleep and recovery posture." }),
45
+ createContextOutput({
46
+ key: "sleepView",
47
+ label: "Sleep view",
48
+ description: "Structured sleep history and derived sleep patterns.",
49
+ modelName: "ForgeSleepView"
50
+ })
51
+ ]
42
52
  });
43
53
  export const SleepPatternsBox = defineHealthBox({
44
54
  id: "surface:sleep-index:patterns",
@@ -48,7 +58,16 @@ export const SleepPatternsBox = defineHealthBox({
48
58
  description: "Trend, stage averages, recovery state, and timing patterns.",
49
59
  category: "Sleep",
50
60
  tags: ["sleep", "patterns"],
51
- execute: (input) => buildSleepWorkbenchExecution(input)
61
+ execute: (input) => buildSleepWorkbenchExecution(input),
62
+ output: [
63
+ createSummaryOutput({ label: "Sleep pattern summary", description: "Summary of trend, stage averages, and recovery state." }),
64
+ createContextOutput({
65
+ key: "sleepView",
66
+ label: "Sleep view",
67
+ description: "Structured sleep trend, stage averages, and recovery signals.",
68
+ modelName: "ForgeSleepView"
69
+ })
70
+ ]
52
71
  });
53
72
  export const SleepBrowserBox = defineHealthBox({
54
73
  id: "surface:sleep-index:browser",
@@ -58,7 +77,16 @@ export const SleepBrowserBox = defineHealthBox({
58
77
  description: "Searchable and virtualized sleep history browser.",
59
78
  category: "Sleep",
60
79
  tags: ["sleep", "browser", "history"],
61
- execute: (input) => buildSleepWorkbenchExecution(input)
80
+ execute: (input) => buildSleepWorkbenchExecution(input),
81
+ output: [
82
+ createSummaryOutput({ label: "Night browser summary", description: "Summary of searchable sleep history." }),
83
+ createContextOutput({
84
+ key: "sleepView",
85
+ label: "Sleep view",
86
+ description: "Structured sleep history for browsing and analysis.",
87
+ modelName: "ForgeSleepView"
88
+ })
89
+ ]
62
90
  });
63
91
  export const SportsSummaryBox = defineHealthBox({
64
92
  id: "surface:sports-index:summary",
@@ -68,7 +96,16 @@ export const SportsSummaryBox = defineHealthBox({
68
96
  description: "Recent workout metrics, streaks, and linked-session totals.",
69
97
  category: "Sports",
70
98
  tags: ["sports", "summary"],
71
- execute: (input) => buildSportsWorkbenchExecution(input)
99
+ execute: (input) => buildSportsWorkbenchExecution(input),
100
+ output: [
101
+ createSummaryOutput({ label: "Sports summary", description: "Summary of recent workout metrics and streaks." }),
102
+ createContextOutput({
103
+ key: "sportsView",
104
+ label: "Sports view",
105
+ description: "Structured workout metrics, streaks, and linked session totals.",
106
+ modelName: "ForgeSportsView"
107
+ })
108
+ ]
72
109
  });
73
110
  export const SportsCompositionBox = defineHealthBox({
74
111
  id: "surface:sports-index:composition",
@@ -78,7 +115,16 @@ export const SportsCompositionBox = defineHealthBox({
78
115
  description: "Workout mix, trend, and session composition context.",
79
116
  category: "Sports",
80
117
  tags: ["sports", "composition", "trend"],
81
- execute: (input) => buildSportsWorkbenchExecution(input)
118
+ execute: (input) => buildSportsWorkbenchExecution(input),
119
+ output: [
120
+ createSummaryOutput({ label: "Composition summary", description: "Summary of workout mix, trend, and session composition." }),
121
+ createContextOutput({
122
+ key: "sportsView",
123
+ label: "Sports view",
124
+ description: "Structured workout mix, trend, and session composition data.",
125
+ modelName: "ForgeSportsView"
126
+ })
127
+ ]
82
128
  });
83
129
  export const SportsBrowserBox = defineHealthBox({
84
130
  id: "surface:sports-index:browser",
@@ -88,5 +134,14 @@ export const SportsBrowserBox = defineHealthBox({
88
134
  description: "Searchable and virtualized workout history browser.",
89
135
  category: "Sports",
90
136
  tags: ["sports", "browser", "history"],
91
- execute: (input) => buildSportsWorkbenchExecution(input)
137
+ execute: (input) => buildSportsWorkbenchExecution(input),
138
+ output: [
139
+ createSummaryOutput({ label: "Session browser summary", description: "Summary of searchable workout history." }),
140
+ createContextOutput({
141
+ key: "sportsView",
142
+ label: "Sports view",
143
+ description: "Structured workout history for browsing and analysis.",
144
+ modelName: "ForgeSportsView"
145
+ })
146
+ ]
92
147
  });
@@ -0,0 +1,50 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import { buildInsightsWorkbenchExecution, buildStaticWorkbenchExecution } from "../../../lib/workbench/runtime.js";
3
+ import { createContextOutput, createSummaryOutput } from "../../../lib/workbench/contracts.js";
4
+ import { createGenericWorkbenchNodeView } from "../shared/generic-node-view.js";
5
+ import { defineWorkbenchBox } from "../shared/define-workbench-box.js";
6
+ function Slot({ children }) {
7
+ return _jsx(_Fragment, { children: children });
8
+ }
9
+ function defineInsightsBox(id, title, description, tags, execute, output) {
10
+ return defineWorkbenchBox(Slot, {
11
+ id,
12
+ surfaceId: "insights",
13
+ routePath: "/insights",
14
+ title,
15
+ icon: "insights",
16
+ description,
17
+ category: "Insights",
18
+ tags,
19
+ inputs: [],
20
+ params: [],
21
+ output,
22
+ tools: [],
23
+ NodeView: createGenericWorkbenchNodeView({
24
+ title,
25
+ description,
26
+ inputs: [],
27
+ params: [],
28
+ output,
29
+ tools: []
30
+ }),
31
+ execute
32
+ });
33
+ }
34
+ export const InsightsFeedBox = defineInsightsBox("surface:insights:feed", "Insights feed", "Current coaching feed, status summary, and evidence-backed insight stream.", ["insights", "feed"], (input) => buildInsightsWorkbenchExecution(input), [
35
+ createSummaryOutput({ label: "Insight summary", description: "Summary of the current coaching feed and evidence-backed insight stream." }),
36
+ createContextOutput({
37
+ key: "insights",
38
+ label: "Insight payload",
39
+ description: "Structured status and coaching payload returned by Forge insights.",
40
+ modelName: "ForgeInsightsPayload"
41
+ })
42
+ ]);
43
+ export const InsightsCoachingBox = defineInsightsBox("surface:insights:coaching", "Coaching recommendation", "Single-action coaching summary for what Forge thinks matters next.", ["insights", "coaching"], (input) => buildStaticWorkbenchExecution(input, {
44
+ focus: "coaching_recommendation"
45
+ }, "Coaching recommendation surface for the highest-leverage next move."), [
46
+ createSummaryOutput({
47
+ label: "Coaching recommendation",
48
+ description: "Summary of the highest-leverage coaching recommendation."
49
+ })
50
+ ]);
@@ -1,10 +1,22 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
2
  import { buildSearchWorkbenchExecution } from "../../../lib/workbench/runtime.js";
3
+ import { createSearchEntitiesTool, createSearchInputs, createSearchOutputs, createSearchParams, createSummaryOutput, createTaskStatusTool } from "../../../lib/workbench/contracts.js";
3
4
  import { createGenericWorkbenchNodeView } from "../shared/generic-node-view.js";
4
5
  import { defineWorkbenchBox } from "../shared/define-workbench-box.js";
5
6
  function Slot({ children }) {
6
7
  return _jsx(_Fragment, { children: children });
7
8
  }
9
+ const kanbanSearchInputs = createSearchInputs({
10
+ itemKind: "task",
11
+ itemLabel: "Task",
12
+ defaultEntityTypes: ["task"],
13
+ defaultLimit: 24
14
+ });
15
+ const kanbanSearchParams = createSearchParams({
16
+ itemKind: "task",
17
+ defaultEntityTypes: ["task"],
18
+ defaultLimit: 24
19
+ });
8
20
  export const KanbanSummaryBox = defineWorkbenchBox(Slot, {
9
21
  id: "surface:kanban-index:summary",
10
22
  surfaceId: "kanban-index",
@@ -14,16 +26,26 @@ export const KanbanSummaryBox = defineWorkbenchBox(Slot, {
14
26
  description: "Board summary and execution posture.",
15
27
  category: "Execution",
16
28
  tags: ["kanban", "summary"],
17
- inputs: [],
18
- params: [],
19
- output: [{ key: "primary", label: "Kanban summary", kind: "content" }],
29
+ inputs: kanbanSearchInputs,
30
+ params: kanbanSearchParams,
31
+ output: [
32
+ createSummaryOutput({
33
+ label: "Kanban summary",
34
+ description: "Summary of board posture and execution pressure."
35
+ })
36
+ ],
20
37
  tools: [],
21
38
  NodeView: createGenericWorkbenchNodeView({
22
39
  title: "Kanban summary",
23
40
  description: "Board summary and execution posture.",
24
- inputs: [],
25
- params: [],
26
- output: [{ key: "primary", label: "Kanban summary", kind: "content" }],
41
+ inputs: kanbanSearchInputs,
42
+ params: kanbanSearchParams,
43
+ output: [
44
+ createSummaryOutput({
45
+ label: "Kanban summary",
46
+ description: "Summary of board posture and execution pressure."
47
+ })
48
+ ],
27
49
  tools: []
28
50
  }),
29
51
  execute: (input) => buildSearchWorkbenchExecution(input, {
@@ -41,30 +63,30 @@ export const KanbanFiltersBox = defineWorkbenchBox(Slot, {
41
63
  description: "Goal, owner, and tag filters for board scope.",
42
64
  category: "Execution",
43
65
  tags: ["kanban", "filters"],
44
- inputs: [],
45
- params: [],
46
- output: [{ key: "primary", label: "Kanban filters", kind: "content" }],
66
+ inputs: kanbanSearchInputs,
67
+ params: kanbanSearchParams,
68
+ output: [
69
+ createSummaryOutput({
70
+ label: "Filter summary",
71
+ description: "Summary of the current Kanban filters and scope."
72
+ })
73
+ ],
47
74
  tools: [
48
- {
49
- key: "forge.search_entities",
50
- label: "Search Forge entities",
51
- description: "Search Forge entities by query and entity types.",
52
- accessMode: "read"
53
- }
75
+ createSearchEntitiesTool("Search Forge entities by query and entity types.")
54
76
  ],
55
77
  NodeView: createGenericWorkbenchNodeView({
56
78
  title: "Kanban filters",
57
79
  description: "Goal, owner, and tag filters for board scope.",
58
- inputs: [],
59
- params: [],
60
- output: [{ key: "primary", label: "Kanban filters", kind: "content" }],
80
+ inputs: kanbanSearchInputs,
81
+ params: kanbanSearchParams,
82
+ output: [
83
+ createSummaryOutput({
84
+ label: "Filter summary",
85
+ description: "Summary of the current Kanban filters and scope."
86
+ })
87
+ ],
61
88
  tools: [
62
- {
63
- key: "forge.search_entities",
64
- label: "Search Forge entities",
65
- description: "Search Forge entities by query and entity types.",
66
- accessMode: "read"
67
- }
89
+ createSearchEntitiesTool("Search Forge entities by query and entity types.")
68
90
  ]
69
91
  }),
70
92
  execute: (input) => buildSearchWorkbenchExecution(input, {
@@ -82,42 +104,28 @@ export const KanbanBoardBox = defineWorkbenchBox(Slot, {
82
104
  description: "Task board with move and execution actions.",
83
105
  category: "Execution",
84
106
  tags: ["kanban", "board", "tasks"],
85
- inputs: [],
86
- params: [],
87
- output: [{ key: "primary", label: "Kanban board", kind: "content" }],
107
+ inputs: kanbanSearchInputs,
108
+ params: kanbanSearchParams,
109
+ output: createSearchOutputs({
110
+ itemKind: "kanban_task",
111
+ itemLabel: "Kanban task"
112
+ }),
88
113
  tools: [
89
- {
90
- key: "forge.search_entities",
91
- label: "Search Forge entities",
92
- description: "Search Forge entities by query and entity types.",
93
- accessMode: "read"
94
- },
95
- {
96
- key: "forge.update_task_status",
97
- label: "Move task",
98
- description: "Update a task status.",
99
- accessMode: "write"
100
- }
114
+ createSearchEntitiesTool("Search Forge entities by query and entity types."),
115
+ createTaskStatusTool("Update a task status.")
101
116
  ],
102
117
  NodeView: createGenericWorkbenchNodeView({
103
118
  title: "Kanban board",
104
119
  description: "Task board with move and execution actions.",
105
- inputs: [],
106
- params: [],
107
- output: [{ key: "primary", label: "Kanban board", kind: "content" }],
120
+ inputs: kanbanSearchInputs,
121
+ params: kanbanSearchParams,
122
+ output: createSearchOutputs({
123
+ itemKind: "kanban_task",
124
+ itemLabel: "Kanban task"
125
+ }),
108
126
  tools: [
109
- {
110
- key: "forge.search_entities",
111
- label: "Search Forge entities",
112
- description: "Search Forge entities by query and entity types.",
113
- accessMode: "read"
114
- },
115
- {
116
- key: "forge.update_task_status",
117
- label: "Move task",
118
- description: "Update a task status.",
119
- accessMode: "write"
120
- }
127
+ createSearchEntitiesTool("Search Forge entities by query and entity types."),
128
+ createTaskStatusTool("Update a task status.")
121
129
  ]
122
130
  }),
123
131
  execute: (input) => buildSearchWorkbenchExecution(input, {
@@ -1,11 +1,12 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
2
  import { buildMovementPlacesExecution, buildStaticWorkbenchExecution } from "../../../lib/workbench/runtime.js";
3
+ import { createRecordListOutput, createSummaryOutput } from "../../../lib/workbench/contracts.js";
3
4
  import { createGenericWorkbenchNodeView } from "../shared/generic-node-view.js";
4
5
  import { defineWorkbenchBox } from "../shared/define-workbench-box.js";
5
6
  function Slot({ children }) {
6
7
  return _jsx(_Fragment, { children: children });
7
8
  }
8
- function defineMovementBox(id, title, description, tags, execute) {
9
+ function defineMovementBox(id, title, description, tags, execute, output) {
9
10
  return defineWorkbenchBox(Slot, {
10
11
  id,
11
12
  surfaceId: "movement-index",
@@ -17,21 +18,30 @@ function defineMovementBox(id, title, description, tags, execute) {
17
18
  tags,
18
19
  inputs: [],
19
20
  params: [],
20
- output: [{ key: "primary", label: title, kind: "content" }],
21
+ output,
21
22
  tools: [],
22
23
  NodeView: createGenericWorkbenchNodeView({
23
24
  title,
24
25
  description,
25
26
  inputs: [],
26
27
  params: [],
27
- output: [{ key: "primary", label: title, kind: "content" }],
28
+ output,
28
29
  tools: []
29
30
  }),
30
31
  execute
31
32
  });
32
33
  }
33
- export const MovementSummaryBox = defineMovementBox("surface:movement-index:summary", "Movement summary", "Tracking mode, daily totals, and passive capture posture.", ["movement", "summary"], (input) => buildStaticWorkbenchExecution(input, null, "Movement summary is available."));
34
- export const MovementSelectionBox = defineMovementBox("surface:movement-index:selection", "Movement selection aggregate", "Selected-stay and selected-trip aggregate totals.", ["movement", "selection", "aggregate"], (input) => buildStaticWorkbenchExecution(input, null, "Selected stay and trip aggregate totals."));
35
- export const MovementTimelineBox = defineMovementBox("surface:movement-index:timeline", "Movement life timeline", "Life-scale stay and trip timeline with edit access.", ["movement", "timeline", "life"], (input) => buildStaticWorkbenchExecution(input, null, "Movement life timeline with stay and trip history."));
36
- export const MovementPlacesBox = defineMovementBox("surface:movement-index:places", "Known places", "Known places, aliases, and category tags.", ["movement", "places"], (input) => buildMovementPlacesExecution(input));
37
- export const MovementDataBrowserBox = defineMovementBox("surface:movement-index:data-browser", "Movement data browser", "Datapoint browsing, invalid records, and movement data cleanup.", ["movement", "data", "browser"], (input) => buildStaticWorkbenchExecution(input, null, "Movement datapoint browser with cleanup actions."));
34
+ export const MovementSummaryBox = defineMovementBox("surface:movement-index:summary", "Movement summary", "Tracking mode, daily totals, and passive capture posture.", ["movement", "summary"], (input) => buildStaticWorkbenchExecution(input, null, "Movement summary is available."), [createSummaryOutput({ label: "Movement summary", description: "Summary of tracking mode, daily totals, and passive capture posture." })]);
35
+ export const MovementSelectionBox = defineMovementBox("surface:movement-index:selection", "Movement selection aggregate", "Selected-stay and selected-trip aggregate totals.", ["movement", "selection", "aggregate"], (input) => buildStaticWorkbenchExecution(input, null, "Selected stay and trip aggregate totals."), [createSummaryOutput({ label: "Selection summary", description: "Summary of selected-stay and selected-trip aggregates." })]);
36
+ export const MovementTimelineBox = defineMovementBox("surface:movement-index:timeline", "Movement life timeline", "Life-scale stay and trip timeline with edit access.", ["movement", "timeline", "life"], (input) => buildStaticWorkbenchExecution(input, null, "Movement life timeline with stay and trip history."), [createSummaryOutput({ label: "Timeline summary", description: "Summary of the movement life timeline and trip history." })]);
37
+ export const MovementPlacesBox = defineMovementBox("surface:movement-index:places", "Known places", "Known places, aliases, and category tags.", ["movement", "places"], (input) => buildMovementPlacesExecution(input), [
38
+ createSummaryOutput({ label: "Places summary", description: "Summary of known places, aliases, and category tags." }),
39
+ createRecordListOutput({
40
+ key: "places",
41
+ label: "Known places",
42
+ description: "Structured list of places known to Forge movement tracking.",
43
+ modelName: "ForgeMovementPlaces",
44
+ itemKind: "movement_place"
45
+ })
46
+ ]);
47
+ export const MovementDataBrowserBox = defineMovementBox("surface:movement-index:data-browser", "Movement data browser", "Datapoint browsing, invalid records, and movement data cleanup.", ["movement", "data", "browser"], (input) => buildStaticWorkbenchExecution(input, null, "Movement datapoint browser with cleanup actions."), [createSummaryOutput({ label: "Data browser summary", description: "Summary of movement datapoint browsing and cleanup." })]);
@@ -1,10 +1,22 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
2
  import { buildSearchWorkbenchExecution, buildStaticWorkbenchExecution } from "../../../lib/workbench/runtime.js";
3
+ import { createNoteTool, createSearchEntitiesTool, createSearchInputs, createSearchOutputs, createSearchParams, createSummaryOutput } from "../../../lib/workbench/contracts.js";
3
4
  import { createGenericWorkbenchNodeView } from "../shared/generic-node-view.js";
4
5
  import { defineWorkbenchBox } from "../shared/define-workbench-box.js";
5
6
  function Slot({ children }) {
6
7
  return _jsx(_Fragment, { children: children });
7
8
  }
9
+ const noteSearchInputs = createSearchInputs({
10
+ itemKind: "note",
11
+ itemLabel: "Note",
12
+ defaultEntityTypes: ["note"],
13
+ defaultLimit: 20
14
+ });
15
+ const noteSearchParams = createSearchParams({
16
+ itemKind: "note",
17
+ defaultEntityTypes: ["note"],
18
+ defaultLimit: 20
19
+ });
8
20
  export const NoteFiltersBox = defineWorkbenchBox(Slot, {
9
21
  id: "surface:notes-index:filters",
10
22
  surfaceId: "notes-index",
@@ -14,30 +26,30 @@ export const NoteFiltersBox = defineWorkbenchBox(Slot, {
14
26
  description: "Entity, tag, text, author, and date filters for notes.",
15
27
  category: "Notes",
16
28
  tags: ["notes", "filters", "search"],
17
- inputs: [],
18
- params: [],
19
- output: [{ key: "primary", label: "Note filters", kind: "content" }],
29
+ inputs: noteSearchInputs,
30
+ params: noteSearchParams,
31
+ output: [
32
+ createSummaryOutput({
33
+ label: "Filter summary",
34
+ description: "Summary of the current note filters and search scope."
35
+ })
36
+ ],
20
37
  tools: [
21
- {
22
- key: "forge.search_entities",
23
- label: "Search Forge entities",
24
- description: "Search Forge entities by query and entity types.",
25
- accessMode: "read"
26
- }
38
+ createSearchEntitiesTool("Search Forge entities by query and entity types.")
27
39
  ],
28
40
  NodeView: createGenericWorkbenchNodeView({
29
41
  title: "Note filters",
30
42
  description: "Entity, tag, text, author, and date filters for notes.",
31
- inputs: [],
32
- params: [],
33
- output: [{ key: "primary", label: "Note filters", kind: "content" }],
43
+ inputs: noteSearchInputs,
44
+ params: noteSearchParams,
45
+ output: [
46
+ createSummaryOutput({
47
+ label: "Filter summary",
48
+ description: "Summary of the current note filters and search scope."
49
+ })
50
+ ],
34
51
  tools: [
35
- {
36
- key: "forge.search_entities",
37
- label: "Search Forge entities",
38
- description: "Search Forge entities by query and entity types.",
39
- accessMode: "read"
40
- }
52
+ createSearchEntitiesTool("Search Forge entities by query and entity types.")
41
53
  ]
42
54
  }),
43
55
  execute: (input) => buildSearchWorkbenchExecution(input, {
@@ -55,30 +67,30 @@ export const NoteComposerBox = defineWorkbenchBox(Slot, {
55
67
  description: "Markdown note composer with links, tags, and capture actions.",
56
68
  category: "Notes",
57
69
  tags: ["notes", "composer", "capture"],
58
- inputs: [],
59
- params: [],
60
- output: [{ key: "primary", label: "Note draft", kind: "content" }],
70
+ inputs: noteSearchInputs,
71
+ params: noteSearchParams,
72
+ output: [
73
+ createSummaryOutput({
74
+ label: "Draft summary",
75
+ description: "Summary of the current note drafting surface."
76
+ })
77
+ ],
61
78
  tools: [
62
- {
63
- key: "forge.create_note",
64
- label: "Create note",
65
- description: "Create an evidence note from markdown content.",
66
- accessMode: "write"
67
- }
79
+ createNoteTool("Create an evidence note from markdown content.")
68
80
  ],
69
81
  NodeView: createGenericWorkbenchNodeView({
70
82
  title: "Note composer",
71
83
  description: "Markdown note composer with links, tags, and capture actions.",
72
- inputs: [],
73
- params: [],
74
- output: [{ key: "primary", label: "Note draft", kind: "content" }],
84
+ inputs: noteSearchInputs,
85
+ params: noteSearchParams,
86
+ output: [
87
+ createSummaryOutput({
88
+ label: "Draft summary",
89
+ description: "Summary of the current note drafting surface."
90
+ })
91
+ ],
75
92
  tools: [
76
- {
77
- key: "forge.create_note",
78
- label: "Create note",
79
- description: "Create an evidence note from markdown content.",
80
- accessMode: "write"
81
- }
93
+ createNoteTool("Create an evidence note from markdown content.")
82
94
  ]
83
95
  }),
84
96
  execute: (input) => buildStaticWorkbenchExecution(input, {
@@ -96,14 +108,20 @@ export const NotesLibraryBox = defineWorkbenchBox(Slot, {
96
108
  tags: ["notes", "library", "history"],
97
109
  inputs: [],
98
110
  params: [],
99
- output: [{ key: "primary", label: "Notes library", kind: "content" }],
111
+ output: createSearchOutputs({
112
+ itemKind: "note",
113
+ itemLabel: "Note"
114
+ }),
100
115
  tools: [],
101
116
  NodeView: createGenericWorkbenchNodeView({
102
117
  title: "Notes library",
103
118
  description: "Filtered library of Forge notes and linked evidence.",
104
119
  inputs: [],
105
120
  params: [],
106
- output: [{ key: "primary", label: "Notes library", kind: "content" }],
121
+ output: createSearchOutputs({
122
+ itemKind: "note",
123
+ itemLabel: "Note"
124
+ }),
107
125
  tools: []
108
126
  }),
109
127
  execute: (input) => buildSearchWorkbenchExecution(input, {