@parhelia/core 0.1.12744 → 0.1.12752

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 (103) hide show
  1. package/dist/agents-view/AgentsView.js +1 -1
  2. package/dist/agents-view/AgentsView.js.map +1 -1
  3. package/dist/agents-view/AgentsWorkspaceView.js +41 -21
  4. package/dist/agents-view/AgentsWorkspaceView.js.map +1 -1
  5. package/dist/components/ui/PlaceholderInput.js +3 -3
  6. package/dist/components/ui/PlaceholderInput.js.map +1 -1
  7. package/dist/components/ui/PlaceholderInputTypes.js +2 -2
  8. package/dist/components/ui/PlaceholderInputTypes.js.map +1 -1
  9. package/dist/components/ui/PlaceholderItemSelector.js +2 -2
  10. package/dist/components/ui/PlaceholderItemSelector.js.map +1 -1
  11. package/dist/editor/LinkEditorDialog.js +2 -2
  12. package/dist/editor/LinkEditorDialog.js.map +1 -1
  13. package/dist/editor/ai/AgentBanners.d.ts +11 -0
  14. package/dist/editor/ai/AgentBanners.js +16 -0
  15. package/dist/editor/ai/AgentBanners.js.map +1 -0
  16. package/dist/editor/ai/AgentCostDisplay.d.ts +12 -0
  17. package/dist/editor/ai/AgentCostDisplay.js +24 -1
  18. package/dist/editor/ai/AgentCostDisplay.js.map +1 -1
  19. package/dist/editor/ai/AgentDocumentList.js +5 -4
  20. package/dist/editor/ai/AgentDocumentList.js.map +1 -1
  21. package/dist/editor/ai/AgentInlineDialogContent.d.ts +17 -0
  22. package/dist/editor/ai/AgentInlineDialogContent.js +32 -0
  23. package/dist/editor/ai/AgentInlineDialogContent.js.map +1 -0
  24. package/dist/editor/ai/AgentSharingSection.d.ts +6 -0
  25. package/dist/editor/ai/AgentSharingSection.js +149 -0
  26. package/dist/editor/ai/AgentSharingSection.js.map +1 -0
  27. package/dist/editor/ai/AgentTerminal.d.ts +2 -1
  28. package/dist/editor/ai/AgentTerminal.js +298 -969
  29. package/dist/editor/ai/AgentTerminal.js.map +1 -1
  30. package/dist/editor/ai/AgentTerminalStatusBar.d.ts +18 -0
  31. package/dist/editor/ai/AgentTerminalStatusBar.js +431 -126
  32. package/dist/editor/ai/AgentTerminalStatusBar.js.map +1 -1
  33. package/dist/editor/ai/Agents.js +1 -1
  34. package/dist/editor/ai/Agents.js.map +1 -1
  35. package/dist/editor/ai/HeartbeatMessage.d.ts +4 -0
  36. package/dist/editor/ai/HeartbeatMessage.js +7 -0
  37. package/dist/editor/ai/HeartbeatMessage.js.map +1 -0
  38. package/dist/editor/ai/InitialThinkingSplash.d.ts +3 -0
  39. package/dist/editor/ai/InitialThinkingSplash.js +9 -0
  40. package/dist/editor/ai/InitialThinkingSplash.js.map +1 -0
  41. package/dist/editor/ai/InlineAiDialog.js +50 -2
  42. package/dist/editor/ai/InlineAiDialog.js.map +1 -1
  43. package/dist/editor/ai/QueuedPromptsPanel.d.ts +4 -0
  44. package/dist/editor/ai/QueuedPromptsPanel.js +36 -0
  45. package/dist/editor/ai/QueuedPromptsPanel.js.map +1 -0
  46. package/dist/editor/ai/TodoListPanel.d.ts +5 -0
  47. package/dist/editor/ai/TodoListPanel.js +113 -0
  48. package/dist/editor/ai/TodoListPanel.js.map +1 -0
  49. package/dist/editor/ai/ToolCallDisplay.js +136 -136
  50. package/dist/editor/ai/ToolCallDisplay.js.map +1 -1
  51. package/dist/editor/ai/UserMessage.d.ts +4 -0
  52. package/dist/editor/ai/UserMessage.js +42 -0
  53. package/dist/editor/ai/UserMessage.js.map +1 -0
  54. package/dist/editor/ai/agentMessageConversion.d.ts +11 -0
  55. package/dist/editor/ai/agentMessageConversion.js +134 -0
  56. package/dist/editor/ai/agentMessageConversion.js.map +1 -0
  57. package/dist/editor/ai/agentMessageGrouping.d.ts +22 -0
  58. package/dist/editor/ai/agentMessageGrouping.js +103 -0
  59. package/dist/editor/ai/agentMessageGrouping.js.map +1 -0
  60. package/dist/editor/ai/agentMessageHelpers.d.ts +23 -0
  61. package/dist/editor/ai/agentMessageHelpers.js +124 -0
  62. package/dist/editor/ai/agentMessageHelpers.js.map +1 -0
  63. package/dist/editor/ai/agentMessageMarkdown.d.ts +2 -0
  64. package/dist/editor/ai/agentMessageMarkdown.js +14 -0
  65. package/dist/editor/ai/agentMessageMarkdown.js.map +1 -0
  66. package/dist/editor/ai/agentTodoExtraction.d.ts +12 -0
  67. package/dist/editor/ai/agentTodoExtraction.js +205 -0
  68. package/dist/editor/ai/agentTodoExtraction.js.map +1 -0
  69. package/dist/editor/client/EditorShell.js +38 -51
  70. package/dist/editor/client/EditorShell.js.map +1 -1
  71. package/dist/editor/client/editContext.d.ts +1 -0
  72. package/dist/editor/client/editContext.js.map +1 -1
  73. package/dist/editor/client/operations.d.ts +3 -1
  74. package/dist/editor/client/operations.js +20 -2
  75. package/dist/editor/client/operations.js.map +1 -1
  76. package/dist/editor/menubar/VersionPreviewCard.js +34 -3
  77. package/dist/editor/menubar/VersionPreviewCard.js.map +1 -1
  78. package/dist/editor/menubar/toolbar-sections/ViewportControls.js +2 -2
  79. package/dist/editor/menubar/toolbar-sections/ViewportControls.js.map +1 -1
  80. package/dist/editor/reviews/SuggestedEdit.js +65 -48
  81. package/dist/editor/reviews/SuggestedEdit.js.map +1 -1
  82. package/dist/editor/reviews/SuggestionDisplayPopover.js +5 -1
  83. package/dist/editor/reviews/SuggestionDisplayPopover.js.map +1 -1
  84. package/dist/editor/services/agentService.d.ts +24 -0
  85. package/dist/editor/services/agentService.js +40 -0
  86. package/dist/editor/services/agentService.js.map +1 -1
  87. package/dist/editor/services/aiService.d.ts +10 -0
  88. package/dist/editor/services/aiService.js.map +1 -1
  89. package/dist/editor/settings/panels/AgentProfileConfigPanel.js +1 -1
  90. package/dist/editor/settings/panels/AgentProfileConfigPanel.js.map +1 -1
  91. package/dist/revision.d.ts +2 -2
  92. package/dist/revision.js +2 -2
  93. package/dist/task-board/TaskBoardWorkspace.js +57 -26
  94. package/dist/task-board/TaskBoardWorkspace.js.map +1 -1
  95. package/dist/task-board/components/ProjectDashboard.js +2 -3
  96. package/dist/task-board/components/ProjectDashboard.js.map +1 -1
  97. package/dist/task-board/components/TaskBoardTitlebar.js +2 -1
  98. package/dist/task-board/components/TaskBoardTitlebar.js.map +1 -1
  99. package/dist/task-board/components/TaskDetailPanel.d.ts +8 -0
  100. package/dist/task-board/components/TaskDetailPanel.js +5 -3
  101. package/dist/task-board/components/TaskDetailPanel.js.map +1 -1
  102. package/package.json +1 -1
  103. package/styles.css +11 -10
