@llblab/pi-telegram 0.46.0 → 0.47.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/BACKLOG.md +0 -1
- package/CHANGELOG.md +8 -0
- package/README.md +2 -2
- package/dist/api/activity.d.ts +6 -0
- package/dist/api/activity.js +6 -0
- package/dist/api/commands.d.ts +6 -0
- package/dist/api/commands.js +6 -0
- package/dist/api/delivery.d.ts +6 -0
- package/dist/api/delivery.js +6 -0
- package/dist/api/inbound.d.ts +6 -0
- package/dist/api/inbound.js +6 -0
- package/dist/api/keyboard.d.ts +6 -0
- package/dist/api/keyboard.js +6 -0
- package/dist/api/outbound.d.ts +6 -0
- package/dist/api/outbound.js +6 -0
- package/dist/api/sections.d.ts +7 -0
- package/dist/api/sections.js +6 -0
- package/dist/api/status.d.ts +6 -0
- package/dist/api/status.js +6 -0
- package/dist/api/updates.d.ts +6 -0
- package/dist/api/updates.js +6 -0
- package/dist/api/voice.d.ts +6 -0
- package/dist/api/voice.js +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/lib/activity-verbosity.d.ts +52 -0
- package/dist/lib/activity-verbosity.js +596 -0
- package/dist/lib/activity.d.ts +220 -0
- package/dist/lib/activity.js +574 -0
- package/dist/lib/agent-messages.d.ts +28 -0
- package/dist/lib/agent-messages.js +86 -0
- package/dist/lib/bindings.d.ts +250 -0
- package/dist/lib/bindings.js +936 -0
- package/dist/lib/bus-api.d.ts +18 -0
- package/dist/lib/bus-api.js +254 -0
- package/dist/lib/bus-follower.d.ts +464 -0
- package/dist/lib/bus-follower.js +1686 -0
- package/dist/lib/bus-leader.d.ts +292 -0
- package/dist/lib/bus-leader.js +2242 -0
- package/dist/lib/bus-transport.d.ts +64 -0
- package/dist/lib/bus-transport.js +140 -0
- package/dist/lib/bus.d.ts +518 -0
- package/dist/lib/bus.js +2055 -0
- package/dist/lib/channel-posts.d.ts +170 -0
- package/dist/lib/channel-posts.js +611 -0
- package/dist/lib/command-templates.d.ts +70 -0
- package/dist/lib/command-templates.js +744 -0
- package/dist/lib/commands.d.ts +541 -0
- package/dist/lib/commands.js +1155 -0
- package/dist/lib/config.d.ts +252 -0
- package/dist/lib/config.js +889 -0
- package/dist/lib/delivery.d.ts +163 -0
- package/dist/lib/delivery.js +542 -0
- package/dist/lib/extension.d.ts +7 -0
- package/dist/lib/extension.js +1608 -0
- package/dist/lib/generative-app-worker.mjs +104 -0
- package/dist/lib/generative-apps.d.ts +212 -0
- package/dist/lib/generative-apps.js +1006 -0
- package/dist/lib/inbound.d.ts +91 -0
- package/dist/lib/inbound.js +502 -0
- package/dist/lib/journal.d.ts +665 -0
- package/dist/lib/journal.js +3701 -0
- package/dist/lib/keyboard.d.ts +23 -0
- package/dist/lib/keyboard.js +37 -0
- package/dist/lib/lifecycle.d.ts +157 -0
- package/dist/lib/lifecycle.js +395 -0
- package/dist/lib/locks.d.ts +164 -0
- package/dist/lib/locks.js +1208 -0
- package/dist/lib/logging.d.ts +50 -0
- package/dist/lib/logging.js +274 -0
- package/dist/lib/media.d.ts +181 -0
- package/dist/lib/media.js +602 -0
- package/dist/lib/menu-model.d.ts +217 -0
- package/dist/lib/menu-model.js +663 -0
- package/dist/lib/menu-queue.d.ts +37 -0
- package/dist/lib/menu-queue.js +408 -0
- package/dist/lib/menu-settings.d.ts +116 -0
- package/dist/lib/menu-settings.js +595 -0
- package/dist/lib/menu-status.d.ts +32 -0
- package/dist/lib/menu-status.js +112 -0
- package/dist/lib/menu-thinking.d.ts +29 -0
- package/dist/lib/menu-thinking.js +82 -0
- package/dist/lib/menu.d.ts +171 -0
- package/dist/lib/menu.js +323 -0
- package/dist/lib/model.d.ts +127 -0
- package/dist/lib/model.js +409 -0
- package/dist/lib/outbound-attachments.d.ts +241 -0
- package/dist/lib/outbound-attachments.js +639 -0
- package/dist/lib/outbound-buttons.d.ts +69 -0
- package/dist/lib/outbound-buttons.js +248 -0
- package/dist/lib/outbound-markup.d.ts +42 -0
- package/dist/lib/outbound-markup.js +678 -0
- package/dist/lib/outbound-voice.d.ts +55 -0
- package/dist/lib/outbound-voice.js +152 -0
- package/dist/lib/outbound.d.ts +185 -0
- package/dist/lib/outbound.js +516 -0
- package/dist/lib/ownership.d.ts +77 -0
- package/dist/lib/ownership.js +174 -0
- package/dist/lib/paths.d.ts +40 -0
- package/dist/lib/paths.js +94 -0
- package/dist/lib/pi.d.ts +72 -0
- package/dist/lib/pi.js +121 -0
- package/dist/lib/polling.d.ts +351 -0
- package/dist/lib/polling.js +1196 -0
- package/dist/lib/preview.d.ts +192 -0
- package/dist/lib/preview.js +614 -0
- package/dist/lib/prompt-templates.d.ts +24 -0
- package/dist/lib/prompt-templates.js +118 -0
- package/dist/lib/prompts.d.ts +57 -0
- package/dist/lib/prompts.js +167 -0
- package/dist/lib/queue.d.ts +766 -0
- package/dist/lib/queue.js +1965 -0
- package/dist/lib/recovery.d.ts +86 -0
- package/dist/lib/recovery.js +285 -0
- package/dist/lib/rendering.d.ts +20 -0
- package/dist/lib/rendering.js +983 -0
- package/dist/lib/replies.d.ts +214 -0
- package/dist/lib/replies.js +737 -0
- package/dist/lib/routing.d.ts +207 -0
- package/dist/lib/routing.js +2282 -0
- package/dist/lib/runtime.d.ts +172 -0
- package/dist/lib/runtime.js +402 -0
- package/dist/lib/sections.d.ts +165 -0
- package/dist/lib/sections.js +327 -0
- package/dist/lib/setup.d.ts +82 -0
- package/dist/lib/setup.js +150 -0
- package/dist/lib/skills.d.ts +8 -0
- package/dist/lib/skills.js +12 -0
- package/dist/lib/status.d.ts +442 -0
- package/dist/lib/status.js +1006 -0
- package/dist/lib/sync.d.ts +179 -0
- package/dist/lib/sync.js +782 -0
- package/dist/lib/target.d.ts +20 -0
- package/dist/lib/target.js +27 -0
- package/dist/lib/telegram-api.d.ts +541 -0
- package/dist/lib/telegram-api.js +1159 -0
- package/dist/lib/text-groups.d.ts +89 -0
- package/dist/lib/text-groups.js +317 -0
- package/dist/lib/thread-cleanup-manager.d.ts +288 -0
- package/dist/lib/thread-cleanup-manager.js +560 -0
- package/dist/lib/thread-display.d.ts +46 -0
- package/dist/lib/thread-display.js +257 -0
- package/dist/lib/thread-naming.d.ts +46 -0
- package/dist/lib/thread-naming.js +78 -0
- package/dist/lib/thread-reconciler.d.ts +239 -0
- package/dist/lib/thread-reconciler.js +644 -0
- package/dist/lib/threads.d.ts +621 -0
- package/dist/lib/threads.js +3679 -0
- package/dist/lib/time-injection.d.ts +15 -0
- package/dist/lib/time-injection.js +56 -0
- package/dist/lib/turns.d.ts +109 -0
- package/dist/lib/turns.js +500 -0
- package/dist/lib/updates.d.ts +1290 -0
- package/dist/lib/updates.js +3634 -0
- package/dist/lib/voice.d.ts +117 -0
- package/dist/lib/voice.js +174 -0
- package/dist/lib/workspace-admission.d.ts +264 -0
- package/dist/lib/workspace-admission.js +1136 -0
- package/dist/lib/workspace-retirement.d.ts +219 -0
- package/dist/lib/workspace-retirement.js +587 -0
- package/dist/lib/workspace-slots.d.ts +30 -0
- package/dist/lib/workspace-slots.js +54 -0
- package/dist/package.json +126 -0
- package/dist/pi-telegram/index.js +1 -0
- package/dist/skills/generated-control-surface/SKILL.md +107 -0
- package/dist/skills/generated-control-surface/references/capability-adapters.md +27 -0
- package/dist/skills/generated-control-surface/references/layout-and-state.md +37 -0
- package/dist/skills/generative-apps/SKILL.md +115 -0
- package/dist/skills/show-me/SKILL.md +166 -0
- package/dist/skills/show-me/references/telegram-surfaces.md +43 -0
- package/dist/skills/telegram-bridge/SKILL.md +129 -0
- package/dist/skills/telegram-bridge/references/configuration.md +15 -0
- package/dist/skills/telegram-bridge/references/delivery-and-threads.md +27 -0
- package/dist/skills/telegram-bridge/references/diagnosis.md +18 -0
- package/docs/architecture.md +1 -1
- package/docs/compact-matrix-literal.md +10 -3
- package/docs/generative-apps.md +15 -13
- package/docs/multi-instance-bus.md +4 -2
- package/docs/outbound.md +1 -1
- package/docs/public-api.md +2 -2
- package/lib/bindings.ts +89 -6
- package/lib/bus-follower.ts +7 -3
- package/lib/bus-leader.ts +44 -19
- package/lib/bus.ts +4 -1
- package/lib/commands.ts +2 -2
- package/lib/config.ts +14 -7
- package/lib/delivery.ts +38 -6
- package/lib/extension.ts +19 -0
- package/lib/generative-apps.ts +379 -13
- package/lib/menu-settings.ts +21 -5
- package/lib/outbound-markup.ts +16 -7
- package/lib/telegram-api.ts +12 -1
- package/lib/thread-display.ts +96 -18
- package/package.json +56 -13
- package/scripts/build-dist.mjs +44 -0
- package/scripts/measure-bus.mjs +8 -1
- package/scripts/measure-workspace.mjs +8 -1
- package/skills/generative-apps/SKILL.md +1 -1
- package/skills/telegram-bridge/SKILL.md +1 -1
package/lib/thread-display.ts
CHANGED
|
@@ -26,30 +26,88 @@ function boundedLabel(base: string, suffix = ""): string {
|
|
|
26
26
|
return `${prefix}${suffix}`;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
function directorySegments(cwd: string): string[] {
|
|
30
|
+
return cwd.split("/").filter(Boolean);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function distinguishingDirectorySegments(cwd: string, directories: readonly string[]): string[] {
|
|
34
|
+
const parts = directorySegments(cwd);
|
|
35
|
+
if (!parts.length) return [];
|
|
32
36
|
for (let depth = 1; depth <= parts.length; depth++) {
|
|
33
37
|
const candidate = labelText(parts.slice(-depth).join("/"));
|
|
34
38
|
const collides = directories.some((other) => other !== cwd &&
|
|
35
|
-
labelText(other
|
|
39
|
+
labelText(directorySegments(other).slice(-depth).join("/")).toLowerCase() ===
|
|
36
40
|
candidate.toLowerCase(),
|
|
37
41
|
);
|
|
38
|
-
if (!collides) return
|
|
42
|
+
if (!collides) return parts.slice(-depth);
|
|
39
43
|
}
|
|
40
|
-
return
|
|
44
|
+
return parts;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function directoryLabel(cwd: string, directories: readonly string[]): string {
|
|
48
|
+
const parts = distinguishingDirectorySegments(cwd, directories);
|
|
49
|
+
return parts.length ? labelText(parts.join("/")) : "/";
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Pure directory tokenization shared by previews, initial titles, and reconciliation. */
|
|
53
|
+
export function tokenizeTelegramDirectorySegment(segment: string): string[] {
|
|
54
|
+
return segment
|
|
55
|
+
.replace(/([\p{Ll}\p{N}])(\p{Lu})/gu, "$1\u0000$2")
|
|
56
|
+
.replace(/(\p{Lu})(\p{Lu}\p{Ll})/gu, "$1\u0000$2")
|
|
57
|
+
.split(/[^\p{L}\p{N}]+|\u0000/gu)
|
|
58
|
+
.filter(Boolean);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function formatDirectoryLabel(
|
|
62
|
+
cwd: string,
|
|
63
|
+
directories: readonly string[],
|
|
64
|
+
mode: "directory-snake" | "directory-title",
|
|
65
|
+
): string {
|
|
66
|
+
const segments = distinguishingDirectorySegments(cwd, directories);
|
|
67
|
+
if (!segments.length) return "/";
|
|
68
|
+
const formatted = segments.map((segment) => {
|
|
69
|
+
const tokens = tokenizeTelegramDirectorySegment(segment);
|
|
70
|
+
if (!tokens.length) return "";
|
|
71
|
+
if (mode === "directory-snake") return tokens.map((token) => token.toLowerCase()).join("_");
|
|
72
|
+
return tokens.map((token) => /\p{L}/u.test(token) && token === token.toUpperCase()
|
|
73
|
+
? token
|
|
74
|
+
: `${token.slice(0, 1).toUpperCase()}${token.slice(1).toLowerCase()}`).join(" ");
|
|
75
|
+
}).filter(Boolean);
|
|
76
|
+
if (!formatted.length) return directoryLabel(cwd, directories);
|
|
77
|
+
return formatted.join(mode === "directory-snake" ? "_" : " / ");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Maps one leader-captured authenticated owner roster onto retained binding identities. */
|
|
81
|
+
export function resolveTelegramLiveWorkspaceBindingKeys(
|
|
82
|
+
bindings: readonly TelegramWorkspaceThreadBinding[],
|
|
83
|
+
leaderTarget: { chatId: number; threadId?: number } | undefined,
|
|
84
|
+
followers: readonly { target?: { chatId: number; threadId?: number } }[],
|
|
85
|
+
): ReadonlySet<string> {
|
|
86
|
+
const targets = new Set<string>();
|
|
87
|
+
const add = (target: { chatId: number; threadId?: number } | undefined) => {
|
|
88
|
+
if (target && typeof target.threadId === "number") {
|
|
89
|
+
targets.add(`${target.chatId}:${target.threadId}`);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
add(leaderTarget);
|
|
93
|
+
for (const follower of followers) add(follower.target);
|
|
94
|
+
return new Set(bindings.filter((binding) =>
|
|
95
|
+
targets.has(`${binding.target.chatId}:${binding.target.threadId}`),
|
|
96
|
+
).map((binding) => binding.bindingKey));
|
|
41
97
|
}
|
|
42
98
|
|
|
43
99
|
/** Missing or ambiguous metadata yields no label rather than inventing identity. */
|
|
44
100
|
export function resolveTelegramWorkspaceDisplayNames(
|
|
45
101
|
bindings: readonly TelegramWorkspaceDisplayBinding[],
|
|
46
102
|
mode: TelegramThreadDisplayMode,
|
|
103
|
+
liveBindingKeys: ReadonlySet<string> = new Set(),
|
|
47
104
|
): Map<string, string> {
|
|
48
105
|
const labels = new Map<string, string>();
|
|
49
106
|
const directories = Array.from(new Set(bindings.map((binding) => binding.cwd)));
|
|
50
|
-
const
|
|
107
|
+
const liveDirectoryCounts = new Map<string, number>();
|
|
51
108
|
for (const binding of bindings) {
|
|
52
|
-
|
|
109
|
+
if (!liveBindingKeys.has(binding.bindingKey)) continue;
|
|
110
|
+
liveDirectoryCounts.set(binding.cwd, (liveDirectoryCounts.get(binding.cwd) ?? 0) + 1);
|
|
53
111
|
}
|
|
54
112
|
const bases = new Map<string, string>();
|
|
55
113
|
for (const binding of bindings) {
|
|
@@ -65,18 +123,27 @@ export function resolveTelegramWorkspaceDisplayNames(
|
|
|
65
123
|
const name = binding.threadName ? labelText(binding.threadName) : slot;
|
|
66
124
|
if (name) labels.set(binding.bindingKey, boundedLabel(name));
|
|
67
125
|
} else {
|
|
68
|
-
const base =
|
|
126
|
+
const base = mode === "directories"
|
|
127
|
+
? directoryLabel(binding.cwd, directories)
|
|
128
|
+
: formatDirectoryLabel(binding.cwd, directories, mode);
|
|
69
129
|
bases.set(binding.bindingKey, base);
|
|
70
|
-
const showSuffix =
|
|
71
|
-
|
|
130
|
+
const showSuffix = mode === "directories"
|
|
131
|
+
? binding.showSlotSuffix || bindings.filter((candidate) => candidate.cwd === binding.cwd).length > 1
|
|
132
|
+
: (liveDirectoryCounts.get(binding.cwd) ?? 0) > 1;
|
|
72
133
|
if (showSuffix && !slot) continue;
|
|
73
|
-
|
|
134
|
+
const suffix = !showSuffix ? "" : mode === "directory-title"
|
|
135
|
+
? ` · ${slot}`
|
|
136
|
+
: `_${slot!.toLowerCase()}`;
|
|
137
|
+
labels.set(binding.bindingKey, boundedLabel(base, suffix));
|
|
74
138
|
}
|
|
75
139
|
}
|
|
76
140
|
// Long or whitespace-normalized paths can collide even after qualification.
|
|
77
|
-
if (mode === "directories") {
|
|
141
|
+
if (mode === "directories" || mode === "directory-snake" || mode === "directory-title") {
|
|
78
142
|
const counts = new Map<string, number>();
|
|
79
|
-
for (const
|
|
143
|
+
for (const binding of bindings) {
|
|
144
|
+
const label = labels.get(binding.bindingKey);
|
|
145
|
+
if (!label || ((mode === "directory-snake" || mode === "directory-title") &&
|
|
146
|
+
!liveBindingKeys.has(binding.bindingKey))) continue;
|
|
80
147
|
const key = label.toLowerCase();
|
|
81
148
|
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
82
149
|
}
|
|
@@ -84,16 +151,24 @@ export function resolveTelegramWorkspaceDisplayNames(
|
|
|
84
151
|
const label = labels.get(binding.bindingKey);
|
|
85
152
|
if (binding.manualThreadName || !label ||
|
|
86
153
|
(counts.get(label.toLowerCase()) ?? 0) < 2) continue;
|
|
154
|
+
if ((mode === "directory-snake" || mode === "directory-title") &&
|
|
155
|
+
(liveDirectoryCounts.get(binding.cwd) ?? 0) < 2) {
|
|
156
|
+
labels.delete(binding.bindingKey);
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
87
159
|
if (!binding.slot || !/^[A-Z]$/u.test(binding.slot)) {
|
|
88
160
|
labels.delete(binding.bindingKey);
|
|
89
161
|
continue;
|
|
90
162
|
}
|
|
91
163
|
labels.set(binding.bindingKey, boundedLabel(bases.get(binding.bindingKey)!,
|
|
92
|
-
`_${binding.slot.toLowerCase()}`));
|
|
164
|
+
mode === "directory-title" ? ` · ${binding.slot}` : `_${binding.slot.toLowerCase()}`));
|
|
93
165
|
}
|
|
94
166
|
}
|
|
95
167
|
const counts = new Map<string, number>();
|
|
96
|
-
for (const
|
|
168
|
+
for (const binding of bindings) {
|
|
169
|
+
const label = labels.get(binding.bindingKey);
|
|
170
|
+
if (!label || ((mode === "directory-snake" || mode === "directory-title") &&
|
|
171
|
+
!liveBindingKeys.has(binding.bindingKey))) continue;
|
|
97
172
|
const key = label.toLowerCase();
|
|
98
173
|
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
99
174
|
}
|
|
@@ -108,6 +183,7 @@ export function resolveTelegramInitialWorkspaceDisplayName(input: {
|
|
|
108
183
|
binding: TelegramWorkspaceDisplayBinding;
|
|
109
184
|
mode: TelegramThreadDisplayMode;
|
|
110
185
|
preserveRetainedManualName?: boolean;
|
|
186
|
+
liveBindingKeys?: ReadonlySet<string>;
|
|
111
187
|
}): string | undefined {
|
|
112
188
|
const retained = input.bindings.find((binding) =>
|
|
113
189
|
binding.bindingKey === input.binding.bindingKey,
|
|
@@ -126,7 +202,7 @@ export function resolveTelegramInitialWorkspaceDisplayName(input: {
|
|
|
126
202
|
candidate.bindingKey !== binding.bindingKey,
|
|
127
203
|
),
|
|
128
204
|
binding,
|
|
129
|
-
], input.mode).get(binding.bindingKey);
|
|
205
|
+
], input.mode, new Set([...(input.liveBindingKeys ?? []), binding.bindingKey])).get(binding.bindingKey);
|
|
130
206
|
}
|
|
131
207
|
|
|
132
208
|
export async function applyTelegramThreadDisplaySetting(
|
|
@@ -155,6 +231,7 @@ export interface TelegramThreadDisplayReconcilerDeps {
|
|
|
155
231
|
getProfileKey(): string;
|
|
156
232
|
getLeaderEpoch(): string | number | undefined;
|
|
157
233
|
captureBindingAuthority(binding: TelegramWorkspaceThreadBinding): (() => boolean) | undefined;
|
|
234
|
+
captureLiveBindingKeys(bindings: readonly TelegramWorkspaceThreadBinding[]): ReadonlySet<string>;
|
|
158
235
|
callApi<TResponse>(
|
|
159
236
|
method: string,
|
|
160
237
|
body: Record<string, unknown>,
|
|
@@ -179,7 +256,8 @@ export function createTelegramThreadDisplayReconciler(
|
|
|
179
256
|
};
|
|
180
257
|
assertAuthority();
|
|
181
258
|
const bindings = deps.store.listWorkspaceBindings();
|
|
182
|
-
const
|
|
259
|
+
const liveBindingKeys = deps.captureLiveBindingKeys(bindings);
|
|
260
|
+
const titles = resolveTelegramWorkspaceDisplayNames(bindings, mode, liveBindingKeys);
|
|
183
261
|
let changed = 0;
|
|
184
262
|
for (const binding of bindings) {
|
|
185
263
|
const isBindingCurrent = deps.captureBindingAuthority(binding);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llblab/pi-telegram",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.47.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -30,15 +30,19 @@
|
|
|
30
30
|
"test": "node --experimental-strip-types --test --test-concurrency=4 --test-reporter=dot tests/*.test.ts",
|
|
31
31
|
"test:verbose": "node --experimental-strip-types --test --test-reporter=spec tests/*.test.ts",
|
|
32
32
|
"typecheck": "tsc --noEmit",
|
|
33
|
+
"build": "node scripts/build-dist.mjs",
|
|
34
|
+
"prepack": "npm run build",
|
|
35
|
+
"check": "node -e \"await import('./dist/pi-telegram/index.js'); console.log('pi-telegram: extension import ok')\"",
|
|
33
36
|
"audit": "npm audit --omit=peer",
|
|
34
37
|
"audit:host": "npm audit",
|
|
35
38
|
"pack:check": "npm pack --dry-run",
|
|
36
|
-
"validate": "npm run typecheck && npm test && npm run audit && npm run pack:check"
|
|
39
|
+
"validate": "npm run build && npm run typecheck && npm test && npm run audit && npm run check && npm run pack:check"
|
|
37
40
|
},
|
|
38
41
|
"files": [
|
|
39
42
|
"index.ts",
|
|
40
43
|
"api/",
|
|
41
44
|
"lib/",
|
|
45
|
+
"dist/",
|
|
42
46
|
"README.md",
|
|
43
47
|
"AGENTS.md",
|
|
44
48
|
"BACKLOG.md",
|
|
@@ -49,23 +53,62 @@
|
|
|
49
53
|
"screenshot.png"
|
|
50
54
|
],
|
|
51
55
|
"exports": {
|
|
52
|
-
".":
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"./
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"./
|
|
61
|
-
|
|
62
|
-
|
|
56
|
+
".": {
|
|
57
|
+
"types": "./dist/index.d.ts",
|
|
58
|
+
"default": "./dist/index.js"
|
|
59
|
+
},
|
|
60
|
+
"./inbound": {
|
|
61
|
+
"types": "./dist/api/inbound.d.ts",
|
|
62
|
+
"default": "./dist/api/inbound.js"
|
|
63
|
+
},
|
|
64
|
+
"./outbound": {
|
|
65
|
+
"types": "./dist/api/outbound.d.ts",
|
|
66
|
+
"default": "./dist/api/outbound.js"
|
|
67
|
+
},
|
|
68
|
+
"./delivery": {
|
|
69
|
+
"types": "./dist/api/delivery.d.ts",
|
|
70
|
+
"default": "./dist/api/delivery.js"
|
|
71
|
+
},
|
|
72
|
+
"./activity": {
|
|
73
|
+
"types": "./dist/api/activity.d.ts",
|
|
74
|
+
"default": "./dist/api/activity.js"
|
|
75
|
+
},
|
|
76
|
+
"./updates": {
|
|
77
|
+
"types": "./dist/api/updates.d.ts",
|
|
78
|
+
"default": "./dist/api/updates.js"
|
|
79
|
+
},
|
|
80
|
+
"./commands": {
|
|
81
|
+
"types": "./dist/api/commands.d.ts",
|
|
82
|
+
"default": "./dist/api/commands.js"
|
|
83
|
+
},
|
|
84
|
+
"./sections": {
|
|
85
|
+
"types": "./dist/api/sections.d.ts",
|
|
86
|
+
"default": "./dist/api/sections.js"
|
|
87
|
+
},
|
|
88
|
+
"./status": {
|
|
89
|
+
"types": "./dist/api/status.d.ts",
|
|
90
|
+
"default": "./dist/api/status.js"
|
|
91
|
+
},
|
|
92
|
+
"./voice": {
|
|
93
|
+
"types": "./dist/api/voice.d.ts",
|
|
94
|
+
"default": "./dist/api/voice.js"
|
|
95
|
+
},
|
|
96
|
+
"./keyboard": {
|
|
97
|
+
"types": "./dist/api/keyboard.d.ts",
|
|
98
|
+
"default": "./dist/api/keyboard.js"
|
|
99
|
+
}
|
|
63
100
|
},
|
|
64
101
|
"pi": {
|
|
65
102
|
"extensions": [
|
|
103
|
+
"./dist/pi-telegram/index.js"
|
|
104
|
+
],
|
|
105
|
+
"sourceExtensions": [
|
|
66
106
|
"./index.ts"
|
|
67
107
|
],
|
|
68
108
|
"skills": [
|
|
109
|
+
"./dist/skills"
|
|
110
|
+
],
|
|
111
|
+
"sourceSkills": [
|
|
69
112
|
"./skills"
|
|
70
113
|
],
|
|
71
114
|
"image": "https://raw.githubusercontent.com/llblab/pi-telegram/main/screenshot.png"
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Builds the distributive JavaScript, declarations, Pi entrypoint, and Skills.
|
|
5
|
+
* Usage: node scripts/build-dist.mjs
|
|
6
|
+
*
|
|
7
|
+
* The build replaces `dist`, compiles with `tsconfig.build.json`, then copies
|
|
8
|
+
* package-owned runtime assets. It does not publish, pack, or modify sources.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { spawnSync } from "node:child_process";
|
|
12
|
+
import { cpSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
|
|
15
|
+
function run(command, args) {
|
|
16
|
+
const result = spawnSync(command, args, { stdio: "inherit" });
|
|
17
|
+
if (result.error) throw result.error;
|
|
18
|
+
if (result.status !== 0) process.exit(result.status ?? 1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
rmSync("dist", { recursive: true, force: true });
|
|
22
|
+
mkdirSync("dist", { recursive: true });
|
|
23
|
+
|
|
24
|
+
run(process.execPath, [
|
|
25
|
+
join("node_modules", "typescript", "bin", "tsc"),
|
|
26
|
+
"-p",
|
|
27
|
+
"tsconfig.build.json",
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
mkdirSync(join("dist", "pi-telegram"), { recursive: true });
|
|
31
|
+
writeFileSync(
|
|
32
|
+
join("dist", "pi-telegram", "index.js"),
|
|
33
|
+
'export { default } from "../index.js";\n',
|
|
34
|
+
"utf8",
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
cpSync("skills", join("dist", "skills"), { recursive: true });
|
|
38
|
+
cpSync("package.json", join("dist", "package.json"));
|
|
39
|
+
cpSync(
|
|
40
|
+
join("lib", "generative-app-worker.mjs"),
|
|
41
|
+
join("dist", "lib", "generative-app-worker.mjs"),
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
run(process.execPath, ["--check", join("dist", "pi-telegram", "index.js")]);
|
package/scripts/measure-bus.mjs
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Counts isolated synchronous bus-registry work at representative sizes.
|
|
3
|
+
* Usage: node --experimental-strip-types scripts/measure-bus.mjs
|
|
4
|
+
*
|
|
5
|
+
* This assertion-backed fixture instruments Map operations only. It does not
|
|
6
|
+
* open sockets, read configured profiles, call Telegram, or measure latency.
|
|
7
|
+
*/
|
|
8
|
+
|
|
2
9
|
import assert from "node:assert/strict";
|
|
3
10
|
import { createTelegramBusFollowerRegistry, createTelegramBusProtocolIdentity } from "../lib/bus.ts";
|
|
4
11
|
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Measures isolated Thread-store filesystem work at representative sizes.
|
|
3
|
+
* Usage: node --experimental-strip-types scripts/measure-workspace.mjs
|
|
4
|
+
*
|
|
5
|
+
* This assertion-backed fixture uses and removes its own temporary directory.
|
|
6
|
+
* It never reads configured profiles, calls Telegram, or measures latency.
|
|
7
|
+
*/
|
|
8
|
+
|
|
2
9
|
import assert from "node:assert/strict";
|
|
3
10
|
import fs from "node:fs/promises";
|
|
4
11
|
import { syncBuiltinESMExports } from "node:module";
|
|
@@ -97,7 +97,7 @@ ordinary prompt → model-mediated interpretation or explanation
|
|
|
97
97
|
- Keep credentials and unrelated private state out of source, state, output, and diagnostics.
|
|
98
98
|
- Route consequences requiring contextual judgment through an ordinary model prompt.
|
|
99
99
|
- Fail closed on unavailable owners, stale actions, malformed state, absent methods, process failures, or uncertain effects.
|
|
100
|
-
-
|
|
100
|
+
- Treat `refreshAfterMs` validation, output-only `refresh`, scheduling after a successful hinted explicit `telegram_bind` delivery, same-handle rescheduling after a current-surface bound action, Delivery edit-failure classification, known unavailable-message invalidation with bounded classified diagnostics, session/runtime live-surface cancellation, and exact direct classic/leader/authenticated-follower target retention as implemented. The Bot API has no ordinary private-message deletion update; `deleted_business_messages` is limited to connected business accounts. Do not claim removal, voice output, proactive deletion-update invalidation, or other behavior still marked incomplete in the runtime document.
|
|
101
101
|
|
|
102
102
|
## Validation
|
|
103
103
|
|
|
@@ -60,7 +60,7 @@ Every enabled button has a self-contained prompt and an optional selection style
|
|
|
60
60
|
- `{label|prompt}` separates visible label from queued prompt.
|
|
61
61
|
- `{label|prompt|selected_style}` and `{|prompt|selected_style}` accept `primary`, `success`, or `danger`.
|
|
62
62
|
- Fourth-position `1`/`true` disables, `0`/`false` enables; omission means enabled. JSON uses boolean `disabled`. `{|Next||1}` omits label/style; `{Next|||1}` omits prompt/style; `{|||1}` is blank (Telegram receives a non-breaking space). Prefer meaningful labels and retain a useful enabled action. Enabled CML requires a prompt. Disabled controls stay visible but have no callback, queued prompt, or bound-method invocation.
|
|
63
|
-
- Top-level cells form vertical rows;
|
|
63
|
+
- Top-level cells form vertical rows; inside a fenced block, adjacent top-level JSON/CML objects may omit the outer array and commas. One nested row groups horizontal peers.
|
|
64
64
|
- Prefer one matrix per related group. Fenced blocks stay in place in Rich mode; HTML compatibility moves them to the footer. Native rows allow eight buttons. Malformed/oversized/unclosed blocks activate nothing; drafts hide them. Outer code fences and quoted/indented examples remain literal.
|
|
65
65
|
- Both placements share prompt/app routing. In-body clicks acknowledge without recoloring; selected-style highlighting remains footer-only.
|
|
66
66
|
|