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,470 @@
1
+ import { getEntityVisual, isEntityKind } from "@/lib/entity-visuals";
2
+ import { KNOWLEDGE_GRAPH_HIERARCHY_LANES, KNOWLEDGE_GRAPH_HIERARCHY_ORDER, KNOWLEDGE_GRAPH_RELATION_FAMILY_LABELS, KNOWLEDGE_GRAPH_RELATION_LABELS, buildKnowledgeGraphNodeId } from "@/lib/knowledge-graph-types";
3
+ export function getKnowledgeGraphNodeVisual(node) {
4
+ const kind = isEntityKind(node.entityKind) ? node.entityKind : "note";
5
+ return getEntityVisual(kind);
6
+ }
7
+ export function getKnowledgeGraphNodeLayer(kind) {
8
+ const index = KNOWLEDGE_GRAPH_HIERARCHY_ORDER.indexOf(kind);
9
+ return index >= 0 ? index : KNOWLEDGE_GRAPH_HIERARCHY_ORDER.length - 1;
10
+ }
11
+ export function getKnowledgeGraphNodeLane(kind) {
12
+ const lane = KNOWLEDGE_GRAPH_HIERARCHY_LANES.find((entry) => entry.kinds.some((entryKind) => entryKind === kind)) ??
13
+ KNOWLEDGE_GRAPH_HIERARCHY_LANES[KNOWLEDGE_GRAPH_HIERARCHY_LANES.length - 1];
14
+ return {
15
+ laneId: lane.id,
16
+ laneLabel: lane.label,
17
+ laneIndex: KNOWLEDGE_GRAPH_HIERARCHY_LANES.findIndex((entry) => entry.id === lane.id)
18
+ };
19
+ }
20
+ function initializeFamilyCounts() {
21
+ return {
22
+ structural: 0,
23
+ contextual: 0,
24
+ taxonomy: 0,
25
+ workspace: 0
26
+ };
27
+ }
28
+ function buildNeighborMap(edges) {
29
+ const neighborMap = new Map();
30
+ for (const edge of edges) {
31
+ const sourcePeers = neighborMap.get(edge.source) ?? new Set();
32
+ sourcePeers.add(edge.target);
33
+ neighborMap.set(edge.source, sourcePeers);
34
+ const targetPeers = neighborMap.get(edge.target) ?? new Set();
35
+ targetPeers.add(edge.source);
36
+ neighborMap.set(edge.target, targetPeers);
37
+ }
38
+ return neighborMap;
39
+ }
40
+ function normalizeFilterText(value) {
41
+ return (value ?? "").trim().toLowerCase();
42
+ }
43
+ function getNodeUpdatedAtValue(node) {
44
+ if (!node.updatedAt) {
45
+ return null;
46
+ }
47
+ const time = Date.parse(node.updatedAt);
48
+ return Number.isFinite(time) ? time : null;
49
+ }
50
+ export function compareKnowledgeGraphNodes(left, right) {
51
+ return (right.importance - left.importance ||
52
+ right.size - left.size ||
53
+ left.title.localeCompare(right.title) ||
54
+ left.id.localeCompare(right.id));
55
+ }
56
+ function compareKnowledgeGraphEdges(left, right) {
57
+ return (right.strength - left.strength ||
58
+ left.relationKind.localeCompare(right.relationKind) ||
59
+ left.label.localeCompare(right.label) ||
60
+ left.id.localeCompare(right.id));
61
+ }
62
+ export function buildRenderedKnowledgeGraphEdges(edges) {
63
+ const edgesByPair = new Map();
64
+ for (const edge of edges) {
65
+ const pairKey = `${edge.source}→${edge.target}`;
66
+ const current = edgesByPair.get(pairKey) ?? [];
67
+ current.push(edge);
68
+ edgesByPair.set(pairKey, current);
69
+ }
70
+ return Array.from(edgesByPair.entries())
71
+ .map(([pairKey, pairEdges]) => {
72
+ const sortedEdges = [...pairEdges].sort(compareKnowledgeGraphEdges);
73
+ const representative = sortedEdges[0];
74
+ const parallelCount = sortedEdges.length;
75
+ const strength = Math.max(...sortedEdges.map((edge) => edge.strength)) *
76
+ Math.min(1.45, 1 + (parallelCount - 1) * 0.12);
77
+ return {
78
+ id: `${pairKey}#${representative.id}`,
79
+ source: representative.source,
80
+ target: representative.target,
81
+ relationKind: representative.relationKind,
82
+ family: representative.family,
83
+ label: parallelCount > 1
84
+ ? `${representative.label} +${parallelCount - 1}`
85
+ : representative.label,
86
+ strength,
87
+ directional: representative.directional,
88
+ structural: representative.structural,
89
+ parallelCount,
90
+ data: sortedEdges
91
+ };
92
+ })
93
+ .sort((left, right) => left.source.localeCompare(right.source) ||
94
+ left.target.localeCompare(right.target) ||
95
+ left.id.localeCompare(right.id));
96
+ }
97
+ export function buildKnowledgeGraphDatasetSignature(nodes, edges) {
98
+ const renderedEdges = buildRenderedKnowledgeGraphEdges(edges);
99
+ const nodeSignature = [...nodes]
100
+ .sort((left, right) => left.id.localeCompare(right.id) ||
101
+ left.updatedAt?.localeCompare(right.updatedAt ?? "") ||
102
+ 0)
103
+ .map((node) => `${node.id}:${node.title}:${node.size}:${node.importance}:${node.updatedAt ?? ""}`)
104
+ .join("|");
105
+ const edgeSignature = renderedEdges
106
+ .map((edge) => `${edge.source}:${edge.target}:${edge.parallelCount}:${edge.label}:${edge.strength.toFixed(3)}`)
107
+ .join("|");
108
+ return `${nodes.length}/${renderedEdges.length}/${nodeSignature}::${edgeSignature}`;
109
+ }
110
+ export function filterKnowledgeGraphData(graph, query) {
111
+ const normalizedQuery = normalizeFilterText(query.q);
112
+ const selectedKinds = new Set(query.entityKinds ?? []);
113
+ const selectedTags = new Set(query.tags ?? []);
114
+ const selectedOwners = new Set(query.owners ?? []);
115
+ const selectedRelations = new Set(query.relationKinds ?? []);
116
+ const updatedFrom = query.updatedFrom ? Date.parse(query.updatedFrom) : null;
117
+ const updatedTo = query.updatedTo ? Date.parse(query.updatedTo) : null;
118
+ const filteredNodes = graph.nodes.filter((node) => {
119
+ if (selectedKinds.size > 0 && !selectedKinds.has(node.entityKind)) {
120
+ return false;
121
+ }
122
+ if (selectedTags.size > 0 &&
123
+ !node.tags.some((tag) => selectedTags.has(tag.id))) {
124
+ return false;
125
+ }
126
+ if (selectedOwners.size > 0) {
127
+ const ownerId = node.owner?.userId;
128
+ if (!ownerId || !selectedOwners.has(ownerId)) {
129
+ return false;
130
+ }
131
+ }
132
+ const updatedAtValue = getNodeUpdatedAtValue(node);
133
+ if (updatedFrom !== null) {
134
+ if (updatedAtValue === null || updatedAtValue < updatedFrom) {
135
+ return false;
136
+ }
137
+ }
138
+ if (updatedTo !== null) {
139
+ if (updatedAtValue === null || updatedAtValue > updatedTo) {
140
+ return false;
141
+ }
142
+ }
143
+ if (!normalizedQuery) {
144
+ return true;
145
+ }
146
+ const haystack = [
147
+ node.title,
148
+ node.subtitle,
149
+ node.description,
150
+ node.owner?.displayName ?? "",
151
+ ...node.tags.map((tag) => tag.label)
152
+ ]
153
+ .join(" ")
154
+ .toLowerCase();
155
+ return haystack.includes(normalizedQuery);
156
+ });
157
+ const filteredNodeIds = new Set(filteredNodes.map((node) => node.id));
158
+ const candidateEdges = graph.edges.filter((edge) => {
159
+ if (!filteredNodeIds.has(edge.source) || !filteredNodeIds.has(edge.target)) {
160
+ return false;
161
+ }
162
+ if (selectedRelations.size > 0 &&
163
+ !selectedRelations.has(edge.relationKind)) {
164
+ return false;
165
+ }
166
+ return true;
167
+ });
168
+ if (selectedRelations.size === 0) {
169
+ return {
170
+ nodes: filteredNodes,
171
+ edges: candidateEdges
172
+ };
173
+ }
174
+ const connectedNodeIds = new Set();
175
+ for (const edge of candidateEdges) {
176
+ connectedNodeIds.add(edge.source);
177
+ connectedNodeIds.add(edge.target);
178
+ }
179
+ return {
180
+ nodes: filteredNodes.filter((node) => connectedNodeIds.has(node.id)),
181
+ edges: candidateEdges
182
+ };
183
+ }
184
+ export function selectKnowledgeGraphVisibleNodeIds({ nodes, edges, limit, focusNodeId }) {
185
+ if (!limit || limit <= 0 || nodes.length <= limit) {
186
+ return new Set(nodes.map((node) => node.id));
187
+ }
188
+ const nodeMap = new Map(nodes.map((node) => [node.id, node]));
189
+ if (focusNodeId && nodeMap.has(focusNodeId)) {
190
+ const neighborMap = buildNeighborMap(edges);
191
+ const visibleIds = new Set();
192
+ const visitedIds = new Set();
193
+ let frontier = [focusNodeId];
194
+ while (frontier.length > 0 && visibleIds.size < limit) {
195
+ const hopNodes = frontier
196
+ .map((nodeId) => nodeMap.get(nodeId) ?? null)
197
+ .filter((node) => Boolean(node))
198
+ .sort(compareKnowledgeGraphNodes);
199
+ for (const node of hopNodes) {
200
+ if (visibleIds.size >= limit) {
201
+ break;
202
+ }
203
+ visibleIds.add(node.id);
204
+ }
205
+ const nextFrontier = new Set();
206
+ for (const nodeId of frontier) {
207
+ visitedIds.add(nodeId);
208
+ for (const neighborId of neighborMap.get(nodeId) ?? []) {
209
+ if (visitedIds.has(neighborId) ||
210
+ visibleIds.has(neighborId) ||
211
+ !nodeMap.has(neighborId)) {
212
+ continue;
213
+ }
214
+ nextFrontier.add(neighborId);
215
+ }
216
+ }
217
+ frontier = Array.from(nextFrontier);
218
+ }
219
+ if (visibleIds.size < limit) {
220
+ for (const node of [...nodes].sort(compareKnowledgeGraphNodes)) {
221
+ if (visibleIds.has(node.id)) {
222
+ continue;
223
+ }
224
+ visibleIds.add(node.id);
225
+ if (visibleIds.size >= limit) {
226
+ break;
227
+ }
228
+ }
229
+ }
230
+ return visibleIds;
231
+ }
232
+ return new Set([...nodes]
233
+ .sort(compareKnowledgeGraphNodes)
234
+ .slice(0, limit)
235
+ .map((node) => node.id));
236
+ }
237
+ export function buildKnowledgeGraphFacets(nodes, edges) {
238
+ const entityKinds = nodes.reduce((counts, node) => {
239
+ counts[node.entityKind] = (counts[node.entityKind] ?? 0) + 1;
240
+ return counts;
241
+ }, {});
242
+ const relationKinds = edges.reduce((counts, edge) => {
243
+ counts[edge.relationKind] = (counts[edge.relationKind] ?? 0) + 1;
244
+ return counts;
245
+ }, {});
246
+ const tags = new Map();
247
+ const owners = new Map();
248
+ let minUpdatedAt = null;
249
+ let maxUpdatedAt = null;
250
+ for (const node of nodes) {
251
+ for (const tag of node.tags) {
252
+ const current = tags.get(tag.id) ?? { ...tag, count: 0 };
253
+ current.count += 1;
254
+ tags.set(tag.id, current);
255
+ }
256
+ if (node.owner?.userId && node.owner.displayName) {
257
+ const current = owners.get(node.owner.userId) ?? {
258
+ userId: node.owner.userId,
259
+ displayName: node.owner.displayName,
260
+ accentColor: node.owner.accentColor,
261
+ kind: node.owner.kind,
262
+ count: 0
263
+ };
264
+ current.count += 1;
265
+ owners.set(node.owner.userId, current);
266
+ }
267
+ if (node.updatedAt) {
268
+ if (!minUpdatedAt || node.updatedAt < minUpdatedAt) {
269
+ minUpdatedAt = node.updatedAt;
270
+ }
271
+ if (!maxUpdatedAt || node.updatedAt > maxUpdatedAt) {
272
+ maxUpdatedAt = node.updatedAt;
273
+ }
274
+ }
275
+ }
276
+ return {
277
+ entityKinds: Object.entries(entityKinds)
278
+ .map(([value, count]) => ({
279
+ value: value,
280
+ label: getEntityVisual(value).label,
281
+ count
282
+ }))
283
+ .sort((left, right) => right.count - left.count || left.label.localeCompare(right.label)),
284
+ relationKinds: Object.entries(relationKinds)
285
+ .map(([value, count]) => ({
286
+ value: value,
287
+ label: KNOWLEDGE_GRAPH_RELATION_LABELS[value],
288
+ count
289
+ }))
290
+ .sort((left, right) => right.count - left.count || left.label.localeCompare(right.label)),
291
+ tags: Array.from(tags.values()).sort((left, right) => right.count - left.count || left.label.localeCompare(right.label)),
292
+ owners: Array.from(owners.values()).sort((left, right) => right.count - left.count || left.displayName.localeCompare(right.displayName)),
293
+ updatedAt: {
294
+ min: minUpdatedAt,
295
+ max: maxUpdatedAt
296
+ }
297
+ };
298
+ }
299
+ export function buildKnowledgeGraphHierarchy(nodes, edges) {
300
+ const sortedNodes = [...nodes].sort((left, right) => {
301
+ const layerDelta = getKnowledgeGraphNodeLayer(left.entityKind) -
302
+ getKnowledgeGraphNodeLayer(right.entityKind);
303
+ if (layerDelta !== 0) {
304
+ return layerDelta;
305
+ }
306
+ return (right.importance - left.importance || left.title.localeCompare(right.title));
307
+ });
308
+ const rowsByLayer = new Map();
309
+ const hierarchyNodes = sortedNodes.map((node) => {
310
+ const { laneId, laneIndex, laneLabel } = getKnowledgeGraphNodeLane(node.entityKind);
311
+ const row = rowsByLayer.get(laneIndex) ?? 0;
312
+ rowsByLayer.set(laneIndex, row + 1);
313
+ return {
314
+ ...node,
315
+ layer: laneIndex,
316
+ laneId,
317
+ laneLabel,
318
+ row
319
+ };
320
+ });
321
+ const nodeMap = new Map(hierarchyNodes.map((node) => [node.id, node]));
322
+ const hierarchyEdges = edges.map((edge) => {
323
+ const sourceNode = nodeMap.get(edge.source);
324
+ const targetNode = nodeMap.get(edge.target);
325
+ const sourceLayer = sourceNode?.layer ?? 0;
326
+ const targetLayer = targetNode?.layer ?? 0;
327
+ return {
328
+ ...edge,
329
+ secondary: targetLayer <= sourceLayer ||
330
+ (edge.family !== "structural" && edge.family !== "taxonomy")
331
+ };
332
+ });
333
+ return {
334
+ nodes: hierarchyNodes,
335
+ edges: hierarchyEdges
336
+ };
337
+ }
338
+ export function buildKnowledgeGraphFocusPayload(nodes, edges, focusNodeId) {
339
+ const nodeMap = new Map(nodes.map((node) => [node.id, node]));
340
+ const focusNode = focusNodeId ? nodeMap.get(focusNodeId) ?? null : null;
341
+ if (!focusNode) {
342
+ return {
343
+ generatedAt: new Date().toISOString(),
344
+ focusNode: null,
345
+ firstRingNodes: [],
346
+ neighborhoodEdges: [],
347
+ familyGroups: [],
348
+ relationCounts: initializeFamilyCounts(),
349
+ secondRingCounts: initializeFamilyCounts()
350
+ };
351
+ }
352
+ const neighborhoodEdges = edges.filter((edge) => edge.source === focusNode.id || edge.target === focusNode.id);
353
+ const neighborIds = Array.from(new Set(neighborhoodEdges.flatMap((edge) => edge.source === focusNode.id ? [edge.target] : [edge.source])));
354
+ const firstRingNodes = neighborIds
355
+ .map((nodeId) => nodeMap.get(nodeId) ?? null)
356
+ .filter((node) => Boolean(node));
357
+ const groupsByRelation = new Map();
358
+ const relationCounts = initializeFamilyCounts();
359
+ const secondRingCounts = initializeFamilyCounts();
360
+ const allNeighbors = buildNeighborMap(edges);
361
+ for (const nodeId of neighborIds) {
362
+ const secondRingPeers = allNeighbors.get(nodeId) ?? new Set();
363
+ for (const peerId of secondRingPeers) {
364
+ if (peerId === focusNode.id || neighborIds.includes(peerId)) {
365
+ continue;
366
+ }
367
+ const peerEdges = edges.filter((edge) => (edge.source === nodeId && edge.target === peerId) ||
368
+ (edge.target === nodeId && edge.source === peerId));
369
+ for (const edge of peerEdges) {
370
+ secondRingCounts[edge.family] += 1;
371
+ }
372
+ }
373
+ }
374
+ for (const edge of neighborhoodEdges) {
375
+ const peerId = edge.source === focusNode.id ? edge.target : edge.source;
376
+ const peer = nodeMap.get(peerId);
377
+ if (!peer) {
378
+ continue;
379
+ }
380
+ relationCounts[edge.family] += 1;
381
+ const existing = groupsByRelation.get(edge.relationKind);
382
+ if (existing) {
383
+ if (!existing.items.some((item) => item.id === peer.id)) {
384
+ existing.items.push(peer);
385
+ }
386
+ continue;
387
+ }
388
+ groupsByRelation.set(edge.relationKind, {
389
+ relationKind: edge.relationKind,
390
+ family: edge.family,
391
+ label: KNOWLEDGE_GRAPH_RELATION_LABELS[edge.relationKind],
392
+ items: [peer]
393
+ });
394
+ }
395
+ const familyGroupsMap = new Map();
396
+ for (const relation of groupsByRelation.values()) {
397
+ const existing = familyGroupsMap.get(relation.family);
398
+ if (existing) {
399
+ existing.relations.push({
400
+ ...relation,
401
+ items: [...relation.items].sort((left, right) => left.title.localeCompare(right.title))
402
+ });
403
+ existing.itemCount += relation.items.length;
404
+ existing.relationCount += 1;
405
+ continue;
406
+ }
407
+ familyGroupsMap.set(relation.family, {
408
+ family: relation.family,
409
+ label: KNOWLEDGE_GRAPH_RELATION_FAMILY_LABELS[relation.family],
410
+ relationCount: 1,
411
+ itemCount: relation.items.length,
412
+ relations: [
413
+ {
414
+ ...relation,
415
+ items: [...relation.items].sort((left, right) => left.title.localeCompare(right.title))
416
+ }
417
+ ]
418
+ });
419
+ }
420
+ return {
421
+ generatedAt: new Date().toISOString(),
422
+ focusNode,
423
+ firstRingNodes: firstRingNodes.sort((left, right) => left.title.localeCompare(right.title)),
424
+ neighborhoodEdges,
425
+ familyGroups: [...familyGroupsMap.values()]
426
+ .map((group) => ({
427
+ ...group,
428
+ relations: group.relations.sort((left, right) => left.label.localeCompare(right.label))
429
+ }))
430
+ .sort((left, right) => left.label.localeCompare(right.label)),
431
+ relationCounts,
432
+ secondRingCounts
433
+ };
434
+ }
435
+ export function getKnowledgeGraphNodeDegree(nodeId, edges) {
436
+ return edges.reduce((count, edge) => {
437
+ if (edge.source === nodeId || edge.target === nodeId) {
438
+ return count + 1;
439
+ }
440
+ return count;
441
+ }, 0);
442
+ }
443
+ export function isKnowledgeGraphNodeFocused(nodeId, focusNodeId, edges) {
444
+ if (!focusNodeId) {
445
+ return false;
446
+ }
447
+ if (nodeId === focusNodeId) {
448
+ return true;
449
+ }
450
+ return edges.some((edge) => (edge.source === focusNodeId && edge.target === nodeId) ||
451
+ (edge.target === focusNodeId && edge.source === nodeId));
452
+ }
453
+ export function buildKnowledgeGraphFocusNodeId(entityType, entityId) {
454
+ return buildKnowledgeGraphNodeId(entityType, entityId);
455
+ }
456
+ export function getKnowledgeGraphFocusRelatedNodeIds(focusNodeId, edges) {
457
+ if (!focusNodeId) {
458
+ return new Set();
459
+ }
460
+ const related = new Set([focusNodeId]);
461
+ for (const edge of edges) {
462
+ if (edge.source === focusNodeId) {
463
+ related.add(edge.target);
464
+ }
465
+ else if (edge.target === focusNodeId) {
466
+ related.add(edge.source);
467
+ }
468
+ }
469
+ return related;
470
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ export function normalizeAssetBasePath(basePath) {
2
+ if (!basePath || basePath === "/") {
3
+ return "/";
4
+ }
5
+ const withLeadingSlash = basePath.startsWith("/") ? basePath : `/${basePath}`;
6
+ return withLeadingSlash.endsWith("/") ? withLeadingSlash : `${withLeadingSlash}/`;
7
+ }
8
+ export function normalizeRouterBasename(basePath) {
9
+ const normalized = normalizeAssetBasePath(basePath);
10
+ if (normalized === "/") {
11
+ return "/";
12
+ }
13
+ return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
14
+ }
15
+ function getBaseUrl() {
16
+ return new URL(normalizeAssetBasePath(import.meta.env.BASE_URL || "/"), window.location.origin);
17
+ }
18
+ export function resolveForgePath(pathname) {
19
+ if (pathname.startsWith("/api/")) {
20
+ return pathname;
21
+ }
22
+ const normalized = pathname.startsWith("/") ? pathname.slice(1) : pathname;
23
+ return new URL(normalized, getBaseUrl()).pathname;
24
+ }