@@ -0,0 +1,205 @@
1
+ export const extractPartialTodos = (jsonText) => {
2
+ try {
3
+ const parsed = JSON.parse(jsonText);
4
+ const result = Array.isArray(parsed) ? parsed : parsed?.items || [];
5
+ return result;
6
+ }
7
+ catch (e) {
8
+ const items = [];
9
+ const textPattern = /"text"\s*:\s*"([^"]+)"/g;
10
+ const textMatches = [];
11
+ let textMatch;
12
+ while ((textMatch = textPattern.exec(jsonText)) !== null) {
13
+ if (textMatch[1]) {
14
+ textMatches.push({
15
+ text: textMatch[1],
16
+ startIdx: textMatch.index,
17
+ });
18
+ }
19
+ }
20
+ for (const { startIdx } of textMatches) {
21
+ let openBrace = -1;
22
+ for (let i = startIdx - 1; i >= 0; i--) {
23
+ if (jsonText[i] === "{") {
24
+ openBrace = i;
25
+ break;
26
+ }
27
+ if (jsonText[i] === "}")
28
+ break;
29
+ }
30
+ if (openBrace === -1)
31
+ continue;
32
+ let closeBrace = -1;
33
+ let depth = 0;
34
+ for (let i = openBrace; i < jsonText.length; i++) {
35
+ if (jsonText[i] === "{")
36
+ depth++;
37
+ if (jsonText[i] === "}") {
38
+ depth--;
39
+ if (depth === 0) {
40
+ closeBrace = i;
41
+ break;
42
+ }
43
+ }
44
+ }
45
+ const objStr = closeBrace !== -1
46
+ ? jsonText.substring(openBrace, closeBrace + 1)
47
+ : jsonText.substring(openBrace) + "}";
48
+ try {
49
+ const obj = JSON.parse(objStr);
50
+ if (obj.title || obj.text) {
51
+ items.push({
52
+ title: obj.title || obj.text,
53
+ status: obj.status || "pending",
54
+ instructions: obj.instructions || obj.note || undefined,
55
+ agentProfileId: obj.agentProfileId || undefined,
56
+ });
57
+ }
58
+ }
59
+ catch (e) {
60
+ // Skip malformed objects
61
+ }
62
+ }
63
+ const lines = jsonText.split("\n");
64
+ for (let i = lines.length - 1; i >= 0; i--) {
65
+ const partialJson = lines.slice(0, i + 1).join("\n");
66
+ let testJson = partialJson;
67
+ const openBraces = (testJson.match(/\{/g) || []).length;
68
+ const closeBraces = (testJson.match(/\}/g) || []).length;
69
+ const openBrackets = (testJson.match(/\[/g) || []).length;
70
+ const closeBrackets = (testJson.match(/\]/g) || []).length;
71
+ testJson += "]".repeat(openBrackets - closeBrackets);
72
+ testJson += "}".repeat(openBraces - closeBraces);
73
+ try {
74
+ const parsed = JSON.parse(testJson);
75
+ const partialItems = Array.isArray(parsed)
76
+ ? parsed
77
+ : parsed?.items || [];
78
+ if (partialItems.length > items.length) {
79
+ return partialItems;
80
+ }
81
+ }
82
+ catch (e) {
83
+ continue;
84
+ }
85
+ }
86
+ return items;
87
+ }
88
+ };
89
+ export const extractTodosFromMessages = (messages) => {
90
+ const todos = [];
91
+ const fencedTodoToken = "```todo_list";
92
+ const plainTodoToken = "todo_list";
93
+ for (const message of messages) {
94
+ if (message.role !== "assistant" || !message.content)
95
+ continue;
96
+ const content = message.content;
97
+ let cursor = 0;
98
+ while (cursor < content.length) {
99
+ const nextFenced = content.indexOf(fencedTodoToken, cursor);
100
+ const nextPlain = content.indexOf(plainTodoToken, cursor);
101
+ let todoStart = -1;
102
+ let isFenced = false;
103
+ if (nextFenced !== -1 && (nextPlain === -1 || nextFenced < nextPlain)) {
104
+ todoStart = nextFenced;
105
+ isFenced = true;
106
+ }
107
+ else if (nextPlain !== -1) {
108
+ const before = nextPlain > 0 ? content[nextPlain - 1] : "\n";
109
+ if (before === "\n" || before === "\r" || nextPlain === 0) {
110
+ todoStart = nextPlain;
111
+ isFenced = false;
112
+ }
113
+ }
114
+ if (todoStart === -1)
115
+ break;
116
+ try {
117
+ let jsonText = "";
118
+ let isComplete = true;
119
+ if (isFenced) {
120
+ const afterToken = todoStart + fencedTodoToken.length;
121
+ const closePos = content.indexOf("```", afterToken);
122
+ if (closePos === -1) {
123
+ jsonText = content.slice(afterToken).trim();
124
+ isComplete = false;
125
+ cursor = content.length;
126
+ }
127
+ else {
128
+ jsonText = content.slice(afterToken, closePos).trim();
129
+ cursor = closePos + 3;
130
+ }
131
+ }
132
+ else {
133
+ const afterToken = todoStart + plainTodoToken.length;
134
+ const braceStart = content.indexOf("{", afterToken);
135
+ if (braceStart === -1)
136
+ break;
137
+ let depth = 0;
138
+ let braceEnd = -1;
139
+ for (let i = braceStart; i < content.length; i++) {
140
+ if (content[i] === "{")
141
+ depth++;
142
+ if (content[i] === "}") {
143
+ depth--;
144
+ if (depth === 0) {
145
+ braceEnd = i;
146
+ break;
147
+ }
148
+ }
149
+ }
150
+ if (braceEnd === -1) {
151
+ jsonText = content.slice(braceStart).trim();
152
+ isComplete = false;
153
+ cursor = content.length;
154
+ }
155
+ else {
156
+ jsonText = content.slice(braceStart, braceEnd + 1).trim();
157
+ cursor = braceEnd + 1;
158
+ }
159
+ }
160
+ const todoItems = isComplete
161
+ ? (() => {
162
+ try {
163
+ const parsed = JSON.parse(jsonText);
164
+ return Array.isArray(parsed) ? parsed : parsed?.items || [];
165
+ }
166
+ catch (e) {
167
+ return [];
168
+ }
169
+ })()
170
+ : extractPartialTodos(jsonText);
171
+ todoItems.forEach((item) => {
172
+ if (!item)
173
+ return;
174
+ const title = item.title ||
175
+ item.text ||
176
+ item.content ||
177
+ item.label ||
178
+ String(item.task || "");
179
+ if (!title)
180
+ return;
181
+ todos.push({
182
+ id: item.id,
183
+ title,
184
+ status: item.status || "pending",
185
+ instructions: item.instructions || item.note || item.description,
186
+ agentProfileId: item.agentProfileId,
187
+ messageId: message.id,
188
+ sourceTitle: item.sourceTitle,
189
+ });
190
+ });
191
+ }
192
+ catch (e) {
193
+ cursor++;
194
+ continue;
195
+ }
196
+ }
197
+ }
198
+ const todoMap = new Map();
199
+ for (const todo of todos) {
200
+ const key = todo.id || todo.title;
201
+ todoMap.set(key, todo);
202
+ }
203
+ return Array.from(todoMap.values());
204
+ };
205
+ //# sourceMappingURL=agentTodoExtraction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentTodoExtraction.js","sourceRoot":"","sources":["../../../src/editor/ai/agentTodoExtraction.ts"],"names":[],"mappings":"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"}
@@ -3718,60 +3718,48 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
3718
3718
  const match = text.match(guidPattern);
