@starlove/orbit 1.3.5 → 1.4.0
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.
- package/Dockerfile +2 -1
- package/README.md +10 -9
- package/SKILL-ORBIT.md +41 -17
- package/dist/full/fonts/Chakra_Petch/ChakraPetch-Bold.ttf +0 -0
- package/dist/full/fonts/Chakra_Petch/ChakraPetch-BoldItalic.ttf +0 -0
- package/dist/full/fonts/Chakra_Petch/ChakraPetch-Italic.ttf +0 -0
- package/dist/full/fonts/Chakra_Petch/ChakraPetch-Light.ttf +0 -0
- package/dist/full/fonts/Chakra_Petch/ChakraPetch-LightItalic.ttf +0 -0
- package/dist/full/fonts/Chakra_Petch/ChakraPetch-Medium.ttf +0 -0
- package/dist/full/fonts/Chakra_Petch/ChakraPetch-MediumItalic.ttf +0 -0
- package/dist/full/fonts/Chakra_Petch/ChakraPetch-Regular.ttf +0 -0
- package/dist/full/fonts/Chakra_Petch/ChakraPetch-SemiBold.ttf +0 -0
- package/dist/full/fonts/Chakra_Petch/ChakraPetch-SemiBoldItalic.ttf +0 -0
- package/dist/full/fonts/Chakra_Petch/OFL.txt +93 -0
- package/dist/full/fonts/Inter/Inter-Italic-VariableFont_opsz,wght.ttf +0 -0
- package/dist/full/fonts/Inter/Inter-VariableFont_opsz,wght.ttf +0 -0
- package/dist/full/fonts/Inter/OFL.txt +93 -0
- package/dist/full/fonts/Inter/README.txt +118 -0
- package/dist/full/fonts/JetBrains_Mono/JetBrainsMono-Italic-VariableFont_wght.ttf +0 -0
- package/dist/full/fonts/JetBrains_Mono/JetBrainsMono-VariableFont_wght.ttf +0 -0
- package/dist/full/fonts/JetBrains_Mono/OFL.txt +93 -0
- package/dist/full/fonts/JetBrains_Mono/README.txt +79 -0
- package/dist/full/fonts/OpenRing-Regular.ttf +0 -0
- package/dist/full/fonts/Open_Sans/OFL.txt +93 -0
- package/dist/full/fonts/Open_Sans/OpenSans-Italic-VariableFont_wdth,wght.ttf +0 -0
- package/dist/full/fonts/Open_Sans/OpenSans-VariableFont_wdth,wght.ttf +0 -0
- package/dist/full/fonts/Open_Sans/README.txt +100 -0
- package/dist/full/fonts/Orbitron/OFL.txt +93 -0
- package/dist/full/fonts/Orbitron/Orbitron-VariableFont_wght.ttf +0 -0
- package/dist/full/fonts/Orbitron/README.txt +68 -0
- package/dist/full/fonts/Rajdhani/OFL.txt +93 -0
- package/dist/full/fonts/Rajdhani/Rajdhani-Bold.ttf +0 -0
- package/dist/full/fonts/Rajdhani/Rajdhani-Light.ttf +0 -0
- package/dist/full/fonts/Rajdhani/Rajdhani-Medium.ttf +0 -0
- package/dist/full/fonts/Rajdhani/Rajdhani-Regular.ttf +0 -0
- package/dist/full/fonts/Rajdhani/Rajdhani-SemiBold.ttf +0 -0
- package/dist/full/fonts/runescape-uf.ttf +0 -0
- package/dist/full/index.html +135 -25
- package/dist/full/js/app.62905fcb.js +952 -0
- package/dist/full/js/app.62905fcb.js.map +7 -0
- package/dist/full/styles.4e60d824.css +1 -0
- package/dist/full/version.json +2 -2
- package/docs/AGENT_PROTOCOL.md +20 -13
- package/docs/ORBIT_DISPATCH.md +73 -38
- package/docs/UPDATING.md +114 -0
- package/package.json +5 -7
- package/public/fonts/Chakra_Petch/ChakraPetch-Bold.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-BoldItalic.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-Italic.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-Light.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-LightItalic.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-Medium.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-MediumItalic.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-Regular.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-SemiBold.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-SemiBoldItalic.ttf +0 -0
- package/public/fonts/Chakra_Petch/OFL.txt +93 -0
- package/public/fonts/Inter/Inter-Italic-VariableFont_opsz,wght.ttf +0 -0
- package/public/fonts/Inter/Inter-VariableFont_opsz,wght.ttf +0 -0
- package/public/fonts/Inter/OFL.txt +93 -0
- package/public/fonts/Inter/README.txt +118 -0
- package/public/fonts/JetBrains_Mono/JetBrainsMono-Italic-VariableFont_wght.ttf +0 -0
- package/public/fonts/JetBrains_Mono/JetBrainsMono-VariableFont_wght.ttf +0 -0
- package/public/fonts/JetBrains_Mono/OFL.txt +93 -0
- package/public/fonts/JetBrains_Mono/README.txt +79 -0
- package/public/fonts/OpenRing-Regular.ttf +0 -0
- package/public/fonts/Open_Sans/OFL.txt +93 -0
- package/public/fonts/Open_Sans/OpenSans-Italic-VariableFont_wdth,wght.ttf +0 -0
- package/public/fonts/Open_Sans/OpenSans-VariableFont_wdth,wght.ttf +0 -0
- package/public/fonts/Open_Sans/README.txt +100 -0
- package/public/fonts/Orbitron/OFL.txt +93 -0
- package/public/fonts/Orbitron/Orbitron-VariableFont_wght.ttf +0 -0
- package/public/fonts/Orbitron/README.txt +68 -0
- package/public/fonts/Rajdhani/OFL.txt +93 -0
- package/public/fonts/Rajdhani/Rajdhani-Bold.ttf +0 -0
- package/public/fonts/Rajdhani/Rajdhani-Light.ttf +0 -0
- package/public/fonts/Rajdhani/Rajdhani-Medium.ttf +0 -0
- package/public/fonts/Rajdhani/Rajdhani-Regular.ttf +0 -0
- package/public/fonts/Rajdhani/Rajdhani-SemiBold.ttf +0 -0
- package/public/fonts/runescape-uf.ttf +0 -0
- package/public/index.html +133 -23
- package/public/js/artifact-drawer.js +79 -0
- package/public/js/board-export.js +161 -0
- package/public/js/board-menu.js +219 -17
- package/public/js/card-actions.js +1 -1
- package/public/js/create-card.js +60 -23
- package/public/js/drawer.js +164 -4
- package/public/js/font-preference.js +229 -0
- package/public/js/format.js +0 -10
- package/public/js/icons.js +16 -0
- package/public/js/local-backend.js +31 -4
- package/public/js/main.js +7 -1
- package/public/js/modal.js +3 -1
- package/public/js/panel.js +58 -0
- package/public/js/settings-tabs.js +1 -1
- package/public/js/settings.js +606 -275
- package/public/js/sse.js +3 -0
- package/public/js/state.js +1 -1
- package/public/js/text-editing.js +128 -0
- package/public/js/ticket-detail.js +377 -148
- package/public/js/ticket-typeahead.js +49 -0
- package/public/js/toast.js +19 -4
- package/public/js/topbar-notes.js +3 -3
- package/public/js/typeahead.js +206 -0
- package/public/js/update-check.js +58 -0
- package/public/styles.css +5447 -3572
- package/src/cli/orbit.js +9 -5
- package/src/core/agent.js +12 -4
- package/src/core/agents-md.js +3 -3
- package/src/core/artifacts.js +149 -0
- package/src/core/board.js +3 -2
- package/src/core/boards.js +0 -1
- package/src/core/css-bundle.js +1 -0
- package/src/core/db.js +6 -0
- package/src/core/dispatch.js +344 -34
- package/src/core/http.js +9 -2
- package/src/core/paths.js +26 -2
- package/src/core/router.js +33 -0
- package/src/core/search.js +3 -2
- package/src/core/snapshots.js +10 -5
- package/src/core/tickets.js +34 -3
- package/src/core/util.js +3 -2
- package/src/core/version-check.js +154 -0
- package/src/mcp/orbit-client.js +18 -2
- package/src/mcp-server.js +19 -14
- package/src/server.js +28 -3
- package/dist/full/js/app.4ae80764.js +0 -742
- package/dist/full/js/app.4ae80764.js.map +0 -7
- package/dist/full/styles.b9e0c130.css +0 -1
package/public/js/sse.js
CHANGED
|
@@ -16,6 +16,7 @@ const CARD_TOUCHING_EVENTS = new Set([
|
|
|
16
16
|
"state_changed",
|
|
17
17
|
"ticket_updated",
|
|
18
18
|
"comment_created",
|
|
19
|
+
"comment_ai_omission_changed",
|
|
19
20
|
"agent_claimed",
|
|
20
21
|
"checkpoint_requested",
|
|
21
22
|
"agent_completed"
|
|
@@ -99,6 +100,8 @@ export function connectEventStream() {
|
|
|
99
100
|
const label = ticket ? `#${ticket.number}` : "ticket";
|
|
100
101
|
toast.info(`New comment on ${label}`);
|
|
101
102
|
scheduleSSEReload();
|
|
103
|
+
} else if (eventType === "comment_ai_omission_changed") {
|
|
104
|
+
scheduleSSEReload();
|
|
102
105
|
} else if (eventType === "agent_claimed") {
|
|
103
106
|
const ticket = findTicket();
|
|
104
107
|
toast.info(`Agent claimed ${ticket ? `#${ticket.number} ${ticket.title}` : "a ticket"}`);
|
package/public/js/state.js
CHANGED
|
@@ -16,7 +16,7 @@ export const state = {
|
|
|
16
16
|
expandedCardIds: new Set(),
|
|
17
17
|
/** "empty" | "ticket" | "settings" — drives the main right overlay drawer (not the New flyout). */
|
|
18
18
|
detailMode: "empty",
|
|
19
|
-
/** "lanes" | "ai" | "
|
|
19
|
+
/** "lanes" | "ai" | "data" | "notes" | "journal" — which Settings tab is active. */
|
|
20
20
|
settingsTab: normalizeSettingsTab(localStorage.getItem("mab_settings_tab")),
|
|
21
21
|
/** Whether to render the priority pill on kanban / related cards. The detail
|
|
22
22
|
* drawer header always shows it. Default on; user can toggle it from the
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// Shared textarea editing helpers. These stay DOM-light so node:test can cover
|
|
2
|
+
// editor behavior without booting the browser app.
|
|
3
|
+
|
|
4
|
+
const DEFAULT_INDENT = "\t";
|
|
5
|
+
|
|
6
|
+
function clampIndex(value, index) {
|
|
7
|
+
const n = Number(index);
|
|
8
|
+
if (!Number.isFinite(n)) return 0;
|
|
9
|
+
return Math.max(0, Math.min(value.length, n));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function lineStartFor(value, index) {
|
|
13
|
+
return value.lastIndexOf("\n", Math.max(0, index - 1)) + 1;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function selectedLineRange(value, selectionStart, selectionEnd) {
|
|
17
|
+
const lineStart = lineStartFor(value, selectionStart);
|
|
18
|
+
const effectiveEnd =
|
|
19
|
+
selectionEnd > selectionStart && value[selectionEnd - 1] === "\n"
|
|
20
|
+
? selectionEnd - 1
|
|
21
|
+
: selectionEnd;
|
|
22
|
+
const nextBreak = value.indexOf("\n", Math.max(lineStart, effectiveEnd));
|
|
23
|
+
return {
|
|
24
|
+
lineStart,
|
|
25
|
+
lineEnd: nextBreak === -1 ? value.length : nextBreak,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function lineStartsForBlock(block, lineStart) {
|
|
30
|
+
const starts = [];
|
|
31
|
+
let cursor = lineStart;
|
|
32
|
+
for (const line of block.split("\n")) {
|
|
33
|
+
starts.push(cursor);
|
|
34
|
+
cursor += line.length + 1;
|
|
35
|
+
}
|
|
36
|
+
return starts;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function leadingOutdentWidth(line) {
|
|
40
|
+
if (line.startsWith("\t")) return 1;
|
|
41
|
+
const spaces = line.match(/^ {1,2}/)?.[0] || "";
|
|
42
|
+
return spaces.length;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function adjustmentBeforePosition(position, lineStarts, widths) {
|
|
46
|
+
let total = 0;
|
|
47
|
+
for (let i = 0; i < lineStarts.length; i += 1) {
|
|
48
|
+
if (position <= lineStarts[i]) continue;
|
|
49
|
+
total += Math.min(widths[i], position - lineStarts[i]);
|
|
50
|
+
}
|
|
51
|
+
return total;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function applyTextareaIndentation({
|
|
55
|
+
value = "",
|
|
56
|
+
selectionStart = 0,
|
|
57
|
+
selectionEnd = selectionStart,
|
|
58
|
+
shiftKey = false,
|
|
59
|
+
indent = DEFAULT_INDENT,
|
|
60
|
+
} = {}) {
|
|
61
|
+
const source = String(value);
|
|
62
|
+
const start = clampIndex(source, selectionStart);
|
|
63
|
+
const end = clampIndex(source, selectionEnd);
|
|
64
|
+
const first = Math.min(start, end);
|
|
65
|
+
const last = Math.max(start, end);
|
|
66
|
+
const indentText = String(indent || DEFAULT_INDENT);
|
|
67
|
+
|
|
68
|
+
if (!shiftKey && first === last) {
|
|
69
|
+
const nextValue = `${source.slice(0, first)}${indentText}${source.slice(last)}`;
|
|
70
|
+
const nextCaret = first + indentText.length;
|
|
71
|
+
return {
|
|
72
|
+
value: nextValue,
|
|
73
|
+
selectionStart: nextCaret,
|
|
74
|
+
selectionEnd: nextCaret,
|
|
75
|
+
handled: true,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const { lineStart, lineEnd } = selectedLineRange(source, first, last);
|
|
80
|
+
const block = source.slice(lineStart, lineEnd);
|
|
81
|
+
const lines = block.split("\n");
|
|
82
|
+
const lineStarts = lineStartsForBlock(block, lineStart);
|
|
83
|
+
|
|
84
|
+
if (!shiftKey) {
|
|
85
|
+
const widths = lines.map(() => indentText.length);
|
|
86
|
+
const nextBlock = lines.map((line) => `${indentText}${line}`).join("\n");
|
|
87
|
+
const selectionStartDelta = adjustmentBeforePosition(first, lineStarts, widths);
|
|
88
|
+
const selectionEndDelta = adjustmentBeforePosition(last, lineStarts, widths);
|
|
89
|
+
return {
|
|
90
|
+
value: `${source.slice(0, lineStart)}${nextBlock}${source.slice(lineEnd)}`,
|
|
91
|
+
selectionStart: first + selectionStartDelta,
|
|
92
|
+
selectionEnd: last + selectionEndDelta,
|
|
93
|
+
handled: true,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const widths = lines.map(leadingOutdentWidth);
|
|
98
|
+
const nextBlock = lines
|
|
99
|
+
.map((line, index) => line.slice(widths[index]))
|
|
100
|
+
.join("\n");
|
|
101
|
+
const selectionStartDelta = adjustmentBeforePosition(first, lineStarts, widths);
|
|
102
|
+
const selectionEndDelta = adjustmentBeforePosition(last, lineStarts, widths);
|
|
103
|
+
return {
|
|
104
|
+
value: `${source.slice(0, lineStart)}${nextBlock}${source.slice(lineEnd)}`,
|
|
105
|
+
selectionStart: first - selectionStartDelta,
|
|
106
|
+
selectionEnd: last - selectionEndDelta,
|
|
107
|
+
handled: true,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function handleTextareaIndentationKeydown(event, textarea = event?.currentTarget) {
|
|
112
|
+
if (!event || event.key !== "Tab") return false;
|
|
113
|
+
if (event.altKey || event.ctrlKey || event.metaKey) return false;
|
|
114
|
+
if (!textarea || textarea.tagName !== "TEXTAREA") return false;
|
|
115
|
+
|
|
116
|
+
event.preventDefault();
|
|
117
|
+
const next = applyTextareaIndentation({
|
|
118
|
+
value: textarea.value,
|
|
119
|
+
selectionStart: textarea.selectionStart,
|
|
120
|
+
selectionEnd: textarea.selectionEnd,
|
|
121
|
+
shiftKey: event.shiftKey,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
textarea.value = next.value;
|
|
125
|
+
textarea.setSelectionRange(next.selectionStart, next.selectionEnd);
|
|
126
|
+
textarea.dispatchEvent(new Event("input", { bubbles: true }));
|
|
127
|
+
return next.handled;
|
|
128
|
+
}
|