@orchestraworks/cli 0.8.0 → 0.9.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/README.md +1 -1
- package/dist/artifacts/prelude.js +416 -88
- package/dist/cli/api/execute.d.ts +2 -5
- package/dist/cli/api/execute.js +67 -40
- package/dist/cli/api/raw.d.ts +3 -1
- package/dist/cli/api/raw.js +33 -6
- package/dist/cli/api/register.js +6 -1
- package/dist/cli/preview.d.ts +5 -4
- package/dist/cli/preview.js +15 -9
- package/dist/cli/upload.d.ts +26 -0
- package/dist/cli/upload.js +64 -16
- package/dist/generated/cli-commands.d.ts +5 -0
- package/dist/generated/cli-commands.json +31100 -17245
- package/dist/generated/cli-dispatch.js +99 -0
- package/dist/generated/managed-skills.js +1 -0
- package/node_modules/@orchestraworks/client/dist/apis/ArtifactsApi.d.ts +3 -3
- package/node_modules/@orchestraworks/client/dist/apis/ArtifactsApi.js +2 -2
- package/node_modules/@orchestraworks/client/dist/apis/FilesApi.d.ts +292 -2
- package/node_modules/@orchestraworks/client/dist/apis/FilesApi.js +988 -30
- package/node_modules/@orchestraworks/client/dist/esm/apis/ArtifactsApi.d.ts +3 -3
- package/node_modules/@orchestraworks/client/dist/esm/apis/ArtifactsApi.js +2 -2
- package/node_modules/@orchestraworks/client/dist/esm/apis/FilesApi.d.ts +292 -2
- package/node_modules/@orchestraworks/client/dist/esm/apis/FilesApi.js +986 -28
- package/node_modules/@orchestraworks/client/dist/esm/models/Artifact.d.ts +12 -53
- package/node_modules/@orchestraworks/client/dist/esm/models/Artifact.js +7 -29
- package/node_modules/@orchestraworks/client/dist/esm/models/Comment.d.ts +2 -2
- package/node_modules/@orchestraworks/client/dist/esm/models/Comment.js +3 -3
- package/node_modules/@orchestraworks/client/dist/esm/models/CommentSummary.d.ts +2 -2
- package/node_modules/@orchestraworks/client/dist/esm/models/CommentSummary.js +3 -3
- package/node_modules/@orchestraworks/client/dist/esm/models/CopyFileRequest.d.ts +38 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/CopyFileRequest.js +47 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/CreateArtifactRequest.d.ts +7 -7
- package/node_modules/@orchestraworks/client/dist/esm/models/CreateAuthHandoffRequest.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/esm/models/CreateFileRequest.d.ts +44 -2
- package/node_modules/@orchestraworks/client/dist/esm/models/CreateFileRequest.js +14 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/CreateRoomTokenRequest.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/esm/models/FileMatch.d.ts +38 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/FileMatch.js +47 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/FileVersion.d.ts +101 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/FileVersion.js +83 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/ModelFile.d.ts +69 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/ModelFile.js +36 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/PageArtifact.d.ts +51 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/{PageArtifactSummary.js → PageArtifact.js} +11 -11
- package/node_modules/@orchestraworks/client/dist/esm/models/PageFileVersion.d.ts +51 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/PageFileVersion.js +56 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/RoomTokenRoom.d.ts +2 -2
- package/node_modules/@orchestraworks/client/dist/esm/models/RoomTokenRoom.js +2 -2
- package/node_modules/@orchestraworks/client/dist/esm/models/RoomTokenRoomRequest.d.ts +3 -3
- package/node_modules/@orchestraworks/client/dist/esm/models/RoomTokenRoomRequest.js +2 -2
- package/node_modules/@orchestraworks/client/dist/esm/models/SelectorAnchor.d.ts +24 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/SelectorAnchor.js +8 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/SnapshotAnchor.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/esm/models/UpdateArtifactRequest.d.ts +0 -8
- package/node_modules/@orchestraworks/client/dist/esm/models/UpdateArtifactRequest.js +0 -2
- package/node_modules/@orchestraworks/client/dist/esm/models/UpdateFileRequest.d.ts +40 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/UpdateFileRequest.js +43 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/WorkItem.d.ts +3 -3
- package/node_modules/@orchestraworks/client/dist/esm/models/WorkItem.js +3 -3
- package/node_modules/@orchestraworks/client/dist/esm/models/WriteFileDataRequest.d.ts +50 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/WriteFileDataRequest.js +51 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/index.d.ts +7 -3
- package/node_modules/@orchestraworks/client/dist/esm/models/index.js +7 -3
- package/node_modules/@orchestraworks/client/dist/models/Artifact.d.ts +12 -53
- package/node_modules/@orchestraworks/client/dist/models/Artifact.js +8 -30
- package/node_modules/@orchestraworks/client/dist/models/Comment.d.ts +2 -2
- package/node_modules/@orchestraworks/client/dist/models/Comment.js +3 -3
- package/node_modules/@orchestraworks/client/dist/models/CommentSummary.d.ts +2 -2
- package/node_modules/@orchestraworks/client/dist/models/CommentSummary.js +3 -3
- package/node_modules/@orchestraworks/client/dist/models/CopyFileRequest.d.ts +38 -0
- package/node_modules/@orchestraworks/client/dist/models/CopyFileRequest.js +54 -0
- package/node_modules/@orchestraworks/client/dist/models/CreateArtifactRequest.d.ts +7 -7
- package/node_modules/@orchestraworks/client/dist/models/CreateAuthHandoffRequest.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/models/CreateFileRequest.d.ts +44 -2
- package/node_modules/@orchestraworks/client/dist/models/CreateFileRequest.js +14 -0
- package/node_modules/@orchestraworks/client/dist/models/CreateRoomTokenRequest.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/models/FileMatch.d.ts +38 -0
- package/node_modules/@orchestraworks/client/dist/models/FileMatch.js +54 -0
- package/node_modules/@orchestraworks/client/dist/models/FileVersion.d.ts +101 -0
- package/node_modules/@orchestraworks/client/dist/models/FileVersion.js +91 -0
- package/node_modules/@orchestraworks/client/dist/models/ModelFile.d.ts +69 -0
- package/node_modules/@orchestraworks/client/dist/models/ModelFile.js +37 -1
- package/node_modules/@orchestraworks/client/dist/models/PageArtifact.d.ts +51 -0
- package/node_modules/@orchestraworks/client/dist/models/{PageArtifactSummary.js → PageArtifact.js} +16 -16
- package/node_modules/@orchestraworks/client/dist/models/PageFileVersion.d.ts +51 -0
- package/node_modules/@orchestraworks/client/dist/models/PageFileVersion.js +63 -0
- package/node_modules/@orchestraworks/client/dist/models/RoomTokenRoom.d.ts +2 -2
- package/node_modules/@orchestraworks/client/dist/models/RoomTokenRoom.js +2 -2
- package/node_modules/@orchestraworks/client/dist/models/RoomTokenRoomRequest.d.ts +3 -3
- package/node_modules/@orchestraworks/client/dist/models/RoomTokenRoomRequest.js +2 -2
- package/node_modules/@orchestraworks/client/dist/models/SelectorAnchor.d.ts +24 -0
- package/node_modules/@orchestraworks/client/dist/models/SelectorAnchor.js +8 -0
- package/node_modules/@orchestraworks/client/dist/models/SnapshotAnchor.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/models/UpdateArtifactRequest.d.ts +0 -8
- package/node_modules/@orchestraworks/client/dist/models/UpdateArtifactRequest.js +0 -2
- package/node_modules/@orchestraworks/client/dist/models/UpdateFileRequest.d.ts +40 -0
- package/node_modules/@orchestraworks/client/dist/models/UpdateFileRequest.js +50 -0
- package/node_modules/@orchestraworks/client/dist/models/WorkItem.d.ts +3 -3
- package/node_modules/@orchestraworks/client/dist/models/WorkItem.js +3 -3
- package/node_modules/@orchestraworks/client/dist/models/WriteFileDataRequest.d.ts +50 -0
- package/node_modules/@orchestraworks/client/dist/models/WriteFileDataRequest.js +58 -0
- package/node_modules/@orchestraworks/client/dist/models/index.d.ts +7 -3
- package/node_modules/@orchestraworks/client/dist/models/index.js +7 -3
- package/node_modules/@orchestraworks/client/package.json +1 -1
- package/package.json +4 -4
- package/templates/engineering-team/package.json +1 -1
- package/templates/todo-factory/package.json +1 -1
- package/node_modules/@orchestraworks/client/dist/esm/models/ArtifactSummary.d.ts +0 -139
- package/node_modules/@orchestraworks/client/dist/esm/models/ArtifactSummary.js +0 -95
- package/node_modules/@orchestraworks/client/dist/esm/models/ArtifactVersion.d.ts +0 -110
- package/node_modules/@orchestraworks/client/dist/esm/models/ArtifactVersion.js +0 -77
- package/node_modules/@orchestraworks/client/dist/esm/models/PageArtifactSummary.d.ts +0 -51
- package/node_modules/@orchestraworks/client/dist/models/ArtifactSummary.d.ts +0 -139
- package/node_modules/@orchestraworks/client/dist/models/ArtifactSummary.js +0 -103
- package/node_modules/@orchestraworks/client/dist/models/ArtifactVersion.d.ts +0 -110
- package/node_modules/@orchestraworks/client/dist/models/ArtifactVersion.js +0 -84
- package/node_modules/@orchestraworks/client/dist/models/PageArtifactSummary.d.ts +0 -51
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ The full guide to every construct, secrets, connections and troubleshooting is [
|
|
|
20
20
|
```bash
|
|
21
21
|
npm install -g @orchestraworks/cli # the CLI, on your path as `orchestra`
|
|
22
22
|
npm install @orchestraworks/cli # the current release
|
|
23
|
-
npm install @orchestraworks/cli@0.
|
|
23
|
+
npm install @orchestraworks/cli@0.9.0 # this exact release
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
Then `import { Factory, Agent, … } from "@orchestraworks/cli"` normally — the package `exports` entry resolves
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
* The runtime a published artifact page gets. It is served with the page on the artifacts host and by
|
|
3
3
|
* `orchestra artifacts preview` from the same file, so a page behaves identically in both.
|
|
4
4
|
*
|
|
5
|
-
* The page never holds
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* overlay is
|
|
5
|
+
* The page never calls the API; it holds no credential but the short-lived links to what it loads, each to bytes
|
|
6
|
+
* its viewer may read. It talks over postMessage to the console frame embedding it, which calls
|
|
7
|
+
* the API with the viewer's session. Opened at its own address, it is read only: `sf.viewer` is null, no comments
|
|
8
|
+
* overlay is drawn, every `sf.data` call rejects, and a link to a library file follows its own address.
|
|
9
9
|
*
|
|
10
|
-
* All three `sf.data` calls answer a promise,
|
|
11
|
-
*
|
|
10
|
+
* All three `sf.data` calls answer a promise, `subscribe` too, resolving to the function that stops it, so
|
|
11
|
+
* outside the console all three reject the same way.
|
|
12
12
|
*/
|
|
13
13
|
(function () {
|
|
14
14
|
"use strict";
|
|
@@ -24,13 +24,27 @@
|
|
|
24
24
|
var QUOTE_LIMIT = 512;
|
|
25
25
|
var CONTEXT_LIMIT = 64;
|
|
26
26
|
var SELECTOR_LIMIT = 1024;
|
|
27
|
+
var ELEMENT_ID_LIMIT = 1024;
|
|
28
|
+
var AGREEMENT_FLOOR = 32;
|
|
29
|
+
var EDIT_CONTEXT_FLOOR = 16;
|
|
30
|
+
var EDIT_SPAN_LIMIT = 512;
|
|
31
|
+
var REDRAW_INTERVAL_MS = 200;
|
|
32
|
+
// Struck copies of removed blocks, and the bar listing them, repeat what the page used to say: their text
|
|
33
|
+
// is never the page's, whatever their style.
|
|
34
|
+
var NOT_PAGE_TEXT = ".sf-removed, #sf-render-changes-bar";
|
|
35
|
+
var VISIBILITY = { visibilityProperty: true, checkVisibilityCSS: true };
|
|
27
36
|
|
|
28
37
|
var pending = {};
|
|
29
38
|
var callCounter = 0;
|
|
30
39
|
var dataListeners = [];
|
|
31
40
|
var comments = [];
|
|
41
|
+
var shownVersion = null;
|
|
32
42
|
var commentMode = false;
|
|
33
43
|
var overlay = null;
|
|
44
|
+
var drawn = {};
|
|
45
|
+
var lastReport = null;
|
|
46
|
+
var lastDraw = 0;
|
|
47
|
+
var redrawTimer = null;
|
|
34
48
|
|
|
35
49
|
function call(name, args) {
|
|
36
50
|
if (!insideConsole) {
|
|
@@ -106,40 +120,148 @@
|
|
|
106
120
|
|
|
107
121
|
function selectorAnchorAt(element, clientX, clientY) {
|
|
108
122
|
var box = element.getBoundingClientRect();
|
|
109
|
-
|
|
123
|
+
var anchor = {
|
|
110
124
|
kind: "selector",
|
|
111
125
|
path: selectorOf(element),
|
|
112
126
|
x: box.width > 0 ? percentage(((clientX - box.left) / box.width) * 100) : 0,
|
|
113
127
|
y: box.height > 0 ? percentage(((clientY - box.top) / box.height) * 100) : 0
|
|
114
128
|
};
|
|
129
|
+
var id = element.getAttribute("id") || "";
|
|
130
|
+
if (/\S/.test(id) && id.length <= ELEMENT_ID_LIMIT && elementsCarrying(id).length === 1) {
|
|
131
|
+
anchor.elementId = id;
|
|
132
|
+
}
|
|
133
|
+
var whole = document.createRange();
|
|
134
|
+
whole.selectNodeContents(element);
|
|
135
|
+
var text = textAnchorOfRange(whole);
|
|
136
|
+
if (text) {
|
|
137
|
+
anchor.quote = text.quote;
|
|
138
|
+
anchor.prefix = text.prefix;
|
|
139
|
+
anchor.suffix = text.suffix;
|
|
140
|
+
}
|
|
141
|
+
return anchor;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function elementsCarrying(id) {
|
|
145
|
+
return Array.prototype.filter.call(document.querySelectorAll("[id]"), function (element) {
|
|
146
|
+
return element.getAttribute("id") === id;
|
|
147
|
+
});
|
|
115
148
|
}
|
|
116
149
|
|
|
117
150
|
function percentage(value) {
|
|
118
151
|
return Math.max(0, Math.min(100, Math.round(value * 100) / 100));
|
|
119
152
|
}
|
|
120
153
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
154
|
+
function eachPageTextNode(root, visit) {
|
|
155
|
+
if (root.nodeType === 3) {
|
|
156
|
+
visit(root);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
var walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, {
|
|
160
|
+
acceptNode: function (node) {
|
|
161
|
+
if (node.nodeType === 3) {
|
|
162
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
163
|
+
}
|
|
164
|
+
return node.matches(NOT_PAGE_TEXT) ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_SKIP;
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
while (walker.nextNode()) {
|
|
168
|
+
visit(walker.currentNode);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** Whether an element shows. A browser that cannot say counts everything as shown. */
|
|
173
|
+
function isShown(element) {
|
|
174
|
+
if (!element) {
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
return typeof element.checkVisibility !== "function" || element.checkVisibility(VISIBILITY);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function hasArea(box) {
|
|
181
|
+
return box.width > 0 && box.height > 0;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function pageTexts() {
|
|
185
|
+
var all = { text: "", nodes: [] };
|
|
186
|
+
var visible = { text: "", nodes: [] };
|
|
187
|
+
if (document.body) {
|
|
188
|
+
var shownParents = new Map();
|
|
189
|
+
eachPageTextNode(document.body, function (node) {
|
|
190
|
+
var value = node.nodeValue || "";
|
|
191
|
+
var parent = node.parentElement;
|
|
192
|
+
if (!shownParents.has(parent)) {
|
|
193
|
+
shownParents.set(parent, isShown(parent));
|
|
194
|
+
}
|
|
195
|
+
var shown = shownParents.get(parent);
|
|
196
|
+
append(all, node, value, shown);
|
|
197
|
+
if (shown) {
|
|
198
|
+
append(visible, node, value, true);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
return { all: all, visible: visible };
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function append(strand, node, value, shown) {
|
|
206
|
+
var from = strand.text.length;
|
|
207
|
+
strand.nodes.push({ node: node, from: from, to: from + value.length, shown: shown });
|
|
208
|
+
strand.text += value;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/** How far into the visible text one boundary of a range sits: the visible characters before it. */
|
|
212
|
+
function visibleOffset(visible, container, offset) {
|
|
213
|
+
var point = document.createRange();
|
|
214
|
+
point.setStart(container, offset);
|
|
215
|
+
for (var index = 0; index < visible.nodes.length; index += 1) {
|
|
216
|
+
var entry = visible.nodes[index];
|
|
217
|
+
if (entry.node === container) {
|
|
218
|
+
return entry.from + offset;
|
|
219
|
+
}
|
|
220
|
+
if (point.comparePoint(entry.node, 0) >= 0) {
|
|
221
|
+
return entry.from;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return visible.text.length;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Walks the selection's common ancestor rather than building the page's text, because this runs on each
|
|
228
|
+
// change of the selection.
|
|
229
|
+
function selectionHasWords(range) {
|
|
230
|
+
var root = range.commonAncestorContainer;
|
|
231
|
+
var element = root.nodeType === 1 ? root : root.parentElement;
|
|
232
|
+
if (!element || element.closest(NOT_PAGE_TEXT)) {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
var found = false;
|
|
236
|
+
eachPageTextNode(root, function (node) {
|
|
237
|
+
if (found || !range.intersectsNode(node) || !isShown(node.parentElement)) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
var value = node.nodeValue || "";
|
|
241
|
+
var from = node === range.startContainer ? range.startOffset : 0;
|
|
242
|
+
var to = node === range.endContainer ? range.endOffset : value.length;
|
|
243
|
+
found = /\S/.test(value.slice(from, to));
|
|
244
|
+
});
|
|
245
|
+
return found;
|
|
127
246
|
}
|
|
128
247
|
|
|
129
|
-
/**
|
|
130
|
-
* The quote plus a little of the text on each side of THAT SPAN, which is what lets the console find the
|
|
131
|
-
* same passage again — a page saying "wrong" four times has four of them, and the context is what names
|
|
132
|
-
* which. The one string this works in is the page's own `textContent`, the text nodes in reading order,
|
|
133
|
-
* which is what the resolver below walks.
|
|
134
|
-
*/
|
|
135
248
|
function textAnchorOfSelection(selection) {
|
|
136
249
|
if (!document.body || selection.rangeCount === 0) {
|
|
137
250
|
return null;
|
|
138
251
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
252
|
+
return textAnchorOfRange(selection.getRangeAt(0));
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* The quote plus a little of the text on each side of THAT SPAN, which is what lets the console find the
|
|
257
|
+
* same passage again — a page saying "wrong" four times has four of them, and the context is what names
|
|
258
|
+
* which.
|
|
259
|
+
*/
|
|
260
|
+
function textAnchorOfRange(range) {
|
|
261
|
+
var visible = pageTexts().visible;
|
|
262
|
+
var text = visible.text;
|
|
263
|
+
var from = visibleOffset(visible, range.startContainer, range.startOffset);
|
|
264
|
+
var selected = text.slice(from, visibleOffset(visible, range.endContainer, range.endOffset));
|
|
143
265
|
var quote = selected.trim().slice(0, QUOTE_LIMIT);
|
|
144
266
|
if (quote === "") {
|
|
145
267
|
return null;
|
|
@@ -274,6 +396,49 @@
|
|
|
274
396
|
}
|
|
275
397
|
}
|
|
276
398
|
|
|
399
|
+
/**
|
|
400
|
+
* A link the platform marked with a library path opens that file or folder in the console, since inside this frame
|
|
401
|
+
* its address names nothing. A Ctrl, Cmd or Shift click, or a middle click, asks the console for a new tab. An Alt
|
|
402
|
+
* click, another button, or a click the page's own script handled goes to the browser.
|
|
403
|
+
*
|
|
404
|
+
* The platform marks every relative link that names a library file or folder the viewer may read, so an unmarked
|
|
405
|
+
* one to another path names nothing this host serves, and following it would blank the frame: a primary click on it
|
|
406
|
+
* does nothing. A link with a scheme, a `//` host, a fragment or a query alone goes to the browser.
|
|
407
|
+
*/
|
|
408
|
+
function onLinkClick(event) {
|
|
409
|
+
// A middle click arrives as `auxclick` alone in current browsers, so `click` takes the primary button only.
|
|
410
|
+
var middle = event.type === "auxclick";
|
|
411
|
+
if (event.defaultPrevented || event.altKey || event.button !== (middle ? 1 : 0)) {
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
var link = event.target && event.target.closest ? event.target.closest("a") : null;
|
|
415
|
+
if (!link) {
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
var path = link.getAttribute("data-sf-path");
|
|
419
|
+
if (path === null) {
|
|
420
|
+
if (!middle && leavesThePagePath(link.getAttribute("href"))) {
|
|
421
|
+
event.preventDefault();
|
|
422
|
+
}
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
event.preventDefault();
|
|
426
|
+
window.parent.postMessage(
|
|
427
|
+
{
|
|
428
|
+
sf: 1,
|
|
429
|
+
event: "open",
|
|
430
|
+
path: path,
|
|
431
|
+
newTab: middle || event.metaKey || event.ctrlKey || event.shiftKey
|
|
432
|
+
},
|
|
433
|
+
consoleOrigin
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
function leavesThePagePath(href) {
|
|
438
|
+
var reference = href === null ? "" : href.trim();
|
|
439
|
+
return reference !== "" && !/^(?:[a-zA-Z][a-zA-Z0-9+.-]*:|\/\/|[#?])/.test(reference);
|
|
440
|
+
}
|
|
441
|
+
|
|
277
442
|
function onSelectionChange() {
|
|
278
443
|
if (!overlay || readOnly) {
|
|
279
444
|
return;
|
|
@@ -283,8 +448,9 @@
|
|
|
283
448
|
overlay.selectionToolbar.hidden = true;
|
|
284
449
|
return;
|
|
285
450
|
}
|
|
286
|
-
var
|
|
287
|
-
|
|
451
|
+
var range = selection.getRangeAt(0);
|
|
452
|
+
var box = range.getBoundingClientRect();
|
|
453
|
+
if ((box.width === 0 && box.height === 0) || !selectionHasWords(range)) {
|
|
288
454
|
overlay.selectionToolbar.hidden = true;
|
|
289
455
|
return;
|
|
290
456
|
}
|
|
@@ -307,57 +473,164 @@
|
|
|
307
473
|
function refreshComments() {
|
|
308
474
|
return call("comments.list", {}).then(function (result) {
|
|
309
475
|
comments = (result && result.comments) || [];
|
|
476
|
+
shownVersion = result && typeof result.versionNumber === "number" ? result.versionNumber : null;
|
|
310
477
|
drawPins();
|
|
311
478
|
return comments;
|
|
312
479
|
});
|
|
313
480
|
}
|
|
314
481
|
|
|
482
|
+
function requestDraw() {
|
|
483
|
+
if (redrawTimer !== null) {
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
redrawTimer = setTimeout(drawPins, Math.max(0, lastDraw + REDRAW_INTERVAL_MS - Date.now()));
|
|
487
|
+
}
|
|
488
|
+
|
|
315
489
|
function drawPins() {
|
|
316
490
|
if (!overlay) {
|
|
317
491
|
return;
|
|
318
492
|
}
|
|
319
|
-
|
|
493
|
+
if (redrawTimer !== null) {
|
|
494
|
+
clearTimeout(redrawTimer);
|
|
495
|
+
redrawTimer = null;
|
|
496
|
+
}
|
|
497
|
+
lastDraw = Date.now();
|
|
498
|
+
if (document.body && !overlay.host.isConnected) {
|
|
499
|
+
document.body.appendChild(overlay.host);
|
|
500
|
+
}
|
|
501
|
+
var texts = null;
|
|
502
|
+
var textsOnce = function () {
|
|
503
|
+
texts = texts || pageTexts();
|
|
504
|
+
return texts;
|
|
505
|
+
};
|
|
506
|
+
var kept = {};
|
|
507
|
+
var lost = [];
|
|
508
|
+
var changed = [];
|
|
320
509
|
comments.forEach(function (comment, index) {
|
|
321
|
-
var position = positionOf(comment
|
|
510
|
+
var position = positionOf(comment, textsOnce);
|
|
322
511
|
if (!position) {
|
|
512
|
+
if (comment.anchor && (comment.anchor.kind === "selector" || comment.anchor.kind === "text")) {
|
|
513
|
+
lost.push(comment.id);
|
|
514
|
+
}
|
|
323
515
|
return;
|
|
324
516
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
517
|
+
if (position.changed) {
|
|
518
|
+
changed.push(comment.id);
|
|
519
|
+
}
|
|
520
|
+
// A pin still drawn keeps its button, so a press and its release on a changing page reach one button.
|
|
521
|
+
var pin = drawn[comment.id] ? drawn[comment.id].button : newPin(comment.id);
|
|
522
|
+
kept[comment.id] = { button: pin, comment: comment };
|
|
328
523
|
pin.textContent = String(index + 1);
|
|
329
524
|
pin.setAttribute("data-status", comment.status || "OPEN");
|
|
330
525
|
pin.style.left = position.left + "px";
|
|
331
526
|
pin.style.top = position.top + "px";
|
|
332
|
-
pin.addEventListener("click", function () {
|
|
333
|
-
openPanel(comment);
|
|
334
|
-
});
|
|
335
|
-
overlay.pins.appendChild(pin);
|
|
336
527
|
});
|
|
528
|
+
Object.keys(drawn).forEach(function (commentId) {
|
|
529
|
+
if (!kept[commentId]) {
|
|
530
|
+
drawn[commentId].button.remove();
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
drawn = kept;
|
|
534
|
+
report(lost, changed);
|
|
337
535
|
}
|
|
338
536
|
|
|
339
|
-
|
|
340
|
-
|
|
537
|
+
function newPin(commentId) {
|
|
538
|
+
var pin = document.createElement("button");
|
|
539
|
+
pin.className = "pin";
|
|
540
|
+
pin.type = "button";
|
|
541
|
+
pin.addEventListener("click", function () {
|
|
542
|
+
if (drawn[commentId]) {
|
|
543
|
+
openPanel(drawn[commentId].comment);
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
overlay.pins.appendChild(pin);
|
|
547
|
+
return pin;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
function report(lost, changed) {
|
|
551
|
+
var message = { sf: 1, event: "pins", lost: lost, changed: changed };
|
|
552
|
+
var said = JSON.stringify(message);
|
|
553
|
+
if (said === lastReport) {
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
lastReport = said;
|
|
557
|
+
window.parent.postMessage(message, consoleOrigin);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
function fromAnotherVersion(comment) {
|
|
561
|
+
return (
|
|
562
|
+
typeof comment.versionNumber === "number" &&
|
|
563
|
+
typeof shownVersion === "number" &&
|
|
564
|
+
comment.versionNumber !== shownVersion
|
|
565
|
+
);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/** Document coordinates, so a scroll needs no repositioning. */
|
|
569
|
+
function positionOf(comment, textsOnce) {
|
|
570
|
+
var anchor = comment.anchor;
|
|
341
571
|
if (!anchor) {
|
|
342
572
|
return null;
|
|
343
573
|
}
|
|
344
574
|
if (anchor.kind === "selector") {
|
|
345
|
-
var
|
|
346
|
-
|
|
575
|
+
var found = fromAnotherVersion(comment)
|
|
576
|
+
? elementElsewhere(anchor, textsOnce())
|
|
577
|
+
: { element: queryFirst(anchor.path), changed: false };
|
|
578
|
+
if (!found || !shownWithBox(found.element)) {
|
|
347
579
|
return null;
|
|
348
580
|
}
|
|
349
|
-
var box = element.getBoundingClientRect();
|
|
581
|
+
var box = found.element.getBoundingClientRect();
|
|
350
582
|
return {
|
|
351
583
|
left: box.left + window.scrollX + (box.width * (anchor.x || 0)) / 100,
|
|
352
|
-
top: box.top + window.scrollY + (box.height * (anchor.y || 0)) / 100
|
|
584
|
+
top: box.top + window.scrollY + (box.height * (anchor.y || 0)) / 100,
|
|
585
|
+
changed: found.changed
|
|
353
586
|
};
|
|
354
587
|
}
|
|
355
588
|
if (anchor.kind === "text") {
|
|
356
|
-
|
|
589
|
+
var match = rangeOfAnchor(anchor, fromAnotherVersion(comment), textsOnce());
|
|
590
|
+
if (!match) {
|
|
591
|
+
return null;
|
|
592
|
+
}
|
|
593
|
+
var quoted = match.range.getBoundingClientRect();
|
|
594
|
+
return {
|
|
595
|
+
left: quoted.left + window.scrollX,
|
|
596
|
+
top: quoted.top + window.scrollY,
|
|
597
|
+
changed: match.changed
|
|
598
|
+
};
|
|
357
599
|
}
|
|
358
600
|
return null;
|
|
359
601
|
}
|
|
360
602
|
|
|
603
|
+
function shownWithBox(element) {
|
|
604
|
+
return isShown(element) && hasArea(element.getBoundingClientRect());
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
function elementElsewhere(anchor, texts) {
|
|
608
|
+
var carriers = anchor.elementId ? elementsCarrying(anchor.elementId) : [];
|
|
609
|
+
if (
|
|
610
|
+
carriers.length === 1 &&
|
|
611
|
+
shownWithBox(carriers[0]) &&
|
|
612
|
+
(!anchor.quote || visibleTextOf(carriers[0], texts.visible).indexOf(anchor.quote) >= 0)
|
|
613
|
+
) {
|
|
614
|
+
return { element: carriers[0], changed: false };
|
|
615
|
+
}
|
|
616
|
+
var match = rangeOfAnchor(anchor, true, texts);
|
|
617
|
+
if (!match) {
|
|
618
|
+
return null;
|
|
619
|
+
}
|
|
620
|
+
var holder = match.range.commonAncestorContainer;
|
|
621
|
+
return { element: holder.nodeType === 1 ? holder : holder.parentElement, changed: match.changed };
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
function visibleTextOf(element, visible) {
|
|
625
|
+
var text = "";
|
|
626
|
+
visible.nodes.forEach(function (entry) {
|
|
627
|
+
if (element.contains(entry.node)) {
|
|
628
|
+
text += visible.text.slice(entry.from, entry.to);
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
return text;
|
|
632
|
+
}
|
|
633
|
+
|
|
361
634
|
function queryFirst(path) {
|
|
362
635
|
if (!path) {
|
|
363
636
|
return null;
|
|
@@ -370,70 +643,98 @@
|
|
|
370
643
|
}
|
|
371
644
|
}
|
|
372
645
|
|
|
373
|
-
function
|
|
374
|
-
|
|
375
|
-
if (!range) {
|
|
646
|
+
function rangeOfAnchor(anchor, anotherVersion, texts) {
|
|
647
|
+
if (!anchor || !anchor.quote) {
|
|
376
648
|
return null;
|
|
377
649
|
}
|
|
378
|
-
var
|
|
379
|
-
|
|
650
|
+
var length = anchor.quote.length;
|
|
651
|
+
if (anotherVersion) {
|
|
652
|
+
var whole = length + (anchor.prefix || "").length + (anchor.suffix || "").length;
|
|
653
|
+
var floor = Math.min(AGREEMENT_FLOOR, whole);
|
|
654
|
+
var ranked = rankedOccurrences(texts.visible.text, anchor);
|
|
655
|
+
for (var index = 0; index < ranked.length && length + ranked[index].agreed >= floor; index += 1) {
|
|
656
|
+
var candidate = spanOf(texts.visible, ranked[index].at, length);
|
|
657
|
+
if (candidate && hasArea(candidate.range.getBoundingClientRect())) {
|
|
658
|
+
return { range: candidate.range, changed: false };
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
return betweenContext(texts.visible, anchor);
|
|
662
|
+
}
|
|
663
|
+
var strand = texts.all;
|
|
664
|
+
var best = rankedOccurrences(strand.text, anchor)[0];
|
|
665
|
+
// A quote missing from all the text came from a selection across hidden text, which only the visible
|
|
666
|
+
// text holds.
|
|
667
|
+
if (!best) {
|
|
668
|
+
strand = texts.visible;
|
|
669
|
+
best = rankedOccurrences(strand.text, anchor)[0];
|
|
670
|
+
}
|
|
671
|
+
if (!best) {
|
|
672
|
+
return betweenContext(texts.visible, anchor);
|
|
673
|
+
}
|
|
674
|
+
var span = spanOf(strand, best.at, length);
|
|
675
|
+
if (!span || !span.first.shown || !span.last.shown) {
|
|
676
|
+
return null;
|
|
677
|
+
}
|
|
678
|
+
return hasArea(span.range.getBoundingClientRect()) ? { range: span.range, changed: false } : null;
|
|
380
679
|
}
|
|
381
680
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
* and maps the match back onto the nodes it spans.
|
|
387
|
-
*/
|
|
388
|
-
function rangeOfAnchor(anchor) {
|
|
389
|
-
if (!anchor || !anchor.quote || !document.body) {
|
|
681
|
+
function betweenContext(strand, anchor) {
|
|
682
|
+
var prefix = anchor.prefix || "";
|
|
683
|
+
var suffix = anchor.suffix || "";
|
|
684
|
+
if (wordLength(prefix) < EDIT_CONTEXT_FLOOR || wordLength(suffix) < EDIT_CONTEXT_FLOOR) {
|
|
390
685
|
return null;
|
|
391
686
|
}
|
|
392
|
-
var
|
|
393
|
-
var
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
687
|
+
var text = strand.text;
|
|
688
|
+
for (var at = text.indexOf(prefix); at >= 0; at = text.indexOf(prefix, at + 1)) {
|
|
689
|
+
var start = at + prefix.length;
|
|
690
|
+
var end = text.slice(start, start + EDIT_SPAN_LIMIT + suffix.length).indexOf(suffix);
|
|
691
|
+
if (end < 0) {
|
|
692
|
+
continue;
|
|
693
|
+
}
|
|
694
|
+
var between = text.slice(start, start + end);
|
|
695
|
+
var trimmed = between.trim();
|
|
696
|
+
if (trimmed === "") {
|
|
697
|
+
continue;
|
|
698
|
+
}
|
|
699
|
+
var lead = between.length - between.replace(/^\s+/, "").length;
|
|
700
|
+
var span = spanOf(strand, start + lead, trimmed.length);
|
|
701
|
+
if (span && hasArea(span.range.getBoundingClientRect())) {
|
|
702
|
+
return { range: span.range, changed: true };
|
|
703
|
+
}
|
|
402
704
|
}
|
|
403
|
-
|
|
705
|
+
return null;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
function wordLength(value) {
|
|
709
|
+
return value.replace(/\s/g, "").length;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
function spanOf(strand, at, length) {
|
|
713
|
+
var end = at + length;
|
|
404
714
|
var range = document.createRange();
|
|
405
|
-
var
|
|
406
|
-
for (var index = 0; index < nodes.length; index += 1) {
|
|
407
|
-
var entry = nodes[index];
|
|
408
|
-
|
|
409
|
-
if (!started && at < to) {
|
|
715
|
+
var first = null;
|
|
716
|
+
for (var index = 0; index < strand.nodes.length; index += 1) {
|
|
717
|
+
var entry = strand.nodes[index];
|
|
718
|
+
if (first === null && at < entry.to) {
|
|
410
719
|
range.setStart(entry.node, at - entry.from);
|
|
411
|
-
|
|
720
|
+
first = entry;
|
|
412
721
|
}
|
|
413
|
-
if (
|
|
722
|
+
if (first !== null && end <= entry.to) {
|
|
414
723
|
range.setEnd(entry.node, end - entry.from);
|
|
415
|
-
return range;
|
|
724
|
+
return { range: range, first: first, last: entry };
|
|
416
725
|
}
|
|
417
726
|
}
|
|
418
727
|
return null;
|
|
419
728
|
}
|
|
420
729
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
* recorded context for the most characters, and the earliest of those on a tie — which is also the answer
|
|
424
|
-
* for an anchor carrying no context, and for a page that has changed until no context matches.
|
|
425
|
-
*/
|
|
426
|
-
function occurrenceOf(text, anchor) {
|
|
427
|
-
var best = -1;
|
|
428
|
-
var bestAgreement = -1;
|
|
730
|
+
function rankedOccurrences(text, anchor) {
|
|
731
|
+
var found = [];
|
|
429
732
|
for (var at = text.indexOf(anchor.quote); at >= 0; at = text.indexOf(anchor.quote, at + 1)) {
|
|
430
|
-
|
|
431
|
-
if (agreed > bestAgreement) {
|
|
432
|
-
best = at;
|
|
433
|
-
bestAgreement = agreed;
|
|
434
|
-
}
|
|
733
|
+
found.push({ at: at, agreed: agreement(text, at, anchor) });
|
|
435
734
|
}
|
|
436
|
-
return
|
|
735
|
+
return found.sort(function (one, other) {
|
|
736
|
+
return other.agreed - one.agreed || one.at - other.at;
|
|
737
|
+
});
|
|
437
738
|
}
|
|
438
739
|
|
|
439
740
|
/** How many characters of the anchor's context the text around this occurrence actually matches. */
|
|
@@ -514,13 +815,40 @@
|
|
|
514
815
|
}
|
|
515
816
|
}
|
|
516
817
|
|
|
818
|
+
function watchForChanges() {
|
|
819
|
+
window.addEventListener("resize", requestDraw);
|
|
820
|
+
window.addEventListener("load", requestDraw);
|
|
821
|
+
if (typeof ResizeObserver === "function") {
|
|
822
|
+
new ResizeObserver(requestDraw).observe(document.documentElement);
|
|
823
|
+
}
|
|
824
|
+
if (typeof MutationObserver === "function") {
|
|
825
|
+
// Without a shadow root the pins live in the host; their changes must not ask for another draw.
|
|
826
|
+
new MutationObserver(function (records) {
|
|
827
|
+
for (var index = 0; index < records.length; index += 1) {
|
|
828
|
+
if (!overlay.host.contains(records[index].target)) {
|
|
829
|
+
requestDraw();
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}).observe(document.documentElement, {
|
|
834
|
+
childList: true,
|
|
835
|
+
subtree: true,
|
|
836
|
+
characterData: true,
|
|
837
|
+
attributes: true
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
|
|
517
842
|
function startOverlay() {
|
|
518
843
|
overlay = buildOverlay();
|
|
519
844
|
overlay.selectionButton.addEventListener("click", onSelectionComment);
|
|
520
845
|
document.addEventListener("click", onDocumentClick, true);
|
|
846
|
+
// In the bubbling phase, so a click comment mode takes in the capturing phase never opens a link.
|
|
847
|
+
document.addEventListener("click", onLinkClick);
|
|
848
|
+
document.addEventListener("auxclick", onLinkClick);
|
|
521
849
|
document.addEventListener("keydown", onKeyDown);
|
|
522
850
|
document.addEventListener("selectionchange", onSelectionChange);
|
|
523
|
-
|
|
851
|
+
watchForChanges();
|
|
524
852
|
refreshComments();
|
|
525
853
|
}
|
|
526
854
|
|
|
@@ -4,11 +4,6 @@ import type { ErrorContext } from "../core/errors.js";
|
|
|
4
4
|
import { type CliIo } from "../core/output.js";
|
|
5
5
|
import { type ResponseSchema } from "../core/redaction.js";
|
|
6
6
|
import type { Profile } from "../core/profile.js";
|
|
7
|
-
/**
|
|
8
|
-
* The schema the reader and the redactor are both handed — `orchestra api` included, so the raw caller and the
|
|
9
|
-
* typed command cannot disagree about which responses are the bare content.
|
|
10
|
-
*/
|
|
11
|
-
export declare function responseSchemaOf(row: CommandRow | undefined): ResponseSchema | undefined;
|
|
12
7
|
/** Named so the error mapper prints the sentence and nothing else — no platform framing, no stack. */
|
|
13
8
|
export declare class CommandUsageError extends Error {
|
|
14
9
|
constructor(message: string);
|
|
@@ -23,6 +18,8 @@ export interface ConventionValues {
|
|
|
23
18
|
outputFile?: string;
|
|
24
19
|
/** A local path whose bytes this create stores first and then names. */
|
|
25
20
|
file?: string;
|
|
21
|
+
/** Asks for the content as Markdown, on a read whose response declares it. */
|
|
22
|
+
markdown?: boolean;
|
|
26
23
|
/** An exact alias of level `never`. */
|
|
27
24
|
approveSecrets?: boolean;
|
|
28
25
|
requireApproval?: string;
|