@standardagents/code-plugin-sdk 1.0.0-alpha.4-hover.1 → 1.0.0-alpha.4-hover.2
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 +5 -5
- package/REFERENCE.md +12 -6
- package/package.json +1 -1
- package/src/index.d.ts +2 -2
- package/src/runtime.mjs +32 -2
package/README.md
CHANGED
|
@@ -11,8 +11,8 @@ Its `package.json` includes a static `standardPlugin` manifest.
|
|
|
11
11
|
{
|
|
12
12
|
"name": "example-status",
|
|
13
13
|
"type": "module",
|
|
14
|
-
"peerDependencies": { "@standardagents/code-plugin-sdk": "^1.0.0-alpha.4-hover.
|
|
15
|
-
"devDependencies": { "@standardagents/code-plugin-sdk": "^1.0.0-alpha.4-hover.
|
|
14
|
+
"peerDependencies": { "@standardagents/code-plugin-sdk": "^1.0.0-alpha.4-hover.2" },
|
|
15
|
+
"devDependencies": { "@standardagents/code-plugin-sdk": "^1.0.0-alpha.4-hover.2" },
|
|
16
16
|
"standardPlugin": {
|
|
17
17
|
"apiVersion": 1,
|
|
18
18
|
"id": "example-status",
|
|
@@ -46,9 +46,9 @@ plugin's own test suite.
|
|
|
46
46
|
|
|
47
47
|
The complete rendering contract is in [REFERENCE.md](./REFERENCE.md). It
|
|
48
48
|
covers rows, styled text, badges, cards, slots, panels, overlays, host-rendered
|
|
49
|
-
views, ANSI canvases, canvas hover text, input focus,
|
|
50
|
-
presentations, remote read-only behavior, and the frontend
|
|
51
|
-
still planned.
|
|
49
|
+
views, ANSI canvases, styled canvas hover text, input focus,
|
|
50
|
+
popover/column/pane presentations, remote read-only behavior, and the frontend
|
|
51
|
+
surfaces that are still planned.
|
|
52
52
|
|
|
53
53
|
Plugin source imports the default package entry. Plugin tests may import
|
|
54
54
|
`@standardagents/code-plugin-sdk/testing` for `createHarness`. Runner internals,
|
package/REFERENCE.md
CHANGED
|
@@ -5,7 +5,7 @@ The public declarations live in
|
|
|
5
5
|
plugin authors.
|
|
6
6
|
|
|
7
7
|
The bundled SDK and the npm package use the same public declarations. This
|
|
8
|
-
reference describes SDK `1.0.0-alpha.4-hover.
|
|
8
|
+
reference describes SDK `1.0.0-alpha.4-hover.2`. Plugins should declare the
|
|
9
9
|
version published for their product build in both `peerDependencies` and
|
|
10
10
|
`devDependencies`; the manifest `apiVersion` remains `1`.
|
|
11
11
|
|
|
@@ -139,11 +139,15 @@ wraps or scrolls. Wide characters take two cells. Cells in default colours
|
|
|
139
139
|
take the viewer's theme, and a blank default cell shows the surface under the
|
|
140
140
|
canvas.
|
|
141
141
|
|
|
142
|
-
`hover` is an optional one-line string
|
|
143
|
-
fit within 512 UTF-8 bytes, and
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
142
|
+
`hover` is an optional one-line string or an array of styled `TextSpan` values.
|
|
143
|
+
The string must be non-empty after trimming, fit within 512 UTF-8 bytes, and
|
|
144
|
+
contain no C0, C1, DEL, or bidirectional formatting character. Styled hover
|
|
145
|
+
values contain at most 32 spans whose joined text follows the same bounds and
|
|
146
|
+
must be non-empty. Span styling supports `foreground`, `background`, `bold`,
|
|
147
|
+
`italic`, and `underline`; `actionId` is rejected because hover text is
|
|
148
|
+
passive. `Canvas.replace` publishes the canvas metadata, so a plugin can update
|
|
149
|
+
the hover text with another `replace` call while retaining the same canvas
|
|
150
|
+
grid.
|
|
147
151
|
|
|
148
152
|
On the current frontend, live canvases in `machine.before` and
|
|
149
153
|
`machine.after` slots are hover targets. The viewer waits 300 milliseconds
|
|
@@ -152,6 +156,8 @@ line owned by the host. Leaving the canvas dismisses it immediately. Hover
|
|
|
152
156
|
does not focus the canvas or change its geometry. The dwell timer and pointer
|
|
153
157
|
state belong to each viewer, so remote viewers can see hover text for a
|
|
154
158
|
machine slot independently.
|
|
159
|
+
Hover overlays for these machine slots use the same 22% sidebar machine colour
|
|
160
|
+
blend as the machine name bar over the viewer's background.
|
|
155
161
|
|
|
156
162
|
`focus(true)` asks for keyboard input and needs `captureInput: true` in the
|
|
157
163
|
canvas spec. While the canvas is shown in a pop-over, column, or plugin pane
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -90,8 +90,8 @@ export interface CanvasSpec {
|
|
|
90
90
|
transparent?: boolean;
|
|
91
91
|
shade?: number;
|
|
92
92
|
captureInput?: boolean;
|
|
93
|
-
/** A bounded one-line string shown while the pointer rests over the canvas. */
|
|
94
|
-
hover?: string;
|
|
93
|
+
/** A bounded one-line string or styled spans shown while the pointer rests over the canvas. */
|
|
94
|
+
hover?: string | TextSpan[];
|
|
95
95
|
}
|
|
96
96
|
export type CanvasContent = { kind: 'canvas'; canvas: CanvasSpec };
|
|
97
97
|
/**
|
package/src/runtime.mjs
CHANGED
|
@@ -12,9 +12,39 @@ function boundedText(value, label, limit = 512) {
|
|
|
12
12
|
}
|
|
13
13
|
const HOVER_FORBIDDEN = /[\u0000-\u001f\u007f-\u009f\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/
|
|
14
14
|
function validateCanvasHover(value) {
|
|
15
|
-
|
|
15
|
+
if (typeof value === 'string') {
|
|
16
|
+
ensure(value.trim().length > 0 && !HOVER_FORBIDDEN.test(value),
|
|
17
|
+
'invalid_payload', 'Invalid canvas hover text')
|
|
18
|
+
ensure(Buffer.byteLength(value) <= LIMITS.canvasHoverBytes,
|
|
19
|
+
'payload_too_large', `Canvas hover text exceeds ${LIMITS.canvasHoverBytes} bytes`)
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
ensure(Array.isArray(value), 'invalid_payload', 'Invalid canvas hover spans')
|
|
23
|
+
ensure(value.length > 0, 'invalid_payload', 'Canvas hover spans must contain text')
|
|
24
|
+
ensure(value.length <= 32, 'payload_too_large', 'Canvas hover spans exceed 32 spans')
|
|
25
|
+
let text = ''
|
|
26
|
+
for (const span of value) {
|
|
27
|
+
ensure(object(span), 'invalid_payload', 'Invalid canvas hover span')
|
|
28
|
+
ensure(typeof span.text === 'string' && !HOVER_FORBIDDEN.test(span.text),
|
|
29
|
+
'invalid_payload', 'Invalid canvas hover span text')
|
|
30
|
+
for (const field of ['foreground', 'background']) {
|
|
31
|
+
if (span[field] !== undefined) {
|
|
32
|
+
ensure(typeof span[field] === 'string' && span[field].trim().length > 0 &&
|
|
33
|
+
!HOVER_FORBIDDEN.test(span[field]), 'invalid_payload', `Invalid canvas hover span ${field}`)
|
|
34
|
+
ensure(Buffer.byteLength(span[field]) <= 64,
|
|
35
|
+
'payload_too_large', `Canvas hover span ${field} exceeds 64 bytes`)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
for (const field of ['bold', 'italic', 'underline']) {
|
|
39
|
+
ensure(span[field] === undefined || typeof span[field] === 'boolean',
|
|
40
|
+
'invalid_payload', `Invalid canvas hover span ${field}`)
|
|
41
|
+
}
|
|
42
|
+
ensure(span.actionId === undefined, 'invalid_payload', 'Canvas hover spans cannot contain actionId')
|
|
43
|
+
text += span.text
|
|
44
|
+
}
|
|
45
|
+
ensure(text.trim().length > 0 && !HOVER_FORBIDDEN.test(text),
|
|
16
46
|
'invalid_payload', 'Invalid canvas hover text')
|
|
17
|
-
ensure(Buffer.byteLength(
|
|
47
|
+
ensure(Buffer.byteLength(text) <= LIMITS.canvasHoverBytes,
|
|
18
48
|
'payload_too_large', `Canvas hover text exceeds ${LIMITS.canvasHoverBytes} bytes`)
|
|
19
49
|
}
|
|
20
50
|
function validateEntity(entity) {
|