@paigy/mcp 0.40.3 → 0.40.5

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.
@@ -2,10 +2,10 @@ import {
2
2
  AGENT_TOOLS,
3
3
  mcpInputSchema,
4
4
  serverInstructions
5
- } from "./chunk-V3VVCML7.js";
5
+ } from "./chunk-AOQ2CNMG.js";
6
6
  import {
7
7
  AGENT_NAME
8
- } from "./chunk-6QQHTUKJ.js";
8
+ } from "./chunk-JSQ6MXBI.js";
9
9
 
10
10
  // src/toolset.ts
11
11
  var ONBOARD_DESCRIPTION = "Get this agent talking to Paigy \u2014 call it FIRST, before contact, and any time you're unsure who you are. One call, and it does whatever the situation needs: NOT SET UP \u2192 hatches an identity instantly if this machine holds a device credential (the user ran the Paigy desktop app or harness), otherwise starts the code ceremony; ALREADY SET UP \u2192 returns your current identity and offers the two things left to decide, renaming it or unpairing; TOKEN NO LONGER VALID \u2192 says so, then re-pairs. Pass { name, voice } to choose who you are when hatching, or to RENAME yourself when already set up (voices: rachel, george, jessica, brian, lily). Safe to call any time: idempotent, and it never writes settings \u2014 the tool-allowlist state it reports is read-only. If it returns a `user_code`, print it to the user immediately and call onboard again with the `device_code`. If it returns `enable_command`, PRINT that command for the user to run \u2014 you cannot apply it yourself (it writes your own permission allowlist, which hosts block as privilege escalation), so print it, don't wait for it, and carry on.";
