@paradow/ledge 0.40.0 → 0.42.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/dist/cli/index.js +799 -404
- package/dist/cli/reduceWorker.js +46 -9
- package/package.json +1 -1
package/dist/cli/reduceWorker.js
CHANGED
|
@@ -243,6 +243,10 @@ var TaskBlockSchema = z5.object({
|
|
|
243
243
|
// ../protocol/src/decisions.ts
|
|
244
244
|
import { z as z6 } from "zod";
|
|
245
245
|
var DecisionSchema = z6.enum(["accept", "deny", "always"]);
|
|
246
|
+
var DecidedBySchema = z6.discriminatedUnion("kind", [
|
|
247
|
+
z6.object({ kind: z6.literal("pc") }),
|
|
248
|
+
z6.object({ kind: z6.literal("device"), id: z6.string().min(1).max(100), name: z6.string().min(1).max(60) })
|
|
249
|
+
]);
|
|
246
250
|
var NOTE_MAX = 4e3;
|
|
247
251
|
|
|
248
252
|
// ../protocol/src/tasks.ts
|
|
@@ -1402,8 +1406,8 @@ var ThreadItemSchema = z22.discriminatedUnion("kind", [
|
|
|
1402
1406
|
imagesDropped: z22.literal(true).optional()
|
|
1403
1407
|
}),
|
|
1404
1408
|
/** `unknown`: answered in the terminal, the daemon only saw the prompt go away; `always`: allowed and not asked again;
|
|
1405
|
-
* `byClose`: denied by Ledge closing the session. */
|
|
1406
|
-
z22.object({ kind: z22.literal("permission"), ...base, tool: z22.string(), text: z22.string(), decision: z22.enum(["accept", "deny", "always", "unknown"]).optional(), byClose: z22.literal(true).optional() }),
|
|
1409
|
+
* `byClose`: denied by Ledge closing the session; `by`: who answered it from Ledge (the PC or a device, its name then). */
|
|
1410
|
+
z22.object({ kind: z22.literal("permission"), ...base, tool: z22.string(), text: z22.string(), decision: z22.enum(["accept", "deny", "always", "unknown"]).optional(), byClose: z22.literal(true).optional(), by: DecidedBySchema.optional() }),
|
|
1407
1411
|
z22.object({ kind: z22.literal("reply"), ...base, text: z22.string() }),
|
|
1408
1412
|
z22.object({ kind: z22.literal("helper"), ...base, task: z22.string(), agentType: z22.string().optional(), state: z22.enum(["working", "exited"]) }),
|
|
1409
1413
|
/** A message this session sent to another agent; `id` is the tool_use_id, `to` the address it used, `peer` the Ledge session id, `received` the paired item's id in the peer's thread, `via` set when Ledge's mailbox carries it. */
|
|
@@ -1486,6 +1490,9 @@ var MobileLinkStateSchema = z23.discriminatedUnion("state", [
|
|
|
1486
1490
|
/** The mobile service did not start (a broken mobile.json, a missing key store): nothing is linked until the daemon restarts. */
|
|
1487
1491
|
z23.object({ state: z23.literal("unavailable"), error: z23.string().max(200) })
|
|
1488
1492
|
]);
|
|
1493
|
+
var DeviceKindSchema = z23.enum(["phone", "tablet"]);
|
|
1494
|
+
var DEVICE_NAME_MAX = 40;
|
|
1495
|
+
var DeviceNameSchema = z23.string().trim().min(1).max(DEVICE_NAME_MAX).regex(/^[^\u0000-\u001f\u007f]+$/);
|
|
1489
1496
|
var MobilePairingSchema = z23.object({
|
|
1490
1497
|
id: z23.string(),
|
|
1491
1498
|
label: z23.string(),
|
|
@@ -1501,7 +1508,16 @@ var MobileStateSchema = z23.object({
|
|
|
1501
1508
|
/** The last sign-in that did not end with a session; cleared by the next one. */
|
|
1502
1509
|
signinError: z23.enum(["expired", "denied", "not_allowed", "failed"]).nullable(),
|
|
1503
1510
|
link: MobileLinkStateSchema,
|
|
1504
|
-
devices: z23.array(z23.object({
|
|
1511
|
+
devices: z23.array(z23.object({
|
|
1512
|
+
id: z23.string(),
|
|
1513
|
+
label: z23.string(),
|
|
1514
|
+
approvedAt: z23.string(),
|
|
1515
|
+
online: z23.boolean(),
|
|
1516
|
+
lastSeenAt: z23.string().optional(),
|
|
1517
|
+
/** Absent from an older daemon; `name` absent: the user gave none, the front derives one from the label. */
|
|
1518
|
+
kind: DeviceKindSchema.optional(),
|
|
1519
|
+
name: z23.string().optional()
|
|
1520
|
+
})),
|
|
1505
1521
|
pairings: z23.array(MobilePairingSchema),
|
|
1506
1522
|
/** « Taper dans les terminaux depuis le téléphone »: absent from an older daemon, which has no phone terminal. */
|
|
1507
1523
|
terminalInput: z23.boolean().optional()
|
|
@@ -1556,6 +1572,8 @@ var SessionEventSchema = z24.object({
|
|
|
1556
1572
|
decision: DecisionSchema.optional(),
|
|
1557
1573
|
/** Decided: the request was refused by Ledge closing the session (its interrupt keys), not by the user's answer. */
|
|
1558
1574
|
byClose: z24.literal(true).optional(),
|
|
1575
|
+
/** Decided: who answered, when the daemon typed it (absent: answered in the terminal, or an older daemon). */
|
|
1576
|
+
by: DecidedBySchema.optional(),
|
|
1559
1577
|
/** The agent's own session id when the hook names it, so the daemon can resume that conversation. */
|
|
1560
1578
|
agentSessionId: z24.string().optional()
|
|
1561
1579
|
});
|
|
@@ -1832,7 +1850,9 @@ var ClientMessageSchema = z24.discriminatedUnion("type", [
|
|
|
1832
1850
|
note: z24.string().trim().min(1).max(NOTE_MAX).optional(),
|
|
1833
1851
|
/** The request the user saw when deciding: refused (the request changed) unless it is still the pending one. Left out by older fronts and the island.
|
|
1834
1852
|
* `key` (pendingKey) covers its whole content; older fronts send kind and text only. */
|
|
1835
|
-
expect: PendingSchema.pick({ kind: true, text: true }).extend({ key: z24.string().max(64).optional() }).optional()
|
|
1853
|
+
expect: PendingSchema.pick({ kind: true, text: true }).extend({ key: z24.string().max(64).optional() }).optional(),
|
|
1854
|
+
/** Who decides: set by the phone gateway for a device (over anything the device sent); left out by a local front, which means the PC. */
|
|
1855
|
+
by: DecidedBySchema.optional()
|
|
1836
1856
|
}),
|
|
1837
1857
|
z24.object({ type: z24.literal("session.focus"), id: z24.string() }),
|
|
1838
1858
|
z24.object({ type: z24.literal("session.kill"), id: z24.string() }),
|
|
@@ -1886,10 +1906,13 @@ var ClientMessageSchema = z24.discriminatedUnion("type", [
|
|
|
1886
1906
|
z24.object({ type: z24.literal("mobile.signout") }),
|
|
1887
1907
|
/** While the link is offline: try again now. */
|
|
1888
1908
|
z24.object({ type: z24.literal("mobile.retry") }),
|
|
1889
|
-
|
|
1909
|
+
/** `replaces`: an approved device this one takes the place of (the same app reinstalled), revoked once this one is stored. */
|
|
1910
|
+
z24.object({ type: z24.literal("mobile.pairing.approve"), id: z24.string().min(1).max(100), replaces: z24.string().min(1).max(100).optional() }),
|
|
1890
1911
|
z24.object({ type: z24.literal("mobile.pairing.deny"), id: z24.string().min(1).max(100) }),
|
|
1891
1912
|
/** `id`: the device's fingerprint. */
|
|
1892
1913
|
z24.object({ type: z24.literal("mobile.device.revoke"), id: z24.string().min(1).max(100) }),
|
|
1914
|
+
/** Names a device (`id`: its fingerprint); the device sees its new name in its next snapshot. */
|
|
1915
|
+
z24.object({ type: z24.literal("mobile.device.rename"), id: z24.string().min(1).max(100), name: DeviceNameSchema }),
|
|
1893
1916
|
/** « Taper dans les terminaux depuis le téléphone »; turned off, every phone loses the hand. */
|
|
1894
1917
|
z24.object({ type: z24.literal("mobile.terminal"), input: z24.boolean() }),
|
|
1895
1918
|
/** « Reprendre la main »: the phone typing into the session's terminal goes back to reading it. */
|
|
@@ -2022,7 +2045,9 @@ var PushSubscriptionSchema = z27.object({
|
|
|
2022
2045
|
});
|
|
2023
2046
|
var PushPayloadSchema = z27.object({
|
|
2024
2047
|
v: z27.literal(1),
|
|
2025
|
-
|
|
2048
|
+
/** `resolved`: a request or question answered (anywhere), replacing its notification under the same tag; only sent to a
|
|
2049
|
+
* device whose subscription says its service worker knows it (`push.subscribe` `resolved`). */
|
|
2050
|
+
kind: z27.enum(["request", "question", "finished", "chat", "decision", "resolved"]),
|
|
2026
2051
|
title: z27.string().max(80),
|
|
2027
2052
|
body: z27.string().max(120),
|
|
2028
2053
|
url: z27.string().regex(/^\/#\/[A-Za-z0-9/%._~-]*$/).max(300),
|
|
@@ -2289,8 +2314,11 @@ var PhoneClientMessageSchema = z28.discriminatedUnion("type", [
|
|
|
2289
2314
|
z28.object({ type: z28.literal("openrig.row"), qitem: QitemIdSchema }),
|
|
2290
2315
|
/** The phone drops its passkey from the daemon. */
|
|
2291
2316
|
z28.object({ type: z28.literal("device.forget"), op: OperationIdSchema }),
|
|
2292
|
-
/** The
|
|
2293
|
-
z28.object({ type: z28.literal("
|
|
2317
|
+
/** The device names itself (on the PC and in its next snapshot); applied to the sender only. */
|
|
2318
|
+
z28.object({ type: z28.literal("device.rename"), op: OperationIdSchema, name: DeviceNameSchema }),
|
|
2319
|
+
/** The phone's push subscription, with the VAPID key it was made with (so a key change is seen). `resolved`: its service
|
|
2320
|
+
* worker shows a `resolved` push, which replaces a request's notification once it is answered elsewhere. */
|
|
2321
|
+
z28.object({ type: z28.literal("push.subscribe"), op: OperationIdSchema, subscription: PushSubscriptionSchema, key: B64U2.length(87), resolved: z28.literal(true).optional() }),
|
|
2294
2322
|
z28.object({ type: z28.literal("push.unsubscribe"), op: OperationIdSchema }),
|
|
2295
2323
|
/** The phone's own chat with Ledge. */
|
|
2296
2324
|
z28.object({ type: z28.literal("chat.ask"), qid: OperationIdSchema, text: z28.string().trim().max(MESSAGE_MAX), attachments: z28.array(AttachmentIdSchema).max(ATTACHMENTS_MAX).optional() }),
|
|
@@ -2382,7 +2410,16 @@ var PhoneServerMessageSchema = z28.discriminatedUnion("type", [
|
|
|
2382
2410
|
openrig: z28.literal(true).optional(),
|
|
2383
2411
|
/** The daemon takes `session.broadcast` (« Écrire au groupe »). */
|
|
2384
2412
|
broadcast: z28.literal(true).optional()
|
|
2385
|
-
}), device: z28.object({
|
|
2413
|
+
}), device: z28.object({
|
|
2414
|
+
confirm: z28.boolean(),
|
|
2415
|
+
push: z28.enum(["on", "off", "stale", "unavailable"]).optional(),
|
|
2416
|
+
chat: z28.literal(true).optional(),
|
|
2417
|
+
contextNear: ContextPrefsSchema.shape.near.optional(),
|
|
2418
|
+
/** This device's id (its fingerprint, as decisions name it in `by`), its kind, and the name the user gave it (absent: none given). */
|
|
2419
|
+
id: z28.string().optional(),
|
|
2420
|
+
kind: DeviceKindSchema.optional(),
|
|
2421
|
+
name: z28.string().optional()
|
|
2422
|
+
}).optional() }),
|
|
2386
2423
|
/** « À toi » on this PC: the answer to `openrig.asks`, then each change, whole. */
|
|
2387
2424
|
z28.object({ type: z28.literal("openrig.asks"), channel: HumanChannelSchema, asks: z28.array(HumanAskSchema), partial: z28.literal(true).optional(), truncated: z28.literal(true).optional() }),
|
|
2388
2425
|
/** An answer's end, as on the desktop (`openrig.answered`), under the phone's `op`. `rejected`: the device check refused it (`reason`). */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paradow/ledge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.42.0",
|
|
4
4
|
"description": "Follow and answer your WSL agent sessions (Claude Code, Codex, Cursor Agent) from the Ledge island on Windows.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": { "ledge": "dist/cli/index.js" },
|