3719
3719
  return match ? match[0] : null;
3720
3720
  };
3721
- const getTextFromElement = (element) => {
3722
- if (!element)
3723
- return null;
3724
- // First, check if there's a text selection - user might have selected the GUID
3721
+ // Resolve the text node + character offset under a click point.
3722
+ // Only the text actually under the cursor is considered, so clicking
3723
+ // text adjacent to a GUID (different text node, or different range
3724
+ // within the same text node) does not trigger navigation.
3725
+ const getCaretAtPoint = (x, y) => {
3726
+ const doc = document;
3727
+ if (typeof doc.caretPositionFromPoint === "function") {
3728
+ const pos = doc.caretPositionFromPoint(x, y);
3729
+ if (pos?.offsetNode) {
3730
+ return { node: pos.offsetNode, offset: pos.offset };
3731
+ }
3732
+ }
3733
+ if (typeof document.caretRangeFromPoint === "function") {
3734
+ const range = document.caretRangeFromPoint(x, y);
3735
+ if (range) {
3736
+ return { node: range.startContainer, offset: range.startOffset };
3737
+ }
3738
+ }
3739
+ return null;
3740
+ };
3741
+ const getGuidFromClickPoint = (event) => {
3742
+ // First, honour an active text selection - the user may have
3743
+ // intentionally highlighted a GUID before ctrl+clicking.
3725
3744
  const selection = window.getSelection();
3726
3745
  if (selection && !selection.isCollapsed) {
3727
- const selectedText = selection.toString();
3728
- const guid = extractGuidFromText(selectedText);
3729
- if (guid)
3730
- return guid;
3731
- }
3732
- // Try to get text content from the element itself
3733
- const textContent = element.textContent?.trim();
3734
- if (textContent) {
3735
- const guid = extractGuidFromText(textContent);
3746
+ const guid = extractGuidFromText(selection.toString());
3736
3747
  if (guid)
3737
3748
  return guid;
3738
3749
  }
3739
- // Check if we clicked on a text node's parent
3740
- if (element.childNodes.length === 1) {
3741
- const firstChild = element.childNodes[0];
3742
- if (firstChild && firstChild.nodeType === Node.TEXT_NODE) {
3743
- const text = firstChild.textContent?.trim();
3744
- if (text) {
3745
- const guid = extractGuidFromText(text);
3746
- if (guid)
3747
- return guid;
3748
- }
3749
- }
3750
- }
3751
- // Walk up the parent tree to find a parent that might contain a GUID
3752
- // This helps with JSON viewers where the GUID is split across elements
3753
- let currentElement = element;
3754
- let depth = 0;
3755
- while (currentElement && depth < 5) {
3756
- const parentText = currentElement.textContent?.trim();
3757
- if (parentText && parentText.length < 200) {
3758
- // Avoid huge text blocks
3759
- const guid = extractGuidFromText(parentText);
3760
- if (guid)
3761
- return guid;
3762
- }
3763
- currentElement = currentElement.parentElement;
3764
- depth++;
3765
- }
3766
- // Try to find GUIDs in nearby text
3767
- const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null);
3768
- let node;
3769
- while ((node = walker.nextNode())) {
3770
- const text = node.textContent?.trim();
3771
- if (text) {
3772
- const guid = extractGuidFromText(text);
3773
- if (guid)
3774
- return guid;
3750
+ const caret = getCaretAtPoint(event.clientX, event.clientY);
3751
+ if (!caret || caret.node.nodeType !== Node.TEXT_NODE)
3752
+ return null;
3753
+ const text = caret.node.textContent ?? "";
3754
+ // Find every GUID match in the clicked text node and require the
3755
+ // click offset to fall inside one of them.
3756
+ const guidPattern = /[\{\(]?[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}[\}\)]?/g;
3757
+ let match;
3758
+ while ((match = guidPattern.exec(text)) !== null) {
3759
+ const start = match.index;
3760
+ const end = start + match[0].length;
3761
+ if (caret.offset >= start && caret.offset <= end) {
3762
+ return match[0];
3775
3763
  }
3776
3764
  }
3777
3765
  return null;
@@ -3781,7 +3769,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
3781
3769
  modifierWasPressedOnMouseDown = event.ctrlKey || event.metaKey;
3782
3770
  };
3783
3771
  const handleCtrlClick = async (event) => {
3784
- const target = event.target;
3785
3772
  // Only proceed if Ctrl/Cmd was already pressed when the mouse interaction started.
3786
3773
  // This avoids accidental navigation when users press Ctrl after selecting text to copy.
3787
3774
  if (!modifierWasPressedOnMouseDown)
@@ -3790,7 +3777,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
3790
3777
  if (!event.ctrlKey && !event.metaKey)
3791
3778
  return;
3792
3779
  modifierWasPressedOnMouseDown = false;
3793
- const text = getTextFromElement(target);
3780
+ const text = getGuidFromClickPoint(event);
3794
3781
  if (text && isGuid(text)) {
3795
3782
  event.preventDefault();
3796
3783
  event.stopPropagation();