@astrosheep/square 0.3.91 → 0.3.92
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/cli/context.js +2 -1
- package/dist/codex-address.d.ts +3 -0
- package/dist/codex-address.js +8 -0
- package/dist/codex-boundary-state.d.ts +6 -8
- package/dist/codex-boundary-state.js +8 -85
- package/dist/codex-hook.d.ts +1 -3
- package/dist/codex-hook.js +20 -76
- package/dist/codex-queue.d.ts +5 -17
- package/dist/codex-queue.js +21 -64
- package/dist/file-lock.d.ts +1 -17
- package/dist/file-lock.js +1 -64
- package/dist/mcp.js +2 -1
- package/dist/packages/agent-delivery/src/codex-boundary.d.ts +13 -0
- package/dist/packages/agent-delivery/src/codex-boundary.js +75 -0
- package/dist/packages/agent-delivery/src/codex-cli.d.ts +10 -0
- package/dist/packages/agent-delivery/src/codex-cli.js +69 -0
- package/dist/packages/agent-delivery/src/codex-endpoint.d.ts +3 -0
- package/dist/packages/agent-delivery/src/codex-endpoint.js +14 -0
- package/dist/packages/agent-delivery/src/codex-hook.d.ts +26 -0
- package/dist/packages/agent-delivery/src/codex-hook.js +58 -0
- package/dist/packages/agent-delivery/src/codex-queue.d.ts +24 -0
- package/dist/packages/agent-delivery/src/codex-queue.js +58 -0
- package/dist/packages/agent-delivery/src/codex.d.ts +7 -0
- package/dist/packages/agent-delivery/src/codex.js +332 -0
- package/dist/packages/agent-delivery/src/errors.d.ts +1 -1
- package/dist/packages/agent-delivery/src/errors.js +1 -0
- package/dist/packages/agent-delivery/src/file-lock.d.ts +17 -0
- package/dist/packages/agent-delivery/src/file-lock.js +64 -0
- package/dist/packages/agent-delivery/src/index.d.ts +17 -3
- package/dist/packages/agent-delivery/src/index.js +29 -4
- package/dist/packages/agent-delivery/src/types.d.ts +58 -3
- package/guides/codex-delivery.md +79 -0
- package/package.json +1 -1
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/codex/.codex-plugin/plugin.json +1 -1
- package/plugins/codex/hooks/hooks.json +3 -0
- package/plugins/paseo/client/markdown.tsx +16 -38
- package/plugins/paseo/client/palette.ts +62 -0
- package/plugins/paseo/client/square-message.tsx +75 -45
- package/plugins/paseo/shared/message.ts +16 -1
|
@@ -1,69 +1,99 @@
|
|
|
1
1
|
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
|
-
import { Pressable, ScrollView, Text, View } from "react-native";
|
|
5
|
-
import {
|
|
6
|
-
import { SquareInline,
|
|
4
|
+
import { Pressable, ScrollView, StyleSheet, Text, View } from "react-native";
|
|
5
|
+
import { parseSquareBlocks, parseSquareVoice, type SquareMessageData } from "../shared/message";
|
|
6
|
+
import { MONO, SquareInline, SquareMarkdownBody } from "./markdown";
|
|
7
|
+
import { squarePalette } from "./palette";
|
|
7
8
|
|
|
8
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* The accent ■ marks the square itself, not a route.
|
|
11
|
+
* Collapsed: ■ who spoke · where · how many, then two preview lines.
|
|
12
|
+
* Expanded: the same header, then the bodies indented under it. Several voices
|
|
13
|
+
* become a stage script: each speaker holds a fixed left column, their words
|
|
14
|
+
* run down a single ruled dialogue column. No narration.
|
|
15
|
+
*/
|
|
9
16
|
export function SquareMessage({ item, theme, layout }: PluginTimelineItemProps<SquareMessageData>) {
|
|
10
17
|
const [expanded, setExpanded] = useState(false);
|
|
18
|
+
const palette = useMemo(() => squarePalette(theme), [theme]);
|
|
11
19
|
const { text, items } = item.data;
|
|
12
20
|
const latest = items?.[items.length - 1];
|
|
13
|
-
// Transform already bounded the collapsed preview; only normalise whitespace for the single line.
|
|
14
21
|
const preview = latest?.preview?.replace(/\s+/g, " ").trim();
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
gap: 4,
|
|
29
|
-
},
|
|
30
|
-
whoRow: { flexDirection: "row" as const, alignItems: "center" as const, gap: 6 },
|
|
31
|
-
glyph: { color: theme.colors.accent, fontSize: 9 },
|
|
32
|
-
actor: { color: foreground, fontSize: 12.5, fontWeight: "600" as const },
|
|
33
|
-
route: { color: muted, fontSize: 12.5, flex: 1 },
|
|
34
|
-
count: { color: muted, fontSize: 11 },
|
|
35
|
-
}), [foreground, layout.compact, muted, theme.colors.accent, theme.colors.border, theme.colors.surface1]);
|
|
36
|
-
|
|
37
|
-
const headline = latest !== undefined ? squareHeadline(latest) : "Square context";
|
|
38
|
-
const routeText = latest?.actor !== undefined && headline.startsWith(latest.actor)
|
|
39
|
-
? headline.slice(latest.actor.length).trim()
|
|
40
|
-
: headline;
|
|
22
|
+
const blocks = useMemo(() => parseSquareBlocks(text), [text]);
|
|
23
|
+
const multi = blocks.length > 1;
|
|
24
|
+
const single = multi ? undefined : parseSquareVoice(blocks[0].actor, blocks[0].meta);
|
|
25
|
+
const names = items !== undefined
|
|
26
|
+
? items.map(entry => entry.actor)
|
|
27
|
+
: blocks.map(block => parseSquareVoice(block.actor, block.meta).speaker);
|
|
28
|
+
const speakers = [...new Set(names.filter((name): name is string => name !== undefined))];
|
|
29
|
+
const squareName = latest?.square ?? blocks[0].meta?.split("·")[1]?.trim() ?? "Square";
|
|
30
|
+
const bell = latest?.route === "bell" || single?.bell === true;
|
|
31
|
+
const trailing = `· ${squareName}${expanded && single?.actId ? ` · ${single.actId}` : !expanded && items && items.length > 1 ? ` · ${items.length}` : ""}`;
|
|
32
|
+
const { accent, border, foreground, foregroundMuted: muted, surface1 } = palette.theme.colors;
|
|
33
|
+
const row = { flexDirection: "row" as const, alignItems: "center" as const, gap: 6 };
|
|
34
|
+
const indent = { paddingLeft: 15 };
|
|
41
35
|
|
|
42
36
|
return (
|
|
43
|
-
<View style={
|
|
37
|
+
<View style={{ backgroundColor: surface1, borderWidth: StyleSheet.hairlineWidth, borderColor: border, borderRadius: 8, paddingHorizontal: 12, paddingVertical: 9, gap: expanded ? 8 : 3 }}>
|
|
44
38
|
<Pressable
|
|
45
39
|
accessibilityRole="button"
|
|
46
|
-
accessibilityLabel={`${expanded ? "收起" : "展开"} ${
|
|
40
|
+
accessibilityLabel={`${expanded ? "收起" : "展开"} ${squareName}: ${speakers.join(", ") || "Square"}`}
|
|
47
41
|
aria-expanded={expanded}
|
|
48
42
|
onPress={() => setExpanded(value => !value)}
|
|
49
|
-
style={({ pressed }) => ({ gap:
|
|
43
|
+
style={({ pressed }) => ({ gap: 3, opacity: pressed ? 0.7 : 1 })}
|
|
50
44
|
>
|
|
51
|
-
<View style={
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
<Text
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
45
|
+
<View style={expanded && multi
|
|
46
|
+
? { ...row, paddingBottom: 7, borderBottomWidth: StyleSheet.hairlineWidth, borderBottomColor: border }
|
|
47
|
+
: row}>
|
|
48
|
+
<Text style={{ color: accent, fontSize: 9 }}>■</Text>
|
|
49
|
+
{expanded && multi ? (
|
|
50
|
+
<>
|
|
51
|
+
<Text numberOfLines={1} style={{ color: foreground, fontSize: 12.5, fontWeight: "500", flex: 1 }}>{squareName}</Text>
|
|
52
|
+
<Icon name="ChevronUp" size={15} color={muted} />
|
|
53
|
+
</>
|
|
54
|
+
) : (
|
|
55
|
+
<>
|
|
56
|
+
<Text numberOfLines={1} style={{ color: foreground, fontSize: 13, fontWeight: "500", flex: 1 }}>
|
|
57
|
+
{speakers.join(", ") || "Square"}
|
|
58
|
+
{bell && <Text style={{ color: muted, fontWeight: "400" }}> · rang the bell</Text>}
|
|
59
|
+
</Text>
|
|
60
|
+
<Text style={{ color: muted, fontSize: 12 }}>{trailing}</Text>
|
|
61
|
+
<Icon name={expanded ? "ChevronUp" : "ChevronDown"} size={15} color={muted} />
|
|
62
|
+
</>
|
|
63
|
+
)}
|
|
59
64
|
</View>
|
|
60
65
|
{!expanded && preview !== undefined && preview !== "" && (
|
|
61
|
-
<
|
|
66
|
+
<View style={indent}>
|
|
67
|
+
<SquareInline text={preview} theme={palette.theme} numberOfLines={2} />
|
|
68
|
+
</View>
|
|
62
69
|
)}
|
|
63
70
|
</Pressable>
|
|
64
71
|
{expanded && (
|
|
65
|
-
<ScrollView style={{ maxHeight: layout.compact ? 280 : 400
|
|
66
|
-
|
|
72
|
+
<ScrollView style={{ maxHeight: layout.compact ? 280 : 400 }} nestedScrollEnabled>
|
|
73
|
+
{multi ? (
|
|
74
|
+
<View style={{ gap: 10 }}>
|
|
75
|
+
{blocks.map((block, index) => {
|
|
76
|
+
const voice = parseSquareVoice(block.actor, block.meta);
|
|
77
|
+
const detail = [voice.bell ? "bell" : undefined, voice.actId].filter(Boolean).join(" · ");
|
|
78
|
+
return (
|
|
79
|
+
<View key={voice.actId ?? index} style={{ flexDirection: "row", alignItems: "flex-start", gap: 10 }}>
|
|
80
|
+
<View style={{ width: 62, paddingTop: 1, gap: 1 }}>
|
|
81
|
+
<View style={{ flexDirection: "row", alignItems: "center", gap: 5 }}>
|
|
82
|
+
<Text style={{ fontSize: 8.5, color: voice.glyph === "○" ? muted : palette.voice }}>{voice.glyph}</Text>
|
|
83
|
+
{voice.speaker && <Text numberOfLines={1} style={{ color: foreground, fontSize: 12.5, fontWeight: "500", flexShrink: 1 }}>{voice.speaker}</Text>}
|
|
84
|
+
</View>
|
|
85
|
+
{(voice.bell || voice.actId) && <Text numberOfLines={1} style={{ color: muted, fontSize: 10.5, fontFamily: MONO, paddingLeft: 13 }}>{detail}</Text>}
|
|
86
|
+
</View>
|
|
87
|
+
<View style={{ flex: 1, borderLeftWidth: StyleSheet.hairlineWidth, borderLeftColor: border, paddingLeft: 10 }}>
|
|
88
|
+
<SquareMarkdownBody text={block.body} theme={palette.theme} />
|
|
89
|
+
</View>
|
|
90
|
+
</View>
|
|
91
|
+
);
|
|
92
|
+
})}
|
|
93
|
+
</View>
|
|
94
|
+
) : (
|
|
95
|
+
<SquareMarkdownBody text={blocks[0].body} theme={palette.theme} style={indent} />
|
|
96
|
+
)}
|
|
67
97
|
</ScrollView>
|
|
68
98
|
)}
|
|
69
99
|
</View>
|
|
@@ -50,6 +50,21 @@ export function parseSquareBlocks(text: string): SquareBlock[] {
|
|
|
50
50
|
return blocks;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
export interface SquareVoice { glyph: string; speaker?: string; bell: boolean; actId?: string }
|
|
54
|
+
|
|
55
|
+
// A voice line is chrome for the card: `● rei rang the bell` names who, how, and which
|
|
56
|
+
// activity. Route prose is parsed into those marks, never rendered as narration.
|
|
57
|
+
export function parseSquareVoice(actorLine?: string, metaLine?: string): SquareVoice {
|
|
58
|
+
const line = actorLine?.trim() ?? "";
|
|
59
|
+
const cleaned = line.replace(/^[●○◎◆■·]\s*/, "").trim();
|
|
60
|
+
return {
|
|
61
|
+
glyph: /^[●○◎·]/.exec(line)?.[0] ?? "●",
|
|
62
|
+
speaker: /\S+/.exec(cleaned)?.[0],
|
|
63
|
+
bell: /rang the bell/i.test(cleaned),
|
|
64
|
+
actId: /act\/\d+/.exec(metaLine ?? "")?.[0],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
53
68
|
export const squareCardDetailsSchema = z.object({
|
|
54
69
|
fullText: z.string().optional(),
|
|
55
70
|
items: z.array(z.object({
|
|
@@ -62,7 +77,7 @@ export const squareCardDetailsSchema = z.object({
|
|
|
62
77
|
})).min(1),
|
|
63
78
|
});
|
|
64
79
|
|
|
65
|
-
/** Human-facing summary; the
|
|
80
|
+
/** Human-facing summary of a route; the card itself leads with people, not this prose. */
|
|
66
81
|
export function squareHeadline(item: z.output<typeof squareCardDetailsSchema>["items"][number]): string {
|
|
67
82
|
if (item.actor === undefined || item.route === undefined) return item.description;
|
|
68
83
|
const to = item.recipient;
|