@@ -101,9 +101,9 @@ var UpdateGoalToolSchema = UpdateGoalSchema.omit({ operationId: true }).extend({
101
101
  var ClaimGoalSchema = z2.object({ goalId: z2.string().uuid().optional() }).strict();
102
102
  var GetGoalSchema = z2.object({ goalId: z2.string().uuid() }).strict();
103
103
  var GET_GOAL_DESCRIPTION = "Read the current authorized Goal brief: state, owner, blockers, open decisions, progress, and the next operation. Foreign or sibling-owned Goals are not disclosed.";
104
- var UPDATE_GOAL_DESCRIPTION = "Update an owned Goal at an exact revision. State, ownership, dependencies, children, progress, and review acknowledgement are explicit; stale revisions are rejected. Returns the new revision and a prose summary.";
104
+ var UPDATE_GOAL_DESCRIPTION = "Update an owned Goal at an exact revision. State, ownership, dependencies, children, progress, and review acknowledgement are explicit; stale revisions are rejected. reviewed: true acknowledges new evidence and closes the Deliveries addressed to you on that Goal, never over an open decision. Returns the new revision and a prose summary.";
105
105
  var CLAIM_GOAL_DESCRIPTION = "Claim the oldest runnable or review-pending Goal you own, or pass goalId to claim that Goal. Returns a Goal-scoped brief, current revision, blockers, and the next valid operation. Claiming creates or renews the execution lease.";
106
- var CHECK_REPLIES_DESCRIPTION = "Your open Deliveries: every Notification or Call currently addressed to you \u2014 a request the user started toward you, an answer relayed to something you asked, a handoff \u2014 each with its durable Entries, accepted decisions and open decision needs, in the same shape a contact read returns. A pure read with no arguments: nothing is consumed, acknowledged or claimed by reading it, so call it on startup, after a long wait, or whenever you want to know what is outstanding. To act on one, claim its Goal (claim_goal) or reread it with contact({deliveryId}). Your runnable and review-pending Goals come from claim_goal, not from here.";
106
+ var CHECK_REPLIES_DESCRIPTION = "Your open Deliveries: every Notification or Call currently addressed to you \u2014 a request the user started toward you, an answer relayed to something you asked, a handoff \u2014 one row each: its Goals, the newest words in brief, accepted decisions and open decision needs, without the Entries. A pure read with no arguments: nothing is consumed, acknowledged or claimed by reading it, so call it on startup, after a long wait, or whenever you want to know what is outstanding. To act on one, claim its Goal (claim_goal) or reread it in full with contact({deliveryId}). Once you have acted on what arrived, update_goal with reviewed: true closes the Deliveries addressed to you on that Goal. Your runnable and review-pending Goals come from claim_goal, not from here.";
107
107
  var CheckRepliesSchema = z2.object({}).strict();
108
108
  var GetThreadSchema = z2.object({
109
109
  parentId: z2.string().describe("The Thread to read \u2014 the threadId a Delivery returned, or the parentId of a search hit.")
@@ -500,67 +500,6 @@ var AwaitItemSchema = z3.discriminatedUnion("type", [
500
500
  inFlight: z3.boolean().optional()
501
501
  })
502
502
  ]);
503
- var CallbackTriggerSchema = z3.enum(["on_done", "on_blocked", "scheduled"]);
504
- var NotifyResponseSchema = z3.object({
505
- notificationId: z3.string(),
506
- workId: z3.string().uuid().optional(),
507
- decisionId: z3.string().uuid().optional(),
508
- status: NotifyStatusSchema,
509
- createdAt: z3.string().datetime(),
510
- answer: UserAnswerSchema.optional(),
511
- answeredAt: z3.string().datetime().optional(),
512
- /** Ride-alongs for THIS agent — pending work it should pick up when it's done with
513
- * what it came for. Present on any reply, because an unwakeable agent's only
514
- * reliable moment is one it initiated. Absent/empty = nothing owed. */
515
- also: z3.array(RideAlongSchema).optional()
516
- });
517
- var NotifyPlanUnitSchema = z3.object({
518
- notificationId: z3.string(),
519
- /** The unit's own heading, so the agent can tell which of its paragraphs this became. */
520
- title: z3.string(),
521
- /** How loudly this unit was arbitrated to arrive — per unit, which is the point of units. */
522
- level: NotifyLevelSchema,
523
- /** Answered from something the user already decided: nobody is interrupted, and a trail card
524
- * says so. The agent should not wait on this one. */
525
- settled: z3.literal(true).optional(),
526
- /** What this unit would need to be answerable and does not carry (#894). A PROPOSAL to the
527
- * agent — nothing here changed the ask, and ignoring it costs nothing. */
528
- needs: z3.array(z3.enum(["options", "visuals"])).optional(),
529
- /** The SHAPE the broker would give this unit, for the agent to ratify (#886/#894). The
530
- * split layer reads prose and can see that a paragraph is a yes/no or a pick-one — but a
531
- * broker that DECIDES that destroys the only fact separating a statement from a real ask
532
- * (#731), so it is offered, never applied: the unit is stored `text` until the agent
533
- * confirms the shape (POST /notify/:id/confirm). Ignoring it costs nothing. */
534
- proposal: z3.object({
535
- select: SelectShapeSchema,
536
- options: z3.array(z3.object({ label: z3.string().min(1) })).optional()
537
- }).optional(),
538
- /** What the broker READ this unit as wanting from the human (#952 layer 2): a `decision`
539
- * between alternatives, an `approval` the agent is blocked on, or `knowledge` it just
540
- * needs to know. Reported so the agent can correct a misread the same way it ratifies a
541
- * shape — the read RAISES (a decision always asks) and never silences a question the
542
- * agent declared (#731, #923). */
543
- wants: z3.enum(["decision", "approval", "knowledge"]).optional()
544
- });
545
- var NotifyPlanSchema = z3.object({
546
- units: z3.array(NotifyPlanUnitSchema),
547
- /** Which unit is this arrival's ONE interruption (units-design.md D23). Absent means nobody
548
- * was interrupted — every unit was either settled or quiet enough to sit in the inbox. */
549
- speaks: z3.string().optional()
550
- });
551
- var UserResponseSchema = z3.object({
552
- requestId: z3.string(),
553
- answer: UserAnswerSchema,
554
- answeredAt: z3.string().datetime(),
555
- transcript: z3.string().optional(),
556
- /** E2EE: the sealed answer (opaque envelope + plaintext `ignored` hint) when the item was
557
- * E2EE-sealed. Present → the server persists it opaquely and branches status on `ignored`;
558
- * the plaintext `answer` is a placeholder (`{ kind: "ignored" }`) the server ignores for a
559
- * sealed row. Absent = today's plaintext answer, unchanged. */
560
- sealed: z3.lazy(() => SealedAnswerSchema).optional(),
561
- /** Coverage report (#396): which of the ask's declared `points` were addressed. */
562
- covered: z3.array(z3.string()).optional()
563
- });
564
503
  var VoiceKeySchema = z3.enum(["rachel", "george", "jessica", "brian", "lily"]);
565
504
  var AgendaTurnSchema = z3.object({
566
505
  /** THE TURN'S IDENTITY (the first-sentence stream, 2026-09-09): the brain call that wrote
@@ -744,10 +683,6 @@ var InboxItemSchema = z3.object({
744
683
  goalState: z3.string().optional()
745
684
  }).optional()
746
685
  });
747
- var SnoozeRequestSchema = z3.object({
748
- requestId: z3.string(),
749
- until: z3.string().datetime()
750
- });
751
686
  var APNS_TOKEN_RE = /^[0-9a-fA-F]{64}$/;
752
687
  var PushTokenSchema = z3.object({
753
688
  voipToken: z3.string().min(1).optional(),
@@ -903,6 +838,9 @@ var ConnectionSummarySchema = z3.object({
903
838
  * harness availabilities + granted workspaces — the option set the phone's
904
839
  * "new session" sheet offers. Absent for ordinary MCP agents. */
905
840
  runtime: z3.object({
841
+ /** The @paigy/harness this host is running — a machine the self-update has not reached
842
+ * shows its age here (`apps/desktop/src/update.ts`). */
843
+ version: z3.string().optional(),
906
844
  harnesses: z3.array(z3.object({ name: z3.string(), label: z3.string(), status: z3.string() })).optional(),
907
845
  workspaces: z3.array(z3.string()).optional()
908
846
  }).optional(),
@@ -965,19 +903,6 @@ var MoveSchema = z3.object({
965
903
  * distilled from a clarify ruling (those carry no agent) or one whose source rows are gone. */
966
904
  learnedFrom: z3.object({ id: z3.string(), name: z3.string() }).nullable()
967
905
  });
968
- var CreateRequestSchema = z3.object({
969
- /** The connection (token id) to send to, from GET /api/tokens. */
970
- tokenId: z3.string(),
971
- /** The user's message to the agent. */
972
- text: z3.string().min(1),
973
- /** Land the request on an existing conversation thread (History → "Continue")
974
- * instead of minting a fresh one. Must belong to the requesting user. */
975
- parentId: z3.string().optional(),
976
- /** Point the agent at a past conversation (possibly with a different agent) as
977
- * starting context (History → "New session from this"). A reference, not a copy —
978
- * the agent reads it via get_thread. Must belong to the requesting user. */
979
- contextParentId: z3.string().optional()
980
- });
981
906
  var QueueQuestionSchema = z3.object({
982
907
  /** The decision need's id — what an answer is accepted against. */
983
908
  id: z3.string(),
@@ -1069,38 +994,6 @@ var NoteSchema = z3.object({
1069
994
  lastRideAt: z3.string().nullable().default(null),
1070
995
  createdAt: z3.string()
1071
996
  });
1072
- var CreateNoteSchema = z3.object({
1073
- /** The intent, in the user's own words. Stored verbatim; the broker only titles it. */
1074
- text: z3.string().min(1).max(4e3),
1075
- /** Capture it as a REMINDER — a note assigned to the user themselves, which rides
1076
- * their next call instead of being handed to an agent. Everything else about the
1077
- * note is identical; this is the one parameter that separates the two. */
1078
- forMe: z3.boolean().optional(),
1079
- /** The not-before, when the user already said one. Absent = the very next call. */
1080
- dueAt: z3.string().datetime().optional(),
1081
- repeat: NoteRepeatSchema.optional()
1082
- });
1083
- var RecordDecisionSchema = z3.object({
1084
- /** An open decision (from /clarify) to answer. */
1085
- decisionId: z3.string().optional(),
1086
- /** For an ad-hoc decision: what was ambiguous. Required without `decisionId`. */
1087
- question: z3.string().min(1).max(500).optional(),
1088
- /** The ruling. */
1089
- answer: z3.string().min(1).max(2e3)
1090
- }).refine((d) => d.decisionId || d.question, { message: "decisionId or question required" });
1091
- var AssignNoteSchema = z3.object({
1092
- /** An EXISTING agent: token id or nickname. Omit when spawning fresh. */
1093
- target: z3.string().min(1).optional(),
1094
- /** Spawn a NEW session for this note (companion.md §2.2): the assignee doesn't
1095
- * exist yet — mint it on a live desktop that advertises the harness+workspace,
1096
- * named after the note. The brief arrives as its opening request. */
1097
- spawn: z3.object({
1098
- hostTokenId: z3.string().uuid(),
1099
- harness: z3.string().min(1),
1100
- workspace: z3.string().min(1)
1101
- }).optional()
1102
- }).refine((a) => !!a.target !== !!a.spawn, { message: "exactly one of target or spawn" });
1103
- var TriageVerdictSchema = z3.enum(["keep", "stale", "close", "assign"]);
1104
997
  var TriageItemSchema = z3.object({
1105
998
  noteId: z3.string(),
1106
999
  /** The note's headline at run time. */
@@ -1234,20 +1127,6 @@ var PairingRevealSchema = z3.object({
1234
1127
  ed25519: z3.string(),
1235
1128
  nonce: z3.string()
1236
1129
  });
1237
- var DeviceCodeRequestSchema = z3.object({
1238
- /** The agent's suggested name for the pairing — the human sees it pre-filled at
1239
- * approval and can override. Optional; blank → a default silly name server-side. */
1240
- suggestedName: z3.string().optional(),
1241
- /** Legacy alias for suggestedName (older MCPs sent `agent`). Accepted for
1242
- * back-compat; `suggestedName` wins when both are present. ponytail: drop once no
1243
- * pre-`name` MCP is in the wild. */
1244
- agent: z3.union([z3.string(), z3.object({ name: z3.string().optional() })]).optional(),
1245
- device: z3.string().optional(),
1246
- proto: z3.string().optional(),
1247
- // compiled-in tag, e.g. "paigy-pair-v2|sas=24"
1248
- commitment: z3.string().optional()
1249
- // agent's Ca
1250
- });
1251
1130
  var DeviceCodeSchema = z3.object({
1252
1131
  device_code: z3.string(),
1253
1132
  user_code: z3.string(),
@@ -1281,11 +1160,6 @@ var DeviceInfoSchema = z3.object({
1281
1160
  phone_reveal: PairingRevealSchema.nullable().optional(),
1282
1161
  uik_pub: z3.string().nullable().optional()
1283
1162
  });
1284
- var DeviceTokenRequestSchema = z3.object({
1285
- device_code: z3.string(),
1286
- reveal: PairingRevealSchema.optional()
1287
- // agent's reveal {x25519, ed25519, nonce}
1288
- });
1289
1163
  var DeviceTokenSchema = z3.object({
1290
1164
  access_token: z3.string(),
1291
1165
  /** The pairing's single name (user-typed at approval, the agent's suggestion, or
@@ -1307,14 +1181,6 @@ var DeviceTokenSchema = z3.object({
1307
1181
  // present once the phone reveals
1308
1182
  uik_pub: z3.string().nullable().optional()
1309
1183
  });
1310
- var DeviceCommitRequestSchema = z3.object({
1311
- code: z3.string(),
1312
- commitment: z3.string()
1313
- // Cb
1314
- });
1315
- var DevicePeerCommitSchema = z3.object({
1316
- commitment: z3.string().nullable()
1317
- });
1318
1184
  var SupportRequestSchema = z3.object({
1319
1185
  email: z3.string().email().max(320),
1320
1186
  message: z3.string().trim().min(1).max(5e3),
@@ -1334,15 +1200,6 @@ var NotificationFeedbackKindSchema = z3.enum([
1334
1200
  "other"
1335
1201
  // anything else — the note carries it.
1336
1202
  ]);
1337
- var NotificationFeedbackSchema = z3.object({
1338
- notificationId: z3.string(),
1339
- kind: NotificationFeedbackKindSchema,
1340
- /** Optional free-text elaboration for a preset; required (non-empty) for 'other'. */
1341
- note: z3.string().trim().max(2e3).optional()
1342
- }).superRefine((r, ctx) => {
1343
- if (r.kind === "other" && !r.note)
1344
- ctx.addIssue({ code: z3.ZodIssueCode.custom, path: ["note"], message: "note is required for 'other' feedback" });
1345
- });
1346
1203
  var FeedbackResolutionSchema = z3.enum(["broker_fixed", "sent_to_agent"]);
1347
1204
  var FeedbackOutcomeSchema = z3.object({
1348
1205
  resolution: FeedbackResolutionSchema,
@@ -3617,9 +3617,9 @@ var UpdateGoalToolSchema = UpdateGoalSchema.omit({ operationId: true }).extend({
3617
3617
  var ClaimGoalSchema = z2.object({ goalId: z2.string().uuid().optional() }).strict();
3618
3618
  var GetGoalSchema = z2.object({ goalId: z2.string().uuid() }).strict();
3619
3619
  var GET_GOAL_DESCRIPTION = "Read the current authorized Goal brief: state, owner, blockers, open decisions, progress, and the next operation. Foreign or sibling-owned Goals are not disclosed.";
3620
- var UPDATE_GOAL_DESCRIPTION = "Update an owned Goal at an exact revision. State, ownership, dependencies, children, progress, and review acknowledgement are explicit; stale revisions are rejected. Returns the new revision and a prose summary.";
3620
+ var UPDATE_GOAL_DESCRIPTION = "Update an owned Goal at an exact revision. State, ownership, dependencies, children, progress, and review acknowledgement are explicit; stale revisions are rejected. reviewed: true acknowledges new evidence and closes the Deliveries addressed to you on that Goal, never over an open decision. Returns the new revision and a prose summary.";
3621
3621
  var CLAIM_GOAL_DESCRIPTION = "Claim the oldest runnable or review-pending Goal you own, or pass goalId to claim that Goal. Returns a Goal-scoped brief, current revision, blockers, and the next valid operation. Claiming creates or renews the execution lease.";
3622
- var CHECK_REPLIES_DESCRIPTION = "Your open Deliveries: every Notification or Call currently addressed to you \u2014 a request the user started toward you, an answer relayed to something you asked, a handoff \u2014 each with its durable Entries, accepted decisions and open decision needs, in the same shape a contact read returns. A pure read with no arguments: nothing is consumed, acknowledged or claimed by reading it, so call it on startup, after a long wait, or whenever you want to know what is outstanding. To act on one, claim its Goal (claim_goal) or reread it with contact({deliveryId}). Your runnable and review-pending Goals come from claim_goal, not from here.";
3622
+ var CHECK_REPLIES_DESCRIPTION = "Your open Deliveries: every Notification or Call currently addressed to you \u2014 a request the user started toward you, an answer relayed to something you asked, a handoff \u2014 one row each: its Goals, the newest words in brief, accepted decisions and open decision needs, without the Entries. A pure read with no arguments: nothing is consumed, acknowledged or claimed by reading it, so call it on startup, after a long wait, or whenever you want to know what is outstanding. To act on one, claim its Goal (claim_goal) or reread it in full with contact({deliveryId}). Once you have acted on what arrived, update_goal with reviewed: true closes the Deliveries addressed to you on that Goal. Your runnable and review-pending Goals come from claim_goal, not from here.";
3623
3623
  var CheckRepliesSchema = z2.object({}).strict();
3624
3624
  var GetThreadSchema = z2.object({
3625
3625
  parentId: z2.string().describe("The Thread to read \u2014 the threadId a Delivery returned, or the parentId of a search hit.")
@@ -4053,67 +4053,6 @@ var AwaitItemSchema = z3.discriminatedUnion("type", [
4053
4053
  inFlight: z3.boolean().optional()
4054
4054
  })
4055
4055
  ]);
4056
- var CallbackTriggerSchema = z3.enum(["on_done", "on_blocked", "scheduled"]);
4057
- var NotifyResponseSchema = z3.object({
4058
- notificationId: z3.string(),
4059
- workId: z3.string().uuid().optional(),
4060
- decisionId: z3.string().uuid().optional(),
4061
- status: NotifyStatusSchema,
4062
- createdAt: z3.string().datetime(),
4063
- answer: UserAnswerSchema.optional(),
4064
- answeredAt: z3.string().datetime().optional(),
4065
- /** Ride-alongs for THIS agent — pending work it should pick up when it's done with
4066
- * what it came for. Present on any reply, because an unwakeable agent's only
4067
- * reliable moment is one it initiated. Absent/empty = nothing owed. */
4068
- also: z3.array(RideAlongSchema).optional()
4069
- });
4070
- var NotifyPlanUnitSchema = z3.object({
4071
- notificationId: z3.string(),
4072
- /** The unit's own heading, so the agent can tell which of its paragraphs this became. */
4073
- title: z3.string(),
4074
- /** How loudly this unit was arbitrated to arrive — per unit, which is the point of units. */
4075
- level: NotifyLevelSchema,
4076
- /** Answered from something the user already decided: nobody is interrupted, and a trail card
4077
- * says so. The agent should not wait on this one. */
4078
- settled: z3.literal(true).optional(),
4079
- /** What this unit would need to be answerable and does not carry (#894). A PROPOSAL to the
4080
- * agent — nothing here changed the ask, and ignoring it costs nothing. */
4081
- needs: z3.array(z3.enum(["options", "visuals"])).optional(),
4082
- /** The SHAPE the broker would give this unit, for the agent to ratify (#886/#894). The
4083
- * split layer reads prose and can see that a paragraph is a yes/no or a pick-one — but a
4084
- * broker that DECIDES that destroys the only fact separating a statement from a real ask
4085
- * (#731), so it is offered, never applied: the unit is stored `text` until the agent
4086
- * confirms the shape (POST /notify/:id/confirm). Ignoring it costs nothing. */
4087
- proposal: z3.object({
4088
- select: SelectShapeSchema,
4089
- options: z3.array(z3.object({ label: z3.string().min(1) })).optional()
4090
- }).optional(),
4091
- /** What the broker READ this unit as wanting from the human (#952 layer 2): a `decision`
4092
- * between alternatives, an `approval` the agent is blocked on, or `knowledge` it just
4093
- * needs to know. Reported so the agent can correct a misread the same way it ratifies a
4094
- * shape — the read RAISES (a decision always asks) and never silences a question the
4095
- * agent declared (#731, #923). */
4096
- wants: z3.enum(["decision", "approval", "knowledge"]).optional()
4097
- });
4098
- var NotifyPlanSchema = z3.object({
4099
- units: z3.array(NotifyPlanUnitSchema),
4100
- /** Which unit is this arrival's ONE interruption (units-design.md D23). Absent means nobody
4101
- * was interrupted — every unit was either settled or quiet enough to sit in the inbox. */
4102
- speaks: z3.string().optional()
4103
- });
4104
- var UserResponseSchema = z3.object({
4105
- requestId: z3.string(),
4106
- answer: UserAnswerSchema,
4107
- answeredAt: z3.string().datetime(),
4108
- transcript: z3.string().optional(),
4109
- /** E2EE: the sealed answer (opaque envelope + plaintext `ignored` hint) when the item was
4110
- * E2EE-sealed. Present → the server persists it opaquely and branches status on `ignored`;
4111
- * the plaintext `answer` is a placeholder (`{ kind: "ignored" }`) the server ignores for a
4112
- * sealed row. Absent = today's plaintext answer, unchanged. */
4113
- sealed: z3.lazy(() => SealedAnswerSchema).optional(),
4114
- /** Coverage report (#396): which of the ask's declared `points` were addressed. */
4115
- covered: z3.array(z3.string()).optional()
4116
- });
4117
4056
  var VoiceKeySchema = z3.enum(["rachel", "george", "jessica", "brian", "lily"]);
4118
4057
  var AgendaTurnSchema = z3.object({
4119
4058
  /** THE TURN'S IDENTITY (the first-sentence stream, 2026-09-09): the brain call that wrote
@@ -4297,10 +4236,6 @@ var InboxItemSchema = z3.object({
4297
4236
  goalState: z3.string().optional()
4298
4237
  }).optional()
4299
4238
  });
4300
- var SnoozeRequestSchema = z3.object({
4301
- requestId: z3.string(),
4302
- until: z3.string().datetime()
4303
- });
4304
4239
  var APNS_TOKEN_RE = /^[0-9a-fA-F]{64}$/;
4305
4240
  var PushTokenSchema = z3.object({
4306
4241
  voipToken: z3.string().min(1).optional(),
@@ -4456,6 +4391,9 @@ var ConnectionSummarySchema = z3.object({
4456
4391
  * harness availabilities + granted workspaces — the option set the phone's
4457
4392
  * "new session" sheet offers. Absent for ordinary MCP agents. */
4458
4393
  runtime: z3.object({
4394
+ /** The @paigy/harness this host is running — a machine the self-update has not reached
4395
+ * shows its age here (`apps/desktop/src/update.ts`). */
4396
+ version: z3.string().optional(),
4459
4397
  harnesses: z3.array(z3.object({ name: z3.string(), label: z3.string(), status: z3.string() })).optional(),
4460
4398
  workspaces: z3.array(z3.string()).optional()
4461
4399
  }).optional(),
@@ -4518,19 +4456,6 @@ var MoveSchema = z3.object({
4518
4456
  * distilled from a clarify ruling (those carry no agent) or one whose source rows are gone. */
4519
4457
  learnedFrom: z3.object({ id: z3.string(), name: z3.string() }).nullable()
4520
4458
  });
4521
- var CreateRequestSchema = z3.object({
4522
- /** The connection (token id) to send to, from GET /api/tokens. */
4523
- tokenId: z3.string(),
4524
- /** The user's message to the agent. */
4525
- text: z3.string().min(1),
4526
- /** Land the request on an existing conversation thread (History → "Continue")
4527
- * instead of minting a fresh one. Must belong to the requesting user. */
4528
- parentId: z3.string().optional(),
4529
- /** Point the agent at a past conversation (possibly with a different agent) as
4530
- * starting context (History → "New session from this"). A reference, not a copy —
4531
- * the agent reads it via get_thread. Must belong to the requesting user. */
4532
- contextParentId: z3.string().optional()
4533
- });
4534
4459
  var QueueQuestionSchema = z3.object({
4535
4460
  /** The decision need's id — what an answer is accepted against. */
4536
4461
  id: z3.string(),
@@ -4622,38 +4547,6 @@ var NoteSchema = z3.object({
4622
4547
  lastRideAt: z3.string().nullable().default(null),
4623
4548
  createdAt: z3.string()
4624
4549
  });
4625
- var CreateNoteSchema = z3.object({
4626
- /** The intent, in the user's own words. Stored verbatim; the broker only titles it. */
4627
- text: z3.string().min(1).max(4e3),
4628
- /** Capture it as a REMINDER — a note assigned to the user themselves, which rides
4629
- * their next call instead of being handed to an agent. Everything else about the
4630
- * note is identical; this is the one parameter that separates the two. */
4631
- forMe: z3.boolean().optional(),
4632
- /** The not-before, when the user already said one. Absent = the very next call. */
4633
- dueAt: z3.string().datetime().optional(),
4634
- repeat: NoteRepeatSchema.optional()
4635
- });
4636
- var RecordDecisionSchema = z3.object({
4637
- /** An open decision (from /clarify) to answer. */
4638
- decisionId: z3.string().optional(),
4639
- /** For an ad-hoc decision: what was ambiguous. Required without `decisionId`. */
4640
- question: z3.string().min(1).max(500).optional(),
4641
- /** The ruling. */
4642
- answer: z3.string().min(1).max(2e3)
4643
- }).refine((d) => d.decisionId || d.question, { message: "decisionId or question required" });
4644
- var AssignNoteSchema = z3.object({
4645
- /** An EXISTING agent: token id or nickname. Omit when spawning fresh. */
4646
- target: z3.string().min(1).optional(),
4647
- /** Spawn a NEW session for this note (companion.md §2.2): the assignee doesn't
4648
- * exist yet — mint it on a live desktop that advertises the harness+workspace,
4649
- * named after the note. The brief arrives as its opening request. */
4650
- spawn: z3.object({
4651
- hostTokenId: z3.string().uuid(),
4652
- harness: z3.string().min(1),
4653
- workspace: z3.string().min(1)
4654
- }).optional()
4655
- }).refine((a) => !!a.target !== !!a.spawn, { message: "exactly one of target or spawn" });
4656
- var TriageVerdictSchema = z3.enum(["keep", "stale", "close", "assign"]);
4657
4550
  var TriageItemSchema = z3.object({
4658
4551
  noteId: z3.string(),
4659
4552
  /** The note's headline at run time. */
@@ -4789,20 +4682,6 @@ var PairingRevealSchema = z3.object({
4789
4682
  ed25519: z3.string(),
4790
4683
  nonce: z3.string()
4791
4684
  });
4792
- var DeviceCodeRequestSchema = z3.object({
4793
- /** The agent's suggested name for the pairing — the human sees it pre-filled at
4794
- * approval and can override. Optional; blank → a default silly name server-side. */
4795
- suggestedName: z3.string().optional(),
4796
- /** Legacy alias for suggestedName (older MCPs sent `agent`). Accepted for
4797
- * back-compat; `suggestedName` wins when both are present. ponytail: drop once no
4798
- * pre-`name` MCP is in the wild. */
4799
- agent: z3.union([z3.string(), z3.object({ name: z3.string().optional() })]).optional(),
4800
- device: z3.string().optional(),
4801
- proto: z3.string().optional(),
4802
- // compiled-in tag, e.g. "paigy-pair-v2|sas=24"
4803
- commitment: z3.string().optional()
4804
- // agent's Ca
4805
- });
4806
4685
  var DeviceCodeSchema = z3.object({
4807
4686
  device_code: z3.string(),
4808
4687
  user_code: z3.string(),
@@ -4836,11 +4715,6 @@ var DeviceInfoSchema = z3.object({
4836
4715
  phone_reveal: PairingRevealSchema.nullable().optional(),
4837
4716
  uik_pub: z3.string().nullable().optional()
4838
4717
  });
4839
- var DeviceTokenRequestSchema = z3.object({
4840
- device_code: z3.string(),
4841
- reveal: PairingRevealSchema.optional()
4842
- // agent's reveal {x25519, ed25519, nonce}
4843
- });
4844
4718
  var DeviceTokenSchema = z3.object({
4845
4719
  access_token: z3.string(),
4846
4720
  /** The pairing's single name (user-typed at approval, the agent's suggestion, or
@@ -4862,14 +4736,6 @@ var DeviceTokenSchema = z3.object({
4862
4736
  // present once the phone reveals
4863
4737
  uik_pub: z3.string().nullable().optional()
4864
4738
  });
4865
- var DeviceCommitRequestSchema = z3.object({
4866
- code: z3.string(),
4867
- commitment: z3.string()
4868
- // Cb
4869
- });
4870
- var DevicePeerCommitSchema = z3.object({
4871
- commitment: z3.string().nullable()
4872
- });
4873
4739
  var SupportRequestSchema = z3.object({
4874
4740
  email: z3.string().email().max(320),
4875
4741
  message: z3.string().trim().min(1).max(5e3),
@@ -4889,15 +4755,6 @@ var NotificationFeedbackKindSchema = z3.enum([
4889
4755
  "other"
4890
4756
  // anything else — the note carries it.
4891
4757
  ]);
4892
- var NotificationFeedbackSchema = z3.object({
4893
- notificationId: z3.string(),
4894
- kind: NotificationFeedbackKindSchema,
4895
- /** Optional free-text elaboration for a preset; required (non-empty) for 'other'. */
4896
- note: z3.string().trim().max(2e3).optional()
4897
- }).superRefine((r, ctx) => {
4898
- if (r.kind === "other" && !r.note)
4899
- ctx.addIssue({ code: z3.ZodIssueCode.custom, path: ["note"], message: "note is required for 'other' feedback" });
4900
- });
4901
4758
  var FeedbackResolutionSchema = z3.enum(["broker_fixed", "sent_to_agent"]);
4902
4759
  var FeedbackOutcomeSchema = z3.object({
4903
4760
  resolution: FeedbackResolutionSchema,
@@ -5607,6 +5464,7 @@ export {
5607
5464
  whoAmI,
5608
5465
  setIdentity,
5609
5466
  heartbeat,
5467
+ contact,
5610
5468
  checkReplies,
5611
5469
  runTool,
5612
5470
  subscribeWake
@@ -10,7 +10,7 @@ import {
10
10
  saveToken,
11
11
  sleep,
12
12
  startE2ee
13
- } from "./chunk-6QQHTUKJ.js";
13
+ } from "./chunk-JSQ6MXBI.js";
14
14
 
15
15
  // src/identity.ts
16
16
  var CLIENT_LABELS = {
package/dist/enable.js CHANGED
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  PAIGY_TOOL_IDS,
4
4
  enablePaigyTools
5
- } from "./chunk-4JDG67EF.js";
6
- import "./chunk-V3VVCML7.js";
7
- import "./chunk-6QQHTUKJ.js";
5
+ } from "./chunk-4KT2EBPI.js";
6
+ import "./chunk-AOQ2CNMG.js";
7
+ import "./chunk-JSQ6MXBI.js";
8
8
 
9
9
  // src/enable.ts
10
10
  function main() {
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  resolvePairing,
6
6
  startPairing,
7
7
  suggestedAgentName
8
- } from "./chunk-TNQOFCZC.js";
8
+ } from "./chunk-WW5Y5D42.js";
9
9
  import {
10
10
  ENABLE_COMMAND,
11
11
  OnboardSchema,
@@ -16,8 +16,8 @@ import {
16
16
  autoConfigureClients,
17
17
  claudeInstallHint,
18
18
  paigyToolsAllowlisted
19
- } from "./chunk-4JDG67EF.js";
20
- import "./chunk-V3VVCML7.js";
19
+ } from "./chunk-4KT2EBPI.js";
20
+ import "./chunk-AOQ2CNMG.js";
21
21
  import {
22
22
  clearSurface,
23
23
  writeSurface
@@ -38,7 +38,7 @@ import {
38
38
  setIdentity,
39
39
  slotName,
40
40
  whoAmI
41
- } from "./chunk-6QQHTUKJ.js";
41
+ } from "./chunk-JSQ6MXBI.js";
42
42
 
43
43
  // src/index.ts
44
44
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
package/dist/listen.js CHANGED
@@ -1,12 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  entryWords
4
- } from "./chunk-V3VVCML7.js";
4
+ } from "./chunk-AOQ2CNMG.js";
5
5
  import {
6
6
  checkReplies,
7
+ contact,
7
8
  getGoal,
8
9
  subscribeWake
9
- } from "./chunk-6QQHTUKJ.js";
10
+ } from "./chunk-JSQ6MXBI.js";
10
11
 
11
12
  // src/listen.ts
12
13
  import { spawn } from "child_process";
@@ -113,7 +114,7 @@ function uninstallService() {
113
114
  // src/listen.ts
114
115
  var emit = (obj) => void process.stdout.write(JSON.stringify(obj) + "\n");
115
116
  function saidIn(delivery) {
116
- return delivery.entries.filter((entry) => entry.kind === "contribution").map((entry) => entryWords(entry)).filter(Boolean).join("\n");
117
+ return ("entries" in delivery ? delivery.entries : []).filter((entry) => entry.kind === "contribution").map((entry) => entryWords(entry)).filter(Boolean).join("\n");
117
118
  }
118
119
  function launchEnv(waiting, reason, goalId) {
119
120
  const env = { PAIGY_WORK: JSON.stringify(waiting), PAIGY_EVENT: reason };
@@ -134,8 +135,10 @@ function launchEnv(waiting, reason, goalId) {
134
135
  async function sweep(reason, goalId) {
135
136
  try {
136
137
  const cmd = process.env.PAIGY_ON_WAKE;
137
- const { deliveries } = await checkReplies();
138
- const lead = (goalId ? deliveries.find((d) => d.goalIds.includes(goalId)) : void 0) ?? deliveries[0];
138
+ const { deliveries: rows } = await checkReplies();
139
+ const lead = (goalId ? rows.find((d) => d.goalIds.includes(goalId)) : void 0) ?? rows[0];
140
+ const full = lead ? await contact({ deliveryId: lead.deliveryId }, { waits: false }).catch(() => null) : null;
141
+ const deliveries = rows.map((d) => d === lead && full ? full : d);
139
142
  const leadGoalId = lead?.goalIds[0];
140
143
  const goal = leadGoalId ? await getGoal(leadGoalId).then((g) => ({ goalId: leadGoalId, contextThreadId: g.contextThreadId, progress: g.progress })).catch(() => null) : null;
141
144
  const waiting = { deliveries, goal };
package/dist/onboard.js CHANGED
@@ -3,13 +3,13 @@ import {
3
3
  resolvePairing,
4
4
  startPairing,
5
5
  suggestedAgentName
6
- } from "./chunk-TNQOFCZC.js";
6
+ } from "./chunk-WW5Y5D42.js";
7
7
  import {
8
8
  autoConfigureClients,
9
9
  claudeInstallHint,
10
10
  openBrowser
11
- } from "./chunk-4JDG67EF.js";
12
- import "./chunk-V3VVCML7.js";
11
+ } from "./chunk-4KT2EBPI.js";
12
+ import "./chunk-AOQ2CNMG.js";
13
13
  import {
14
14
  AGENT_NAME,
15
15
  TOKEN_PATH,
@@ -20,7 +20,7 @@ import {
20
20
  saveToken,
21
21
  setIdentity,
22
22
  whoAmI
23
- } from "./chunk-6QQHTUKJ.js";
23
+ } from "./chunk-JSQ6MXBI.js";
24
24
 
25
25
  // src/onboard.ts
26
26
  function reportRegistered() {
package/dist/slot.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  AGENT_NAME
4
- } from "./chunk-6QQHTUKJ.js";
4
+ } from "./chunk-JSQ6MXBI.js";
5
5
 
6
6
  // src/slot.ts
7
7
  process.stdout.write(AGENT_NAME);
@@ -9,7 +9,7 @@ import {
9
9
  readToken,
10
10
  sessionSlot,
11
11
  slotName
12
- } from "./chunk-6QQHTUKJ.js";
12
+ } from "./chunk-JSQ6MXBI.js";
13
13
 
14
14
  // src/statusline.ts
15
15
  import { mkdirSync, readFileSync, realpathSync, writeFileSync } from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paigy/mcp",
3
- "version": "0.40.3",
3
+ "version": "0.40.5",
4
4
  "description": "Paigy MCP server — the AI agent harness that calls you. Lets an agent notify a user and await their reply.",
5
5
  "license": "MIT",
6
6
  "type": "module",