@issuegraph/editor 0.1.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.
Files changed (143) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +238 -0
  3. package/dist/audit/findings.d.ts +225 -0
  4. package/dist/audit/findings.d.ts.map +1 -0
  5. package/dist/audit/findings.js +348 -0
  6. package/dist/audit/findings.js.map +1 -0
  7. package/dist/audit/styles.d.ts +37 -0
  8. package/dist/audit/styles.d.ts.map +1 -0
  9. package/dist/audit/styles.js +72 -0
  10. package/dist/audit/styles.js.map +1 -0
  11. package/dist/audit/surface.d.ts +155 -0
  12. package/dist/audit/surface.d.ts.map +1 -0
  13. package/dist/audit/surface.js +202 -0
  14. package/dist/audit/surface.js.map +1 -0
  15. package/dist/create/draft.d.ts +119 -0
  16. package/dist/create/draft.d.ts.map +1 -0
  17. package/dist/create/draft.js +114 -0
  18. package/dist/create/draft.js.map +1 -0
  19. package/dist/create/keys.d.ts +225 -0
  20. package/dist/create/keys.d.ts.map +1 -0
  21. package/dist/create/keys.js +228 -0
  22. package/dist/create/keys.js.map +1 -0
  23. package/dist/create/placement.d.ts +69 -0
  24. package/dist/create/placement.d.ts.map +1 -0
  25. package/dist/create/placement.js +76 -0
  26. package/dist/create/placement.js.map +1 -0
  27. package/dist/firstpass/batch.d.ts +190 -0
  28. package/dist/firstpass/batch.d.ts.map +1 -0
  29. package/dist/firstpass/batch.js +143 -0
  30. package/dist/firstpass/batch.js.map +1 -0
  31. package/dist/firstpass/candidates.d.ts +128 -0
  32. package/dist/firstpass/candidates.d.ts.map +1 -0
  33. package/dist/firstpass/candidates.js +39 -0
  34. package/dist/firstpass/candidates.js.map +1 -0
  35. package/dist/firstpass/keys.d.ts +90 -0
  36. package/dist/firstpass/keys.d.ts.map +1 -0
  37. package/dist/firstpass/keys.js +112 -0
  38. package/dist/firstpass/keys.js.map +1 -0
  39. package/dist/firstpass/queue.d.ts +183 -0
  40. package/dist/firstpass/queue.d.ts.map +1 -0
  41. package/dist/firstpass/queue.js +159 -0
  42. package/dist/firstpass/queue.js.map +1 -0
  43. package/dist/firstpass/render.d.ts +100 -0
  44. package/dist/firstpass/render.d.ts.map +1 -0
  45. package/dist/firstpass/render.js +216 -0
  46. package/dist/firstpass/render.js.map +1 -0
  47. package/dist/firstpass/styles.d.ts +36 -0
  48. package/dist/firstpass/styles.d.ts.map +1 -0
  49. package/dist/firstpass/styles.js +148 -0
  50. package/dist/firstpass/styles.js.map +1 -0
  51. package/dist/firstpass/view.d.ts +82 -0
  52. package/dist/firstpass/view.d.ts.map +1 -0
  53. package/dist/firstpass/view.js +60 -0
  54. package/dist/firstpass/view.js.map +1 -0
  55. package/dist/firstpass/words.d.ts +105 -0
  56. package/dist/firstpass/words.d.ts.map +1 -0
  57. package/dist/firstpass/words.js +28 -0
  58. package/dist/firstpass/words.js.map +1 -0
  59. package/dist/index.d.ts +150 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +147 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/overlay/grammar.d.ts +259 -0
  64. package/dist/overlay/grammar.d.ts.map +1 -0
  65. package/dist/overlay/grammar.js +223 -0
  66. package/dist/overlay/grammar.js.map +1 -0
  67. package/dist/overlay/render.d.ts +125 -0
  68. package/dist/overlay/render.d.ts.map +1 -0
  69. package/dist/overlay/render.js +439 -0
  70. package/dist/overlay/render.js.map +1 -0
  71. package/dist/overlay/styles.d.ts +41 -0
  72. package/dist/overlay/styles.d.ts.map +1 -0
  73. package/dist/overlay/styles.js +124 -0
  74. package/dist/overlay/styles.js.map +1 -0
  75. package/dist/picker/render.d.ts +80 -0
  76. package/dist/picker/render.d.ts.map +1 -0
  77. package/dist/picker/render.js +112 -0
  78. package/dist/picker/render.js.map +1 -0
  79. package/dist/picker/styles.d.ts +26 -0
  80. package/dist/picker/styles.d.ts.map +1 -0
  81. package/dist/picker/styles.js +116 -0
  82. package/dist/picker/styles.js.map +1 -0
  83. package/dist/picker/view.d.ts +135 -0
  84. package/dist/picker/view.d.ts.map +1 -0
  85. package/dist/picker/view.js +117 -0
  86. package/dist/picker/view.js.map +1 -0
  87. package/dist/picker/words.d.ts +53 -0
  88. package/dist/picker/words.d.ts.map +1 -0
  89. package/dist/picker/words.js +28 -0
  90. package/dist/picker/words.js.map +1 -0
  91. package/dist/reevaluate/render.d.ts +77 -0
  92. package/dist/reevaluate/render.d.ts.map +1 -0
  93. package/dist/reevaluate/render.js +211 -0
  94. package/dist/reevaluate/render.js.map +1 -0
  95. package/dist/reevaluate/styles.d.ts +24 -0
  96. package/dist/reevaluate/styles.d.ts.map +1 -0
  97. package/dist/reevaluate/styles.js +182 -0
  98. package/dist/reevaluate/styles.js.map +1 -0
  99. package/dist/reevaluate/view.d.ts +102 -0
  100. package/dist/reevaluate/view.d.ts.map +1 -0
  101. package/dist/reevaluate/view.js +111 -0
  102. package/dist/reevaluate/view.js.map +1 -0
  103. package/dist/reevaluate/words.d.ts +54 -0
  104. package/dist/reevaluate/words.d.ts.map +1 -0
  105. package/dist/reevaluate/words.js +29 -0
  106. package/dist/reevaluate/words.js.map +1 -0
  107. package/dist/scale/commands.d.ts +60 -0
  108. package/dist/scale/commands.d.ts.map +1 -0
  109. package/dist/scale/commands.js +49 -0
  110. package/dist/scale/commands.js.map +1 -0
  111. package/dist/scale/ladder.d.ts +141 -0
  112. package/dist/scale/ladder.d.ts.map +1 -0
  113. package/dist/scale/ladder.js +243 -0
  114. package/dist/scale/ladder.js.map +1 -0
  115. package/dist/scale/render.d.ts +85 -0
  116. package/dist/scale/render.d.ts.map +1 -0
  117. package/dist/scale/render.js +194 -0
  118. package/dist/scale/render.js.map +1 -0
  119. package/dist/scale/styles.d.ts +21 -0
  120. package/dist/scale/styles.d.ts.map +1 -0
  121. package/dist/scale/styles.js +105 -0
  122. package/dist/scale/styles.js.map +1 -0
  123. package/dist/workspace/inspector.d.ts +117 -0
  124. package/dist/workspace/inspector.d.ts.map +1 -0
  125. package/dist/workspace/inspector.js +140 -0
  126. package/dist/workspace/inspector.js.map +1 -0
  127. package/dist/workspace/rail.d.ts +122 -0
  128. package/dist/workspace/rail.d.ts.map +1 -0
  129. package/dist/workspace/rail.js +216 -0
  130. package/dist/workspace/rail.js.map +1 -0
  131. package/dist/workspace/render.d.ts +139 -0
  132. package/dist/workspace/render.d.ts.map +1 -0
  133. package/dist/workspace/render.js +366 -0
  134. package/dist/workspace/render.js.map +1 -0
  135. package/dist/workspace/selection.d.ts +92 -0
  136. package/dist/workspace/selection.d.ts.map +1 -0
  137. package/dist/workspace/selection.js +83 -0
  138. package/dist/workspace/selection.js.map +1 -0
  139. package/dist/workspace/styles.d.ts +39 -0
  140. package/dist/workspace/styles.d.ts.map +1 -0
  141. package/dist/workspace/styles.js +313 -0
  142. package/dist/workspace/styles.js.map +1 -0
  143. package/package.json +58 -0
