@paigy/mcp 0.40.34 → 0.40.37

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.
@@ -4,12 +4,12 @@ import {
4
4
  serverInstructions,
5
5
  sessionStartHook,
6
6
  withSessionStartHook
7
- } from "./chunk-YIMNBJEF.js";
7
+ } from "./chunk-4UCAUMA3.js";
8
8
  import {
9
9
  CODEX_ENV,
10
10
  agentName,
11
11
  withCodexEnv
12
- } from "./chunk-5YTQF6KQ.js";
12
+ } from "./chunk-X5ICLVW3.js";
13
13
 
14
14
  // src/toolset.ts
15
15
  var CONFIGURE_DESCRIPTION = "Set this agent up with Paigy \u2014 call it FIRST, before contact, and any time you're unsure who you are. One call does whatever the situation needs: NOT SET UP \u2192 if this machine holds a device credential (the user ran the Paigy desktop app or harness) it hatches an identity INSTANTLY, no code and no approval; otherwise it starts the code ceremony. ALREADY SET UP \u2192 returns your current identity and the two things left to decide, renaming it or logging out. 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 (pick your own; 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.\n\nTHE CODE CEREMONY does not open a browser; the user enters the code in the Paigy app (or scans `qr`). A result with { user_code, device_code, qr, user_message } has already started polling for approval in the background: you MUST immediately print the `user_message` (the bare code) to the user, AND in that same turn call configure again with that `device_code` to collect the result. It returns the moment the user approves; on { status:'pending' } call again to keep waiting; on { status:'awaiting_confirmation' } (E2EE) show the bare `user_message` verify code and call again to finish. The leading text block of every result states the code plainly, so it shows even if you emit no prose.\n\nOn { status:'paired' }, or whenever it returns `enable_command`, ALWAYS follow the `enable_prompt`: PRINT that command for the user to run, so Paigy's tools stop prompting each time. 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.\n\nLOG OUT with { logOut: true }: it logs out THIS agent only \u2014 its token is revoked server-side and its local entry removed. Other agents and this device's credential are untouched, and a later configure re-hatches instantly while the device credential exists. Disconnecting the device itself is not an agent tool.";
@@ -1123,6 +1123,31 @@ var AgendaTurnSchema = z12.object({
1123
1123
  ifSilent: z12.boolean().optional()
1124
1124
  });
1125
1125
  var CLAIM_STALE_MS = 30 * 6e4;
