@astrosheep/square 0.3.106 → 0.4.1
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/dist/activity-feed.js +1 -1
- package/dist/artifact-store.d.ts +41 -0
- package/dist/artifact-store.js +272 -0
- package/dist/artifact.d.ts +6 -12
- package/dist/artifact.js +43 -344
- package/dist/attention-presentation.d.ts +13 -7
- package/dist/attention-presentation.js +29 -68
- package/dist/boundary-presentation.d.ts +3 -16
- package/dist/boundary-presentation.js +29 -109
- package/dist/card-presentation.d.ts +1 -0
- package/dist/card-presentation.js +2 -0
- package/dist/catch-decisions.d.ts +2 -2
- package/dist/catch-decisions.js +7 -3
- package/dist/catch-selection.d.ts +8 -0
- package/dist/catch-selection.js +5 -0
- package/dist/claude-delivery.d.ts +14 -12
- package/dist/claude-delivery.js +42 -142
- package/dist/claude-mcp-context.js +2 -2
- package/dist/claude-mod.js +28 -140
- package/dist/claude-transport.d.ts +5 -0
- package/dist/claude-transport.js +34 -0
- package/dist/cli/context.d.ts +2 -2
- package/dist/cli/context.js +7 -10
- package/dist/cli/maintenance-commands.d.ts +0 -4
- package/dist/cli/maintenance-commands.js +2 -29
- package/dist/cli/observation-commands.d.ts +2 -0
- package/dist/cli/observation-commands.js +12 -2
- package/dist/cli/program.js +1 -1
- package/dist/cli/registry.js +4 -3
- package/dist/codex-address.d.ts +2 -2
- package/dist/codex-boundary-state.d.ts +1 -5
- package/dist/codex-boundary-state.js +0 -4
- package/dist/codex-hook.d.ts +7 -10
- package/dist/codex-hook.js +69 -33
- package/dist/codex-queue.d.ts +10 -11
- package/dist/codex-queue.js +32 -34
- package/dist/codex-watch.d.ts +2 -0
- package/dist/codex-watch.js +100 -0
- package/dist/decisions.js +3 -3
- package/dist/delivery-deferral.d.ts +1 -19
- package/dist/delivery-deferral.js +1 -29
- package/dist/delivery-frame.d.ts +7 -0
- package/dist/delivery-frame.js +11 -0
- package/dist/delivery-ledger-sqlite.d.ts +97 -0
- package/dist/delivery-ledger-sqlite.js +496 -0
- package/dist/delivery-ledger.d.ts +196 -0
- package/dist/delivery-ledger.js +268 -0
- package/dist/delivery-lifetime.d.ts +6 -0
- package/dist/delivery-lifetime.js +45 -0
- package/dist/harness-links.js +61 -7
- package/dist/harness.js +12 -17
- package/dist/help.js +3 -6
- package/dist/http-delivery.d.ts +5 -9
- package/dist/http-delivery.js +20 -79
- package/dist/inbox.d.ts +6 -57
- package/dist/inbox.js +24 -380
- package/dist/index.d.ts +7 -4
- package/dist/index.js +5 -2
- package/dist/mcp.d.ts +2 -1
- package/dist/mcp.js +40 -70
- package/dist/message.d.ts +7 -0
- package/dist/message.js +23 -0
- package/dist/model.d.ts +15 -91
- package/dist/model.js +2 -140
- package/dist/neutral.d.ts +72 -0
- package/dist/neutral.js +27 -0
- package/dist/notifications.d.ts +24 -26
- package/dist/notifications.js +39 -143
- package/dist/operation-control.d.ts +4 -0
- package/dist/operation-control.js +20 -0
- package/dist/operation-presentation.d.ts +1 -2
- package/dist/operation-presentation.js +1 -7
- package/dist/owner.d.ts +2 -2
- package/dist/owner.js +1 -1
- package/dist/packages/agent-delivery/src/claude-native.d.ts +2 -0
- package/dist/packages/agent-delivery/src/claude-native.js +5 -0
- package/dist/packages/agent-delivery/src/codex-boundary.d.ts +11 -6
- package/dist/packages/agent-delivery/src/codex-boundary.js +31 -40
- package/dist/packages/agent-delivery/src/codex-hook.d.ts +17 -12
- package/dist/packages/agent-delivery/src/codex-hook.js +26 -39
- package/dist/packages/agent-delivery/src/codex.d.ts +3 -0
- package/dist/packages/agent-delivery/src/codex.js +41 -4
- package/dist/packages/agent-delivery/src/index.d.ts +3 -1
- package/dist/packages/agent-delivery/src/index.js +1 -1
- package/dist/packages/agent-delivery/src/paseo.js +11 -2
- package/dist/packages/agent-delivery/src/types.d.ts +1 -0
- package/dist/paseo-delivery.d.ts +5 -5
- package/dist/paseo-delivery.js +19 -99
- package/dist/paseo.d.ts +1 -1
- package/dist/paseo.js +1 -1
- package/dist/plugins/opencode/index.d.ts +5 -3
- package/dist/plugins/opencode/index.js +99 -21
- package/dist/plugins/opencode-shared/delivery.d.ts +23 -0
- package/dist/plugins/opencode-shared/delivery.js +109 -0
- package/dist/plugins/opencode-v1/index.d.ts +28 -0
- package/dist/plugins/opencode-v1/index.js +41 -0
- package/dist/plugins/opencode-v1/runtime.d.ts +56 -0
- package/dist/plugins/opencode-v1/runtime.js +152 -0
- package/dist/plugins/opencode-v1/transport.d.ts +13 -0
- package/dist/plugins/opencode-v1/transport.js +50 -0
- package/dist/plugins/paseo/shared/card-presentation.d.ts +10 -0
- package/dist/plugins/paseo/shared/card-presentation.js +7 -0
- package/dist/ports.d.ts +33 -214
- package/dist/presentation.d.ts +5 -5
- package/dist/presentation.js +1 -0
- package/dist/runtime.js +2 -2
- package/dist/search.js +1 -1
- package/dist/session-lifecycle.d.ts +8 -7
- package/dist/session-lifecycle.js +40 -42
- package/dist/sqlite-framing.d.ts +8 -0
- package/dist/sqlite-framing.js +31 -0
- package/dist/sqlite-square.d.ts +16 -26
- package/dist/sqlite-square.js +199 -262
- package/dist/sqlite-values.d.ts +21 -0
- package/dist/sqlite-values.js +78 -0
- package/dist/square-api.d.ts +1 -1
- package/dist/square-api.js +5 -8
- package/dist/square-core.d.ts +0 -1
- package/dist/square-domain.d.ts +12 -10
- package/dist/square-domain.js +105 -223
- package/dist/square-facade.d.ts +25 -76
- package/dist/square-location.d.ts +6 -1
- package/dist/square-location.js +1 -1
- package/dist/square-post.d.ts +53 -0
- package/dist/square-post.js +4 -0
- package/dist/square-posting.d.ts +13 -0
- package/dist/square-posting.js +174 -0
- package/dist/square-producer-sqlite.d.ts +11 -0
- package/dist/square-producer-sqlite.js +210 -0
- package/dist/square-receive.d.ts +2 -3
- package/dist/square-sqlite.d.ts +33 -42
- package/dist/square-sqlite.js +236 -768
- package/dist/square-tools.d.ts +8 -0
- package/dist/square-tools.js +39 -0
- package/dist/square-values.d.ts +27 -0
- package/dist/square-values.js +90 -0
- package/dist/views.d.ts +6 -6
- package/dist/views.js +14 -9
- package/dist/wake-sink.d.ts +4 -11
- package/dist/wake-sink.js +8 -32
- package/dist/wake-transports.d.ts +4 -0
- package/dist/wake-transports.js +11 -0
- package/examples/symmetric-domains.mjs +29 -249
- package/guides/change-waits.md +13 -53
- package/guides/claude-native.md +19 -172
- package/guides/codex-delivery.md +55 -78
- package/guides/delivery-primitives.md +48 -207
- package/guides/operation-cancellation.md +2 -5
- package/guides/participant-ownership.md +25 -89
- package/guides/pi-native-delivery.md +19 -56
- package/guides/pi-tools.md +6 -8
- package/guides/row-runtime-delivery-evidence.md +2 -0
- package/guides/row-storage-design.md +19 -44
- package/guides/square-api.md +113 -538
- package/package.json +8 -8
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/hooks/hooks.json +1 -1
- package/plugins/claude/{hooks/register.js → mods/square.js} +4 -7
- package/plugins/claude/types.d.ts +1 -1
- package/plugins/codex/.codex-plugin/plugin.json +1 -1
- package/plugins/codex/hooks/hooks.json +11 -23
- package/plugins/opencode/index.ts +91 -23
- package/plugins/opencode-shared/delivery.ts +91 -0
- package/plugins/opencode-v1/index.ts +36 -0
- package/plugins/opencode-v1/runtime.ts +134 -0
- package/plugins/opencode-v1/transport.ts +41 -0
- package/plugins/paseo/OVERVIEW.md +5 -5
- package/plugins/paseo/README.md +7 -6
- package/plugins/paseo/client/markdown.tsx +5 -5
- package/plugins/paseo/client/square-message.tsx +28 -24
- package/plugins/paseo/client/transform.ts +8 -5
- package/plugins/paseo/shared/card-presentation.ts +16 -0
- package/plugins/paseo/shared/message.ts +6 -11
- package/plugins/pi/square-pi.js +167 -451
- package/dist/channel.d.ts +0 -74
- package/dist/channel.js +0 -92
- package/dist/claude-delivery-status.d.ts +0 -13
- package/dist/claude-delivery-status.js +0 -46
- package/dist/cmd/notify-once.d.ts +0 -2
- package/dist/cmd/notify-once.js +0 -29
- package/dist/delivery-attempts.d.ts +0 -52
- package/dist/delivery-attempts.js +0 -73
- package/dist/delivery-effects.d.ts +0 -139
- package/dist/delivery-effects.js +0 -163
- package/dist/delivery-health.d.ts +0 -51
- package/dist/delivery-health.js +0 -173
- package/dist/delivery-operations.d.ts +0 -9
- package/dist/delivery-operations.js +0 -168
- package/dist/delivery-primitives.d.ts +0 -5
- package/dist/delivery-primitives.js +0 -3
- package/dist/delivery.d.ts +0 -45
- package/dist/delivery.js +0 -106
- package/dist/plugins/opencode/delivery.d.ts +0 -19
- package/dist/plugins/opencode/delivery.js +0 -238
- package/dist/presentation-operations.d.ts +0 -18
- package/dist/presentation-operations.js +0 -86
- package/dist/square-index.d.ts +0 -16
- package/dist/square-index.js +0 -106
- package/dist/square-legacy-framing.d.ts +0 -11
- package/dist/square-legacy-framing.js +0 -64
- package/dist/square-migration-host-ledger.d.ts +0 -26
- package/dist/square-migration-host-ledger.js +0 -169
- package/dist/square-migration.d.ts +0 -30
- package/dist/square-migration.js +0 -599
- package/guides/migration.md +0 -156
- package/plugins/opencode/delivery.ts +0 -211
|
@@ -5,10 +5,10 @@ who reached you and where. Expand it to see the original custom-message content,
|
|
|
5
5
|
select text, or copy it in full. The card follows the active Paseo theme on
|
|
6
6
|
desktop and mobile.
|
|
7
7
|
|
|
8
|
-
Requires Paseo 0.11.2 or newer with custom-message tool rows (#6090).
|
|
9
|
-
|
|
10
|
-
context use a neutral
|
|
8
|
+
Requires Paseo 0.11.2 or newer with custom-message tool rows (#6090). Structured messages
|
|
9
|
+
carry producer-neutral origin, author, reference, badge and full body details. Plain messages and
|
|
10
|
+
joining context use a neutral notification heading.
|
|
11
11
|
|
|
12
12
|
The plugin changes presentation only. It does not send prompts or alter model
|
|
13
|
-
context.
|
|
14
|
-
|
|
13
|
+
context. Expansion shows the delivered full display body, within a bounded preview,
|
|
14
|
+
while model-facing text stays clipped as before. No producer storage fetch is needed.
|
package/plugins/paseo/README.md
CHANGED
|
@@ -16,8 +16,9 @@ Paseo supplies all runtime modules. No Git preparation step is needed. Plugins
|
|
|
16
16
|
are trusted, unsandboxed code running inside the Paseo app.
|
|
17
17
|
|
|
18
18
|
Requires Paseo >=0.11.2 with custom-message tool rows (#6090). Structured notification
|
|
19
|
-
cards use
|
|
20
|
-
`
|
|
19
|
+
cards use `details.items` with producer-neutral presentation facts: `kind: 'presentation'`, `origin`,
|
|
20
|
+
optional `author`, `ref` and `badge`, and the full Markdown `body`. Missing or malformed details fall
|
|
21
|
+
back to the original plain text.
|
|
21
22
|
|
|
22
23
|
## Display
|
|
23
24
|
|
|
@@ -27,9 +28,9 @@ and unrecognized rows remain unchanged.
|
|
|
27
28
|
|
|
28
29
|
The heading and expanded messages use `metadata.details.items` directly, never
|
|
29
30
|
reverse-parsing notification envelopes or body text for senders, IDs or message
|
|
30
|
-
boundaries. Each expanded item keeps its full source body, author, exact
|
|
31
|
-
and
|
|
32
|
-
are not compressed into a misleading range; items from different
|
|
31
|
+
boundaries. Each expanded item keeps its full source body, author, exact reference
|
|
32
|
+
and badge, even when the model preview was clipped or omitted. References with gaps
|
|
33
|
+
are not compressed into a misleading range; items from different origins remain
|
|
33
34
|
separate. Collapsing shows only the last item's preview. Body text containing square
|
|
34
35
|
tags is ordinary content, not another notification.
|
|
35
36
|
|
|
@@ -44,7 +45,7 @@ Long content scrolls inside a bounded panel. The
|
|
|
44
45
|
card does not fetch extra activity or mark anything seen. Live events and fetched history use
|
|
45
46
|
the same transformer.
|
|
46
47
|
|
|
47
|
-
An accent glyph,
|
|
48
|
+
An accent glyph, author and origin label identify the card. The header and its arrow
|
|
48
49
|
toggle an inline drawer. It uses Paseo theme colors, selectable text, accessible
|
|
49
50
|
expansion state and compact layout on narrow displays. Removing the plugin restores
|
|
50
51
|
Paseo's ordinary custom-message row.
|
|
@@ -166,14 +166,14 @@ export function SquareCue({ label, theme }: { label: ReactNode; theme: PluginThe
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
/**
|
|
169
|
-
* A body of Markdown: no envelope
|
|
170
|
-
* `lead` runs the
|
|
169
|
+
* A body of Markdown: no envelope — the words only, at full width.
|
|
170
|
+
* `lead` runs the author into the first line; `author` names whoever performs an action.
|
|
171
171
|
*/
|
|
172
|
-
export function SquareMarkdownBody({ text, theme, lead,
|
|
172
|
+
export function SquareMarkdownBody({ text, theme, lead, author }: {
|
|
173
173
|
text: string;
|
|
174
174
|
theme: PluginTheme;
|
|
175
175
|
lead?: string;
|
|
176
|
-
|
|
176
|
+
author?: string;
|
|
177
177
|
}) {
|
|
178
178
|
const styles = useMemo(() => makeStyles(theme.colors), [theme.colors]);
|
|
179
179
|
const tokens = useMemo(() => lexer(text).filter(token => token.type !== "space"), [text]);
|
|
@@ -182,7 +182,7 @@ export function SquareMarkdownBody({ text, theme, lead, actor }: {
|
|
|
182
182
|
const key = `body-${index}`;
|
|
183
183
|
if (isAction(token)) {
|
|
184
184
|
const words = renderInlines(children(children(token)[0]!), styles, key);
|
|
185
|
-
return <SquareCue key={key} theme={theme} label={
|
|
185
|
+
return <SquareCue key={key} theme={theme} label={author === undefined ? words : <>{author} {words}</>} />;
|
|
186
186
|
}
|
|
187
187
|
if (pending === undefined) return renderBlocks([token], styles, key);
|
|
188
188
|
const name = pending;
|
|
@@ -2,17 +2,17 @@ import type { PluginTimelineItemProps } from "@getpaseo/plugin/client";
|
|
|
2
2
|
import { Icon } from "@getpaseo/plugin/client/react-native";
|
|
3
3
|
import { useMemo, useState } from "react";
|
|
4
4
|
import { Pressable, ScrollView, Text, View } from "react-native";
|
|
5
|
-
import type
|
|
5
|
+
import { COLLAPSED_PREVIEW_MAX_CHARS, outputPreview, type SquareMessageData } from "../shared/message";
|
|
6
6
|
import { MONO, SquareCue, SquareInline, SquareMarkdownBody } from "./markdown";
|
|
7
7
|
import { squarePalette } from "./palette";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* A matte slate slip in the timeline's shared 4px-corner family: square seal ■,
|
|
11
11
|
* thin quote guide under the header.
|
|
12
|
-
* Header (both states): ■
|
|
12
|
+
* Header (both states): ■ origin · authors … refs · how many.
|
|
13
13
|
* Collapsed: two preview lines. Expanded: the whole scene, at full width.
|
|
14
|
-
* Each structured message keeps its own
|
|
15
|
-
* A
|
|
14
|
+
* Each structured message keeps its own author, reference and body.
|
|
15
|
+
* A badge or an *action* is stage direction, a caption on a hairline.
|
|
16
16
|
*/
|
|
17
17
|
export function SquareMessage({ item, theme, layout }: PluginTimelineItemProps<SquareMessageData>) {
|
|
18
18
|
const [expanded, setExpanded] = useState(false);
|
|
@@ -20,18 +20,20 @@ export function SquareMessage({ item, theme, layout }: PluginTimelineItemProps<S
|
|
|
20
20
|
const palette = useMemo(() => squarePalette(theme), [theme]);
|
|
21
21
|
const items = "items" in item.data ? item.data.items : undefined;
|
|
22
22
|
const text = "text" in item.data ? item.data.text : undefined;
|
|
23
|
+
const presentations = items?.filter(entry => "origin" in entry);
|
|
23
24
|
const latest = items?.at(-1);
|
|
24
25
|
// Keep the source's own line breaks: collapsed and expanded text must wrap alike.
|
|
25
|
-
const preview = latest
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const trailing = [
|
|
34
|
-
|
|
26
|
+
const preview = latest && "text" in latest ? outputPreview(latest.text, COLLAPSED_PREVIEW_MAX_CHARS)
|
|
27
|
+
: latest?.preview ?? text;
|
|
28
|
+
const authors = [...new Set(presentations?.flatMap(entry => entry.author === undefined ? [] : [entry.author]))];
|
|
29
|
+
const chorus = authors.length > 1;
|
|
30
|
+
const origins = [...new Set(presentations?.map(entry => entry.origin))];
|
|
31
|
+
const originName = origins.join(", ") || "Notification";
|
|
32
|
+
const badge = presentations?.at(-1)?.badge;
|
|
33
|
+
// Exact references never imply intervening messages; each origin keeps its own references.
|
|
34
|
+
const trailing = [presentations?.flatMap(entry => entry.ref === undefined ? []
|
|
35
|
+
: [origins.length > 1 ? `${entry.origin} ${entry.ref}` : entry.ref]).join(", "),
|
|
36
|
+
presentations && presentations.length > 1 ? String(presentations.length) : undefined].filter(Boolean).join(" · ");
|
|
35
37
|
const { accent, border, foreground, foregroundMuted: muted, surface1 } = palette.theme.colors;
|
|
36
38
|
// On web the header brightens its details under the cursor; touch keeps them quiet.
|
|
37
39
|
const detail = layout.platform === "web" && hovered ? foreground : muted;
|
|
@@ -45,7 +47,7 @@ export function SquareMessage({ item, theme, layout }: PluginTimelineItemProps<S
|
|
|
45
47
|
]}>
|
|
46
48
|
<Pressable
|
|
47
49
|
accessibilityRole="button"
|
|
48
|
-
accessibilityLabel={`${expanded ? "收起" : "展开"} ${
|
|
50
|
+
accessibilityLabel={`${expanded ? "收起" : "展开"} ${originName}: ${authors.join(", ") || "Notification"}`}
|
|
49
51
|
aria-expanded={expanded}
|
|
50
52
|
onPress={() => setExpanded(value => !value)}
|
|
51
53
|
onHoverIn={() => setHovered(true)}
|
|
@@ -55,9 +57,9 @@ export function SquareMessage({ item, theme, layout }: PluginTimelineItemProps<S
|
|
|
55
57
|
<View style={row}>
|
|
56
58
|
<View style={{ width: 6, height: 6, borderRadius: palette.seal.borderRadius, backgroundColor: accent }} />
|
|
57
59
|
<Text numberOfLines={1} style={{ color: foreground, fontSize: 11.5, lineHeight: 17, fontWeight: "600", flex: 1 }}>
|
|
58
|
-
{
|
|
59
|
-
{(
|
|
60
|
-
<Text style={{ color: muted, fontWeight: "400", fontSize: 10.5 }}> · {[
|
|
60
|
+
{originName}
|
|
61
|
+
{(authors.length > 0 || badge) && (
|
|
62
|
+
<Text style={{ color: muted, fontWeight: "400", fontSize: 10.5 }}> · {[authors.join(", "), badge].filter(Boolean).join(" · ")}</Text>
|
|
61
63
|
)}
|
|
62
64
|
</Text>
|
|
63
65
|
{trailing !== "" && <Text numberOfLines={1} style={{ color: detail, fontSize: 9.5, fontFamily: MONO, fontVariant: ["tabular-nums"], flexShrink: 1 }}>{trailing}</Text>}
|
|
@@ -65,19 +67,21 @@ export function SquareMessage({ item, theme, layout }: PluginTimelineItemProps<S
|
|
|
65
67
|
</View>
|
|
66
68
|
{!expanded && preview !== undefined && preview !== "" && (
|
|
67
69
|
<View style={{ ...indent, marginTop: 5, marginLeft: 2.5, paddingLeft: palette.quote.paddingLeft, borderLeftWidth: palette.quote.borderLeftWidth, borderLeftColor: palette.quote.borderLeftColor }}>
|
|
68
|
-
<SquareInline text={preview} theme={palette.theme} numberOfLines={2} lead={chorus ? latest
|
|
70
|
+
<SquareInline text={preview} theme={palette.theme} numberOfLines={2} lead={chorus && latest && "author" in latest ? latest.author : undefined} />
|
|
69
71
|
</View>
|
|
70
72
|
)}
|
|
71
73
|
</Pressable>
|
|
72
74
|
{expanded && (
|
|
73
75
|
<ScrollView style={{ maxHeight: layout.compact ? 280 : 400, marginTop: 3 }} nestedScrollEnabled>
|
|
74
76
|
<View style={{ ...indent, gap: 7 }}>
|
|
75
|
-
{items === undefined ? <SquareMarkdownBody text={text ?? ""} theme={palette.theme} /> : items.map((entry, index) => (
|
|
77
|
+
{items === undefined ? <SquareMarkdownBody text={text ?? ""} theme={palette.theme} /> : items.map((entry, index) => "text" in entry ? (
|
|
78
|
+
<SquareMarkdownBody key={index} text={entry.text} theme={palette.theme} />
|
|
79
|
+
) : (
|
|
76
80
|
<View key={index} style={{ gap: 6 }}>
|
|
77
|
-
{entry.
|
|
78
|
-
? <SquareCue theme={palette.theme} label={
|
|
79
|
-
: <Text style={{ color: muted, fontSize: 11, fontFamily: MONO }}>{entry.
|
|
80
|
-
<SquareMarkdownBody text={entry.body} theme={palette.theme} lead={chorus ? entry.
|
|
81
|
+
{entry.badge
|
|
82
|
+
? <SquareCue theme={palette.theme} label={[[entry.author, entry.badge].filter(Boolean).join(" "), entry.origin, entry.ref].filter(Boolean).join(" · ")} />
|
|
83
|
+
: <Text style={{ color: muted, fontSize: 11, fontFamily: MONO }}>{[entry.origin, entry.ref].filter(Boolean).join(" · ")}</Text>}
|
|
84
|
+
<SquareMarkdownBody text={entry.body} theme={palette.theme} lead={chorus ? entry.author : undefined} author={entry.author} />
|
|
81
85
|
</View>
|
|
82
86
|
))}
|
|
83
87
|
</View>
|
|
@@ -13,13 +13,16 @@ export const transformSquareMessage: PluginTimelineTransformerContribution<"tool
|
|
|
13
13
|
let data: SquareMessageData;
|
|
14
14
|
if (details.success) {
|
|
15
15
|
const items = details.data.items, latest = items.at(-1)!;
|
|
16
|
-
const preview = outputPreview(latest.preview ?? latest.body, COLLAPSED_PREVIEW_MAX_CHARS);
|
|
16
|
+
const preview = outputPreview("text" in latest ? latest.text : latest.preview ?? latest.body, COLLAPSED_PREVIEW_MAX_CHARS);
|
|
17
17
|
let remaining = OUTPUT_DISPLAY_MAX_CHARS - preview.length;
|
|
18
|
-
const clipped = items.reduce((sum, entry) => sum + entry.body.length, 0) > remaining;
|
|
19
|
-
data = { items: items.map((
|
|
20
|
-
const
|
|
18
|
+
const clipped = items.reduce((sum, entry) => sum + ("text" in entry ? entry.text : entry.body).length, 0) > remaining;
|
|
19
|
+
data = { items: items.map((entry, index) => {
|
|
20
|
+
const source = "text" in entry ? entry.text : entry.body;
|
|
21
|
+
const body = clipped ? outputPreview(source, Math.floor(remaining / (items.length - index))) : source;
|
|
21
22
|
remaining -= body.length;
|
|
22
|
-
|
|
23
|
+
if ("text" in entry) return { text: body };
|
|
24
|
+
const { preview: _preview, ...presentation } = entry;
|
|
25
|
+
return { ...presentation, body, ...(index === items.length - 1 ? { preview } : {}) };
|
|
23
26
|
}) };
|
|
24
27
|
} else {
|
|
25
28
|
data = { text: outputPreview(item.detail.text) };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Producer-neutral display facts; independent of model-facing delivery text. */
|
|
2
|
+
export type CardPresentation = {
|
|
3
|
+
readonly kind: 'presentation';
|
|
4
|
+
readonly origin: string;
|
|
5
|
+
readonly author?: string;
|
|
6
|
+
readonly ref?: string;
|
|
7
|
+
readonly badge?: string;
|
|
8
|
+
readonly body: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function isCardPresentation(value: unknown): value is CardPresentation {
|
|
12
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return false;
|
|
13
|
+
const item = value as Record<string, unknown>;
|
|
14
|
+
return item.kind === 'presentation' && typeof item.origin === 'string' && typeof item.body === 'string'
|
|
15
|
+
&& ['author', 'ref', 'badge'].every(key => item[key] === undefined || typeof item[key] === 'string');
|
|
16
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { isCardPresentation, type CardPresentation } from "./card-presentation.ts";
|
|
2
3
|
|
|
3
4
|
/** Aggregate client display budget, including omission lines; source history stays unchanged. */
|
|
4
5
|
export const OUTPUT_DISPLAY_MAX_CHARS = 32_000;
|
|
@@ -15,17 +16,11 @@ export function outputPreview(text: string, maxChars = OUTPUT_DISPLAY_MAX_CHARS)
|
|
|
15
16
|
return head + middle + tail;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
/**
|
|
19
|
+
/** Receiver display facts, with a bounded preview derived on the client. */
|
|
20
|
+
const presentationItemSchema = z.custom<CardPresentation>(isCardPresentation)
|
|
21
|
+
.and(z.object({ preview: z.string().optional() }));
|
|
19
22
|
export const squareCardDetailsSchema = z.object({
|
|
20
|
-
items: z.array(z.object({
|
|
21
|
-
square: z.string(),
|
|
22
|
-
actor: z.string(),
|
|
23
|
-
act: z.string().regex(/^act\/(0|[1-9]\d*)$/),
|
|
24
|
-
body: z.string(),
|
|
25
|
-
recipient: z.string().optional(),
|
|
26
|
-
route: z.enum(["mention", "reply", "attention", "bell"]),
|
|
27
|
-
preview: z.string().optional(),
|
|
28
|
-
})).min(1),
|
|
23
|
+
items: z.array(z.union([presentationItemSchema, z.object({ text: z.string() })])).min(1),
|
|
29
24
|
});
|
|
30
25
|
|
|
31
26
|
export const squareMessageSchema = z.union([
|
|
@@ -33,4 +28,4 @@ export const squareMessageSchema = z.union([
|
|
|
33
28
|
z.object({ text: z.string() }),
|
|
34
29
|
]);
|
|
35
30
|
export type SquareMessageData = z.output<typeof squareMessageSchema>;
|
|
36
|
-
export type
|
|
31
|
+
export type PresentationItem = z.output<typeof presentationItemSchema>;
|