@@ -0,0 +1,313 @@
1
+ /**
2
+ * The workspace's structural stylesheet: three fixed zones, and nothing else.
3
+ *
4
+ * Same contract as the viewer's, the ladder's and the re-evaluate surface's —
5
+ * layout, weight and state, never a value. Every colour, length and font is a
6
+ * `var(--ig-…)` the host's theme resolves, and `styles.test.ts` scans these
7
+ * bytes for a literal or an unresolvable token.
8
+ *
9
+ * ## Fixed, and that is the requirement
10
+ *
11
+ * §17f gives the rail and the canvas opposite obligations — the rail is
12
+ * complete at any backlog size, the canvas refuses above its budget — and
13
+ * assembling them must not average the two. Positions are therefore FIXED
14
+ * rather than negotiated: `grid-template-columns` gives the rail and the
15
+ * inspector their own tracks and the canvas the remaining `1fr`, so a large
16
+ * document grows the canvas's refusal rather than squeezing the rail out of
17
+ * the layout.
18
+ *
19
+ * The rail scrolls in its own track. That is what makes windowing a rendering
20
+ * decision rather than a visible one: the reader scrolls a complete order, and
21
+ * which slice is currently drawn is the host's business.
22
+ *
23
+ * ## Dark only, with no forked token set
24
+ *
25
+ * Light was cut after pass 1, so there is no second palette here and no
26
+ * `prefers-color-scheme` block. The single palette is the viewer's, reached
27
+ * through its custom properties — a forked set would be exactly the drifting
28
+ * second implementation the package split exists to remove.
29
+ *
30
+ * ## No animation, anywhere
31
+ *
32
+ * §17a: the audit is ambient, and a count that animates is a count demanding
33
+ * attention it has not earned. The re-evaluate surface already rejected the
34
+ * animated re-sort for a stronger reason — rows moving under the cursor mean
35
+ * the next edit targets the wrong thing — and this is the file where both
36
+ * could creep back in without touching a line of TypeScript.
37
+ */
38
+ export const workspaceStylesheet = `
39
+ .ig-workspace {
40
+ display: grid;
41
+ /* HEADER SPANS, THE THREE ZONES SIT UNDER IT. The audit count is ambient: it
42
+ belongs to the whole workspace rather than to one zone, and putting it in a
43
+ zone's own track would make it move when that zone resized. */
44
+ grid-template-areas:
45
+ 'header header header'
46
+ 'rail canvas inspector';
47
+ /* The rail and the inspector are sized in TYPE, not in pixels: a host that
48
+ scales the type scales the zones with it, which a fixed track would not.
49
+
50
+ A LENGTH TIMES A UNITLESS COUNT, which is the viewer's own idiom
51
+ (styles.ts writes min-width: calc(var(--ig-char-width) * 4)). An earlier
52
+ version multiplied --ig-char-width by --ig-label-char-width, having read
53
+ the second as "how many characters wide a label is". It is not: it is the
54
+ average width OF one character, and themeCss renders every metric with px
55
+ — so the expression was calc(7.8px * 6px), which is not a length. CSS
56
+ discards a declaration it cannot parse, so the whole template went with it
57
+ and all three zones fell back to auto columns: long content could then
58
+ squeeze the canvas, which is the one thing fixed positions exist to stop.
59
+ Nothing failed loudly, because an invalid declaration is simply absent.
60
+
61
+ 40 is a reading measure for a title plus its id, in characters. */
62
+ grid-template-columns:
63
+ calc(var(--ig-char-width) * 40)
64
+ 1fr
65
+ calc(var(--ig-char-width) * 40);
66
+ grid-template-rows: auto 1fr;
67
+ gap: var(--ig-space);
68
+ background: var(--ig-bg);
69
+ color: var(--ig-text-body);
70
+ font-family: var(--ig-font-ui);
71
+ font-size: var(--ig-font-size);
72
+ line-height: var(--ig-line-height);
73
+ }
74
+
75
+ .ig-zone {
76
+ min-width: 0;
77
+ /* Without this a long title in any zone sets that track's minimum width and
78
+ the grid stops honouring its own template. */
79
+ min-height: 0;
80
+ }
81
+
82
+ .ig-zone[data-zone='header'] {
83
+ grid-area: header;
84
+ }
85
+
86
+ .ig-zone[data-zone='rail'] {
87
+ grid-area: rail;
88
+ /* The rail scrolls; the window slides underneath. */
89
+ overflow-y: auto;
90
+ border-right: var(--ig-stroke) solid var(--ig-line);
91
+ }
92
+
93
+ .ig-zone[data-zone='canvas'] {
94
+ grid-area: canvas;
95
+ overflow: auto;
96
+ }
97
+
98
+ .ig-zone[data-zone='inspector'] {
99
+ grid-area: inspector;
100
+ overflow-y: auto;
101
+ border-left: var(--ig-stroke) solid var(--ig-line);
102
+ }
103
+
104
+ /* THE AMBIENT LEFT-BAR. A 2px gold rule on the affected row and nothing else —
105
+ no fill, no icon, no badge. §17a's whole ask is that encoding errors stay
106
+ visible while you work rather than pulling you out of it.
107
+
108
+ An inset box-shadow rather than a border: a border changes the row's box and
109
+ would shift every marked row against its neighbours, which is a layout jump
110
+ the eye reads as movement. The width is the theme's spine, so the bar scales
111
+ with the rest of the rail. */
112
+ .ig-zone[data-zone='rail'] [data-ig-audit] {
113
+ box-shadow: inset var(--ig-spine-width) 0 0 0 var(--ig-accent);
114
+ }
115
+
116
+ .ig-zone[data-zone='rail'] [data-ig-audit='misleading'] {
117
+ box-shadow: inset var(--ig-spine-width) 0 0 0 var(--ig-state-invalid);
118
+ }
119
+
120
+ /* THE ROWS OUTSIDE THE WINDOW, AS HEIGHT. The rail scrolls, so without a spacer
121
+ at each end the container is exactly as tall as the drawn rows and native
122
+ scrolling stops at the end of the first window — leaving a host no offset to
123
+ turn into the next start, and a reader no way to reach rank 287 of 312.
124
+
125
+ NO BACKTICKS ANYWHERE IN THIS FILE'S COMMENTS. The stylesheet is a template
126
+ literal, so a backtick closes it — and the failure is a parse error pages
127
+ away from the character that caused it.
128
+
129
+ THE PITCH IS THE OUTER BOX, NOT THE ROW HEIGHT. A .ig-slot is
130
+ min-height: --ig-row-height PLUS margin-bottom: --ig-space-tight, so
131
+ row-to-row is the sum of the two. Sized on --ig-row-height alone, this
132
+ undercounted EVERY omitted row by the gap — 44 of a 50px pitch on the default
133
+ theme, so 300 omitted rows left the scroll extent 1,800px short and a host
134
+ dividing its scroll position by the measured pitch could reach about offset
135
+ 264 of 300. The tail of the order became unreachable by the very mechanism
136
+ added to make it reachable.
137
+
138
+ That is a SYSTEMATIC undercount, not the approximation below, which is why it
139
+ is corrected exactly rather than tolerated: the gap is constant per row and
140
+ both terms are theme metrics.
141
+
142
+ --ig-rail-rows is the count, set inline by the renderer. What remains
143
+ approximate is only VARIABLE row height — a row carrying holds is taller than
144
+ a bare one — so the scrollbar stays proportional rather than exact. Measuring
145
+ that needs a mount, which this package does not have. */
146
+ .ig-rail-spacer {
147
+ height: calc((var(--ig-row-height) + var(--ig-space-tight)) * var(--ig-rail-rows, 0));
148
+ }
149
+
150
+ .ig-inspector {
151
+ display: flex;
152
+ flex-direction: column;
153
+ gap: var(--ig-space);
154
+ padding: var(--ig-space);
155
+ }
156
+
157
+ .ig-inspector-empty {
158
+ margin: 0;
159
+ color: var(--ig-text-muted);
160
+ font-size: var(--ig-font-size-small);
161
+ }
162
+
163
+ .ig-inspector-issue {
164
+ display: flex;
165
+ flex-direction: column;
166
+ gap: var(--ig-space-tight);
167
+ }
168
+
169
+ .ig-inspector-title {
170
+ margin: 0;
171
+ font-size: var(--ig-font-size);
172
+ color: var(--ig-text);
173
+ }
174
+
175
+ .ig-inspector-key {
176
+ font-family: var(--ig-font-mono);
177
+ color: var(--ig-text-muted);
178
+ }
179
+
180
+ .ig-inspector-position {
181
+ margin: 0;
182
+ font-family: var(--ig-font-mono);
183
+ color: var(--ig-text-muted);
184
+ }
185
+
186
+ .ig-inspector-position[data-ready='true'] {
187
+ color: var(--ig-station-ready);
188
+ }
189
+
190
+ .ig-inspector-holds {
191
+ list-style: none;
192
+ margin: 0;
193
+ padding: 0;
194
+ display: flex;
195
+ flex-direction: column;
196
+ gap: var(--ig-space-tight);
197
+ }
198
+
199
+ /* The two hold families never share a treatment — layer 1's rule, carried
200
+ across so the inspector cannot contradict the rail it sits beside. */
201
+ .ig-inspector-hold[data-family='graph'] {
202
+ color: var(--ig-station-held);
203
+ }
204
+
205
+ .ig-inspector-hold[data-family='tracker'] {
206
+ color: var(--ig-text-muted);
207
+ }
208
+
209
+ .ig-inspector-relationships {
210
+ display: flex;
211
+ flex-direction: column;
212
+ gap: var(--ig-space-tight);
213
+ }
214
+
215
+ .ig-inspector-heading {
216
+ margin: 0;
217
+ font-size: var(--ig-font-size-small);
218
+ color: var(--ig-text-muted);
219
+ }
220
+
221
+ .ig-inspector-clear {
222
+ align-self: flex-start;
223
+ background: var(--ig-surface-2);
224
+ color: var(--ig-text-body);
225
+ border: var(--ig-stroke) solid var(--ig-line);
226
+ border-radius: var(--ig-radius);
227
+ padding: var(--ig-space-tight) var(--ig-space);
228
+ font-family: var(--ig-font-ui);
229
+ font-size: var(--ig-font-size-small);
230
+ cursor: pointer;
231
+ }
232
+
233
+ .ig-inspector-clear:focus-visible {
234
+ outline: var(--ig-focus-ring) solid var(--ig-focus);
235
+ outline-offset: var(--ig-space-tight);
236
+ }
237
+
238
+ .ig-relationship-list {
239
+ list-style: none;
240
+ margin: 0;
241
+ padding: 0;
242
+ display: flex;
243
+ flex-direction: column;
244
+ gap: var(--ig-space-tight);
245
+ }
246
+
247
+ .ig-relationship {
248
+ display: flex;
249
+ gap: var(--ig-space-tight);
250
+ align-items: baseline;
251
+ padding: var(--ig-space-tight);
252
+ border: var(--ig-stroke) solid var(--ig-line);
253
+ border-radius: var(--ig-radius);
254
+ background: var(--ig-surface);
255
+ }
256
+
257
+ /* Hue by field, from the theme's own edge tokens — the same channel layer 1
258
+ uses, so a relationship reads the same colour in the list as on the canvas. */
259
+ .ig-relationship[data-edge='blocked-by'] {
260
+ border-left-color: var(--ig-edge-blocked-by);
261
+ }
262
+
263
+ .ig-relationship[data-edge='duplicate-of'] {
264
+ border-left-color: var(--ig-edge-duplicate-of);
265
+ }
266
+
267
+ .ig-relationship[data-edge='serialize-with'] {
268
+ border-left-color: var(--ig-edge-serialize-with);
269
+ }
270
+
271
+ .ig-relationship[data-edge='together-with'] {
272
+ border-left-color: var(--ig-edge-together-with);
273
+ }
274
+
275
+ .ig-relationship[data-edge='decomposed-from'] {
276
+ border-left-color: var(--ig-edge-decomposed-from);
277
+ }
278
+
279
+ /* The button fills its row, so the whole relationship is the hit target rather
280
+ than the words inside it. Transparent and borderless: the li already carries
281
+ the border and the hue, and a second box around it would read as two
282
+ controls. */
283
+ .ig-relationship-select {
284
+ flex: 1;
285
+ display: flex;
286
+ gap: var(--ig-space-tight);
287
+ align-items: baseline;
288
+ background: none;
289
+ border: none;
290
+ padding: 0;
291
+ font-family: inherit;
292
+ font-size: inherit;
293
+ color: inherit;
294
+ text-align: left;
295
+ cursor: pointer;
296
+ }
297
+
298
+ .ig-relationship-select:focus-visible {
299
+ outline: var(--ig-focus-ring) solid var(--ig-focus);
300
+ outline-offset: var(--ig-space-tight);
301
+ }
302
+
303
+ .ig-relationship-kind {
304
+ font-family: var(--ig-font-mono);
305
+ color: var(--ig-text-body);
306
+ }
307
+
308
+ .ig-relationship-ref {
309
+ font-family: var(--ig-font-mono);
310
+ color: var(--ig-text-muted);
311
+ }
312
+ `;
313
+ //# sourceMappingURL=styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../src/workspace/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkRlC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@issuegraph/editor",
3
+ "version": "0.1.0",
4
+ "description": "Everything that mutates an Issuegraph document: edit affordances drawn as overlays on a viewer, dispatching through a store. Composes the viewer and the store through their public surfaces and performs no write itself.",
5
+ "keywords": [
6
+ "issuegraph",
7
+ "dependency-graph",
8
+ "backlog",
9
+ "scheduling",
10
+ "editor"
11
+ ],
12
+ "license": "Apache-2.0",
13
+ "author": "Autonomy LLC",
14
+ "type": "module",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "default": "./dist/index.js"
19
+ }
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "LICENSE",
24
+ "README.md"
25
+ ],
26
+ "sideEffects": false,
27
+ "publishConfig": {
28
+ "access": "public",
29
+ "provenance": true
30
+ },
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "git+https://github.com/autnmy/issuegraph.git",
34
+ "directory": "packages/editor"
35
+ },
36
+ "homepage": "https://github.com/autnmy/issuegraph#readme",
37
+ "bugs": {
38
+ "url": "https://github.com/autnmy/issuegraph/issues"
39
+ },
40
+ "engines": {
41
+ "node": ">=18"
42
+ },
43
+ "dependencies": {
44
+ "@issuegraph/core": "^0.1.2",
45
+ "@issuegraph/store": "^0.1.1",
46
+ "@issuegraph/viewer": "^0.1.2"
47
+ },
48
+ "devDependencies": {
49
+ "@types/node": "^22.18.0",
50
+ "typescript": "^6.0.3",
51
+ "@issuegraph/reader": "^0.3.0"
52
+ },
53
+ "scripts": {
54
+ "build": "tsc -p tsconfig.json",
55
+ "typecheck": "tsc -p tsconfig.test.json",
56
+ "test": "node --test --test-timeout=20000 \"src/**/*.test.ts\""
57
+ }
58
+ }