1126
+ var CallQuestionSchema = z12.object({
1127
+ id: z12.string(),
1128
+ entryId: z12.string(),
1129
+ title: z12.string(),
1130
+ state: z12.enum(["open", "answered"]),
1131
+ answer: z12.string().nullable(),
1132
+ /** WHO ASKED IT (owner, 2026-09-23, Goal a345e906: each agenda row wears its agent's face) — the
1133
+ * request Entry's author, as the same three facts the item's own `tokenId`/`name`/`voice`
1134
+ * carry for the call's one agent, so the phone draws it with the same seed. Absent when the
1135
+ * author is not an agent this account holds (unpaired since, or a person). */
1136
+ agent: z12.object({ tokenId: z12.string(), name: z12.string(), voice: VoiceKeySchema.optional() }).optional(),
1137
+ /** ITS OPTIONS, WHEN THERE IS SOMETHING TO SEE (owner, 2026-09-25: "Yes, add it"): the options
1138
+ * its need offers, exactly as its own card carries them, present only when one of them has a
1139
+ * preview (`html` or `image`). The call screen opens them from the agenda row, so a preview is
1140
+ * never re-sent as a second card to be seen mid-call. Words-only options are `choices`. */
1141
+ options: z12.array(OptionSchema).optional(),
1142
+ /** ITS OPTIONS WHEN THEY ARE WORDS (owner, 2026-10-02, on a call: "whenever there are pre-made
1143
+ * options … now for a checklist, we should also show them on the screen"; design C, 2026-10-08):
1144
+ * numbered chips above the call's controls, so a checklist is never only something read aloud. A
1145
+ * field of its own so `options` keeps meaning "previews": a phone on an older bundle opens the
1146
+ * preview layout for any `options`, and must see exactly what it did. */
1147
+ choices: z12.array(OptionSchema).optional(),
1148
+ /** HOW MANY MAY BE PICKED, beside its `choices`: one, any (`many`) or an order (`rank`). */
1149
+ select: z12.enum(["one", "many", "rank"]).optional()
1150
+ });
1126
1151
  var InboxItemSchema = z12.object({
1127
1152
  id: z12.string(),
1128
1153
  tokenId: z12.string().optional(),
@@ -1164,31 +1189,10 @@ var InboxItemSchema = z12.object({
1164
1189
  * `turn` topic (`asking`, `settled`), because the bot never sees a DecisionNeed id. `title` is
1165
1190
  * the card's own concise heading; `answer` the accepted answer in words, null while open. It
1166
1191
  * REPLACED `agenda` (turns), which nothing ever filled. */
1167
- questions: z12.array(z12.object({
1168
- id: z12.string(),
1169
- entryId: z12.string(),
1170
- title: z12.string(),
1171
- state: z12.enum(["open", "answered"]),
1172
- answer: z12.string().nullable(),
1173
- /** WHO ASKED IT (owner, 2026-09-23, Goal a345e906: each agenda row wears its agent's face) — the
1174
- * request Entry's author, as the same three facts the item's own `tokenId`/`name`/`voice`
1175
- * carry for the call's one agent, so the phone draws it with the same seed. Absent when the
1176
- * author is not an agent this account holds (unpaired since, or a person). */
1177
- agent: z12.object({ tokenId: z12.string(), name: z12.string(), voice: VoiceKeySchema.optional() }).optional(),
1178
- /** ITS OPTIONS, WHEN THERE IS SOMETHING TO SEE (owner, 2026-09-25: "Yes, add it"): the options
1179
- * its need offers, exactly as its own card carries them, present only when one of them has a
1180
- * preview (`html` or `image`). The call screen opens them from the agenda row, so a preview is
1181
- * never re-sent as a second card to be seen mid-call. Words-only options are `choices`. */
1182
- options: z12.array(OptionSchema).optional(),
1183
- /** ITS OPTIONS WHEN THEY ARE WORDS (owner, 2026-10-02, on a call: "whenever there are pre-made
1184
- * options … now for a checklist, we should also show them on the screen"; design C, 2026-10-08):
1185
- * numbered chips above the call's controls, so a checklist is never only something read aloud. A
1186
- * field of its own so `options` keeps meaning "previews": a phone on an older bundle opens the
1187
- * preview layout for any `options`, and must see exactly what it did. */
1188
- choices: z12.array(OptionSchema).optional(),
1189
- /** HOW MANY MAY BE PICKED, beside its `choices`: one, any (`many`) or an order (`rank`). */
1190
- select: z12.enum(["one", "many", "rank"]).optional()
1191
- })).optional(),
1192
+ questions: z12.array(CallQuestionSchema).optional(),
1193
+ /** The same call carrying order, including request Entries with no DecisionNeed as reports.
1194
+ * Additive: questions stays decision-only for every other surface and older bundles. */
1195
+ callItems: z12.array(CallQuestionSchema.extend({ state: z12.enum(["open", "answered", "report"]) })).optional(),
1192
1196
  visuals: z12.array(VisualSchema).optional(),
1193
1197
  /** The connected agent's name (the single pairing name — user-typed, or the
1194
1198
  * agent's suggestion, or a default silly name). */
@@ -1387,12 +1391,29 @@ var UserSettingsSchema = z12.object({
1387
1391
  * clobber guard as voiceMode: absent = leave unchanged on write. */
1388
1392
  broker: BrokerTuningSchema.optional()
1389
1393
  });
1394
+ var GoalLatestSchema = z12.object({
1395
+ from: z12.enum(["person", "agent"]),
1396
+ said: z12.string(),
1397
+ at: z12.string(),
1398
+ entryId: z12.string(),
1399
+ /** ITS SUMMARY IN AT MOST TEN WORDS (owner, 2026-10-08: "the same switch to the more summarized sources
1400
+ * at the work tab top level screen too"): what the talker or filer wrote on the Entry; absent when
1401
+ * none was. The Work row reads it before `said`. */
1402
+ summary: z12.string().optional(),
1403
+ /** AN AGENT'S UPDATE OR QUESTION AS ITS UNITS' TITLES (owner, 2026-10-08: "send the 50 chars from the title
1404
+ * of each unit"): each at most 50 characters, in order; absent when it has none. */
1405
+ titles: z12.array(z12.string()).optional(),
1406
+ /** A PROGRESS NOTE'S ONE POINT ("An agent's progress note -> maybe let's cap it at 200 chars"): the
1407
+ * update's own line, before its units; the row caps it at 200. Absent on anything else. */
1408
+ line: z12.string().optional()
1409
+ });
1390
1410
  var HistoryWorkSchema = z12.object({
1391
1411
  id: z12.string(),
1392
1412
  title: z12.string(),
1393
1413
  state: z12.enum(["done", "cancelled"]),
1394
1414
  /** Who held it (`agent:<tokenId>` or `human:<userId>`). */
1395
- assignee: z12.string()
1415
+ assignee: z12.string(),
1416
+ latest: GoalLatestSchema.nullable().optional()
1396
1417
  });
1397
1418
  var HistoryEntrySchema = z12.union([
1398
1419
  z12.object({ at: z12.string(), card: InboxItemSchema }),
@@ -1460,7 +1481,7 @@ var ConnectionSummarySchema = z12.object({
1460
1481
  /** The @paigy/harness this host is running — a machine the self-update has not reached
1461
1482
  * shows its age here (`apps/desktop/src/update.ts`). */
1462
1483
  version: z12.string().optional(),
1463
- harnesses: z12.array(z12.object({ name: z12.string(), label: z12.string(), status: z12.string() })).optional(),
1484
+ harnesses: z12.array(z12.object({ name: z12.string(), label: z12.string(), status: z12.string(), models: z12.array(z12.string()).optional() })).optional(),
1464
1485
  workspaces: z12.array(z12.string()).optional(),
1465
1486
  /** THE GIT REPOS IN THOSE FOLDERS (2026-10-01, Goal 26982211): each granted folder that is a
1466
1487
  * repo, and each repo directly inside one, with its `origin` remote. A session started for
@@ -1620,22 +1641,7 @@ var QueueItemSchema = z12.object({
1620
1641
  * shows the moment it is written, and the agent's reply or next note replaces it by being newer.
1621
1642
  * `said` is bounded to 280 characters server-side (a line, not the conversation). Null when the
1622
1643
  * Goal carries no readable Entry; optional, so hand-built queues need not spell it. */
1623
- latest: z12.object({
1624
- from: z12.enum(["person", "agent"]),
1625
- said: z12.string(),
1626
- at: z12.string(),
1627
- entryId: z12.string(),
1628
- /** ITS SUMMARY IN AT MOST TEN WORDS (owner, 2026-10-08: "the same switch to the more summarized sources
1629
- * at the work tab top level screen too"): what the talker or filer wrote on the Entry; absent when
1630
- * none was. The Work row reads it before `said`. */
1631
- summary: z12.string().optional(),
1632
- /** AN AGENT'S UPDATE OR QUESTION AS ITS UNITS' TITLES (owner, 2026-10-08: "send the 50 chars from the title
1633
- * of each unit"): each at most 50 characters, in order; absent when it has none. */
1634
- titles: z12.array(z12.string()).optional(),
1635
- /** A PROGRESS NOTE'S ONE POINT ("An agent's progress note -> maybe let's cap it at 200 chars"): the
1636
- * update's own line, before its units; the row caps it at 200. Absent on anything else. */
1637
- line: z12.string().optional()
1638
- }).nullable().optional(),
1644
+ latest: GoalLatestSchema.nullable().optional(),
1639
1645
  /** WHEN THIS PERSON LAST PUT A HAND ON IT THEMSELVES (owner, Paigy Goal 16d18f51, 2026-09-30):
1640
1646
  * the newest Entry on the Goal they wrote, of any kind — a line they added, a reply to a note, an
1641
1647
  * answer to a question, a voice note filed as work. Null when the only hands on it have been its
@@ -1707,58 +1713,6 @@ var NoteSchema = z12.object({
1707
1713
  lastRideAt: z12.string().nullable().default(null),
1708
1714
  createdAt: z12.string()
1709
1715
  });
1710
- var TriageItemSchema = z12.object({
1711
- noteId: z12.string(),
1712
- /** The note's headline at run time. */
1713
- title: z12.string(),
1714
- /** WHY, in one short human line, evidence first — this is read on a phone underneath
1715
- * the note's title: "no movement in 34 days", "worked 3 notes in this repo this week".
1716
- * Never a model's reasoning transcript, never an id. */
1717
- why: z12.string()
1718
- });
1719
- var TriageAssignmentSchema = z12.object({
1720
- /** The agent's token id — what `dispatchNote` resolves and what a request is addressed to. */
1721
- agent: z12.string(),
1722
- /** Its display name at run time (the name on the hatchling's card). Denormalized for the
1723
- * same reason as `title`: the card must render from the proposal alone. */
1724
- agentName: z12.string(),
1725
- notes: z12.array(TriageItemSchema)
1726
- });
1727
- var TriageStatusSchema = z12.enum(["open", "superseded", "dismissed"]);
1728
- var SubmitTriageSchema = z12.object({
1729
- /** Which runtime judged: "ollama" (inference never left the machine) or a harness the
1730
- * user already runs under their own credentials ("claude" / "codex" / "agy"). Recorded
1731
- * so the phone can say where the content went — an unattributed privacy claim is worth
1732
- * nothing, and #1106's promise is precisely "Paigy's servers never see this". */
1733
- provider: z12.string().min(1).max(60),
1734
- /** The concrete model when the provider names one (an ollama tag); null otherwise. */
1735
- model: z12.string().max(200).nullable().optional(),
1736
- /** How many open notes the run actually looked at — the denominator on the phone
1737
- * ("6 of 50"), and the honest answer to "did it read the whole queue?". */
1738
- reviewed: z12.number().int().min(0).max(1e4).default(0),
1739
- close: z12.array(TriageItemSchema).max(200).default([]),
1740
- stale: z12.array(TriageItemSchema).max(200).default([]),
1741
- assign: z12.array(TriageAssignmentSchema).max(50).default([])
1742
- });
1743
- var TriageProposalSchema = SubmitTriageSchema.extend({
1744
- id: z12.string(),
1745
- runAt: z12.string(),
1746
- status: TriageStatusSchema,
1747
- model: z12.string().nullable().default(null)
1748
- });
1749
- var AcceptTriageSchema = z12.discriminatedUnion("group", [
1750
- z12.object({ group: z12.literal("close"), noteIds: z12.array(z12.string()).max(200).optional() }),
1751
- z12.object({ group: z12.literal("stale"), noteIds: z12.array(z12.string()).max(200).optional() }),
1752
- z12.object({
1753
- group: z12.literal("assign"),
1754
- agent: z12.string().min(1),
1755
- noteIds: z12.array(z12.string()).max(200).optional()
1756
- })
1757
- ]);
1758
- var AcceptTriageResultSchema = z12.object({
1759
- accepted: z12.array(z12.string()),
1760
- failed: z12.array(z12.object({ noteId: z12.string(), reason: z12.string() }))
1761
- });
1762
1716
  var DeliveryModeSchema = z12.enum(["poll", "self_hosted"]);
1763
1717
  var RegisterDeliverySchema = z12.object({ mode: DeliveryModeSchema });
1764
1718
  var OAuthStartSchema = z12.object({
@@ -2636,6 +2636,31 @@ var AgendaTurnSchema = z12.object({
2636
2636
  ifSilent: z12.boolean().optional()
2637
2637
  });
2638
2638
  var CLAIM_STALE_MS = 30 * 6e4;
2639
+ var CallQuestionSchema = z12.object({
2640
+ id: z12.string(),
2641
+ entryId: z12.string(),
2642
+ title: z12.string(),
2643
+ state: z12.enum(["open", "answered"]),
2644
+ answer: z12.string().nullable(),
2645
+ /** WHO ASKED IT (owner, 2026-09-23, Goal a345e906: each agenda row wears its agent's face) — the
2646
+ * request Entry's author, as the same three facts the item's own `tokenId`/`name`/`voice`
2647
+ * carry for the call's one agent, so the phone draws it with the same seed. Absent when the
2648
+ * author is not an agent this account holds (unpaired since, or a person). */
2649
+ agent: z12.object({ tokenId: z12.string(), name: z12.string(), voice: VoiceKeySchema.optional() }).optional(),
2650
+ /** ITS OPTIONS, WHEN THERE IS SOMETHING TO SEE (owner, 2026-09-25: "Yes, add it"): the options
2651
+ * its need offers, exactly as its own card carries them, present only when one of them has a
2652
+ * preview (`html` or `image`). The call screen opens them from the agenda row, so a preview is
2653
+ * never re-sent as a second card to be seen mid-call. Words-only options are `choices`. */
2654
+ options: z12.array(OptionSchema).optional(),
2655
+ /** ITS OPTIONS WHEN THEY ARE WORDS (owner, 2026-10-02, on a call: "whenever there are pre-made
2656
+ * options … now for a checklist, we should also show them on the screen"; design C, 2026-10-08):
2657
+ * numbered chips above the call's controls, so a checklist is never only something read aloud. A
2658
+ * field of its own so `options` keeps meaning "previews": a phone on an older bundle opens the
2659
+ * preview layout for any `options`, and must see exactly what it did. */
2660
+ choices: z12.array(OptionSchema).optional(),
2661
+ /** HOW MANY MAY BE PICKED, beside its `choices`: one, any (`many`) or an order (`rank`). */
2662
+ select: z12.enum(["one", "many", "rank"]).optional()
2663
+ });
2639
2664
  var InboxItemSchema = z12.object({
2640
2665
  id: z12.string(),
2641
2666
  tokenId: z12.string().optional(),
@@ -2677,31 +2702,10 @@ var InboxItemSchema = z12.object({
2677
2702
  * `turn` topic (`asking`, `settled`), because the bot never sees a DecisionNeed id. `title` is
2678
2703
  * the card's own concise heading; `answer` the accepted answer in words, null while open. It
2679
2704
  * REPLACED `agenda` (turns), which nothing ever filled. */
2680
- questions: z12.array(z12.object({
2681
- id: z12.string(),
2682
- entryId: z12.string(),
2683
- title: z12.string(),
2684
- state: z12.enum(["open", "answered"]),
2685
- answer: z12.string().nullable(),
2686
- /** WHO ASKED IT (owner, 2026-09-23, Goal a345e906: each agenda row wears its agent's face) — the
2687
- * request Entry's author, as the same three facts the item's own `tokenId`/`name`/`voice`
2688
- * carry for the call's one agent, so the phone draws it with the same seed. Absent when the
2689
- * author is not an agent this account holds (unpaired since, or a person). */
2690
- agent: z12.object({ tokenId: z12.string(), name: z12.string(), voice: VoiceKeySchema.optional() }).optional(),
2691
- /** ITS OPTIONS, WHEN THERE IS SOMETHING TO SEE (owner, 2026-09-25: "Yes, add it"): the options
2692
- * its need offers, exactly as its own card carries them, present only when one of them has a
2693
- * preview (`html` or `image`). The call screen opens them from the agenda row, so a preview is
2694
- * never re-sent as a second card to be seen mid-call. Words-only options are `choices`. */
2695
- options: z12.array(OptionSchema).optional(),
2696
- /** ITS OPTIONS WHEN THEY ARE WORDS (owner, 2026-10-02, on a call: "whenever there are pre-made
2697
- * options … now for a checklist, we should also show them on the screen"; design C, 2026-10-08):
2698
- * numbered chips above the call's controls, so a checklist is never only something read aloud. A
2699
- * field of its own so `options` keeps meaning "previews": a phone on an older bundle opens the
2700
- * preview layout for any `options`, and must see exactly what it did. */
2701
- choices: z12.array(OptionSchema).optional(),
2702
- /** HOW MANY MAY BE PICKED, beside its `choices`: one, any (`many`) or an order (`rank`). */
2703
- select: z12.enum(["one", "many", "rank"]).optional()
2704
- })).optional(),
2705
+ questions: z12.array(CallQuestionSchema).optional(),
2706
+ /** The same call carrying order, including request Entries with no DecisionNeed as reports.
2707
+ * Additive: questions stays decision-only for every other surface and older bundles. */
2708
+ callItems: z12.array(CallQuestionSchema.extend({ state: z12.enum(["open", "answered", "report"]) })).optional(),
2705
2709
  visuals: z12.array(VisualSchema).optional(),
2706
2710
  /** The connected agent's name (the single pairing name — user-typed, or the
2707
2711
  * agent's suggestion, or a default silly name). */
@@ -2900,12 +2904,29 @@ var UserSettingsSchema = z12.object({
2900
2904
  * clobber guard as voiceMode: absent = leave unchanged on write. */
2901
2905
  broker: BrokerTuningSchema.optional()
2902
2906
  });
2907
+ var GoalLatestSchema = z12.object({
2908
+ from: z12.enum(["person", "agent"]),
2909
+ said: z12.string(),
2910
+ at: z12.string(),
2911
+ entryId: z12.string(),
2912
+ /** ITS SUMMARY IN AT MOST TEN WORDS (owner, 2026-10-08: "the same switch to the more summarized sources
2913
+ * at the work tab top level screen too"): what the talker or filer wrote on the Entry; absent when
2914
+ * none was. The Work row reads it before `said`. */
2915
+ summary: z12.string().optional(),
2916
+ /** AN AGENT'S UPDATE OR QUESTION AS ITS UNITS' TITLES (owner, 2026-10-08: "send the 50 chars from the title
2917
+ * of each unit"): each at most 50 characters, in order; absent when it has none. */
2918
+ titles: z12.array(z12.string()).optional(),
2919
+ /** A PROGRESS NOTE'S ONE POINT ("An agent's progress note -> maybe let's cap it at 200 chars"): the
2920
+ * update's own line, before its units; the row caps it at 200. Absent on anything else. */
2921
+ line: z12.string().optional()
2922
+ });
2903
2923
  var HistoryWorkSchema = z12.object({
2904
2924
  id: z12.string(),
2905
2925
  title: z12.string(),
2906
2926
  state: z12.enum(["done", "cancelled"]),
2907
2927
  /** Who held it (`agent:<tokenId>` or `human:<userId>`). */
2908
- assignee: z12.string()
2928
+ assignee: z12.string(),
2929
+ latest: GoalLatestSchema.nullable().optional()
2909
2930
  });
2910
2931
  var HistoryEntrySchema = z12.union([
2911
2932
  z12.object({ at: z12.string(), card: InboxItemSchema }),
@@ -2973,7 +2994,7 @@ var ConnectionSummarySchema = z12.object({
2973
2994
  /** The @paigy/harness this host is running — a machine the self-update has not reached
2974
2995
  * shows its age here (`apps/desktop/src/update.ts`). */
2975
2996
  version: z12.string().optional(),
2976
- harnesses: z12.array(z12.object({ name: z12.string(), label: z12.string(), status: z12.string() })).optional(),
2997
+ harnesses: z12.array(z12.object({ name: z12.string(), label: z12.string(), status: z12.string(), models: z12.array(z12.string()).optional() })).optional(),
2977
2998
  workspaces: z12.array(z12.string()).optional(),
2978
2999
  /** THE GIT REPOS IN THOSE FOLDERS (2026-10-01, Goal 26982211): each granted folder that is a
2979
3000
  * repo, and each repo directly inside one, with its `origin` remote. A session started for
@@ -3133,22 +3154,7 @@ var QueueItemSchema = z12.object({
3133
3154
  * shows the moment it is written, and the agent's reply or next note replaces it by being newer.
3134
3155
  * `said` is bounded to 280 characters server-side (a line, not the conversation). Null when the
3135
3156
  * Goal carries no readable Entry; optional, so hand-built queues need not spell it. */
3136
- latest: z12.object({
3137
- from: z12.enum(["person", "agent"]),
3138
- said: z12.string(),
3139
- at: z12.string(),
3140
- entryId: z12.string(),
3141
- /** ITS SUMMARY IN AT MOST TEN WORDS (owner, 2026-10-08: "the same switch to the more summarized sources
3142
- * at the work tab top level screen too"): what the talker or filer wrote on the Entry; absent when
3143
- * none was. The Work row reads it before `said`. */
3144
- summary: z12.string().optional(),
3145
- /** AN AGENT'S UPDATE OR QUESTION AS ITS UNITS' TITLES (owner, 2026-10-08: "send the 50 chars from the title
3146
- * of each unit"): each at most 50 characters, in order; absent when it has none. */
3147
- titles: z12.array(z12.string()).optional(),
3148
- /** A PROGRESS NOTE'S ONE POINT ("An agent's progress note -> maybe let's cap it at 200 chars"): the
3149
- * update's own line, before its units; the row caps it at 200. Absent on anything else. */
3150
- line: z12.string().optional()
3151
- }).nullable().optional(),
3157
+ latest: GoalLatestSchema.nullable().optional(),
3152
3158
  /** WHEN THIS PERSON LAST PUT A HAND ON IT THEMSELVES (owner, Paigy Goal 16d18f51, 2026-09-30):
3153
3159
  * the newest Entry on the Goal they wrote, of any kind — a line they added, a reply to a note, an
3154
3160
  * answer to a question, a voice note filed as work. Null when the only hands on it have been its
@@ -3220,58 +3226,6 @@ var NoteSchema = z12.object({
3220
3226
  lastRideAt: z12.string().nullable().default(null),
3221
3227
  createdAt: z12.string()
3222
3228
  });
3223
- var TriageItemSchema = z12.object({
3224
- noteId: z12.string(),
3225
- /** The note's headline at run time. */
3226
- title: z12.string(),
3227
- /** WHY, in one short human line, evidence first — this is read on a phone underneath
3228
- * the note's title: "no movement in 34 days", "worked 3 notes in this repo this week".
3229
- * Never a model's reasoning transcript, never an id. */
3230
- why: z12.string()
3231
- });
3232
- var TriageAssignmentSchema = z12.object({
3233
- /** The agent's token id — what `dispatchNote` resolves and what a request is addressed to. */
3234
- agent: z12.string(),
3235
- /** Its display name at run time (the name on the hatchling's card). Denormalized for the
3236
- * same reason as `title`: the card must render from the proposal alone. */
3237
- agentName: z12.string(),
3238
- notes: z12.array(TriageItemSchema)
3239
- });
3240
- var TriageStatusSchema = z12.enum(["open", "superseded", "dismissed"]);
3241
- var SubmitTriageSchema = z12.object({
3242
- /** Which runtime judged: "ollama" (inference never left the machine) or a harness the
3243
- * user already runs under their own credentials ("claude" / "codex" / "agy"). Recorded
3244
- * so the phone can say where the content went — an unattributed privacy claim is worth
3245
- * nothing, and #1106's promise is precisely "Paigy's servers never see this". */
3246
- provider: z12.string().min(1).max(60),
3247
- /** The concrete model when the provider names one (an ollama tag); null otherwise. */
3248
- model: z12.string().max(200).nullable().optional(),
3249
- /** How many open notes the run actually looked at — the denominator on the phone
3250
- * ("6 of 50"), and the honest answer to "did it read the whole queue?". */
3251
- reviewed: z12.number().int().min(0).max(1e4).default(0),
3252
- close: z12.array(TriageItemSchema).max(200).default([]),
3253
- stale: z12.array(TriageItemSchema).max(200).default([]),
3254
- assign: z12.array(TriageAssignmentSchema).max(50).default([])
3255
- });
3256
- var TriageProposalSchema = SubmitTriageSchema.extend({
3257
- id: z12.string(),
3258
- runAt: z12.string(),
3259
- status: TriageStatusSchema,
3260
- model: z12.string().nullable().default(null)
3261
- });
3262
- var AcceptTriageSchema = z12.discriminatedUnion("group", [
3263
- z12.object({ group: z12.literal("close"), noteIds: z12.array(z12.string()).max(200).optional() }),
3264
- z12.object({ group: z12.literal("stale"), noteIds: z12.array(z12.string()).max(200).optional() }),
3265
- z12.object({
3266
- group: z12.literal("assign"),
3267
- agent: z12.string().min(1),
3268
- noteIds: z12.array(z12.string()).max(200).optional()
3269
- })
3270
- ]);
3271
- var AcceptTriageResultSchema = z12.object({
3272
- accepted: z12.array(z12.string()),
3273
- failed: z12.array(z12.object({ noteId: z12.string(), reason: z12.string() }))
3274
- });
3275
3229
  var DeliveryModeSchema = z12.enum(["poll", "self_hosted"]);
3276
3230
  var WAKE_EVENT = "wake";
3277
3231
  var wakeChannel = (tokenId) => `wake:${tokenId}`;
@@ -3834,39 +3788,6 @@ async function listConnections(opts = {}) {
3834
3788
  if (!res.ok) throw new Error(`list_connections failed: ${res.status} ${await res.text()}`);
3835
3789
  return await res.json();
3836
3790
  }
3837
- async function submitTriage(run, opts = {}) {
3838
- const res = await ensureAuthed(await reach(`${BACKEND_URL}/api/triage`, {
3839
- method: "POST",
3840
- headers: { "content-type": "application/json", authorization: `Bearer ${authToken(opts.token)}` },
3841
- body: JSON.stringify(run)
3842
- }));
3843
- if (!res.ok) throw new Error(`submit_triage failed: ${res.status} ${await res.text()}`);
3844
- return await res.json();
3845
- }
3846
- async function getTriage(opts = {}) {
3847
- const res = await ensureAuthed(await reach(`${BACKEND_URL}/api/triage`, {
3848
- headers: { authorization: `Bearer ${authToken(opts.token)}` }
3849
- }));
3850
- if (!res.ok) throw new Error(`get_triage failed: ${res.status} ${await res.text()}`);
3851
- return await res.json();
3852
- }
3853
- async function acceptTriage(proposalId, body, opts = {}) {
3854
- const res = await ensureAuthed(await reach(`${BACKEND_URL}/api/triage/${encodeURIComponent(proposalId)}/accept`, {
3855
- method: "POST",
3856
- headers: { "content-type": "application/json", authorization: `Bearer ${authToken(opts.token)}` },
3857
- body: JSON.stringify(body)
3858
- }));
3859
- if (!res.ok) throw new Error(`accept_triage failed: ${res.status} ${await res.text()}`);
3860
- return await res.json();
3861
- }
3862
- async function dismissTriage(proposalId, opts = {}) {
3863
- const res = await ensureAuthed(await reach(`${BACKEND_URL}/api/triage/${encodeURIComponent(proposalId)}/dismiss`, {
3864
- method: "POST",
3865
- headers: { authorization: `Bearer ${authToken(opts.token)}` }
3866
- }));
3867
- if (!res.ok) throw new Error(`dismiss_triage failed: ${res.status} ${await res.text()}`);
3868
- return await res.json();
3869
- }
3870
3791
  async function searchRecords(input, opts = {}) {
3871
3792
  const res = await ensureAuthed(await (opts.reach ?? reach)(`${BACKEND_URL}/api/records/search`, {
3872
3793
  method: "POST",
@@ -4084,6 +4005,7 @@ function conversation(e) {
4084
4005
  from: who(entry.authorParticipant),
4085
4006
  at: at(entry.createdAt),
4086
4007
  said: sealed ? "[encrypted]" : entryWords(entry).trim(),
4008
+ caveat: entry.callOngoing ? "Call ongoing; what the person decides may change." : void 0,
4087
4009
  units: askUnits(entry, e.entries ?? []).map((u) => `${u.title}: ${u.body}`),
4088
4010
  re: re ? handle(re) : void 0,
4089
4011
  options,
@@ -4621,10 +4543,6 @@ export {
4621
4543
  registerDelivery,
4622
4544
  listNotes,
4623
4545
  listConnections,
4624
- submitTriage,
4625
- getTriage,
4626
- acceptTriage,
4627
- dismissTriage,
4628
4546
  searchRecords,
4629
4547
  checkActivity,
4630
4548
  readDelivery,
@@ -6,7 +6,7 @@ import {
6
6
  saveToken,
7
7
  setIdentity,
8
8
  sleep
9
- } from "./chunk-5YTQF6KQ.js";
9
+ } from "./chunk-X5ICLVW3.js";
10
10
 
11
11
  // src/identity.ts
12
12
  var CLIENT_LABELS = {
@@ -13,7 +13,6 @@ import {
13
13
  RevokedError,
14
14
  TOKEN_PATH,
15
15
  UnpairedError,
16
- acceptTriage,
17
16
  acknowledge,
18
17
  agentName,
19
18
  authToken,
@@ -23,10 +22,8 @@ import {
23
22
  contact,
24
23
  currentRepo,
25
24
  deleteToken,
26
- dismissTriage,
27
25
  finishSessionEnd,
28
26
  getGoals,
29
- getTriage,
30
27
  hatch,
31
28
  heartbeat,
32
29
  isNetworkError,
@@ -61,12 +58,11 @@ import {
61
58
  sleep,
62
59
  slotIdentity,
63
60
  slotName,
64
- submitTriage,
65
61
  subscribeWake,
66
62
  updateSlot,
67
63
  whoAmI,
68
64
  withCodexEnv
69
- } from "./chunk-5YTQF6KQ.js";
65
+ } from "./chunk-X5ICLVW3.js";
70
66
  export {
71
67
  AGENT_TOOLS,
72
68
  AGENT_TOOL_NAMES,
@@ -82,7 +78,6 @@ export {
82
78
  RevokedError,
83
79
  TOKEN_PATH,
84
80
  UnpairedError,
85
- acceptTriage,
86
81
  acknowledge,
87
82
  agentName,
88
83
  authToken,
@@ -92,10 +87,8 @@ export {
92
87
  contact,
93
88
  currentRepo,
94
89
  deleteToken,
95
- dismissTriage,
96
90
  finishSessionEnd,
97
91
  getGoals,
98
- getTriage,
99
92
  hatch,
100
93
  heartbeat,
101
94
  isNetworkError,
@@ -130,7 +123,6 @@ export {
130
123
  sleep,
131
124
  slotIdentity,
132
125
  slotName,
133
- submitTriage,
134
126
  subscribeWake,
135
127
  updateSlot,
136
128
  whoAmI,
package/dist/enable.js CHANGED
@@ -3,9 +3,9 @@ import {
3
3
  PAIGY_TOOL_IDS,
4
4
  enablePaigyTools,
5
5
  installSessionListening
6
- } from "./chunk-VVQ4OQOB.js";
7
- import "./chunk-YIMNBJEF.js";
8
- import "./chunk-5YTQF6KQ.js";
6
+ } from "./chunk-3ECJXVIL.js";
7
+ import "./chunk-4UCAUMA3.js";
8
+ import "./chunk-X5ICLVW3.js";
9
9
 
10
10
  // src/enable.ts
11
11
  function main() {
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  resolvePairing,
10
10
  startPairing,
11
11
  suggestedAgentName
12
- } from "./chunk-7ZM5RGW4.js";
12
+ } from "./chunk-YEW373XZ.js";
13
13
  import {
14
14
  ConfigureSchema,
15
15
  ENABLE_COMMAND,
@@ -17,14 +17,14 @@ import {
17
17
  SERVER_INSTRUCTIONS,
18
18
  TOOLS,
19
19
  paigyToolsAllowlisted
20
- } from "./chunk-VVQ4OQOB.js";
20
+ } from "./chunk-3ECJXVIL.js";
21
21
  import {
22
22
  decideListen,
23
23
  existingListener,
24
24
  harnessDriven,
25
25
  listenerKey,
26
26
  wakeStatusPath
27
- } from "./chunk-YIMNBJEF.js";
27
+ } from "./chunk-4UCAUMA3.js";
28
28
  import {
29
29
  clearSurface,
30
30
  writeSurface
@@ -45,7 +45,7 @@ import {
45
45
  setClient,
46
46
  slotName,
47
47
  whoAmI
48
- } from "./chunk-5YTQF6KQ.js";
48
+ } from "./chunk-X5ICLVW3.js";
49
49
 
50
50
  // src/index.ts
51
51
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
package/dist/listen.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  removeListenMark,
12
12
  wakeStatusPath,
13
13
  writeListenMark
14
- } from "./chunk-YIMNBJEF.js";
14
+ } from "./chunk-4UCAUMA3.js";
15
15
  import {
16
16
  agentName,
17
17
  getGoals,
@@ -20,7 +20,7 @@ import {
20
20
  receive,
21
21
  slotName,
22
22
  subscribeWake
23
- } from "./chunk-5YTQF6KQ.js";
23
+ } from "./chunk-X5ICLVW3.js";
24
24
 
25
25
  // src/listen.ts
26
26
  import { createHash } from "crypto";
package/dist/onboard.js CHANGED
@@ -3,13 +3,13 @@ import {
3
3
  resolvePairing,
4
4
  startPairing,
5
5
  suggestedAgentName
6
- } from "./chunk-7ZM5RGW4.js";
6
+ } from "./chunk-YEW373XZ.js";
7
7
  import {
8
8
  autoConfigureClients,
9
9
  claudeInstallHint,
10
10
  openBrowser
11
- } from "./chunk-VVQ4OQOB.js";
12
- import "./chunk-YIMNBJEF.js";
11
+ } from "./chunk-3ECJXVIL.js";
12
+ import "./chunk-4UCAUMA3.js";
13
13
  import {
14
14
  TOKEN_PATH,
15
15
  agentName,
@@ -20,7 +20,7 @@ import {
20
20
  saveToken,
21
21
  setIdentity,
22
22
  whoAmI
23
- } from "./chunk-5YTQF6KQ.js";
23
+ } from "./chunk-X5ICLVW3.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
  agentName
4
- } from "./chunk-5YTQF6KQ.js";
4
+ } from "./chunk-X5ICLVW3.js";
5
5
 
6
6
  // src/slot.ts
7
7
  process.stdout.write(agentName());
package/dist/stalled.js CHANGED
@@ -29,7 +29,7 @@ async function main() {
29
29
  const dir = join(homedir(), ".paigy", "stalled-reminded");
30
30
  const mark = join(dir, `${session || "session"}-${day}`);
31
31
  if (existsSync(mark)) return;
32
- const { receive } = await import("./dist-HRRH3KO4.js");
32
+ const { receive } = await import("./dist-WIKMO2VH.js");
33
33
  const reply = stopReply((await receive()).stalled ?? [], input.hook_event_name ?? "Stop");
34
34
  if (!reply) return;
35
35
  mkdirSync(dir, { recursive: true });
@@ -7,7 +7,7 @@ import {
7
7
  readToken,
8
8
  sessionSlot,
9
9
  slotName
10
- } from "./chunk-5YTQF6KQ.js";
10
+ } from "./chunk-X5ICLVW3.js";
11
11
 
12
12
  // src/statusline.ts
13
13
  import { realpathSync } from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paigy/mcp",
3
- "version": "0.40.34",
3
+ "version": "0.40.37",
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",